Skip to main content
Herm supports connecting Model Context Protocol (MCP) servers to your deployments. This gives the agent access to your first-party tools and external data sources through a standardized protocol — no adapter code. MCP configuration is split across two concerns:
  1. The deployment declares which servers the agent connects to, by name and URL, with an optional tool allowlist.
  2. Credentials stay out of the declaration. Servers that need auth get it through secret references, never inline tokens.

Declare MCP servers on the deployment

Specify servers in the mcp_servers array when creating or updating a deployment:
const deployment = await herm.deployments.create({
  customer_id: "cus_123",
  name: "Acme Creative Agent",
  system_prompt: "You are Acme's media generation agent.",
  mcp_servers: [
    {
      name: "prism-media",
      url: "https://api.prismvideos.com/mcp",
      tools: ["search_models", "generate_image", "generate_video"],
    },
  ],
});
You can also add, update, or remove servers on a live deployment with the Tools API — changes apply to the agent’s next run.

mcp_servers field reference

Each entry in the mcp_servers array defines one connection.
FieldDescription
nameRequired. A unique name for this server within the deployment. Surfaced as the origin prefix on tools and on tool_call events
urlRequired. The endpoint of the remote MCP server. Must be reachable from Herm’s infrastructure
toolsOptional. Allowlist of tool names as reported by the server. Omit to expose every tool the server publishes
Constraints:
  • A deployment can declare up to 20 MCP servers. Server names must be unique within the array.
  • On updates, the mcp_servers array is fully replaced.

Configure which MCP tools are available

By default, every tool the server publishes is exposed to the agent. To enable only specific tools, list them in the allowlist:
{
  "name": "github",
  "url": "https://api.githubcopilot.com/mcp/",
  "tools": ["get_issue", "list_issues", "add_issue_comment"]
}
This pattern is useful when a server exposes many tools but the agent only needs a few, or when you want tools added by the server operator to stay off until you review them. A tool missing from the allowlist is invisible to the agent — it isn’t listed, so the model can’t attempt it. A common variant is scoping by plan tier — one shared server, different allowlists per customer:
await herm.mcpServers.update("dep_7xK9s2", "prism-media", {
  tools: ["search_models", "generate_image", "generate_video", "generate_audio"],
});

MCP tool output handling

When an MCP tool returns very large output, it’s written to a file in the deployment’s workspace. The model receives a truncated preview with the file path and can read the full content from there.

Authentication

Two separate questions, two mechanisms:
  • Your server authenticating the caller. Herm sends the deployment’s customer_id with every tool call, so your server can scope data access per customer without per-request tokens.
  • Herm authenticating to your server. If the server requires a credential, pass it as a secret reference on the deployment and reference the environment variable in your server configuration. Raw tokens never appear in the declaration, the sandbox, or logs.

Handle connection failures

Deployment creation does not validate MCP connectivity. If a server is unreachable or rejects its credential, the deployment still works and the agent runs without that server’s tools.
SignalMeaning
status: "unreachable" on List MCP serversThe server could not be reached at last attempt — surface this in your dashboard
error event on the SSE stream with mcp_serverA tool call failed mid-run because the server was unreachable or rejected auth
Connections are retried at the start of each run, so a recovered server’s tools reappear without any action on your side.

Tool calls on the event stream

Every MCP tool invocation appears on the SSE stream as a tool_call followed by a tool_result, so your UI can narrate progress and your logs capture an audit trail:
event: tool_call
data: {"run_id":"run_4mPx81","tool":"generate_video","arguments":{"prompt":"..."}}

event: tool_result
data: {"run_id":"run_4mPx81","tool":"generate_video","result":{"status":"queued"}}