MCP Servers
MCP (Model Context Protocol) servers extend your agents with custom tools and resources, enabling integration with external services like GitHub, PostHog, databases, and more.
What is MCP?
Section titled “What is MCP?”Model Context Protocol (MCP) is an open protocol that allows AI assistants to interact with external tools and data sources. MCP servers provide:
- Tools: Custom functions the agent can call (e.g., create GitHub issues, query databases)
- Resources: Data sources the agent can read (e.g., documentation, knowledge bases)
- Prompts: Predefined prompt templates
When you configure an MCP server for an agent, all tools from that server become available to the agent during its sessions.
Configuration
Section titled “Configuration”MCP servers are configured per-agent in the mcp_servers field. Each server has a unique name (key) and configuration.
Process-Based Servers
Section titled “Process-Based Servers”Most MCP servers run as local processes, spawned when the agent starts:
name: codermcp_servers: github: command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: ${GITHUB_TOKEN}| Field | Type | Description |
|---|---|---|
type | string | Transport — stdio. Optional; inferred as stdio when no url is set |
command | string | Executable to run |
args | string[] | Command-line arguments |
env | object | Environment variables (supports ${VAR} interpolation) |
timeout | integer | Per-server tool-call timeout in milliseconds (values below 1000 are ignored) |
alwaysLoad | boolean | Always include this server’s tools in the prompt instead of deferring them behind tool search |
HTTP-Based Servers
Section titled “HTTP-Based Servers”Some MCP servers run as HTTP services:
mcp_servers: custom-api: url: http://localhost:8080/mcp| Field | Type | Description |
|---|---|---|
type | string | Transport — http or sse. Optional; inferred as http when url is set |
url | string | URL endpoint for the MCP server |
headers | object | Request headers sent with every call — carries bearer / API-key auth |
timeout | integer | Per-server tool-call timeout in milliseconds (values below 1000 are ignored) |
alwaysLoad | boolean | Always include this server’s tools in the prompt instead of deferring them behind tool search |
SSE and Authenticated Remote Servers
Section titled “SSE and Authenticated Remote Servers”type is only inferred as http or stdio, never sse — a server that speaks Server-Sent Events must say so explicitly. Authentication for a remote server goes in headers:
mcp_servers: linear: type: sse url: https://mcp.linear.app/sse headers: Authorization: Bearer ${LINEAR_API_KEY} timeout: 30000Tool Naming Convention
Section titled “Tool Naming Convention”MCP tools are namespaced using the mcp__<server>__<tool> pattern:
mcp__<server-name>__<tool-name>For example, if you configure a server named github:
mcp_servers: github: command: npx args: ["-y", "@modelcontextprotocol/server-github"]Its tools become available as:
mcp__github__create_issuemcp__github__list_issuesmcp__github__create_pull_request- etc.
The server name in the tool identifier comes from the key you use in mcp_servers, not the package name.
Combining with Permissions
Section titled “Combining with Permissions”Use allowed_tools and denied_tools to control which MCP tools an agent can use.
Wildcard Support
Section titled “Wildcard Support”Allow all tools from a specific server using wildcards:
allowed_tools: - Read - Write - Edit - mcp__github__* # All GitHub MCP tools - mcp__posthog__* # All PostHog MCP toolsSpecific Tools Only
Section titled “Specific Tools Only”For tighter security, allow only specific tools:
allowed_tools: - Read - Write - mcp__github__list_issues - mcp__github__create_pull_request # Other GitHub tools are blockedDenying Specific MCP Tools
Section titled “Denying Specific MCP Tools”Block specific tools while allowing others:
allowed_tools: - mcp__github__*denied_tools: - mcp__github__delete_repository # Block dangerous operationsCommon MCP Servers
Section titled “Common MCP Servers”GitHub Server
Section titled “GitHub Server”Access GitHub APIs for issues, PRs, repositories:
mcp_servers: github: command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: ${GITHUB_TOKEN}Tools provided:
mcp__github__list_issuesmcp__github__create_issuemcp__github__create_pull_requestmcp__github__search_repositories- And more…
Required environment:
export GITHUB_TOKEN=ghp_your_token_herePostHog Server
Section titled “PostHog Server”Analytics and feature flag management:
mcp_servers: posthog: command: npx args: ["-y", "@anthropic/posthog-mcp-server"] env: POSTHOG_API_KEY: ${POSTHOG_API_KEY} POSTHOG_PROJECT_ID: ${POSTHOG_PROJECT_ID}Tools provided:
mcp__posthog__query-runmcp__posthog__feature-flag-get-allmcp__posthog__create-feature-flagmcp__posthog__experiment-create- And more…
Required environment:
export POSTHOG_API_KEY=phx_your_api_keyexport POSTHOG_PROJECT_ID=12345Filesystem Server
Section titled “Filesystem Server”Controlled filesystem access:
mcp_servers: filesystem: command: npx args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]Tools provided:
mcp__filesystem__read_filemcp__filesystem__write_filemcp__filesystem__list_directorymcp__filesystem__create_directory- And more…
The filesystem server restricts access to the specified directory path.
PostgreSQL Server
Section titled “PostgreSQL Server”Database access:
mcp_servers: postgres: command: npx args: ["-y", "@modelcontextprotocol/server-postgres"] env: DATABASE_URL: ${DATABASE_URL}Tools provided:
mcp__postgres__querymcp__postgres__list_tablesmcp__postgres__describe_table
Memory Server
Section titled “Memory Server”Persistent memory/knowledge base:
mcp_servers: memory: command: npx args: ["-y", "@modelcontextprotocol/server-memory"]Tools provided:
mcp__memory__storemcp__memory__retrievemcp__memory__search
Full Examples
Section titled “Full Examples”Development Agent with GitHub
Section titled “Development Agent with GitHub”A coder agent that can interact with GitHub issues and PRs:
name: dev-agentdescription: "Implements features from GitHub issues"
repo: myorg/my-projectworkspace: my-project
mcp_servers: github: command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: ${GITHUB_TOKEN}
allowed_tools: - Read - Write - Edit - Glob - Grep - mcp__github__* - "Bash(git *)" - "Bash(npm *)" - "Bash(pnpm *)"Analytics Agent with PostHog
Section titled “Analytics Agent with PostHog”An agent that can query analytics and manage experiments:
name: analytics-agentdescription: "Manages product analytics and experiments"
mcp_servers: posthog: command: npx args: ["-y", "@anthropic/posthog-mcp-server"] env: POSTHOG_API_KEY: ${POSTHOG_API_KEY} POSTHOG_PROJECT_ID: ${POSTHOG_PROJECT_ID}
allowed_tools: - Read - Glob - Grep - mcp__posthog__query-run - mcp__posthog__insights-get-all - mcp__posthog__feature-flag-get-all - mcp__posthog__experiment-get-alldenied_tools: - mcp__posthog__delete-feature-flag # Block destructive operations - mcp__posthog__experiment-deleteMulti-Server Agent
Section titled “Multi-Server Agent”An agent with access to multiple MCP servers:
name: full-stack-agentdescription: "Full-stack development with multiple integrations"
mcp_servers: github: command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: ${GITHUB_TOKEN}
filesystem: command: npx args: ["-y", "@modelcontextprotocol/server-filesystem", "/workspace/docs"]
postgres: command: npx args: ["-y", "@modelcontextprotocol/server-postgres"] env: DATABASE_URL: ${DATABASE_URL}
allowed_tools: - Read - Write - Edit - mcp__github__* - mcp__filesystem__* - mcp__postgres__query - mcp__postgres__list_tablesdenied_tools: - mcp__postgres__* # Then allow specific ones aboveCustom MCP Server
Section titled “Custom MCP Server”Run your own MCP server implementation:
mcp_servers: internal-tools: command: node args: ["./mcp-servers/internal-tools.js"] env: API_KEY: ${INTERNAL_API_KEY} API_URL: https://api.internal.example.comServer Lifecycle
Section titled “Server Lifecycle”MCP servers follow the agent session lifecycle:
- Startup: When an agent session begins, herdctl spawns all configured MCP servers
- Connection: Servers connect via stdio (process-based), HTTP, or SSE
- Available: Tools become available for the agent to use
- Shutdown: When the session ends, process-based servers are terminated
Environment Variables
Section titled “Environment Variables”MCP server configurations support environment variable interpolation using ${VAR} syntax:
mcp_servers: github: command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: ${GITHUB_TOKEN} # From shell environment GITHUB_ENTERPRISE_URL: ${GH_ENTERPRISE} # Custom variableSet these in your shell or .env file before running herdctl.
Security Considerations
Section titled “Security Considerations”Principle of Least Privilege
Section titled “Principle of Least Privilege”Only grant access to tools an agent actually needs:
# Good: Specific toolsallowed_tools: - mcp__github__list_issues - mcp__github__create_pull_request
# Risky: All toolsallowed_tools: - mcp__github__*Protect Sensitive Tokens
Section titled “Protect Sensitive Tokens”Never hardcode tokens in configuration:
# Badenv: GITHUB_TOKEN: ghp_actualtoken123
# Goodenv: GITHUB_TOKEN: ${GITHUB_TOKEN}Limit Filesystem Access
Section titled “Limit Filesystem Access”When using the filesystem server, restrict to specific directories:
mcp_servers: filesystem: command: npx args: ["-y", "@modelcontextprotocol/server-filesystem", "/workspace/safe-dir"] # Agent can only access /workspace/safe-dir and subdirectoriesDeny Destructive Operations
Section titled “Deny Destructive Operations”Block dangerous tools even when using wildcards:
allowed_tools: - mcp__github__*denied_tools: - mcp__github__delete_repository - mcp__github__delete_branchDebugging
Section titled “Debugging”Check MCP Server Status
Section titled “Check MCP Server Status”# View logs including MCP server outputherdctl logs --agent my-agent
# Check if MCP servers started correctlyherdctl status --agent my-agentCommon Issues
Section titled “Common Issues”Server fails to start:
- Check that the command is installed (
npx,node, etc.) - Verify environment variables are set
- Check for typos in package names
Tools not available:
- Verify the server name in
mcp_serversmatches the pattern inallowed_tools - Check that the MCP server actually provides the expected tools
- Look for startup errors in agent logs
Authentication errors:
- Verify environment variables are correctly set
- Check token permissions match required scopes
- Ensure tokens haven’t expired
Schema Reference
Section titled “Schema Reference”mcp_servers: [server-name]: type?: "stdio" | "sse" | "http" # Transport (inferred: http if url set, else stdio) command?: string # Executable for process-based servers args?: string[] # Command arguments env?: Record<string, string> # Environment variables url?: string # URL for HTTP/SSE-based servers headers?: Record<string, string> # Request headers for sse/http servers timeout?: number # Per-server tool-call timeout in ms (below 1000 ignored) alwaysLoad?: boolean # Always include this server's tools in the promptEvery field is passed through to the Agent SDK unchanged. A bare url with no type still becomes type: "http", so existing configs keep working.
Related Pages
Section titled “Related Pages”- Agent Configuration — Full agent config reference
- plugins — Claude Code plugins, which can also supply MCP servers
- Permissions — Tool permission controls
- Environment Variables — Environment configuration