← All posts

FloMorphic Is Now an MCP Server — Drive It From Claude or Any Agent

Point Claude, or any agent, at one URL and it can drive the whole platform: build flows, run them, query your stores, resume parked work.

FloMorphic now runs its own MCP server. It's mounted at /mcp, and it turns the platform into a set of tools an agent can call. Point Claude Desktop at it and you can ask it to build a workflow, run it, query one of your stores, or pick up a task someone left waiting — without opening the web app once.

One thing to clear up first, because the naming trips people up. FloMorphic has had an MCP node for a while: a node you drop into a flow that calls out to some external MCP server. There, FloMorphic is the client. What this post is about is the opposite job — FloMorphic as the server, so an agent can call in.

They share the protocol and nothing else. The two don't touch in the code, neither one runs through the other, and you can use either, both, or neither. If you've never gone near the MCP node, you're not missing any context here.


One endpoint, the whole surface

The server runs in-process, on the same API and the same store the web app uses. That detail is worth knowing, because of what it buys you: every tool is a thin wrapper over the exact call a REST handler makes. Nothing gets reimplemented, so a write over MCP and the same write from the web app are literally the same write. A flow an agent builds this way lays out, compiles, and runs like one you drew by hand.

It's on by default — set MCP_ENABLED=false to turn it off — and when you enable API auth, /mcp sits behind the same bearer token as every other route.


What your agent can do

Roughly forty-five tools, grouped by the surface they mirror. Read tools (list / get) exist for every entity; here are the ones that do something:

Workflows — author and validate

ToolWhat it does
flo_upsert_workflowCreate or update a workflow from a Vue-Flow graph — the same save the visual editor performs
flo_compile_workflowRun the inflow compiler over a candidate graph to validate it, without saving
flo_get_workflowFetch a flow, optionally with the lowered node graph it compiles to

AI designer — build a flow from a goal

ToolWhat it does
flo_get_design_guidePull the exact designer instructions the web app's build-with-AI dialog uses — node catalog, scope/branching rules, this install's plugin actions
flo_plan_patchConvert a readable graph patch into a Vue-Flow graph and compile it — no save, returns any design problems
flo_apply_patchSame conversion, then save it as a workflow

The agent designs a flow from the same brain a person does, then lands it through the same compiler and upsert. There's also a flo_design_workflow MCP prompt carrying that guidance for clients that surface prompts.

Runs — launch, watch, stop

ToolWhat it does
flo_start_processLaunch a run on the inflow engine (or schedule it for a future time)
flo_stop_processAsk the engine to stop a running run
flo_get_processInspect what a run did — status, error, request, timing, results

Context — the state a run reads and writes

ToolWhat it does
flo_upsert_contextCreate or edit a context document — the live state object a run reads and enriches
flo_get_contextSee what a process produced

Prompts — first-class, reusable assets

ToolWhat it does
flo_upsert_promptCreate or update a prompt template with documented {{variables}} and tags

Adding a prompt template through an agent is one of the primary reasons the server exists.

Memory — real databases your agent can query

This one tends to get overlooked. A document store is a real backing table with a schema you define, and the server hands it to your agent as a database it can read and write over MCP:

ToolWhat it does
flo_create_document_storeProvision a store: a table name and its column schema [{name, type, primary?}]
flo_query_documentsRun read-only SQL over the table — a single SELECT (or WITH…SELECT); writes, DDL, PRAGMA, and multi-statement input are rejected, and an unbounded query is capped at 1000 rows
flo_list_documentsPage through rows, newest first
flo_write_document / flo_update_document / flo_delete_documentStore, replace, or remove a JSON document
flo_create_vector_storeProvision a semantic store with a captured embedding config
flo_search_vectors / flo_index_vectorEmbed-and-search or embed-and-store, reusing that config

So your agent can literally "query the incidents table for everything still open this week" and get rows back — the SQL runs through the same guarded read path the platform uses, so a malformed or write query is refused rather than executed. Between the document store (structured SQL) and the vector store (semantic search), an agent has both a queryable database and a retrieval memory, over the same URL.

Human-in-the-loop — answer what parked

ToolWhat it does
flo_answer_human_taskRecord an answer to one of a task's questions
flo_close_human_taskClose a task — and for a parked flow, resume the workflow from where it stopped

Closing a task is the one action with a consequence beyond the record: it binds the outcome into the run's context and continues the flow. An agent can pick up a process a person left waiting.

Triggers & settings — wire it to fire again

ToolWhat it does
flo_set_webhook_triggerCreate the webhook that launches a flow from a public /hooks/<slug> URL
flo_set_schedule_triggerCreate a cron or interval schedule that starts a run and re-arms
flo_upsert_node_settingManage a node's reusable config profile (tokens, endpoints, providers)

Both trigger tools reuse the REST controller's normalization — slug minting, auth checks, scheduler re-arm — so an MCP-created trigger behaves identically to a web-app one.

The extension palette (flo_list_extensions / flo_get_extension) is browse-only: the live plugin proxy calls need a runtime, so MCP just reads the catalog.


Walkthrough 1 — a settings profile for a plugin or builtin node

Nodes rarely run naked. An LLM node needs a provider and key; a plugin node needs its access token; a HITL node needs a bot's model. In FloMorphic that reusable, named config is a node-settings profile, bound to a node's kind or plugin identity by its nodeUniqId — and an agent can create one with flo_upsert_node_setting.

The pattern is: browse the palette to find the node's identity, then upsert a profile against it.

1. flo_list_extensions            → find the node (builtin or imported plugin)
2. flo_get_extension { id }       → read its nodeUniqId and expected fields
3. flo_upsert_node_setting {
     nodeUniqId: "<the node/plugin identity>",
     nodeType:   "llm",           // or "plugin", "http", "hitl", …
     title:      "OpenAI – prod",
     settings:   { provider: "openai", model: "gpt-4o", token: "sk-…" }
   }

settings is a free-form key/value object, so the same tool profiles a builtin node (an LLM provider, an HTTP base URL) and an imported plugin (its access token or endpoint) — whatever that node's config expects. Once saved, any node of that kind can reference the profile by id, and flo_list_node_settings { node: "<nodeUniqId>" } lists the profiles available to one node — the exact list the web app's node drawer shows.


Walkthrough 2 — build a workflow, end to end

There are two ways to author a flow over MCP. The one worth reaching for is the AI designer, because it hands your agent the same guidance the web app's build-with-AI dialog uses instead of leaving it to guess the graph format.

1. flo_get_design_guide { goal: "summarize an incoming webhook
                                  and file it in a document store" }
   → the node catalog, scope/branching rules, $this per-row templating,
     wiring/joining rules, and THIS install's available plugin actions

2. flo_plan_patch { nodes: […], edges: […] }
   → converts your readable "graph patch" into a real Vue-Flow graph,
     compiles it, and returns a `problems` list flagging exactly the
     mistakes the guide warns about — fix them here, before saving

3. flo_apply_patch { title: "Webhook Filer", nodes: […], edges: […] }
   → same conversion, then SAVES it — identical to drawing it by hand

A patch is the readable authoring form: nodes are {ref, kind, title, key?, scope?, data?} where ref is a local name you invent and edges refer to nodes by ref. One node must be a startNode. The guide explains the two rules that bite hardest — a many-valued scope runs a node once per element (a queue inside one node, not a branch), and a wait-for-all join only belongs where two or more edges converge.

Prefer to build the Vue-Flow graph directly? flo_upsert_workflow takes raw nodes/edges and saves them (with flo_compile_workflow to validate a draft first). Either path runs the same normalizer and compiler the visual editor does, so the result is a first-class workflow.

Then wire it and run it, all still over MCP:

4. flo_upsert_context { title: "run state" }      → seed the state doc
5. flo_start_process  { flowId, contextId }       → launch it on the engine
6. flo_get_process    { indexId }                 → read status and results
7. flo_set_webhook_trigger { flowId, … }          → make it fire on its own

Your agent designed the flow, gave it state, ran it, read what happened, and armed it to fire again — without opening the app once.


Connect Claude Desktop

FloMorphic speaks Streamable HTTP, which Claude Desktop reaches through a custom connector:

  1. Start FloMorphic — the endpoint is at http://localhost:8025/mcp (swap host/port for your deploy).
  2. In Claude Desktop, open Settings → Connectors → Add custom connector.
  3. Paste the URL http://localhost:8025/mcp and save.
  4. If you run with AUTH_ENABLED=true, add your bearer token in the connector's header field as Authorization: Bearer <token>.

Claude will list the flo_* tools. Ask it to "list my workflows" or "build a flow that summarizes an incoming webhook and files it in a document store" and it'll call them.

Connect any other agent

For a client that reads a JSON config (or your own agent built on an SDK), point it at the same endpoint. If a client only speaks stdio, bridge it:

{
  "mcpServers": {
    "flomorphic": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:8025/mcp"]
    }
  }
}

Add --header "Authorization: Bearer <token>" to the args when auth is on. Any agent that speaks MCP — a coding assistant, an orchestration framework, your own loop — gets the same forty-five tools.


Why it's worth pointing an agent at

Two things set this apart from a bolted-on API wrapper.

The first is that it's the real surface, not a summary of it. Because each tool runs the same code path as the matching REST handler, there's no second implementation sitting around to drift out of sync. Whatever the product can do, the agent can do, and it stays that way on its own.

The second is that the read and write tools together close the loop with the runtime. An agent can look at what ran, what it produced, and what's still waiting — then act on it: launch a flow, stop one, resume a parked task, wire a trigger. Build a flow, run it, read the result, answer the human task it stopped on, all in one conversation.

And since it's the first question people ask: no, this has nothing to do with the MCP node. The node lets a flow call out to other people's tools; this server lets other people's agents drive FloMorphic. Opposite directions, no dependency between them. The only thing they share is the protocol.


Repo: github.com/FloMorphic/getting-started

Concepts and docs: inflowenger.com/flomorphic

Related reading: the two axes of extending an agent platform, why context is the unit of execution, and how a parked flow resumes as if no time had passed — the same resumption an agent can now trigger with flo_close_human_task.