MCP servers
Model Context Protocol (MCP) is how you connect external tools to the orchestrator without writing a plugin. Connect any MCP server and its tools become first-class in the agent's tool registry — same multi-round semantics, same citation contract, same idempotency guarantees.
Why MCP
Three reasons we standardized on MCP rather than building our own plugin protocol:
- It's the broadly-adopted standard for tool integration with LLMs. Anthropic, OpenAI's Apps SDK, and others use it. Servers you write for CCD-Suite work for other clients; servers others wrote work in CCD-Suite.
- Transport-agnostic. stdio, HTTP, WebSocket — pick what fits.
- Authentication built in. MCP supports auth flows so you don't have to roll your own per-server.
What an MCP server provides
An MCP server exposes three things to the client (the orchestrator):
| Purpose | |
|---|---|
| Tools | Functions the agent can call (get_weather, query_my_database, etc.). |
| Resources | Data the agent can read (file contents, query results). |
| Prompts | Reusable prompt templates the server suggests. |
In CCD-Suite, the orchestrator primarily uses Tools — Resources get pulled in as needed by tools that reference them, and Prompts are surfaced as suggested skills in Settings → Skills.
Connecting an MCP server
Settings → Integrations → MCP servers → Add server. You provide:
- Name — display label.
- Transport — HTTP / WebSocket / (self-host only) stdio.
- URL or command — endpoint or command line.
- Auth — OAuth (for hosted servers) or API key (for static ones) or none.
The platform handshakes with the server (initialize + tools/ list), discovers its capabilities, and registers them. Tools
become available to the orchestrator under a namespaced prefix:
mcp_<server_name>__<tool_name>
So a Postgres server you've connected as "warehouse" exposes
mcp_warehouse__query, mcp_warehouse__list_tables, etc.
What the agent sees
To the orchestrator, MCP tools are indistinguishable from built-in tools. Same shape, same multi-round flow, same citation contract. The only difference: every MCP call goes through the platform's sandbox boundary, which:
- Times out at 30 s (configurable per server, max 5 min).
- Logs the input + output for audit.
- Enforces the platform's per-tenant rate limits.
- Surfaces server errors as tool_result with
is_error: true.
The orchestrator handles errors the same way it handles any other tool failure — retry, substitute, or surface to the user.
Auth + permissions
MCP servers run with the tenant's authority. Two key implications:
- Multi-tenant safety: every server connection is tenant- scoped. The orchestrator running on tenant A's behalf can ONLY reach servers tenant A has connected. There's no cross-tenant leakage even if the underlying server is multi-tenant.
- Per-user scoping (optional): admins can mark a server as "user-scoped", in which case each user has their own OAuth token. Useful for servers that operate against personal data (your inbox, your calendar) rather than tenant data.
Common server types operators connect
A non-exhaustive sample:
| Server | What it's for |
|---|---|
| GitHub MCP | Search issues, read code, propose PRs. |
| Postgres MCP | Run SELECT queries against your warehouse. |
| Slack MCP | Read channels, search messages, post threads. |
| Linear MCP | Read issues, create tickets, assign work. |
| File system MCP (self-host) | Read/write tenant-scoped files. |
| Custom (yours) | Anything you want the agent to be able to do. |
Writing your own MCP server
The MCP spec covers the wire protocol. Reference implementations exist in TypeScript, Python, Rust. Minimum effort for a useful server is ~30 lines plus your tool implementations.
Conventions we recommend:
- Tool descriptions matter. The model reads them to decide when to use the tool. Be specific.
- Return structured data. JSON beats free-form text — the orchestrator citations-trace works better when tool results have identifiable rows.
- Be idempotent. The platform retries failed calls; your server should not double-charge.
- Stay fast. Each tool call lives inside the orchestrator's per-turn budget. Sub-second is great; multi-second is acceptable for genuinely expensive work; minute-plus and you're better off with an async pattern (return a job_id, expose a status tool).
Self-host nuances
- stdio transport supported in self-host (runs the MCP server as a subprocess of ai-services). Useful for local-only servers that don't need a network endpoint. Cloud doesn't allow stdio (no shell access to platform containers).
- No connection limit by default. Self-host operators can connect any number of servers. Cloud caps at 10 per tenant by default (raisable per plan tier).
Debugging
Settings → Integrations → MCP servers → click a server → recent calls. Shows the last 100 tool calls with input, output, latency, error status. Useful when a tool isn't behaving as expected.
For self-host operators, deeper logs are in the ai-services container — see Observability.
Read next
- Tool calling — the protocol level MCP tools join.
- OAuth providers — the other major integration class.