MCP Server

Connect Claude Desktop, Claude Code, or any MCP-compatible client to your Zafeguard workspace. Execute workflows and components, and let your AI assistant build workflows on the canvas directly.

MCP Server

Zafeguard runs a Model Context Protocol (MCP) server alongside the SDK API. Point any MCP-compatible client — Claude Desktop, Claude Code, Cursor, or your own — at it and your AI assistant can:

  • Inspect workflows, components, and runs.
  • Execute workflows and components on demand.
  • Build workflows directly on the canvas — drop in components, position them, wire data ports and sequence edges, attach dynamic variables.

The server speaks the MCP Streamable HTTP transport over a single endpoint.

Endpoint

POST https://api.zafeguard.com/v1/mcp

Enabling MCP for a workspace

MCP is disabled by default on every workspace. To turn it on:

  1. Open Workspace Settings → scroll to MCP — AI agent access.
  2. Flip the toggle to on. A token like zmcp_abc12345… is generated and shown once.
  3. Copy the token immediately and paste it into your MCP client config. The raw value is shown once and never again — if you lose it, click Rotate token to issue a new one (the old one stops working instantly).

You can disable MCP at any time without losing the token; re-enabling later reactivates the same value. Requests to /v1/mcp from a disabled workspace are rejected with 401 Unauthorized — MCP is disabled for this workspace.

Authentication

MCP uses a workspace-specific MCP token (zmcp_…), not the SDK API key (ws_…). The token is dedicated to MCP traffic and can be rotated independently of your SDK keys.

Send:

HeaderValue
x-mcp-tokenYour workspace MCP token (zmcp_…)
Content-Typeapplication/json
Acceptapplication/json, text/event-stream

Anyone with the MCP token can run components, trigger workflows, and modify the canvas. Store it in your OS keychain or an environment variable — never check it into source control.

There is no Ed25519 request signing — MCP clients can't sign. Rate limits, monthly/weekly usage caps, and credit-debt rules still apply to MCP traffic.

Tools

All tools are scoped to the workspace that owns the MCP token. Tools that reference a workflowId verify the workflow belongs to your workspace before doing anything.

Help

ToolPurposeInput
helpCall FIRST. Returns operating instructions for this server plus links to the canonical llms.txt, the component catalog, and the live JSON Schema endpoint. Reading this once at the start of a session prevents wasted credits from guessed IDs or module names.— (none)

Read tools

ToolPurposeInput
list_workflowsList workflows in the workspacelimit?: number (default 50, max 100)
list_componentsList components in a workflow (ID, name, module, position, config)workflowId: uuid
list_component_connectionsList data wires + sequence edges in a workflowworkflowId: uuid

Execution tools

ToolPurposeInput
execute_workflowTrigger a workflow runworkflowId: uuid, input?: object
get_workflow_runGet run status, stages, outputsrunId: uuid
execute_componentRun a single component directlymodule: string, input: object, config?: object, callbackUrl?: string, callbackSecret?: string
get_component_executionGet component execution status/resultexecutionId: uuid

Workflow-builder tools

These let the agent construct workflows visually — same effect as drag-and-drop in the canvas editor.

ToolPurposeInput
rename_workflowChange a workflow's display nameworkflowId: uuid, name: string
delete_workflowSoft-delete a workflow (rejected when active runs exist)workflowId: uuid
create_componentAdd a component to a workflowworkflowId: uuid, module: string, name?: string, position?: [x, y]
move_componentChange canvas position onlyworkflowId: uuid, componentId: uuid, position: [x, y]
update_componentRename + reposition + patch configworkflowId: uuid, componentId: uuid, name?, position?, config?
delete_componentRemove a component (cascades wires)workflowId: uuid, componentId: uuid
connect_componentsWire a data input to an outputworkflowId, componentId, inputKey, outputComponentId, outputKey
disconnect_componentsRemove a data connectionworkflowId, componentId, connectionId
insert_forwarderSplit an existing data connection by inserting a FORWARDER relay node. Useful when crossing or overlapping connection lines hurt readability — place the forwarder somewhere convenient and the line bends through it. The original connection is removed and re-wired as source → forwarder.value → target.workflowId, targetComponentId, connectionId, position?: [x, y]
connect_sequenceWire a control-flow (sequence) edgeworkflowId, componentId, fromSequenceKey, nextComponentId, toSequenceKey
disconnect_sequenceRemove a sequence edgeworkflowId, componentId, edgeId
create_dynamic_variableAttach a dynamic input/output variableworkflowId, componentId, body
delete_dynamic_variableRemove a dynamic variableworkflowId, componentId, dynamicVariableId

Versioning tools

Agents can iterate on the draft and read history. Publishing a draft to live and restoring earlier versions are dashboard-only actions — not available via MCP.

ToolPurposeInput
revert_draftDiscard unpublished draft changes and rehydrate the draft from the currently-live version. Rejects with an error if the workflow has no published version yet.workflowId: uuid, message?: string (≤200 chars, recorded in history)
import_draftReplace the workflow draft with an uploaded JSON snapshot (matches the ExportWorkflowResponse shape). The imported content stays unpublished — the canvas shows "● unpublished changes" until a human publishes it.workflowId: uuid, data: { version, name, components[] }, filename?: string
list_workflow_versionsList surviving published versions, newest first. Each entry includes versionName (A.B.C), kind (PUBLISH or RESTORE), publishedAt, publishedByUser, notes, isLive, and snapshot byte size.workflowId: uuid
get_workflow_versionFetch a single published version including its full snapshot JSON. Useful for inspecting what a historical version actually contained.workflowId: uuid, versionNumber: number
list_workflow_historyUnified GitHub-commits-style activity feed: merges PUBLISH / RESTORE entries with REVERT / IMPORT events into one chronological list. Paginated.workflowId: uuid, limit?: number (max 200), offset?: number

All tools return their payload as a single text content block containing pretty-printed JSON.

Setup — Claude Desktop

Claude Desktop loads MCP servers from claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Add a zafeguard entry under mcpServers:

{
  "mcpServers": {
    "zafeguard": {
      "transport": "http",
      "url": "https://api.zafeguard.com/v1/mcp",
      "headers": {
        "x-mcp-token": "zmcp_your_workspace_mcp_token_here"
      }
    }
  }
}

Restart Claude Desktop. The Zafeguard tools should appear in the slash-command menu (/tools).

Setup — Claude Code

Add the server with the claude mcp add command:

claude mcp add --transport http zafeguard https://api.zafeguard.com/v1/mcp \
  --header "x-mcp-token=zmcp_your_workspace_mcp_token_here"

Or edit ~/.claude/mcp_servers.json directly with the same shape as the Claude Desktop config above.

Verify the connection:

claude mcp list
# zafeguard   http  https://api.zafeguard.com/v1/mcp   connected

Setup — generic HTTP client

Any client that can issue JSON-RPC over HTTP can talk to the server. Each request is a JSON-RPC 2.0 envelope. Example: list tools.

curl -X POST https://api.zafeguard.com/v1/mcp \
  -H "x-mcp-token: zmcp_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'

Call a tool:

curl -X POST https://api.zafeguard.com/v1/mcp \
  -H "x-mcp-token: zmcp_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "execute_workflow",
      "arguments": {
        "workflowId": "3f7a1b2c-...",
        "input": { "userId": "u_123", "amount": "100" }
      }
    }
  }'

Example prompts (Claude)

Once the server is connected, you can ask Claude natural-language questions:

"List the workflows in my Zafeguard workspace."

"Run the daily-treasury-sweep workflow with input { "vault": "0xabc..." } and tell me when it completes."

"Get the status of run 9e4c7b1a-.... If any stage failed, summarise the error."

"Build me a simple workflow that takes an EVM address as input, fetches its USDC balance, and emits the value. Place the trigger at [0,0], the balance check at [240,0], and wire the address through."

Claude picks the right tools, calls them with arguments inferred from your prompt, and renders responses.

Errors

The server returns standard JSON-RPC error envelopes:

Code / statusMeaning
-32600Invalid JSON-RPC request
-32601Method not found
-32602Invalid params (tool arguments failed Zod validation)
-32603Internal error
HTTP 401 — Missing MCP tokenNo x-mcp-token header
HTTP 401 — Invalid MCP token formatHeader present but doesn't start with zmcp_
HTTP 401 — Invalid MCP tokenToken does not match any workspace
HTTP 401 — MCP is disabled for this workspaceToken is valid but the workspace has MCP turned off
HTTP 429Rate limit, monthly usage cap, or insufficient credits

A 429 from a rate-limit hit includes a Retry-After header (seconds).

Security model

  • The token is dedicated to MCP — rotating it doesn't affect SDK API keys, and vice versa.
  • Only the SHA-256 hash and an AES-GCM-encrypted copy of the token are persisted. The plaintext only ever lives in your MCP client config.
  • Every tool closes over the workspace ID resolved from the token — there's no way for a tool argument to "escape" the workspace. Workflow-builder tools additionally verify the target workflow belongs to the same workspace before mutating it.
  • The endpoint is stateless: each request instantiates a fresh McpServer and tears it down on response close. No cross-request state.
  • The SDK's Ed25519 signing path remains the more secure option for server-to-server integrations — use it whenever you control both ends.

On this page