Skip to content

10,049 tokens in. 318 out. Secrets stay home.

$ brew tap mmornati/leanproxy-mcp https://github.com/mmornati/leanproxy-mcp
$ brew install leanproxy-mcp

A local token firewall between your AI client and every MCP server. It cuts what tool schemas and tool results cost you, and it redacts, screens and pins everything on the way through. One Go binary, and nothing leaves your machine unless you turn it on.

On the belt
10,049 tok
Threats
0 boxed · 0 leaked
Overhead
0.56 ms p50 · 0.74 ms p95
Binary
16.4 MiB · 20 MiB RSS

Scan of the benchmark catalog: 5 servers, 118 tools, with sizes as measured by make harness against the real binary. The secret is a planted test value. Drag the scan line, or use the arrow keys.

What the scanner looks for

Two kinds of cargo come through every MCP call: weight you pay for on every turn, and payloads that can hurt you. LeanProxy handles both in the same pass, before anything reaches your model provider.

Weight tokens you pay for

  • Router or passthrough Four router tools cost 318 tokens instead of every schema on every turn. Clients that already search their own tools get every tool listed as server__tool instead.
  • search_tools BM25 search across every server. A lookup costs 152 tokens on average, and it puts the right tool in the top 5 for 85.5% of 83 labeled intents.
  • Response governor Per-tool field projection, head/tail and structural truncation, dedup within a session, and paging back through read_result.
  • Response cache An opt-in, exact-match cache for read tools you allowlist, bounded by bytes.

Threats payloads that can hurt you

  • Secret redaction 29 built-in patterns, in both directions, on by default. Add your own, or switch on the high-entropy detector for keys no pattern knows.
  • Prompt injection guard Switch it on and a local classifier screens requests, tool results, resources and prompts. Each risk band can block, quarantine, redact or annotate.
  • Tool pinning Hashes every upstream tool definition and flags rug pulls, hidden instructions and invisible unicode until you approve them.
  • Per-tool policy Allow, deny or confirm by tool glob and by annotation. Calls to tools a server never advertised are refused.
  • Sandboxed servers Runs third-party stdio servers in a Docker or Podman container, with no network and no filesystem access by default.

Cleared what you can check afterwards

  • doctor security A read-only report mapped to the OWASP MCP Top 10, with --json for CI.
  • Savings report Built from real counters, broken down by server and by session.
  • OpenTelemetry Traces and metrics for every proxied call, exported over OTLP to the collector you already run.
  • tools pins and policy check See what changed upstream before you approve it, and test a rule before a call hits it.

Measured, with the test conditions attached

Three recorded working sessions, replayed through the binary. Native MCP keeps all five servers' schemas in context on every turn; the harness bills later turns at a 0.25× cache-read rate, a conservative assumption (some providers charge less). The LeanProxy bars include its own discovery calls.

Native MCP LeanProxy, search_tools LeanProxy, list_tools
Morning Sport4 prompts · 2 of 5 servers
17,586
1,148 −93.5% +4 turns
2,470 −86.0% +3 turns
Dev Workflow5 prompts · 2 of 5 servers
20,098
3,143 −84.4% +6 turns
5,234 −74.0% +3 turns
Full Day7 prompts · 3 of 5 servers
25,123
8,793 −65.0% +10 turns
7,302 −70.9% +4 turns

The savings leave out the token cost of the extra discovery turns, so read them as upper bounds. In Full Day, 3 of 7 searches missed and paid for a list_tools fallback as well. Earlier versions of this table left both costs out and showed 81.5–93.7%.

Specifications. Measured by make harness on linux/amd64 (4 CPUs).
ParameterMeasuredTest condition
Proxy overhead0.56 ms p50 · 0.74 ms p95Proxied minus direct, per call
Pipelined burst9,723 req/s · 0 errors500 calls spread over 5 servers
Large tool results234,700 → 18,515 tok −92.1%Response governor, max_tokens: 4000, pages back byte-identical via read_result
Repeated reads13,780 → 3,640 tok −73.6%response.dedup: on, same file read 3×
Secret leaks0 of 3Planted fake secrets, both directions, including search_tools output
Memory20.4 MiB idle · 22.5 MiB after burstResident set size
Binary size16.4 MiBlinux/amd64, stripped

Full methodology and raw numbers

Your client already searches its tools? Good.

Claude Code, Claude Desktop, Cursor and VS Code already defer and search large tool lists on their own. For them, LeanProxy stops hiding schemas behind a router. It lists every upstream tool as server__tool, with full metadata and tools/list_changed, and gets out of the way.

It still redacts, screens, pins and enforces policy on every listed tool and every call. And the response side doesn't depend on the mode: large tool results drop by 92.1% and repeated reads by 73.6% in the harness, whichever client you use.

Which mode each client gets, and why

Through the checkpoint in three steps

  1. Install the binary

    Homebrew or a release archive on macOS and Linux (amd64 and arm64), or go build from source.

    brew tap mmornati/leanproxy-mcp \
      https://github.com/mmornati/leanproxy-mcp
    brew install leanproxy-mcp
  2. Put your servers behind it

    Add each server once to ~/.config/leanproxy_servers.yaml. Coming from Claude Code or OpenCode? leanproxy-mcp migrate imports what they already have.

    leanproxy-mcp server add filesystem -- \
      npx -y @modelcontextprotocol/server-filesystem ~/projects
  3. Point your client at LeanProxy

    Replace the servers in your client with one stdio server, or run a shared HTTP gateway with serve.

    # Claude Code; other clients: same command
    claude mcp add leanproxy -- \
      leanproxy-mcp server run --stdio

Quick start for every client

How it compares

Based on each project's own public documentation as of September 2026. These projects move fast, so check the source before you rely on a row.

LeanProxyMCPProxyToolHiveDocker MCP GatewayLiteLLM
Response-side token governorYes————
Injection classifier, request and responseYes, local————
Tool pinning, drift detectionYesSchema quarantine———
Per-tool allow / deny / confirmYes—Access policies—Per key / team
Sandboxed stdio serversOpt-in—YesYesn/a
Tool search across serversBM25BM25———

— means not documented. All five run as local, self-hosted binaries.