06 / Integrations

Model Context Protocol (MCP) — Server & Client

On this page 14

Synaplan speaks MCP in both directions:

  • As an MCP server, Synaplan lets AI clients — Claude, Cursor, VS Code, and any other Model Context Protocol host — use your Synaplan workspace as a set of tools, with one connection and one API key.
  • As an outbound MCP client, Synaplan connects to your external MCP servers (a CRM, a wiki, Jira / Confluence, an n8n endpoint, …) and lets the multi-task planner pull live data from them into an answer — and, when you allow write actions on a server, create tickets or pages. Per user, per assistant.

Status: Early access. Today's server tools are synaplan_chat (the full AI pipeline), rag_search, rag_similar, memory_search, memory_add, file_ingest, list_chats, get_messages, list_prompts and list_assistants, plus resources (your documents and memories) and prompts (your task prompts). Administrators additionally get recent_errors (the redacted troubleshooting ring). A few extras are on the roadmap, and the protocol surface may still change.

Why MCP (beyond the REST API)#

The REST API and OpenAI-compatible endpoints are ideal when you write the integration. MCP is different: the client discovers what Synaplan can do and calls it automatically — no per-client glue code. Point a compatible host at one URL and your Synaplan knowledge base and memories become tools the model can use on its own.

Endpoint#

Transport Streamable HTTP (MCP protocol 2025-11-25)
Production POST https://web.synaplan.com/mcp
Development POST http://localhost:8000/mcp
Discovery GET https://web.synaplan.com/.well-known/oauth-protected-resource/mcp

Authentication#

Authenticate every request with a Synaplan API key (create one under Manage → Developer & devices → API Keys). Either header works:

  • X-API-Key: YOUR_SYNAPLAN_API_KEY
  • Authorization: Bearer YOUR_SYNAPLAN_API_KEY

Enterprise SSO deployments may also send an OIDC bearer token (Keycloak). Unauthenticated requests receive a 401 with a WWW-Authenticate header pointing at the RFC 9728 Protected Resource Metadata document, so OAuth-capable clients can discover the authorization server automatically.

Every call is scoped to the account that owns the key — tools only ever see that user's documents and memories.

Connect a client#

Most MCP hosts let you add a remote (HTTP) server with custom headers. The configuration usually looks like this:

json
{
  "mcpServers": {
    "synaplan": {
      "url": "https://web.synaplan.com/mcp",
      "headers": {
        "X-API-Key": "YOUR_SYNAPLAN_API_KEY"
      }
    }
  }
}

The exact file and location depend on the client (Claude Desktop, Cursor, VS Code, …) — use your host's "add remote MCP server" flow and supply the URL and header above.

Available tools#

Tool Description Arguments
synaplan_chat Send a message through Synaplan's full AI pipeline — intent classification → web search → RAG over your documents → long-term memories → inference — and get a synthesized answer. The conversation is saved and appears in list_chats. message (required), chat_id (optional — continue an existing conversation)
rag_search Semantic search across your vectorized documents and knowledge base. query (required), limit (1–50, default 10), min_score (0–1, default 0.3), group_key
memory_search Search your stored long-term memories (preferences, facts, context). query (required), category, limit (1–50, default 5)
rag_similar Find chunks similar to a given document, by the message_id returned from rag_search. message_id (required), limit (1–50, default 10)
memory_add Store a new long-term memory (a durable fact or preference) for the user. category (required), key (required, min 3 chars), value (required)
file_ingest Add a text document to the user's knowledge base — chunked, embedded, and stored so it becomes retrievable via rag_search. name (required), content (required), group_key
list_chats List the user's conversations (most recently updated first). limit (1–200, default 50)
get_messages Read the messages of one of the user's chats, in chronological order. chat_id (required), limit (1–100, default 50)
list_prompts List the user's task prompts (internal tools:* prompts excluded). (none)
list_assistants List the published assistants the user may talk to, with the assistant:{slug} alias a client can pass to pin one. Present when assistants are enabled. (none)
recent_errors Administrators only. The redacted ring of recent server-side errors and notable events, for troubleshooting an install from an AI client. Every field is allow-listed; free text is never returned raw. mode (summary = counts by level / event / route, or a detail list), level, query, request_id filters

Each tool returns both human-readable text and structured JSON.

Try it with cURL#

MCP uses JSON-RPC 2.0 over a single endpoint. The flow is initialize → tools/list → tools/call.

1. Initialize — returns an Mcp-Session-Id response header to reuse:

shell
curl -i -X POST https://web.synaplan.com/mcp \
     -H "X-API-Key: YOUR_SYNAPLAN_API_KEY" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

2. List tools — replace SESSION with the Mcp-Session-Id from step 1:

shell
curl -X POST https://web.synaplan.com/mcp \
     -H "X-API-Key: YOUR_SYNAPLAN_API_KEY" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -H "MCP-Protocol-Version: 2025-11-25" \
     -H "Mcp-Session-Id: SESSION" \
     -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

3. Call a tool:

shell
curl -X POST https://web.synaplan.com/mcp \
     -H "X-API-Key: YOUR_SYNAPLAN_API_KEY" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -H "MCP-Protocol-Version: 2025-11-25" \
     -H "Mcp-Session-Id: SESSION" \
     -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"rag_search","arguments":{"query":"quarterly report","limit":5}}}'

Resources#

The server exposes read-only resource templates so a host can pull specific context by URI:

URI template Returns
synaplan://file/{id} The extracted text of one of your documents (by file id).
synaplan://memory/{id} One of your stored memories, as JSON (by memory id).

Discover them with resources/templates/list, then fetch with resources/read:

shell
curl -X POST https://web.synaplan.com/mcp \
     -H "X-API-Key: YOUR_SYNAPLAN_API_KEY" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -H "MCP-Protocol-Version: 2025-11-25" \
     -H "Mcp-Session-Id: SESSION" \
     -d '{"jsonrpc":"2.0","id":4,"method":"resources/read","params":{"uri":"synaplan://file/123"}}'

Prompts#

Your Synaplan task prompts (e.g. general, docsummary, mediamaker, officemaker, plus any custom prompts) are exposed as MCP prompts your host can select. Internal system prompts are never exposed. Each prompt accepts an optional input argument that is appended to the instruction:

shell
curl -X POST https://web.synaplan.com/mcp \
     -H "X-API-Key: YOUR_SYNAPLAN_API_KEY" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -H "MCP-Protocol-Version: 2025-11-25" \
     -H "Mcp-Session-Id: SESSION" \
     -d '{"jsonrpc":"2.0","id":5,"method":"prompts/get","params":{"name":"docsummary","arguments":{"input":"<your text>"}}}'

The outbound MCP client: connect your tools to Synaplan#

The direction above is others calling Synaplan. The outbound MCP client is the reverse: Synaplan calls your MCP servers. Connect a Streamable HTTP MCP endpoint — your CRM, an internal wiki, Jira / Confluence, an n8n workflow exposed as MCP — and its tools become data sources the multi-task planner can use inside a task plan (mcp_fetch node) and, when you allow it, actions (mcp_action node). Ask "look up customer Acme in our CRM and summarize their last order" and the plan fetches the real record, then answers grounded in it; ask "open a Jira ticket for this" on a server with write actions allowed and the plan creates it — after your approval when the tool is write-class.

Set it up (three steps)#

  1. Connect a server — Manage → Connections → MCP Servers (/channels/mcp) in the app: add the Streamable HTTP URL and an optional auth header (stored encrypted), start from the Jira / Confluence presets (any Jira- or Confluence-capable MCP endpoint, for example a self-hosted Atlassian MCP service), or pick Notion / Higgsfield and sign in with your account (see MCP OAuth connectors). Test the connection, browse the tools Synaplan discovered, and decide per server whether write actions are allowed. Destructive tools stay refused regardless.
  2. Let an assistant use it — in the assistant builder, Tools and skills → connected apps (MCP) lists your servers; tick the ones this assistant may call (on an instance with assistants switched off, the same switch is Instructions → your prompt → Available tools → MCP Data Sources). Every connected tool is also part of the one tool registry, so read / write / destructive policies apply.
  3. Ask — when a request needs external data, the planner places an mcp_fetch (or mcp_action) step with the server and tool chosen from your connection list, and downstream steps consume the result.

Guarantees#

  • Reads run, writes ask, deletes are refused — read-safe tools run on their own; write-class tools need allow write actions on that server and follow the instance approval policy (default: ask); tools annotated destructive are never called.
  • Tenant-isolated — connections and credentials are resolved per user; no other account can reach your servers.
  • SSRF-guarded and timeout-bounded — every outbound call goes through the shared SSRF policy, and a slow server degrades one step, never the whole answer.
  • No hallucinated tools — an assistant or topic without the MCP opt-in (or a user without connections) never exposes the capability to the planner at all.

Platform configuration (self-hosting)#

The client is controlled by BCONFIG flags (per-user row → global row → built-in default):

Flag Meaning Shipped value
MCP.CLIENT_ENABLED Master switch for any outbound MCP traffic on (seeded)
MCP.OAUTH_CONNECTORS_ENABLED Users may sign in to remote MCP servers (Notion, Higgsfield, …) off (seeded)
MCP.NODE_TIMEOUT Per-call timeout in seconds (clamped 3–120) 15
MULTITASK.MCP_FETCH_ENABLED Lets the planner place mcp_fetch nodes on (seeded)
MULTITASK.MCP_ACTION_ENABLED Lets the planner place mcp_action nodes on servers with write actions allowed on (seeded)

Hosted servers that require an account sign-in (they reject a static token) are documented separately: MCP OAuth connectors — Notion, Higgsfield, the admin flag, and example JSON configurations.

The global rows are inserted by the idempotent app:seed command, which runs automatically on every container start (after migrations) — so a normal deploy activates the client. Seeding is insert-if-missing: an operator's explicit 0 row is the kill switch and survives every deploy. While the master switch is off, the settings UI says so and connections can be prepared but no calls are executed.

Roadmap#

Planned additions, in priority order:

  • A synaplan://chat/{shareToken} resource for shared conversations.
  • A listing in the public MCP registry for one-click install.
  • Per-topic multi-select UI for MCP server allowlists.

See also#