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:

  1. 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.
  2. Transport-agnostic. stdio, HTTP, WebSocket — pick what fits.
  3. 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
ToolsFunctions the agent can call (get_weather, query_my_database, etc.).
ResourcesData the agent can read (file contents, query results).
PromptsReusable 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:

  1. 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.
  2. 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:

ServerWhat it's for
GitHub MCPSearch issues, read code, propose PRs.
Postgres MCPRun SELECT queries against your warehouse.
Slack MCPRead channels, search messages, post threads.
Linear MCPRead 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