Herkos / Docs / Use with your agent

Use Herkos with your agent

Herkos is a transparent stdio MCP proxy. It presents as an MCP server to whatever launches it and forwards to the real server, so it works in front of any MCP client - Claude Code, Cursor, Cline, Codex, and more - with no client-specific code. Wrapping a server is one config change.

The one pattern

Wherever your client lists its MCP servers, a server is a command plus args. To broker it, point the command at herkos serve and pass the real command after --. Everything else - the server, its environment, the agent - is unchanged.

command + args
beforenpx -y @modelcontextprotocol/server-github
afterherkos serve --allow-tool get_issue -- npx -y @modelcontextprotocol/server-github
What this buys you

The agent can call only the tools you --allow-tool, and (as of the tool-list filter) only sees those tools in its catalog. Add --receipts <dir> for a signed audit log, and --isolate to cut the server's own network. The exact config file differs by client; the wrap is always the same.

JSON configs: the mcpServers and servers shapes

Most clients store MCP servers as {"mcpServers": {name: {command, args}}} JSON; some use a top-level {"servers": {...}} object of the same shape. Each lives in its own location - for example .mcp.json / ~/.claude.json, ~/.cursor/mcp.json, or .vscode/mcp.json (e.g. Claude Code, Cursor, VS Code, GitHub Copilot). The wrapped entry:

{
  "mcpServers": {
    "github": {
      "command": "herkos",
      "args": ["serve", "--allow-tool", "get_issue", "--",
               "npx", "-y", "@modelcontextprotocol/server-github"]
    }
  }
}

For this format, herkos register does the rewrite for you, in place, leaving no un-brokered entry behind:

$ herkos register --config .mcp.json --server github --allow-tool get_issue

Or broker every local stdio server in the config in one pass: register --all launches each server once, discovers the tools it exposes, and pins them as its allowlist (so a tool added by a later update is denied), skipping remotes and already-brokered entries.

$ herkos register --all --config .mcp.json

Codex

Codex stores MCP servers as TOML in ~/.codex/config.toml. Same wrap, TOML syntax:

[mcp_servers.github]
command = "herkos"
args = ["serve", "--allow-tool", "get_issue", "--",
        "npx", "-y", "@modelcontextprotocol/server-github"]

The broker itself is verified to speak the MCP stdio protocol both ways; the TOML config above is the wrapping pattern in Codex's format. herkos register does not rewrite TOML yet, so this one is hand-edited for now.

Other MCP clients

Any client that launches a stdio MCP server works identically: find where it lists servers, and point the command at herkos serve -- <the real command>. If it uses either the mcpServers or the servers JSON shape, scan and register (including register --all) handle it automatically; a format outside those JSON shapes, such as Codex TOML, is the same one-line wrap, hand-edited.

Honest scope

The broker is client-agnostic, verified end to end with the official @modelcontextprotocol/sdk client - the same library Claude Code, Cursor, and Cline use - connecting through Herkos to a reference server: it completed the handshake, saw only the allowlisted tools, called an allowed one, and had a denied one blocked in-path. Config locations vary by client and change over time, so check your client's own MCP docs for the exact file; the wrap (command points at herkos serve) does not change. scan and register auto-detect both JSON launch-config shapes - the mcpServers object and the servers object - so most clients are a single command (and register --all brokers every local stdio server at once); a format outside those JSON shapes, such as Codex TOML, is the same one-line wrap, hand-edited.