MCP Orchestrator
Agrega herramientas de múltiples servidores MCP con búsqueda unificada BM25/regex y carga diferida.
Documentación
MCP Orchestrator
Un centro central que se conecta a múltiples servidores MCP downstream, agrega sus herramientas y proporciona acceso unificado con potentes capacidades de búsqueda de herramientas.
Construido alrededor de carga diferida de herramientas — busca en todos tus servidores sin agotar la ventana de contexto de Claude.
Características
- Registro de servidores basado en configuración: Añade servidores MCP downstream mediante un archivo de configuración JSON
- Espaciado de nombres de herramientas: Formato automático
server_name__tool_name - Búsqueda de herramientas: Búsqueda unificada BM25/regex con soporte de carga diferida
- Autenticación flexible: Cabeceras estáticas guardadas o reenvío de tokens
- Múltiples transportes: stdio o HTTP
- Caché de definiciones de herramientas: Definiciones en caché, paso directo de resultados sin procesar
- Backends de almacenamiento: En memoria (desarrollo) o Redis (producción)
Inicio rápido
Instalación
pip install mcp-orchestrator
Ejecutar el servidor MCP
# Run as stdio MCP server (for Claude Desktop, Cursor, etc.)
mcp-orchestrator
# Or run with Python directly
python -m mcp_orchestrator.main
Transporte HTTP:
ORCHESTRATOR_TRANSPORT=http ORCHESTRATOR_PORT=8080 python -m mcp_orchestrator.main
Esto inicia el servidor en http://localhost:8080/mcp con CORS habilitado.
Configuración de servidores
Añade servidores MCP downstream en 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"]
}
]
}
Búsqueda de herramientas
El orquestador proporciona búsqueda unificada de herramientas (BM25 por defecto, regex opcional):
# 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
})
Arquitectura
┌─────────────────────────────────────────────────────┐
│ 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 │
└─────────┘ └─────────┘ └─────────┘
Configuración
Variables de entorno
| Variable | Por defecto | Descripción |
|---|---|---|
STORAGE_BACKEND | memory | Backend de almacenamiento (memory o redis) |
REDIS_URL | redis://localhost:6379/0 | URL de conexión a Redis |
MCP_ORCHESTRATOR_TOOL_CACHE_TTL | 300 | TTL de caché de esquema de herramientas en segundos |
MCP_ORCHESTRATOR_DEFAULT_CONNECTION_MODE | stateless | Modo de conexión por defecto |
MCP_ORCHESTRATOR_CONNECTION_TIMEOUT | 30.0 | Tiempo de espera de conexión en segundos |
MCP_ORCHESTRATOR_MAX_RETRIES | 3 | Número máximo de reintentos |
ORCHESTRATOR_TRANSPORT | stdio | Transporte MCP (stdio o http) |
ORCHESTRATOR_PORT | 8080 | Puerto para transporte HTTP |
ORCHESTRATOR_HOST | 0.0.0.0 | Host para transporte HTTP |
ORCHESTRATOR_LOG_LEVEL | INFO | Nivel de registro |
SERVER_CONFIG_PATH | server_config.json | Ruta al archivo de configuración del servidor |
Integración con Claude Desktop
Añade a tu configuración de Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"mcp-orchestrator": {
"command": "mcp-orchestrator",
"env": {
"STORAGE_BACKEND": "memory",
"ORCHESTRATOR_LOG_LEVEL": "INFO"
}
}
}
}
Herramientas MCP
tool_search
Busca herramientas usando clasificación de relevancia BM25 o coincidencia de patrones regex.
@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
Descubre herramientas de un servidor downstream registrado.
@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
Llama a una herramienta directamente en un servidor MCP downstream.
@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
"""
Resultados de búsqueda de herramientas
Las herramientas de búsqueda devuelven resultados en el formato esperado por el sistema de búsqueda de herramientas de Claude:
{
"success": true,
"tool_references": [
{
"type": "tool_reference",
"tool_name": "server_name__tool_name"
}
],
"total_matches": 5,
"query": "weather"
}
Pruebas
Ejecuta la suite de pruebas:
uv run pytest
Ejecuta con cobertura:
uv run pytest --cov=mcp_orchestrator
Estructura del proyecto
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)
Licencia
Licencia MIT
Contribuciones
¡Las contribuciones son bienvenidas! Consulta CONTRIBUTING.md para las pautas.