Docs
API Reference

MCP Server

Connect Claude, ChatGPT, Claude Code, Cursor or your own agent to your organization's Agents, Flows and Apps over the Model Context Protocol, to run them, to build and publish them, and to provision end users.

MCP Server

Every organization has an MCP server. Connect an AI client to it and that client can run your published Agents, Flows and Apps as tools, create and edit them from your editor, and, for admins, manage end users, plans, groups and Portals. It is the same surface as the External API, shaped for a model to use.

https://builder.formwise.ai/api/v1/orgs/<your-org-slug>/mcp

Your organization's exact address, with a copy button and the setup snippets below filled in, is in Settings → API under MCP server.

Availability

The MCP server is available on the Pro and Agency plans. Every connection is tied to a member of your organization: what a client can do follows that member's role, and removing the member from the organization ends their connections on the next call.

Connecting

There are two ways to connect, depending on the client.

Sign in through the client

Clients with their own connector screen, such as Claude (web, desktop and mobile) and ChatGPT, take only the address. Paste it, and the client sends you to FormWise to sign in and approve the connection; nothing to copy.

  1. In the client, add a connector (Claude: Settings → Connectors → Add custom connector; ChatGPT: Settings → Connectors → Create).
  2. Paste your organization's MCP address.
  3. Sign in to FormWise when asked and approve. You are back in the client with the tools available.

Each connection appears under Connected apps in Settings → API, with the app's name, when it connected and when it was last used. Disconnect ends it immediately.

Paste a personal key

Clients that take a header, such as Claude Code, Cursor, VS Code and most agent frameworks, use a personal API key. Create one in Settings → API (see Authentication); it acts as you, with your role's permissions.

claude mcp add --transport http formwise https://builder.formwise.ai/api/v1/orgs/<your-org-slug>/mcp \
  --header "Authorization: Bearer fw_live_..."

Organization keys are not accepted by the MCP server: every connection must be a person. Use an organization key with the REST API for headless jobs instead.

What the client can do

The tool list is built for the connected member on every request, so a newly published Agent shows up on the next call and a tool the member's role doesn't allow is simply absent. Call whoami in any client to see the organization, your role and what you can do.

Every id argument also takes the object's exact name or slug (an end user's email, a Portal's entry key, a version's name), resolved inside your organization. When nothing matches, the error names up to five near matches so the model can correct itself in one step; when two objects share a name, it lists both with their ids. Ids from another organization, or from anything the connection cannot see, never resolve.

Agents and Apps

ToolWhat it does
list_agentsEvery published Agent and App, with ids
run_agentSend a message to an Agent or App by id
agent_<name>, app_<name>One dedicated tool per published Agent or App, so the client sees them by name, while you can run ten or fewer (see Choosing tool families)

A run returns a reply and a conversationId. A client that passes the id back continues the same conversation with the history restored on the server; omitting it starts fresh. Each run spends your organization's credits, exactly like a run in the builder.

Flows

ToolWhat it does
list_flowsEvery published Flow with the inputs it takes
run_flowRun a Flow by id with its inputs
flow_<name>One dedicated tool per published Flow whose parameters are the Flow's questions, under the same ten-or-fewer rule as the Agent tools

This is the part built for models. A Flow that asks for a company name, a plan tier and a team size becomes a tool with those three parameters, typed (choices become an enumeration, numbers are numbers, required questions are required), so the client fills them in and the Flow runs as if the person had submitted the form. Inputs are validated before anything runs or is charged. A Flow with no questions is talked to like an Agent.

Knowledgebases

Your Knowledgebases are searchable directly, with no Agent in between, so a connected client can look something up, quote its source, and file notes back for your Agents to use on later runs. The guide Use FormWise as a data layer walks through the loop client by client.

ToolWhat it does
list_knowledgebasesEvery Knowledgebase you can read, with source and page counts
search_knowledgebaseSearch documents, pages and your own memories, in one Knowledgebase or all of them; every result carries a citation
list_pages, read_pageThe page index of a Knowledgebase, and one page in full
list_sources, get_sourceThe ingested documents of a Knowledgebase and whether each is searchable; get_source is one document with its ingestion status brought up to date, for polling after an upload
list_changesWhat was added or updated since a point in time, oldest first, with a cursor to continue
create_knowledgebaseA new, empty Knowledgebase (members and above; plans may cap how many, and the tool says so)
save_page, append_pageFile notes: save_page creates a page (no id) or edits one in place with anchored operations (with id); append_page adds to the end of one (members and above)
upload_sourceAdd a document, not a note: inline markdown or text, or a public URL, indexed through the same path as a builder upload (members and above)
create_folder, move_pageGroup pages: make a folder, then create pages inside it or move existing ones in; list_pages shows the tree

A document uploaded with upload_source goes through exactly the path a file from the builder's Sources tab takes: the original is kept, the row is attached to the Knowledgebase under the plan's sources-per-Knowledgebase cap, and the indexing service is handed the content. Indexing is not instant, so the answer is processing with the source's id; get_source reports ready once it can be searched, and list_changes shows it as created and then ready. A URL is checked to be a public http(s) address before anything fetches it. When the organization reviews agent writes, an upload waits as pending_review in Monitor → Reviews, out of every search, until a person approves it (which starts indexing) or rejects it (which deletes it). The Sources tab marks documents added this way "via MCP" or "via API". Indexing is free; the same holds for POST /v1/knowledgebases/{id}/sources, which also takes a file as multipart/form-data.

Searching documents spends one of your organization's credits per call; pages, reads and the changes feed are free, and the tool says so. Pages are also offered as resources (formwise://knowledgebases/<id>/pages/<page-id>), so clients that support resources can attach a page as context without a tool call. There is no delete over MCP. Edits are anchored: save_page with an id takes a list of operations (replace, insert before or after, prepend, append, replace a range) that name the exact text to change, each anchor must appear exactly once, and a miss refuses the whole call with nothing changed, so the model never re-sends a page it has only partly read. When your organization reviews agent writes a write comes back as pending_review and waits for a person in the dashboard. Pages written this way are read by your Agents later, so the tools tell the model to treat content copied from the web or from messages as untrusted before saving it.

One tool to create or update

Creating and updating are the same tool: save_agent, save_flow, save_app and save_page create when called without an id and update the draft (or page) when called with one, the way Linear's save_issue works. Fewer tools means less schema in every request and fewer wrong picks. The earlier create_*, update_* and edit_page names are still accepted for one release and mapped on arrival, marked the same way as legacy argument names; they no longer appear in the tool list.

Argument names

Every tool argument and result field is camelCase (knowledgebaseId, pageId, conversationId, nextCursor), the same spelling as the REST authoring and Knowledgebase endpoints. The snake_case names the run and knowledge tools shipped with, and notebookIds on set_agent_knowledge, are still accepted for one release and mapped on arrival; a call that uses them is marked +legacy in the knowledgebase activity log so you can see when your clients have moved over.

Keeping answers small

Every list tool pages: it answers { items, nextCursor }, takes limit (default 50, max 200) and cursor, and a walk with the cursor is gapless because the cursor names the last item handed out rather than a position. fields keeps only the named fields on each item, and an unknown name is refused with the list of valid ones, so the model never guesses. list_pages and the list_authored_* tools also take updatedSince.

The big reads take view. The default, summary, is what a model plans with: get_flow_draft returns the questions, inputs and a node outline without the node document; get_agent_draft and get_app_draft preview their long texts (the first 2 KB, with the total size) and count starters and test cases; read_page previews the markdown; get_execution names the tools called without their arguments. Pass view: "full" when the whole thing is needed, which is always the case before an anchored patch.

Choosing tool families

MCP has no lazy loading: every tool's schema reaches the model on every request, and a model picks the right tool less reliably as the list grows. A connection can therefore ask for only the families it needs. The tools are grouped into five:

FamilyWhat it holds
runlist_agents, run_agent, list_flows, run_flow, get_execution
authoringDrafts, versions, publishing, testing, integrations and templates for Agents, Flows and Apps
knowledgeEverything under Knowledgebases
provisioningEnd users, groups, plans and Portals (admins)
agentsThe dedicated agent_<name>, app_<name> and flow_<name> tools

Add ?tools= to the address with a comma-separated list, for example …/mcp?tools=knowledge,run for a research client or …/mcp?tools=run for an operator that only runs what is already published. The Connect card in Settings → API offers the choice as checkboxes and writes it into the address and every setup snippet; a client that signs in through a browser sees the requested families on the approval screen. A personal key created while a choice is made remembers it, so that key registers the same families at the plain address. whoami and search_docs are always present, and whoami reports toolFamilies, so a model can explain why a tool is missing.

The choice only narrows. Your role still decides what a family may contain, a family the role does not allow registers nothing, an unknown family name is refused with the valid ones, and the address and the key's stored list combine as their intersection.

The dedicated agents family has one more rule: it is registered only while the connection can run ten or fewer published Agents, Apps and Flows in total. Past that, list_agents and run_agent (and the Flow pair) carry the load, so a large organization never pushes dozens of schemas into every request. run_agent and run_flow always reach everything that is published.

Limiting a connection to some Knowledgebases

A role is all or nothing: a member who can read Knowledgebases can read every one the organization has. A connection does not have to be. When you create a personal key with the Knowledgebases family on, the Connect card offers Knowledgebases a key may reach: leave it at all of them, or tick the ones this key is for, and the key can then list, search, read and write those and nothing else. A client that signs in through a browser makes the same choice on its approval screen, and the approval names what was chosen. Organization API keys under API keys take the same choice, which applies to the REST endpoints under /v1/knowledgebases too.

The list only narrows. It is checked against the organization when it is saved, so a key never names a Knowledgebase that is not yours, and it is intersected with the organization's Knowledgebases on every call, so one that is later deleted simply drops out. A Knowledgebase outside the list answers not_found, the same as one that does not exist, and a search over all never includes it. search_agent_knowledge previews only the attached Knowledgebases inside the list. whoami reports knowledgebases as "all" or the list of ids, so a model can explain a short list_knowledgebases. Existing keys and connections are unchanged.

Retrying a create

A client that times out and retries a create would make two pages, two drafts, two end users. Every create (save_page, create_folder, create_knowledgebase, save_agent, save_flow and save_app without an id, provision_end_user) takes an idempotencyKey: any unique string up to 64 characters. A retry with the same key within 24 hours returns the first result again, marked replayed: true, and writes nothing; the same key with different arguments is conflict. Keys are scoped to your organization and to the tool, so the same key on create_folder and on save_page is two requests. The REST API takes the same thing as an Idempotency-Key header.

How the tools describe themselves

Every tool's description follows one checklist so a model can act on it without guessing: a title, at most 600 characters, the cost named in one sentence (Free. or Spends the organization's credits.), every id argument naming the tool that hands the id out, every pair of arguments that cannot be combined saying so on both halves, and the recovery step for each error it can return (not_found names the list tool to call; conflict says to read again). The server instructions carry the rules that apply to every call: send real newlines rather than the two characters , read before you write, pass expectedUpdatedAt on edits and an idempotencyKey on a create you might retry.

The docs

Every connection also gets search_docs: this documentation, searchable from the client, so the model answers "how does FormWise handle X" from a page it can cite rather than from memory. It reads the same index the search box on this site uses, touches none of your organization's data, and is free.

End users, groups, plans and Portals (admins)

Members with the admin or owner role also get the provisioning tools: list and provision end users, list plans, create and manage user groups and their members and grants, list Portals, and admit or un-admit groups at a Portal. They mirror the REST provisioning endpoints one for one, and every change is recorded against the member who made it. Removals are marked as destructive so agent clients confirm before acting; creates and additions are safe to retry.

Build and edit from your editor

Members with the member role or above can also create, edit, test and publish the organization's own Agents, Flows and Apps through the same server, so Claude Code, Cursor or a script can manage them. The tools appear only for a caller whose key carries the write scope (agents:write, flows:write, apps:write) and whose current role allows it; viewers never see them, and only admins and owners see delete_*.

Drafts and publishing

Every edit changes a draft. Nothing reaches end users until you publish, and publishing is always an explicit call: publish_agent, publish_flow or publish_app. That makes the loop safe to run from a model:

  1. get_agent_draft, get_flow_draft or get_app_draft to read the current draft. Each returns updatedAt.
  2. Edit with save_agent or save_app (pass the id; without one they create), or the Flow tools (save_flow for the name, set_flow_questions, add_flow_node, update_flow_node, delete_flow_node, replace_flow_workflow). Pass the updatedAt you read as expectedUpdatedAt; if someone else changed the draft in the meantime the call is refused with conflict and nothing is written. Read again and retry. Long prompts are edited in place rather than re-sent: save_agent takes systemInstructionPatch and update_flow_node takes promptPatch, the same anchored operations as edit_page, applied to the prompt as it currently is.
  3. run_draft runs the unpublished draft once, billed to the organization like any run. Its conversations never mix with the published version's. The result carries a trace: which model ran, the names of the pieces the prompt was built from, the tools available and called, and the credits spent. get_execution returns the same trace for any run by its executionId.
  4. run_test_cases runs up to ten cases through the quality judge, using the tool's rubric or each case's expectedBehavior, and reports pass or fail per case with the agent node to fix. Save cases once with set_test_cases (or have generate_test_cases propose them) and a rubric with set_quality_rubric; then run_test_cases with no cases runs the saved suite. compare_models runs the same suite on two to four models and reports pass rate, latency and credits per run. All of these need the quality checker on your plan.
  5. diff_agent_draft shows what publishing would change for end users: the prompt as a unified diff, then model, capabilities, sub-agents, integrations and starters.
  6. publish_* snapshots the draft as a new version and makes it live. list_*_versions shows every version and who published it; restore_*_version re-publishes an earlier one; revert_*_draft undoes the last edit.

An App can only be published once its adviser and every member are published; the refusal lists what to publish first. Models are chosen from list_models, which returns each model's engine, purpose, credits per run and capabilities, the builder's presets, and marks the ones your organization cannot use.

Building an Agent

Read the resource agent://guide (also get_agent_guide) first. It explains how the run-time prompt is composed from your instructions and the platform's pieces, what each built-in capability does and costs, the defaults a new Agent gets (web search and web scrape are on until you turn them off), and a prompt skeleton. list_agent_templates offers starting points, each with instructions, identity, capabilities, starters and test cases that work together; pass one as template to save_agent and override any field.

An Agent needs things to know and to do. set_agent_knowledge attaches Knowledgebases, and search_agent_knowledge shows what the Agent's own retrieval returns for a question, before anyone asks it.

For services, describe the job to suggest_integrations ("send the invoice by email", "log the call in the CRM") and it returns the toolkits and the exact actions that do it, each marked connected or not, with a suggested approval level per action. list_integrations is the keyword search for a name you already know, and get_integration_actions lists one toolkit's actions. set_agent_integrations attaches them to an Agent, naming the actions and when the end user must approve each; set_flow_node_integrations does the same for an agent node inside a Flow. When a toolkit is not connected yet, the result carries a connectUrl (admins and owners; get_connect_link mints one on its own). Give the link to the person: it opens the same sign-in the builder's popup runs, and once they finish, the Agent can use the service. Attaching a toolkit also enables it for your organization's runs, the same step the builder takes when it connects one.

Writing a Flow from scratch

A Flow is a document of ordered nodes. The server publishes its schema as the resource flow://schema (also get_flow_schema): the document shape and rules, every node type with its fields and an example, and the question types. A Flow's questions are its run parameters, so set_flow_questions is also how you define what a caller passes.

Activity

Every change made this way is recorded with who made it, from which surface (dashboard, API, MCP or the assistant) and what changed, under Monitor → Activity → Tool changes. Each draft also reports its last change, and each version its publisher.

A snippet for your CLAUDE.md

Call get_setup_snippet and paste the result into your repository's CLAUDE.md (or any agent instructions file). It tells a coding agent to read before it writes, to test before it publishes, and to ask before it deletes. The same operations are available as plain HTTP under /v1 for scripts and CI.

The Portal-level server

Your end users get their own MCP server, per Portal, at the Portal's address followed by /mcp (on a custom domain, on that domain). It exposes the Agents, Flows and Apps their plan unlocks, runs spend their plan's credits, and it is whitelabeled: nothing in it names FormWise. It is off by default. Turn it on per Portal under the Portal's access settings (Allow MCP connections), and mark which plans include it in the plan editor (Include MCP access). Once both are on, subscribers find their connection address and their connected apps under Account settings → Connected apps in the Portal.

End users connect the same two ways members do. Clients with a connector screen (Claude, ChatGPT) sign in through the Portal's own sign-in and approve the connection. Clients that take a header (Claude Code, Cursor, scripts) use a personal API key the end user creates on the same card, with ready-to-paste snippets. Keys carry a neutral sk_live_ prefix, belong to one person at one Portal, and are checked against that person's standing and plan on every request, so a key stops working when the plan lapses and starts again when it is renewed. Each person can hold up to five keys per Portal and revoke any of them there.

Without MCP

The same capabilities are plain HTTP. The OpenAPI specification works with generic OpenAPI-to-MCP bridges and typed client generators if you would rather integrate that way.

On this page