cursor-mcp-token-facade
# cursor-mcp-token-facade
**MIT** · Cursor-facing MCP facade that keeps **token spend low** by exposing **5 host tools** while proxying an unlimited number of child MCP servers behind a staged catalog.
> This is the **public, generalized** package. It ships typical open examples (`filesystem`, `memory`, `fetch`, …). It does **not** include private house wiring.
```
Cursor host (always 5)
search_tools · invoke_tool · mcp_status · search_resources · read_resource
│
▼
staged catalog: mode=names (default) | mode=schema | limit
│
┌────┴────┬──────────┬─────────┐
filesystem memory fetch* github* (* enabled:false until needed)
```
---
## License (why MIT)
| License | Fit for this project |
|---|---|
| **MIT (chosen)** | Default for small Node/MCP utilities. Max adoption, trivial for Cursor users to vendor or fork. Matches `@modelcontextprotocol/sdk` ecosystem norms. |
| Apache-2.0 | Better if you need an explicit patent grant for corporate legal. Use if your org requires it; functionally similar for this size of tool. |
| GPL / AGPL | Poor fit — scares adoption for editor tooling people copy into private configs. |
**Recommendation:** ship **MIT**. Keep proprietary child configs (paths, secrets, moat servers) in a **private** repo; publish only the frozen facade + generic examples.
---
## Why tokens drop (typical model)
Assumptions: ~40 child tools with mid-size JSON schemas; Cursor injects ListTools every turn; agent searches before invoke.
| Path | Fat (all schemas on host) | Facade + staged catalog | Δ |
|---|---|---|---|
| Host ListTools / turn | ~1 000–3 000+ tok | ~**100–400** tok (5 slim tools) | often **−60% to −90%** |
| Discover 3 tools | full schemas dumped | `mode=names` ~**0.3–0.4×** schema mode | ~**−60%** on search |
| Idle heavy servers | still listed / sometimes spawned | `enabled: false` → **0 process, 0 schemas** | idle tax → **0** |
Exact savings depend on your children. Rule: **never** put full child schemas on the host; use `search_tools` → `mode=schema` only for the tool you are about to call.
---
## Quick start (behind Cursor)
```bash
git clone https://github.com/rcjavier/cursor-mcp-token-facade.git
cd cursor-mcp-token-facade
npm install
mkdir -p "${WORKSPACE_ROOT:-$HOME/workspace}/sandbox" # filesystem child root
cp examples/profiles/token-light.child-servers.json child-servers.json
# or: cp child-servers.json.example child-servers.json
chmod +x start.sh
```
Wire **one** absolute path into the project `.cursor/mcp.json`:
```json
{
"mcpServers": {
"cursor-mcp-token-facade": {
"command": "/ABSOLUTE/PATH/cursor-mcp-token-facade/start.sh",
"args": []
}
}
}
```
Disable duplicate marketplace MCP plugins for the same servers you put behind the facade (otherwise Cursor still dumps their tools onto the host).
Reload Cursor MCP.
### Agent loop
```
1. search_tools { "query": "file", "mode": "names", "limit": 10 }
2. search_tools { "query": "filesystem__read_file", "mode": "schema", "limit": 1 }
3. invoke_tool { "tool_name": "filesystem__read_file", "payload": { ... } }
```
Built-ins always available: `echo`, `calc`, plus `mcp_status`.
---
## Child config (typical examples)
| Child | Default | How |
|---|---|---|
| `filesystem` | ON | `npx -y @modelcontextprotocol/server-filesystem ${WORKSPACE_ROOT}/sandbox` |
| `memory` | ON | `npx -y @modelcontextprotocol/server-memory` |
| `everything` | OFF | Official demo kitchen-sink server |
| `fetch` | OFF | HTTP fetch MCP |
| `github` | OFF | HTTP + `Authorization: Bearer ${GITHUB_PAT}` |
Flip with `"enabled": false` and reload. Schema: [`child-servers.schema.json`](child-servers.schema.json). Live file `child-servers.json` is gitignored — never commit secrets.
Env expansion: `${WORKSPACE_ROOT}`, `${HOME}`, `${GITHUB_PAT}`, …
---
## Develop
```bash
npm test # staged catalog + token-light profile contracts
npm start # stdio (what Cursor uses)
MCP_FACADE_MODE=http npm run start:daemon # optional localhost JSON door :8766
```
---
## What this is / is not
| Is | Is not |
|---|---|
| Frozen token-law facade + generic examples | Your private stack / moat MCP wiring |
| Drop-in Cursor stdio server | A replacement for Cursor’s plugin OAuth UX |
| Safe to open-source under MIT | A dump of machine-specific `child-servers.json` |
Private, opinionated instances should stay private. Publish the pattern; keep the moat local.
TDQS
Scored across 5 tools
Each tool targets a distinct facet of the facade: search_tools (tool discovery), invoke_tool (execution), mcp_status (child server roster), search_resources and read_resource (resource discovery and access). Descriptions actively cross-reference each other to steer agents away from misselection, e.g. 'Use this for roster — not search_tools/invoke_tool descriptions.'
Four of five names follow a clean verb_noun snake_case pattern (search_tools, invoke_tool, search_resources, read_resource). mcp_status breaks the pattern as a noun phrase, though it is still readable and unambiguous.
Five tools is well-suited to a thin facade layer: discovery, invocation, status, and resource read/write-lite operations. Nothing feels redundant or padded, and no core proxy role is left without a tool.
The set covers tool discovery/invocation, server status, and resource search/read, giving a workable lifecycle for proxying child MCP servers. However, MCP prompts (search_prompts/get_prompt) are absent, and there is no bulk schema listing for tools, which could force repeated single-tool fetches.