Skip to main content
Glama
rcjavier

cursor-mcp-token-facade

by rcjavier
README.md
# 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

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

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.'

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues