mcp-orchestrator
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-orchestratorsearch all connected servers for a tool that sends email"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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_nameformatTool 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)
Related MCP server: super-mcp
Quick Start
Installation
pip install mcp-orchestratorRunning the MCP Server
# Run as stdio MCP server (for Claude Desktop, Cursor, etc.)
mcp-orchestrator
# Or run with Python directly
python -m mcp_orchestrator.mainHTTP Transport:
ORCHESTRATOR_TRANSPORT=http ORCHESTRATOR_PORT=8080 python -m mcp_orchestrator.mainThis 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 ( |
|
| Redis connection URL |
|
| Tool schema cache TTL in seconds |
|
| Default connection mode |
|
| Connection timeout in seconds |
|
| Maximum retry attempts |
|
| MCP transport ( |
|
| Port for HTTP transport |
|
| Host for HTTP transport |
|
| Logging level |
|
| 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 pytestRun with coverage:
uv run pytest --cov=mcp_orchestratorProject 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.
Available Tools
2 toolscall_remote_toolA
Call a tool directly on a registered remote MCP server through the orchestrator.
This tool allows direct invocation of any tool on a downstream MCP server. The tool name should be in the format 'server_name__tool_name' (e.g., 'context7__query-docs').
Args: tool_name: Full tool name in format 'server_name__tool_name' arguments: Tool arguments as a dictionary (optional) auth_header: Optional auth header to use for this call (overrides registered auth)
Returns: Raw tool call result from the remote server
| Name | Required | Description | Default |
|---|---|---|---|
| arguments | No | ||
| tool_name | Yes | ||
| auth_header | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that the result is a raw remote call result and that auth_header overrides registered auth. It does not mention error behavior, side effects, or the fact that arbitrary remote tool calls may be destructive, which would be useful for such a generic passthrough tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized with a short introductory statement, Args, and Returns sections. It is readable and information-dense. There is minor redundancy between 'Call a tool directly' and 'allows direct invocation of any tool,' but it does not hurt comprehension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a generic arbitrary remote invocation with no output schema and no annotations, so the description needs to cover a lot. It covers the naming convention, arguments, auth override, and raw return. It does not explain how to discover registered servers/tools, how to handle errors, or warn about side effects, leaving some gaps for an agent invoking arbitrary downstream tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description explains all three parameters: tool_name format, arguments as an optional dictionary, and auth_header as an optional override. The concrete example ('context7__query-docs') adds real value beyond the bare schema. It could go further on argument structure, but it is solid.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it calls a tool on a remote MCP server through the orchestrator. It also clarifies the exact name format, which helps distinguish it from generic tool use. However, it does not explicitly contrast itself with the sibling tool_search beyond implying direct remote invocation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is for direct invocation of a known remote tool, and gives the name format. It does not explicitly say when to prefer tool_search or when not to use this tool, so usage guidance is present but not fully developed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tool_searchA
Search for tools using BM25 relevance ranking or regex pattern matching.
Searches across tool names, descriptions, and argument names/descriptions. By default, uses BM25 natural language search. Set use_regex=True to search using Python regex patterns instead. Returns tool_reference blocks for discovered tools with deferred loading.
Args: query: Natural language query (BM25) or regex pattern (if use_regex=True) max_results: Maximum number of results (1-10, default 3) use_regex: If True, treat query as regex pattern; otherwise use BM25 search
Returns: Tool search results with tool_reference blocks for discovered tools
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| use_regex | No | ||
| max_results | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the return type (tool_reference blocks) and the deferred loading behavior, which is useful. It does not explicitly state it is read-only, but the nature of a search tool makes that implicit. No contradictions with annotations (none present).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, followed by scope, modes, return, and Args. It is efficient and well-structured, with no redundant sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the tool's function, search scope, two modes, return type, and deferred loading. With an output schema present, the description does not need to detail the return structure further. All parameters are documented and the tool is simple enough that no additional context is required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description fully compensates. The Args section explains each parameter's meaning: query semantics depend on use_regex, max_results range (1-10) and default, and use_regex purpose. This adds significant value beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for tools using BM25 or regex, explicitly specifying the resource and action. It differentiates from the sibling call_remote_tool by its focus on discovery rather than invocation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance on when to use each search mode (natural language vs regex) via the use_regex flag. Does not explicitly mention when to prefer this tool over call_remote_tool, but the purpose is distinct enough for an agent to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.2- First observed
call_remote_tool - First observed
tool_search
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one searches/disovers tools across servers, the other invokes a specific remote tool. There is no overlap or ambiguity between them.
Both names are snake_case and descriptive, but 'tool_search' follows a noun_verb pattern while 'call_remote_tool' follows verb_remote_noun. This is a minor inconsistency; renaming to 'search_tools' would make it perfectly uniform.
With only 2 tools, the server feels slightly thin for an orchestrator role. The tool count is borderline below the typical 3-15 range, but the two tools cover core orchestration functions (discovery and invocation).
The pair covers the main workflow: search for tools and call them. However, missing operations like listing registered servers, checking server health, or managing registrations mean the surface is not fully complete for a comprehensive orchestrator, though workable for basic flows.
Maintenance
Related MCP Connectors
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
The Remote MCP server acts as a standardized bridge between LLM applications (like Claude, ChatGPT, and Cursor) and external services, enabling AI agents to access external tools and resources. Its primary capability is providing a centralized search tool to discover other MCP servers and their respective tools. Unlike local implementations, it runs remotely with OAuth authentication and permission controls for security.
Search, vet & assemble MCP servers from your agent: verified tools, risk labels, and trust scores.
MCP Gateway: wrap any MCP server with cold-start retries, uptime SLA, and per-execution MPP billing.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables centralized management and unified interface for multiple child MCP servers (filesystem, sqlite, etc.), allowing users to discover, launch, and execute tools across different MCP servers through a single gateway.-
- AlicenseNot gradedqualityCmaintenanceA gateway that aggregates multiple MCP servers into a single endpoint, namespacing their tools and forwarding calls, so an agent connects to one MCP to access the entire stack.MIT
- AlicenseNot gradedqualityBmaintenanceActs as an MCP gateway aggregating multiple child MCP servers into a single namespaced interface, with an optional memory layer that caches tool results to reduce redundant calls.15 npmMIT
- AlicenseAqualityAmaintenanceEnables AI harnesses to connect to a single MCP endpoint that routes to multiple downstream MCP servers, discovering and executing capabilities on demand while keeping tool schemas out of context.450 npmApache 2.0