Skip to content

MCP Servers

rluisr edited this page Jul 23, 2026 · 1 revision

MCP Servers

English | 日本語

How maestro connects Claude Managed Agents to GitHub, Linear, Figma, and your own tools.

Rules of the road

Managed Agents MCP constraints that drive the design:

Supported Not supported
Remote Streamable HTTP MCP stdio MCP attached directly to the agent
Auth via Vault credentials (static_bearer / mcp_oauth) Putting authorization_token on mcp_servers[]
sessions.create with vault_ids Per-turn MCP headers on the session API
Up to ~20 MCP servers per agent Local-only Agent SDK mcpServers: { command, args } shapes

Three pieces must stay consistent:

  1. Agent definitionmcp_servers[] URL + mcp_toolset with matching mcp_server_name
  2. Vault credential — same mcp_server_url as the definition
  3. DB row (mcp_servers table / WebUI) — what maestro ensures into the vault at run start
Agent definition  ─┐
  mcp_servers      ├─ hash → agents.create / update
  tools            ─┘
Vault credentials  ── vault_ids ──► sessions.create
DB mcp_servers     ── ensure at run start ──► Vault

Builtin: GitHub MCP

Field Value
name github
URL https://api.githubcopilot.com/mcp/
Auth GitHub App installation token for the target repo (minted per run)
WebUI Builtin row — name/url/enabled locked; permission policy editable

You do not configure a PAT. The App from Installation is enough.

Multi-repo warning: Vault MCP credentials are keyed by URL. A shared VAULT_ID across repos can let one installation token overwrite another. Prefer per-run managed vaults (default) or separate vaults; avoid one long-lived shared vault for many repos.


Linear

For origin: "linear_issue" runs:

  1. Enable an MCP server whose URL is https://mcp.linear.app/mcp (constant LINEAR_MCP_URL)
  2. Provide a vault-compatible token (token_env_name on the row must resolve at run time)
  3. Start runs with linearIssue + primary repo (PR still lands on GitHub)

Without an enabled Linear MCP server, Linear-origin runs fail at validation.


stdio → Remote MCP (Figma and friends)

stdio servers (e.g. figma-developer-mcp) cannot attach to Managed Agents. Bridge them:

flowchart LR
  cma[Managed Agents]
  vault[Vault static_bearer]
  edge[HTTPS edge]
  gw[MCP Gateway]
  proxy[mcp-proxy]
  stdio[stdio MCP]

  vault -.->|Bearer| cma
  cma --> edge --> gw --> proxy --> stdio
Loading

1. Declare the process (mcp-proxy.json)

{
  "mcpServers": {
    "figma": {
      "command": "node_modules/.bin/figma-developer-mcp",
      "args": ["--stdio", "--skip-image-downloads"]
    }
  }
}
  • Keys become URL path segments → use URL-safe names (no spaces)
  • Image-download tools write to the MCP host filesystem (not the agent sandbox) — prefer --skip-image-downloads or tool allowlists

2. Run mcp-proxy + gateway

Local: ENABLE_DEV_TUNNEL=true (ngrok + gateway + proxy). See docs/DEVELOPMENT.md.

Production: container start.sh / start-mcp.sh with public MCP hostname:

https://mcp.example.com/servers/figma/mcp

3. Register in WebUI

MCP servers → add:

Field Example
name figma
url https://mcp.example.com/servers/figma/mcp
enabled on
token_env_name MCP_GATEWAY_TOKEN

maestro ensures a Vault static_bearer whose mcp_server_url matches the row URL and whose token comes from that env var.

4. Secrets split

Secret Lives where Purpose
MCP_GATEWAY_TOKEN maestro env + Vault bearer CMA → your gateway
Anthropic outbound CIDR edge / gateway allowlist Who may call the gateway (160.79.104.0/21 today)
FIGMA_API_KEY (etc.) host env for the stdio process Upstream API — never needs to enter the agent vault

Adding a new remote MCP (operator)

No code change if the server is already HTTP MCP:

  1. Obtain a stable HTTPS URL and a bearer (or OAuth material)
  2. Put the bearer in an env var on the maestro host
  3. WebUI → MCP servers → name, url, token_env_name, enable
  4. Next run: vault ensure + agent registry hash update picks it up
  5. Optionally tighten system prompts so the agent knows when to use it

Adding via code (advanced)

For builtins baked into agent definitions, follow the three-piece pattern in-repo:

  1. URL constant in src/shared/constants.ts
  2. mcp_servers + mcp_toolset on parent/child agent builders
  3. Vault ensure in src/shared/vault.ts (mcp_server_url exact match)

Registry hashes definitions and calls agents.update when they change.


Permission policies

MCP toolsets support Managed Agents permission policies (e.g. always_allow). Builtin GitHub uses allow-by-default for agent autonomy; tighten in WebUI when you need human gates.


Local vs production URLs

Environment Typical MCP URL
Local + dev tunnel https://<random>.ngrok.app/servers/<name>/mcp (DB upserted on start)
Production https://mcp.yourdomain.com/servers/<name>/mcp
GitHub builtin https://api.githubcopilot.com/mcp/ (Anthropic-reachable; no gateway)

Free ngrok URLs change every process start — expect vault/DB churn unless you use a reserved domain.


Do not

❌ stdio command in agent mcp_servers
❌ authorization_token on mcp_servers in AgentCreateParams
❌ mcp_servers on sessions.create
❌ Putting upstream API keys (Figma, etc.) into the agent vault when only the stdio host needs them
❌ Exposing mcp-proxy to the internet without gateway Bearer + network allowlist

Related

Clone this wiki locally