Because too many MCP routers turned out to be quite poo.
Run multiple local MCP servers (stdio), aggregate, expose as HTTP. Done.
🚽 No request retries, backend supervision, restart policy, plugin system, policy engine, metrics endpoint, protocol models, authentication or custom JSON-RPC bullshit.
- Catalog projection is configuration.
- Call routing is a lookup.
- Everything else belongs to the SDK or outside the process.
Caution
mcpee provides no authentication or sandboxing.
Keep it on loopback, or put authentication in front of it if you expose it remotely.
Want sandboxing? Run your MCP binaries through codex sandbox windows, Seatbelt, bubblewrap, or whatever else fits your platform.
mcpee doesn't care. 🤗
- frontend: stateless Streamable HTTP at
/mcp - default listen address:
127.0.0.1:8080 - backends:
stdioMCP servers owned for the process lifetime - projected names:
<backend>__<tool> - startup fails if any backend cannot connect/list tools, or if projection is invalid
- descriptions, schemas, annotations, icons, results, errors, and request cancellation are passed through via the official SDK
- logs go
brrto stderr
listen: 127.0.0.1:8080
backends:
- name: exec
command: fs-mcp-rs
- name: my-stdio-mcp
command: my-mcp-binary
args:
- foxtrot
- unicorn
env:
CHARLIE: KILOBuilt on top of github.com/modelcontextprotocol/go-sdk. Whatever it needs, we it need too.
Use mise run to discover all tasks (build / test / etc..)
The tests cover catalog projection/routing, metadata preservation, collisions/invalid names, argument forwarding, backend result forwarding, and configuration defaults.