Labsco
nazar256 logo

MCP Aggregator

โ˜… 32

from nazar256

An MCP (Model Context Protocol) aggregator that allows you to combine multiple MCP servers into a single endpoint allowing to filter specific tools.

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅโœ“ VerifiedFreeAdvanced setup

MCP Aggregator

An MCP (Model Context Protocol) aggregator that allows you to combine multiple MCP servers into a single interface. The code is mostly AI-generated.

Why combine MCP servers into one?

The primary reason for this app was to work around Cursor's limitation of only being able to use 2 MCP servers at a time. No matter which, in my case when I added 3rd MCP server, it was breaking the ability to use one of other two.

Overview

The MCP Aggregator acts as a bridge between Cursor (or any other MCP client) and multiple MCP servers. It functions both as an MCP server (when talking to Cursor) and as an MCP client (when talking to backend MCP servers).

Key features:

  • Provides a stdio interface for Cursor and other MCP clients
  • Connects to multiple backend MCP servers
  • Prefixes methods from backend servers (e.g., "shortcut_search_stories" for "search_stories" method from a "shortcut" MCP)
  • Automatically sanitizes tool names by replacing dashes with underscores for Cursor compatibility
  • Configurable via environment variables and JSON config file
  • Debug logging with configurable levels

Use cases

Unified MCP config for multiple clients

One practical use case is to maintain a single MCP configuration file that is shared across different MCP-capable clients (e.g. Cursor, Windsurf, Gemini-CLI, Codex, Claude Code, GitHub Copilot agents, etc.).

Instead of configuring each client with its own list of MCP servers and duplicating secrets, you:

  • Configure all backend MCP servers (and their secrets) once in the aggregator config.
  • Point each client to the same combine-mcp binary with the same MCP_CONFIG file.
  • Let the aggregator handle prefixing, filtering and normalization of tools for every client.

This has a few benefits:

  • Single source of truth for which MCP servers and tools are available.
  • Centralized secret management โ€“ API tokens and other credentials live only in the aggregator config.
  • Consistent behaviour across different IDEs/agents without per-client MCP reconfiguration.
  • Secrets isolation โ€“ no need to share secrets with AI agent tools directly.

Tool Name Sanitization

The MCP Aggregator automatically sanitizes tool names by replacing dashes with underscores. This is necessary because Cursor has a known issue where it cannot properly detect or use tools with dashes in their names.

For example:

  • Original tool name: get-user
  • Sanitized tool name: get_user
  • Prefixed tool name (for shortcut server): shortcut_get_user

The sanitization is transparent - when you call a tool using the sanitized name, the aggregator maps it back to the original name when forwarding the request to the backend server.

Tool Filtering

The MCP Aggregator supports optional tool filtering per server. This is useful when you want to:

  • Limit the number of exposed tools to stay within Cursor's tool limit (40 tools maximum)
  • Only expose specific tools from each server
  • Avoid tool name conflicts between servers
  • Improve performance by reducing the number of tools to process

To enable tool filtering, add a tools object to your server configuration with an allowed array listing the tools you want to expose:

{
  "mcpServers": {
    "shortcut": {
      "command": "npx",
      "args": ["-y", "@shortcut/mcp"],
      "env": {
        "SHORTCUT_API_TOKEN": "your-shortcut-api-token-here"
      },
      "tools": {
        "allowed": [
          "search-stories",
          "get-story",
          "create-story",
          "assign-current-user-as-owner"
        ]
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "your-github-token-here"
      },
      "tools": {
        "allowed": [
          "create-pr",
          "list-prs",
          "get-pr",
          "merge-pr"
        ]
      }
    }
  }
}