Skip to main content
Glama
ishaanpilar
by ishaanpilar

mcp-slim-proxy

A client-agnostic Model Context Protocol proxy that slims the tool-definition context tax.

Every MCP tool call serializes the full tool schema into the model's context window. Wire up a dozen chatty servers and your agent spends most of its budget reading its own menu — one reported team burned 143k of a 200k token budget (72%) on tool definitions before doing any work.

mcp-slim-proxy sits between any MCP client (Claude Desktop, Cursor, a custom agent) and any number of upstream MCP servers. Instead of exposing all N servers' schemas, it exposes a handful of meta-tools:

meta-tool

what it does

search_tools

natural-language search over the aggregated catalog → names + one-line summaries (cheap)

load_tool

pull specific tools' full schemas into the live tool list so they become callable (tools/list_changed)

unload_tool

drop tools back out to reclaim context

load_bundle

load a named, preconfigured group of tools at once

proxy_report

live before/after token accounting

The agent searches in plain language, loads only the handful of tools it needs, and calls them — the proxy forwards each call to the owning upstream transparently. Everything else stays out of context.

The win scales with server count

The slimmed side stays ~flat (meta-tools + a small working set) while a naive aggregating proxy grows linearly. From scripts/benchmark.py (tiktoken counts):

servers

tools

baseline tokens

slimmed tokens

saved

1

10

1,384

951

31.3%

5

50

6,904

951

86.2%

10

100

13,804

951

93.1%

25

250

34,504

951

97.2%

100

1000

138,004

951

99.3%

Install

uv venv
uv pip install -e ".[tokens,http]"   # tokens = exact tiktoken counts; http = serve over HTTP

Extras: tokens (tiktoken), http (starlette+uvicorn), embeddings (sentence-transformers semantic ranker), dev (tests).

Related MCP server: MCPLens

Configure

The config mirrors the familiar mcpServers block from Claude Desktop / Cursor. Both stdio and streamable-HTTP upstreams are supported.

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    },
    "remote": {
      "url": "https://example.com/mcp",
      "headers": { "Authorization": "Bearer ${MY_MCP_TOKEN}" }
    }
  },
  "settings": {
    "compressDescriptions": true,
    "ranker": "bm25",
    "searchLimit": 8,
    "alwaysLoad": ["filesystem__read_file"],
    "bundles": { "files": ["filesystem__read_file", "filesystem__write_file"] },
    "lazyConnect": true,
    "cache": true,
    "cacheTtlSeconds": 86400
  }
}

${ENV_VAR} references are expanded so secrets stay in the environment. Add "enabled": false to keep a server in the file but skip it. The settings block is optional; every key shown is a default.

Run

As a stdio MCP server (the transport clients spawn):

mcp-slim-proxy --config config.json

Over HTTP instead (point an HTTP-capable client at http://host:port/mcp):

mcp-slim-proxy --config config.json --transport http --port 8848

Example Claude Desktop entry:

{
  "mcpServers": {
    "slim": { "command": "mcp-slim-proxy", "args": ["--config", "/abs/path/config.json"] }
  }
}

Measure the savings

Connect, print the before/after token report, and exit — no client needed:

mcp-slim-proxy --config examples/multi.config.json --report          # human
mcp-slim-proxy --config examples/multi.config.json --report --json   # for CI

The JSON report also lists connected/failed upstreams, always-loaded tools, and cross-server duplicate groups. Run the scaling table with python scripts/benchmark.py.

How it works

   client                 mcp-slim-proxy                upstream MCP servers
  ┌──────┐  stdio/http ┌──────────────────────┐  stdio/http   ┌───────────┐
  │agent │◀───────────▶│ search_tools         │◀─────────────▶│ filesystem│
  └──────┘  meta-tools │ load_tool / _bundle  │  (lazy conn)  ├───────────┤
            + loaded   │ unload_tool          │               │ gmail     │
            tools      │ proxy_report ─┐ BM25 │               ├───────────┤
                       └───────────────┴──────┘               │ remote…   │
                              catalog cache (disk)            └───────────┘
  • Aggregation — connects to every upstream as an MCP client and namespaces tools as <server>__<tool> to avoid collisions. A failed upstream is logged and skipped, not fatal.

  • Lexical search — a dependency-free BM25 index over each tool's name, description, and parameter names (camelCase / snake_case aware). Deterministic and trivially benchmarkable. An optional embeddings ranker is available via "ranker": "embeddings" + the embeddings extra.

  • Description compression — strips boilerplate ("Use this tool to…") and schema-duplicating Args:/Returns: blocks before a schema enters context. Applied only to exposed tools; the report baseline stays uncompressed so reported savings are honest.

  • Dedupe — near-identical tools across servers share a signature; search collapses them and --report --json lists the duplicate groups.

  • Lazy connect + cross-session cache — the aggregated catalog is cached to disk (keyed by the server set), so repeated sessions don't re-pay tool discovery; a server is only actually connected when one of its tools is first called. --refresh re-discovers; --clear-cache wipes it. Connection lifecycles are owned by a single host task so shutdown is clean under anyio.

  • Lazy schemas — full schemas enter context only when load_tool / load_bundle runs, which fires tools/list_changed so the client re-fetches.

Develop

uv pip install -e ".[dev,tokens,http]"
uv run pytest -q --timeout=60

Tests cover the catalog/BM25, compression, cache round-trips, config parsing, the token report, and full stdio and HTTP client loops against bundled demo servers (examples/demo_server.py, examples/db_server.py).

Roadmap

  • Embeddings ranker is wired but ships behind an extra; add a bundled small model.

  • Per-tool call metrics in the report.

  • Hot-reload of upstream tool lists on tools/list_changed from upstreams.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Acts as a proxy for multiple MCP servers, reducing context window usage from 15,000+ tokens to ~500 tokens by dynamically loading servers on-demand and exposing only 3 tools instead of all tool definitions.
    5
    GPL 3.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    A context-efficient proxy that replaces individual tool schemas with three meta-tools for semantic search, schema retrieval, and tool routing. It enables agents to manage hundreds of backend tools while maintaining a constant context footprint of approximately 500 tokens.
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A generic MCP proxy that filters which tools are exposed from a remote MCP server, reducing context window token usage by only loading the tools you actually need.
    6 npm
    1
    MIT