LABSCO SUMMARY
Tool filtering is the feature that outlives the Cursor bug it was written for.
Fronting five servers means five tool lists arriving in the model's context, most of which it will never call; the per-server allowed array trims that to the handful you actually use. The other durable benefit is the single config: point every client at the same file and the same binary, and secrets stop being copied into four separate client configurations.
What it is
An MCP aggregator written in Go. It is a server to your client and a client to your backend servers: it launches each configured server, collects their tools, prefixes each tool with the server's name, and presents the whole set through one stdio connection. It was built because Cursor breaks when a third MCP server is added, and it doubles as a way to keep one MCP configuration for every client you run.
What you get
- Several backend MCP servers reachable through a single stdio connection, so a client that struggles past two servers sees only one
- Tools namespaced by their server —
search_storiesfrom ashortcutserver becomesshortcut_search_stories— so two servers can expose the same tool name without colliding - Dashes rewritten to underscores automatically, because Cursor cannot reliably detect tools with dashes in their names; the aggregator maps the sanitised name back when forwarding
- Per-server tool filtering: a
tools.allowedarray picks exactly which tools are exposed, which is how you stay under Cursor's limit of 40 tools - One configuration file for every client — Cursor, Windsurf, Gemini CLI, Codex, Claude Code, Copilot agents — so backend servers and their secrets are defined once
- Secrets isolation: API tokens live in the aggregator config rather than being handed to each client
- Debug logging with configurable levels and an optional log file
Requirements
No account and no key of its own; each backend server keeps whatever credentials it needs, declared in one JSON config. Install with the project's shell script, go install github.com/nazar256/combine-mcp/cmd/combine-mcp@latest, or the container image ghcr.io/nazar256/combine-mcp:latest. MCP_CONFIG is required and points at the configuration file — the format is the familiar mcpServers object, so an existing Cursor config can be copied across. MCP_LOG_LEVEL takes error, info, debug or trace and defaults to info, MCP_LOG_FILE names a log file, MCP_PROTOCOL_VERSION pins a protocol version for compatibility, and MCP_CURSOR_MODE turns on Cursor-specific adjustments. The README notes the code is mostly AI-generated.
Setup effort
One command — curl -fsSL https://raw.githubusercontent.com/nazar256/combine-mcp/main/install.sh | bash
USE CASES
01
Using more MCP servers than your client will tolerate
Register the aggregator as the only server; the rest are reached through it with prefixed names.
02
Staying under a client's tool limit
Set an allowlist per backend so only the tools you use are exposed, instead of the full surface of every server.
03
Keeping one MCP setup across several IDEs and agents
Define servers and secrets once and point every client at the same binary and config file, so nothing drifts between them.
04
Keeping API tokens away from the agent's config
Let the aggregator hold the credentials and pass through only the tool calls, rather than writing tokens into each client's settings.
BEFORE YOU INSTALL
What to know first
Requires
macOS or Linux on x86_64 or arm64 for the install script, or Go for go install
Where it runs
The documented client runs the server on your machine.
INSTALLATION
Connect your client
Server setup
TERMINAL
curl -fsSL https://raw.githubusercontent.com/nazar256/combine-mcp/main/install.sh | bashMCP Clients
Cursor
CURSOR · JSON
{
"mcpServers": {
"aggregator": {
"command": "combine-mcp",
"env": {
"MCP_CONFIG": "/Users/<YOUR_USERNAME>/.config/mcp/config.json"
}
}
}
}MCP_CONFIG is the full path of your aggregator config file. combine-mcp reads MCP_CONFIG as a literal path and does not expand ~, so the README's own ~/.config/mcp/config.json fails as written.