The API is workflows
Flowdrome’s AI integration isn’t a sidecar service bolted onto the product — it is built out of the product. The MCP endpoint and the Authoring REST API are implemented as two workflows you can open in the Studio and read, node by node:
AI client ──HTTP──▶ /mcp (transport only) ──▶ "MCP Server" workflow
AI client ──stdio─▶ relay (transport only) ──┘ │ svc:authoring-api/…
"Authoring API" workflow
│ platform SDK
▼
the Nucleus
MCP Server implements the Model Context Protocol as a graph: a routed HTTP trigger takes the
JSON-RPC POST, a parse node validates the envelope (notifications → 202, garbage → 400), a
Switch fans out on the method (initialize / tools/list / ping / tools/call), a second
Switch routes tools/call to one node per tool, and a shared finalize node shapes and
truncates every reply. The tool catalog an AI sees when it calls tools/list is served by a
node in that graph.
Authoring API implements the tools’ behavior: one routed trigger serving ten endpoints with
bearer auth on the trigger, one script branch per route speaking the platform SDK, and a graph
path for every status — bad token exits the unauthorized port into a 401 response node, an
invalid graph exits into a 422 with coded issues, a stale baseVersion into a 409.
The layers outside the canvas contain no protocol knowledge: /mcp forwards each message
verbatim to the MCP Server workflow, and the stdio relay pipes lines to /mcp. Both workflows
are seeded automatically on a fresh Nucleus, so all of this works out of the box.
The svc: URL scheme
The MCP Server’s tool nodes call the Authoring API the way any workflow calls another
first-class service workflow — with a svc: URL:
svc:authoring-api/catalog
svc:authoring-api/workflows/wf_123
svc:name/path routes to /api/svc/{slug} on the Nucleus, where slug is the target
workflow’s name lowercased and dashed (Authoring API → authoring-api). It is the
production-grade sibling of the mock: scheme: same mechanics —
a workflow answers the HTTP request — but named for what it is. Anything a node can do with a
URL (HTTP Request, integrations, script fetch) understands both.
Same trust model as mocks: the engine’s own workers reach /api/svc freely on loopback; remote
callers need a Nucleus token with Run capability.
Locked workflows
Both service workflows ship with "locked": true in their document — a flag any workflow can
carry:
- View-only everywhere. The Studio opens a locked workflow read-only: the canvas is
inspectable but inert (no dragging, wiring, deleting, or config edits), with a
Locked — view only badge. The server backstops the UI: any document write or delete
answers
423 Locked— that covers REST, the SDK, and AI agents alike. - Unlocking is a deliberate act. The only mutation a locked workflow accepts is
PUT /api/workflows/{id}/lockedwith{ "locked": false }, and it requires Manage capability — editing stays a separate, lesser permission. - It travels with the document.
lockedis a top-level field offlowdrome.workflow.v1, so it survives export/import and ships inside the auto-seeded system workflows.
Lock your own workflows the same way — a production flow nobody should touch, a template you hand to a team, or anything an agent builds that you want frozen after review.
Why build it this way?
Three reasons, in increasing order of importance:
- Transparency. There is no hidden middleware to trust — the entire API surface is readable on a canvas, and its error paths are wires you can follow.
- One engine. The API benefits from everything workflows get for free: run history with
full data capture, the debugger, versioning, the fleet. When an AI calls
create_workflow, that call is itself a run you can open and single-step. - Proof. If the platform’s own AI protocol server can be a workflow — JSON-RPC parsing, method dispatch, per-tool fan-out, response shaping — then the primitives (routed triggers, switches, script nodes, response nodes) are strong enough for whatever API you need to build on it.