mcp-lazy-proxy
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-lazy-proxyList my open GitHub issues: first get_mcp_tools for github, then call_mcp_tool."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Lazy Proxy
Lazy MCP proxy for LLM clients. Instead of injecting every backend MCP server's tool schemas into the model context, it exposes just two meta-tools — get_mcp_tools and call_mcp_tool — that load and invoke backend servers on demand. The model sees a tiny, stable tool surface. Backends are connected lazily, their tool lists are cached, and idle connections are closed automatically.
Why
I run local models on a small mini PC — a KAMRUI Hyper H1 with an AMD Ryzen 7 6800H, 32 GB RAM, and 16 GB of shared UMA vRAM for the iGPU. It works surprisingly well, but context bloat is the one thing that keeps tripping me up the moment I plug in the MCPs I actually use every day.
With 9 MCP servers wired up (GitHub, Sentry, n8n, etc), a plain "hello" was eating roughly 41k of context in opencode — and I only have 64k to play with on local models. A model I really like, Qwen3.5-35B-A3B-UD-IQ3_S, would spend a solid minute chewing through the prompt before it got to do anything useful.
So I wrote this in a single night session. Now my "hello" costs just under 10k of context :>
Related MCP server: Lightweight GitHub MCP
What makes this different
Other lazy MCP proxies are all-or-nothing: they either keep every backend lazy or inject everything eagerly. This proxy is the only one that lets you pick a middle ground.
Favorites — mark a handful of backends you reach for every session as
favoriteand their schemas are injected up front (no discovery round-trip), while the rest stay lazy. A real context-vs-latency knob, not a binary choice.Live discovery, no build step — tools are fetched on demand at runtime. No pre-generated tool hierarchy to keep in sync.
Filtered discovery —
get_mcp_toolstakesqueryandlimit, so the model pulls only the relevant subset of a backend's schemas.Connection lifecycle — backends connect lazily and auto-close after 5 minutes idle, so resources aren't held for the whole session.
Remote + local — one proxy handles both HTTP/Streamable and stdio backends.
Measured, not guessed —
bench.mjsquantifies the lazy/favorites/all-eager tradeoff with real numbers.
Features
Only two tool schemas injected into the model context, no matter how many backends you configure
get_mcp_toolsdiscovers a backend's tools (with optional name/description filter and result limit)call_mcp_toolforwards a tool invocation to any backendBackends connect lazily on first use and close after 5 minutes idle
Supports both remote (HTTP/Streamable) and local (stdio subprocess) MCP servers
Per-backend
instructionlets you tell the model what each MCP is forAdvertises the backend catalog via MCP
instructions, so the model knows what's available up frontMark a backend as a
favoriteto inject its schemas eagerly while the rest stay lazy
Quick start
Requirements: Node.js 18+. Install and build:
npm install
npm run buildCreate a config file pointing at your MCP servers. See Configuration for the full shape.
{
"mcpServers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer <TOKEN>" },
"instruction": "GitHub: issues, pull requests, code search. Use for anything repo-related."
},
"local-tool": {
"type": "local",
"command": "npx",
"args": ["-y", "some-mcp-server"],
"instruction": "A local stdio MCP server."
}
}
}Point your MCP client at it as a stdio server. For example, in an MCP client config:
{
"mcpServers": {
"lazy-proxy": {
"command": "npx",
"args": ["-y", "@sarthakpranesh/mcp-lazy-proxy", "--config", "/path/to/mcp.json"]
}
}
}Configuration
The proxy takes a single JSON config file via --config <path>. It must have an mcpServers object; each entry is a backend with either a url (remote) or a command (local).
Backend reference
Field | Required | Description |
| Remote | HTTP(S) endpoint of a remote MCP server (Streamable HTTP). |
| No | Extra headers for the remote server, e.g. |
| Local | Executable to spawn for a local stdio MCP server. |
| No | Arguments passed to the local command. |
| No | Extra environment variables for the local command. |
| No | Human/LLM-facing description of what this MCP is for. Shown in the catalog and returned by |
| No |
|
Using the proxy
The proxy advertises two meta-tools to the model.
get_mcp_tools
Discover what a backend can do before calling it. Returns the backend's instruction plus a filtered list of tool names, descriptions, and input schemas.
Argument | Type | Description |
| string | Name of the MCP backend from the proxy config. |
| string | Optional substring filter on tool name/description. |
| number | Optional cap on results (default 50). |
call_mcp_tool
Invoke a tool on a backend. Use the tool name and arguments returned by get_mcp_tools.
Argument | Type | Description |
| string | Name of the MCP backend from the proxy config. |
| string | Tool name as returned by |
| object | Arguments per the tool's input schema. |
Workflow
The model reads the advertised catalog (backend names + instructions).
It calls
get_mcp_toolsto load a backend's schemas.It calls
call_mcp_toolto run a tool, passing the discovered arguments.
Favorites
All-lazy guarantees the smallest context footprint, but every call first pays a get_mcp_tools round-trip to bring the backend's schemas into context. Mark a backend as a favorite and its schemas are injected up front instead — so the model can call its tools directly, no discovery step required. The rest stay lazy.
{
"mcpServers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"headers": { "Authorization": "Bearer <TOKEN>" },
"favorite": true,
"instruction": "GitHub: issues, pull requests, code search."
}
}
}Pick a handful you reach for every session; leave long-tail backends lazy.
Benchmark
bench.mjs compares three modes against a backend of your choice: all-lazy, favorites (that one backend eager), and all-eager. It measures injected schemas, approximated context tokens, and end-to-end latency of one real tool call ( skips the impact added from extra inference required from get_mcp_tools to call_mcp_tool, but added manually ).
npm run build
node bench.mjs # defaults to the github backend
BENCH_MCP="promptify" BENCH_TOOL="get_prompts" node bench.mjsSample output for BENCH_MCP=github and BENCH_TOOL=get_me:
mode | injected tools | context (approx tokens) | end-to-end call | impact from added inference |
lazy | 2 | 167 | 3.69s | high |
favorites | 46 | 9845 | 437ms | non fav - high, fav - none |
all | 118 | 31820 | 417ms | none |
Impact on context: github mcp as favorite adds 9678 tokens vs all-lazy this is highly dependent on which mcp(s) you add to favorites; all-eager adds 31820 tokens for all my 9 MCPs vs all-lazy.
latency: favorites first-call 3.25s faster than all-lazy, without the time taken in inference from get_mcp_tools to call_mcp_tool. For cloud models this will be fast, for local models this might add a second.
The numbers are approximate — token count is estimated at 4 chars/token and excludes the model's own prompt overhead — but the shape is consistent: all-lazy is the cheapest, all-eager the fastest, favorites sits somewhere in the middle.
Troubleshooting
Problem | What to try |
| The name must match a key in |
| Every backend needs one of the two; check the config for typos. |
Backend not reachable | For remote servers, confirm the URL and |
Model calls a tool that doesn't exist | Run |
Backend keeps reconnecting | Connections close after 5 minutes idle by design; that's expected. |
Contributing
Want to change code, fix bugs, or improve docs? The project is a small TypeScript MCP server. src/index.ts wires up the meta-tools and eager favorites, src/backend.ts manages lazy connections and caching, and src/config.ts parses the config. Run npm run typecheck to typecheck, node smoke.mjs for a smoke test, and node bench.mjs for the benchmark against your local MCP config.
This server cannot be deployed
Maintenance
Related MCP Connectors
Search, inspect and invoke every public tool on Invokera through one MCP connection.
Search, vet & assemble MCP servers from your agent: verified tools, risk labels, and trust scores.
The MCP server that finds MCP servers. Aggregates Official Registry, Glama, and Smithery.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceActs 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.5GPL 3.0
- AlicenseNot gradedqualityDmaintenanceA configurable proxy that filters GitHub MCP server tools via YAML whitelist, reducing context consumption from 100+ tools to only the ones you need while providing meta-tools to discover available functionality.MIT
- AlicenseNot gradedqualityDmaintenanceReduces LLM context window overhead by proxying multiple MCP servers through a few efficient dispatch tools instead of registering hundreds of individual tool schemas. It supports multi-account routing and tool discovery for both CLI-based and persistent MCP server configurations.MIT

Crabeye MCP Bridgeofficial
AlicenseNot gradedqualityDmaintenanceConsolidates multiple upstream MCP servers behind a single STDIO interface, exposing search_tools and run_tool to avoid context bloat.40 npm14MIT