io.github.rupinder2/mcp-gateway
Aggregates tools from multiple MCP servers with unified BM25/regex search and deferred loading.
Ask AI about io.github.rupinder2/mcp-gateway
Powered by Claude Β· Grounded in docs
I know everything about io.github.rupinder2/mcp-gateway. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
MCP Orchestrator
A central hub that connects to multiple downstream MCP servers, aggregates their tools, and provides unified access with powerful tool search capabilities.
Built around deferred tool loading β search across all your servers without blowing Claude's context window.
Features
- Config-based Server Registration: Add downstream MCP servers via JSON config file
- Tool Namespacing: Automatic
server_name__tool_nameformat - Tool Search: Unified BM25/regex search with deferred loading support
- Flexible Authentication: Static saved headers or token forwarding
- Multiple Transports: stdio or HTTP
- Tool Definition Caching: Cached definitions, raw result passthrough
- Storage Backends: In-memory (development) or Redis (production)
Quick Start
Installation
pip install mcp-orchestrator
Running the MCP Server
# Run as stdio MCP server (for Claude Desktop, Cursor, etc.)
mcp-orchestrator
# Or run with Python directly
python -m mcp_orchestrator.main
HTTP Transport:
ORCHESTRATOR_TRANSPORT=http ORCHESTRATOR_PORT=8080 python -m mcp_orchestrator.main
This starts the server on http://localhost:8080/mcp with CORS enabled.
Configuring Servers
Add downstream MCP servers in server_config.json:
{
"servers": [
{
"name": "my-server",
"url": "http://localhost:8080/mcp",
"transport": "http",
"auth_type": "static",
"auth_headers": {
"Authorization": "Bearer my-token"
}
},
{
"name": "my-stdio-server",
"url": "server.py",
"transport": "stdio",
"command": "uv",
"args": ["run", "python", "server.py"]
}
]
}
Searching for Tools
The orchestrator provides unified tool search (BM25 by default, regex optional):
# BM25 search (default - natural language)
results = await mcp_client.call_tool("tool_search", {
"query": "get weather information",
"max_results": 3
})
# Regex search (set use_regex=true)
results = await mcp_client.call_tool("tool_search", {
"query": "weather|forecast",
"use_regex": true,
"max_results": 3
})
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Orchestrator β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β FastMCP Server β β
β β βββββββββββββββ ββββββββββββββββββββ β β
β β β tool_search β β call_remote_tool β β β
β β βββββββββββββββ ββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββ ββββββββββββ ββββββββββββββββ β
β β Server β β Tool β β Storage β β
β β Registry β β Search β β(Memory/Redis)β β
β ββββββββββββ ββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββΌββββββββββββββββββββ
βΌ βΌ βΌ
βββββββββββ βββββββββββ βββββββββββ
β MCP Svr β β MCP Svr β β MCP Svr β
β #1 β β #2 β β #N β
βββββββββββ βββββββββββ βββββββββββ
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
STORAGE_BACKEND | memory | Storage backend (memory or redis) |
REDIS_URL | redis://localhost:6379/0 | Redis connection URL |
MCP_ORCHESTRATOR_TOOL_CACHE_TTL | 300 | Tool schema cache TTL in seconds |
MCP_ORCHESTRATOR_DEFAULT_CONNECTION_MODE | stateless | Default connection mode |
MCP_ORCHESTRATOR_CONNECTION_TIMEOUT | 30.0 | Connection timeout in seconds |
MCP_ORCHESTRATOR_MAX_RETRIES | 3 | Maximum retry attempts |
ORCHESTRATOR_TRANSPORT | stdio | MCP transport (stdio or http) |
ORCHESTRATOR_PORT | 8080 | Port for HTTP transport |
ORCHESTRATOR_HOST | 0.0.0.0 | Host for HTTP transport |
ORCHESTRATOR_LOG_LEVEL | INFO | Logging level |
SERVER_CONFIG_PATH | server_config.json | Path to server configuration file |
Claude Desktop Integration
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"mcp-orchestrator": {
"command": "mcp-orchestrator",
"env": {
"STORAGE_BACKEND": "memory",
"ORCHESTRATOR_LOG_LEVEL": "INFO"
}
}
}
}
MCP Tools
tool_search
Search for tools using BM25 relevance ranking or regex pattern matching.
@mcp.tool()
async def tool_search(
query: str,
max_results: int = 3,
use_regex: bool = False,
) -> dict:
"""Search for tools using BM25 or regex.
By default uses BM25 natural language search. Set use_regex=True
to search using Python regex patterns instead.
"""
discover_tools
Discover tools from a registered downstream server.
@mcp.tool()
async def discover_tools(
server_name: str,
) -> dict:
"""Discover tools from a registered server and index them for search.
Returns the list of discovered tools with their schemas.
"""
call_remote_tool
Call a tool directly on a downstream MCP server.
@mcp.tool()
async def call_remote_tool(
tool_name: str,
arguments: Optional[dict] = None,
auth_header: Optional[str] = None,
) -> Any:
"""Call a tool on a downstream server.
Args:
tool_name: Namespaced tool name (server_name__tool_name)
arguments: Tool arguments
auth_header: Optional auth header to override server's configured auth
"""
Tool Search Results
The search tools return results in the format expected by Claude's tool search system:
{
"success": true,
"tool_references": [
{
"type": "tool_reference",
"tool_name": "server_name__tool_name"
}
],
"total_matches": 5,
"query": "weather"
}
Testing
Run the test suite:
uv run pytest
Run with coverage:
uv run pytest --cov=mcp_orchestrator
Project Structure
mcp-orchestrator/
βββ src/mcp_orchestrator/
β βββ __init__.py
β βββ main.py # Entry point
β βββ models.py # Pydantic models
β βββ mcp_server.py # FastMCP server
β βββ config_loader.py # Config file loader
β βββ server/
β β βββ registry.py # Server registry
β βββ tools/
β β βββ router.py # Tool router
β β βββ search.py # Tool search service
β βββ storage/
β βββ base.py # Storage interface
β βββ memory.py # In-memory backend
β βββ redis.py # Redis backend
βββ tests/
β βββ test_registry.py
β βββ test_search.py
β βββ test_storage.py
β βββ test_models.py
β βββ test_integration.py
βββ server_config.json # Pre-configured downstream servers
βββ pyproject.toml
βββ README.md
βββ .env # Environment variables (not committed)
License
MIT License
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
