MCP Sieve — semantic tool selection proxy for LLMs. Aggregates downstream MCP servers into 2 static tools (select + call) via Ollama embeddings.
Project description
MCP Sieve
A semantic proxy for MCP servers. Solves tool selection degradation — when an LLM has too many tools, it picks the wrong ones.
The sieve sits between the client (Claude Code, Hermes, any MCP client) and downstream MCP servers. The client sees 2 tools instead of dozens: mcp_router_select + mcp_router_call. The first finds relevant tools via embeddings, the second proxies the call.
How it works
Client (Claude Code / Hermes)
↓ sees only 2 tools
mcp_router_select(task="...") → embeddings → top-N relevant tools
mcp_router_call(tool_name, arguments) → proxies to downstream
↓
downstream MCP servers (time, fetch, git, arxiv, playwright, ...)
Two call paths:
-
Path 1 (notifications/tools/list_changed):
selectfinds tools → sieve updatestools/list→ client calls tools directly. Works with clients that support dynamic toolset updates. -
Path 2 (mcp_router_call proxy): for clients with a frozen toolset (Hermes, Claude Code with prompt caching).
selectreturns tools withinputSchema→callproxies execution. No/resetneeded when new downstream tools are discovered.
Install
git clone <repo> ~/Projects/mcp-sieve
cd ~/Projects/mcp-sieve
uv pip install -e .
Requires Ollama with an embed model:
ollama pull nomic-embed-text
Quick start
Copy the example config and edit it:
cp config.example.yaml config.yaml
# edit config.yaml — add your downstream servers and paths
Run standalone:
python -m mcp_router.server
Server listens on stdio (JSON-RPC).
Connect to Claude Code
In ~/.claude.json → projects["<path>"].mcpServers:
"sieve": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "/path/to/mcp-sieve", "mcp-sieve"],
"env": {
"MCP_ROUTER_CONFIG": "/path/to/mcp-sieve/config.yaml"
}
}
Or via CLI:
claude mcp add sieve -- uvx --from /path/to/mcp-sieve mcp-sieve
Windows:
MCP_ROUTER_CONFIGis required —uvxinstalls the package into an isolated venv,__file__points into uv-cache. See Windows notes below.
Connect to Hermes
hermes mcp add sieve --command uvx --args "--from" --args "/path/to/mcp-sieve" --args "mcp-sieve"
hermes mcp test sieve
# /reset in chat
Config
config.yaml (see config.example.yaml for a full template):
downstream:
- name: time
command: uvx
args: ["mcp-server-time"]
- name: fetch
command: uvx
args: ["mcp-server-fetch"]
- name: git
command: uvx
args: ["mcp-server-git", "--repository", "/path/to/your/repo"]
# Windows: npx is a .cmd file — needs cmd /c
- name: context7
command: cmd
args: ["/c", "npx", "-y", "@upstash/context7-mcp@latest"]
- name: filesystem
command: cmd
args: ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
# Remote MCP over HTTP (streamable) or SSE — no local process.
# transport defaults to stdio; a bare url implies http.
- name: gitmcp
transport: http
url: "https://gitmcp.io/docs"
embeddings:
ollama_url: "http://127.0.0.1:11434/api/embeddings"
model: "nomic-embed-text"
top_n: 10
Env variables:
MCP_ROUTER_CONFIG— path toconfig.yaml(otherwise looks in CWD or next to source)MCP_SIEVE_DOWNSTREAM_<N>_NAME/_COMMAND/_ARGS/_URL/_TRANSPORT— define downstream servers without a file (Docker/k8s).Nstarts at 1, stops at the first gap._ARGSis a JSON array or whitespace-split. A same-named entry overrides the yaml one.MCP_SIEVE_OLLAMA_URL/MCP_SIEVE_EMBED_MODEL/MCP_SIEVE_TOP_N— embeddings overrides
Crashed downstream servers (Ollama, npx) auto-reconnect with exponential backoff — no restart needed.
Windows notes
-
npx →
cmd /c npx:npxis a.cmdfile, Python subprocess (MCP SDK) can't find it without a shell.uvxis a real binary, works directly. -
uvx --from and dependencies:
uvx --from <project>installs the package into an isolated uv-cache venv. All imports must be inpyproject.toml[project.dependencies]— implicit deps from the dev env won't be picked up. -
uv cache clean: if the cache is locked (
os error 32), kill MCP server processes first:powershell -Command "Get-Process | Where-Object { $_.ProcessName -match 'mcp|uv' } | Stop-Process -Force" uv cache clean --force
-
Debug connection failures:
claude --debugwrites to~/.claude/debug/<session>.txt. GrepServer stderr:for real server tracebacks.
Stack
- MCP Python SDK (
mcp) — stdio + HTTP/SSE transports,notifications/tools/list_changed - Ollama — local embeddings (
nomic-embed-text), free - numpy — cosine similarity
- httpx — HTTP client for Ollama API
Fallback
If Ollama is unavailable — the sieve doesn't crash. mcp_router_select returns all downstream tools without ranking, with a warning in the response.
Performance
Tested with 9 downstream servers (74 tools):
mcp_router_select: 83–166msmcp_router_call: 15–774ms (longest: playwright browser navigation)- Startup: ~16s (all 9 downstream connect + 74 embeddings built)
Status
Working end-to-end in Claude Code and Hermes. See TASKS.md for the roadmap and benchmark results.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_sieve-0.1.0.tar.gz.
File metadata
- Download URL: mcp_sieve-0.1.0.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d75d605ec028e95a580860e7e8c4f5913c3297e8860fe21be589ed731155636e
|
|
| MD5 |
40b0ed41c0549b84bc1e60a86b6691ff
|
|
| BLAKE2b-256 |
062a16a002bad9d18fa10109673b199be92f4622a1bada24d76b88b988b47ce5
|
File details
Details for the file mcp_sieve-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_sieve-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb6a4c5175113638c22d10b8cd9effae910870b63795eae887f599e13cef1c13
|
|
| MD5 |
a3b033f1e5084475f0f90e6a3e4bd84f
|
|
| BLAKE2b-256 |
d36875113389db930885a0fda7f67bc50bdb052c77f17f5fa845c072b9647d16
|