Skip to main content

dhis2w-mcp-router

A domain-neutral MCP router: front many upstream MCP servers behind two meta-tools so an agent gets lazy, searchable tool discovery instead of a huge up-front tool payload.

It is the portable, MCP-native equivalent of the Claude Agent SDK's ToolSearch — but it works with any MCP client (local models via LM Studio / Ollama / llama.cpp, or cloud agents), not just Claude's SDK.

Why

A big MCP server (e.g. ~337 dhis2-mcp tools) dumps ~49k tokens of tool schemas into context up front — which overflows small local models and costs cloud models on every call. The single-tool dhis2_cli bridge avoids that by collapsing everything behind one tool, but then the agent must discover a CLI (run --help, trial commands) — discovery overhead. The router is the middle ground:

tool payload discovery typed schemas guardable chokepoint
full MCP server huge (all schemas) none yes per-tool
single-tool bridge tiny (1 tool) high (learn a CLI) no yes (1 tool)
router (this) tiny (2 meta-tools) low (search) yes (search returns schemas) yes (1 dispatch)

The two tools

  • search_tools(query, limit) — matching tools with their namespaced names (server__tool) and input schemas.
  • call_tool(name, arguments) — dispatch one tool to its upstream and return the result.

call_tool is a single chokepoint, so a policy guard sits there — the same security property as the bridge, with typed discovery on top.

Read-only mode

Set MCP_ROUTER_READONLY=1 (global) or mark a single upstream "readonly": true in the config to run read-only: write tools are hidden from search_tools and refused by call_tool (a PermissionError). Tools are classified by their readOnlyHint annotation when present, else by a read-verb heuristic on the tool name (fail-closed). This is how a local model safely drives the surface on a shared host — front play read-only and local read-write in the same config.

Config

Point it at any MCP servers via a JSON config (env MCP_ROUTER_CONFIG, default mcp-router.json):

{
  "servers": [
    {"name": "dhis2", "command": "uv", "args": ["run", "--directory", "/repo", "dhis2w-mcp"],
     "env": {"DHIS2_PROFILE": "play42"}}
  ]
}

Run it as a stdio MCP server: uv run dhis2w-mcp-router.

Ranking

search_tools ranking is pluggable. The default KeywordRanker scores by query-term hits (no deps). Add an embeddings block (url + model, an OpenAI-compatible /v1/embeddings endpoint — e.g. a local embedder in LM Studio / Ollama) to rank by semantic similarity instead, which fixes keyword mis-ranks (e.g. "data element count" → metadata_count first). It is not a silver bullet on terse queries with a small local embedder; a larger embedder or a hybrid is the further upgrade.

Status

Published to PyPI from 1.2.0, in lockstep with the rest of the dhis2w-* workspace. The core (core.py) is domain-neutral (FastMCP + httpx only, no dhis2w-* imports), so the same code could also extract to a standalone mcp-router repo without a rewrite. Whether the router should become the default MCP surface for all clients (not just small local models) is still gated on the bench-router numbers — see the roadmap.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dhis2w_mcp_router-1.13.1.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dhis2w_mcp_router-1.13.1-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file dhis2w_mcp_router-1.13.1.tar.gz.

File metadata

  • Download URL: dhis2w_mcp_router-1.13.1.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for dhis2w_mcp_router-1.13.1.tar.gz
Algorithm Hash digest
SHA256 b43949196ab4806c19cb5d3917844ccbec868b2eb23d1b42d17bed0a49ec65b1
MD5 c2cd7eb43757ee843fe3614ea01f3a53
BLAKE2b-256 bf2d7e99c46643e5510978216e965bc9762af2c0a2e54c391862eac6cefe9421

See more details on using hashes here.

Provenance

The following attestation bundles were made for dhis2w_mcp_router-1.13.1.tar.gz:

Publisher: pypi-publish.yml on winterop-com/dhis2w-utils

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dhis2w_mcp_router-1.13.1-py3-none-any.whl.

File metadata

File hashes

Hashes for dhis2w_mcp_router-1.13.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d1e54ad14af3dd8e48afe852325baa168c9c78d2087bbd384bed40df9f87d991
MD5 7b9471ef3e31364072240a248d8e0e30
BLAKE2b-256 04edd440b8cb1e0d80c0ad276685efb314627ace4e777c93fb51847d8c951fa7

See more details on using hashes here.

Provenance

The following attestation bundles were made for dhis2w_mcp_router-1.13.1-py3-none-any.whl:

Publisher: pypi-publish.yml on winterop-com/dhis2w-utils

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.13.4

2 files

1.13.3

2 files

1.13.2

2 files

This release

1.13.1 This release

2 files

1.13.0

2 files

1.12.0

2 files

1.11.0

2 files

1.10.0

2 files

1.9.0

2 files

1.8.3

2 files

1.8.2

2 files

1.8.1

2 files

1.8.0

2 files

1.7.0

2 files

1.6.0

2 files

1.5.0

2 files

1.3.0

2 files

1.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page