Every MCP server you add taxes every turn, whether or not the task needs it. Routing turns that fixed cost into a variable one: the client carries a handful of broker tools, and the full inventory is queried only when a task actually calls for it. The cost is a hop — the model asks which tool, then calls it — and a dependency stack, since the good selection path wants a container runtime and a vector database running alongside.
A router for MCP servers. It spawns your child servers, embeds their tool definitions into a vector store, and presents them to a client through a single connection — either proxying every tool under a namespace, or answering natural-language queries about which tool fits the task so the client only ever sees the relevant few.
- A meta-tool that takes a plain-English `query` and a `max_results`, and returns the most relevant tools as name, description and owning server — you then call them directly — `find_tools`
- Every child tool still reachable by name, published under a namespaced form that folds a dotted server-and-tool name into one legal MCP identifier and truncates to the 64-character limit the protocol mandates
- Three selection strategies behind that one call: vector similarity over embeddings (the default), selection by a local LLM, and RAG-based selection that pulls in indexed child-server documentation before choosing
- Configuration reuse rather than a second inventory — the servers file takes the same `mcpServers` shape your client config already uses, so you can point it straight at your existing Claude Desktop config and re-expose the same children through the routing layer
- Resilient startup: if the embedding service, the vector store or the LLM fails to initialize, it logs a warning and keeps going — child tools stay reachable even with nothing else running
- A separate dashboard process with a web UI for watching child-server health and debugging why a given query selected the tools it did
No account and no key. Python 3.11+ and uv, which supplies the `uvx` command the documented config uses. Docker or Apple Container is needed to run Qdrant, which backs vector-based tool selection — optional if you point at an already-running Qdrant or skip routing entirely. LM Studio is optional for local embeddings and LLM-based selection; without it the server falls back to a bundled sentence-transformers model automatically. The project is `mcpdeck` (0.3.0 in pyproject), launched from git with uvx and pointed at your servers file with `--mcp-servers-json`. Note the split: the stdio path for MCP clients keeps the web UI disabled even if your config enables it, because the dashboard prints to stdout and would corrupt the JSON-RPC channel — use the dashboard command when you want the UI.
One command — uv tool install git+https://github.com/anirudhlath/mcpdeck
