Model Context Protocol (MCP) — Server & Client
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, an n8n endpoint, …) and lets the multi-task planner pull live data from them into an answer — read-only, per user, per topic.
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, andlist_prompts, plus resources (your documents and memories) and prompts (your task prompts). 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 in Settings → API Keys). Either header works:
X-API-Key: YOUR_SYNAPLAN_API_KEYAuthorization: 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:
{
"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) |
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:
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:
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:
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:
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:
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, an n8n workflow exposed as MCP —
and its read-safe tools become data sources the
multi-task planner can use inside a task plan
(mcp_fetch 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.
Set it up (three steps)
- Connect a server — Channels → MCP Servers in the app: add the Streamable HTTP URL and an optional auth header (stored encrypted), test the connection, and browse the tools Synaplan discovered.
- Opt a topic in — AI Instructions → your prompt → Available tools → MCP Data Sources: the per-topic switch that lets the planner see your connected tools (optionally restricted to specific servers).
- Ask — when a request needs external data, the planner places an
mcp_fetchstep with the server and tool chosen from your connection list, and downstream steps consume the fetched text.
Guarantees
- Read-only (v1) — Synaplan only calls read-safe tools; nothing mutates your systems.
- 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 — a 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.NODE_TIMEOUT |
Per-call timeout in seconds (clamped 3–120) | 15 |
MULTITASK.MCP_FETCH_ENABLED |
Lets the planner place mcp_fetch nodes |
on (seeded) |
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.