MCP servers
The Model Context Protocol (MCP) is the wire format agents use to call host capabilities — list tools, call them, get results. Vonzio runs an MCP server for each capability surface and injects them into the agent container at task-start time.
If you’re new to MCP entirely: Anthropic’s MCP spec. The short version: it’s JSON-RPC 2.0 over HTTP (or stdio), with tools/list and tools/call methods.
MCP servers Vonzio ships
Section titled “MCP servers Vonzio ships”| Server | Endpoint | What it does | Injected when |
|---|---|---|---|
memory | /mcp/memory | Read/write persistent memory rows scoped to (user, profile). | memory_enabled !== false on the profile. |
notify | /mcp/notify | Send a notification through any of the user’s notification channels. | Always (when INTERNAL_SERVER_URL is set). |
gmail | /mcp/gmail | Search / read / send Gmail on behalf of the user. | User has a Gmail integration granted to this profile. |
teller | /mcp/teller | Read bank enrollments, balances, transactions, account details. | User has a Teller integration granted to this profile. |
vonzio | /mcp/platform | Internal platform operations: spawn child tasks, run playbooks, query memory across profiles. | Always. |
Custom HTTP MCPs from third parties: add to a profile’s mcp_servers array and they’re injected the same way.
Authentication
Section titled “Authentication”Each MCP server uses bearer token authentication. The orchestrator mints a short-lived token per task and stores it in an in-memory Map<token, session_context>. When the agent calls the MCP endpoint, the server resolves the token to a {userId, sessionId, profileId, …} context and applies it server-side.
Crucially: the token never grants more than the session’s own context. An agent can’t forge a profileId to access another profile’s data. Server-side resolution is the only source of truth for userId / profileId.
Tokens are cleaned up in a finally block when the task ends — they’re not durable.
Integration-backed MCP servers (gmail, teller) are gated by scope. If the integration is scope='agents' and the running profile isn’t in profile_ids, the MCP server isn’t injected at all — the agent doesn’t see gmail_* / teller_* tools in its tools/list response.
The injection mechanism
Section titled “The injection mechanism”When dispatchSession runs, after profile resolution it builds a nonSdkServers array:
nonSdkServers.push({ name: "memory", type: "http", url: `${INTERNAL_SERVER_URL}/mcp/memory`, headers: { Authorization: `Bearer ${memToken}` },});The agent container receives this array as JSON via the agent-runner config. The Claude Agent SDK initializes MCP clients for each entry, calls tools/list to discover, then exposes them to the model as mcp__<server>__<tool> tools.
Adding your own MCP server
Section titled “Adding your own MCP server”To inject a third-party MCP server into agents on a specific profile:
-
Set up the server (it must speak MCP over HTTP, including auth if needed).
-
PATCH the profile to add to
mcp_servers:{"mcp_servers": [{ "name": "memory", "type": "sdk" },{ "name": "notify", "type": "sdk" },{"name": "mycorp-crm","type": "http","url": "https://crm.mycorp.com/mcp","headers": { "Authorization": "Bearer <static-or-env>" }}]} -
The agent will see
mcp__mycorp_crm__<tool_name>on its next session.