← back to gallery

MCP Tool Budget

Live token cost of every public MCP server — Cursor 40-tool cap and Claude Code context made visible

dev-toolsmcpclaude-codecursortokensleaderboardai-agentssmithery
Open product ↗

mcp-tool-budget

Live token-cost leaderboard for every public MCP server. Real gpt-tokenizer (o200k_base, GPT-4o family) over real Smithery-published tool schemas. No mocks. No seed data. No Math.random().

Live: https://holyai.me/mcp-tool-budget/
Stack: Node 20 · Express · better-sqlite3 (WAL) · node-cron · helmet · compression · gpt-tokenizer
Port: 4813 · BASE_PATH: /mcp-tool-budget · Auth: none — every endpoint is public.

---

Why

In mid-2026, the average AI-coding-agent user installs five or more MCP servers (filesystem,
GitHub, Slack, Brave Search, Playwright, …). Every tool definition the MCP client publishes
gets serialised into the LLM system prompt of every turn. Typical numbers:

If two MCP servers do the same job, which one is cheaper for my agent to load? Nobody answers this publicly. mcp-tool-budget answers it.

How the numbers are computed

Every 6 hours (env REFRESH_CRON, default 0 /6 UTC):

  1. List every public MCP server from Smithery:
  2. GET https://registry.smithery.ai/servers?page=N (paginated until exhausted).
  3. Rank by useCount and take the top MAX_SERVERS (default 600).
  4. Detail-fetch each: GET https://registry.smithery.ai/servers/<qualifiedName>. The response's
  5. tools[] is the live tool schema list — name, description, JSON-schema input.
  6. Tokenize each tool: encode(JSON.stringify({ name, description, inputSchema })).length using
  7. gpt-tokenizer with the o200k_base encoding. This is the same tokenizer the Cursor /
  8. Claude Code 200 K context budget is denominated in.
  9. Persist to SQLite (servers, tools, snapshots). One snapshot per server per refresh so
  10. we can show "this server grew by N tokens this week".

If Smithery is down or rate-limits us, the prior row is kept verbatim and last_ok=0 is exposed
in the API so the UI can show "stale (since …)" honestly. Nothing is faked.

Source data

| Source | URL | Frequency |
|---|---|---|
| Smithery server list | https://registry.smithery.ai/servers?page=N | 6 h |
| Smithery server detail | https://registry.smithery.ai/servers/<qualifiedName> | 6 h |
| Tokenizer | gpt-tokenizer (o200k_base) | in-process, deterministic |

Honesty caveats

Routes

All routes mount under BASE_PATH=/mcp-tool-budget.

| Method | Path | Purpose |
|---|---|---|
| GET | / | leaderboard SPA |
| GET | /server/:qualifiedName | detail SPA |
| GET | /budget | budget calculator SPA |
| GET | /health | { ok: true, servers_indexed, last_refresh } — no auth, 200 |
| GET | /api/stats | counts + refresh status |
| GET | /api/servers?sort=&order=&limit=&offset=&q= | leaderboard data |
| GET | /api/servers/:qualifiedName | full detail + per-tool tokens + recent snapshots |
| GET | /api/diff/:qualifiedName?days=N | token delta vs N days ago |
| POST | /api/refresh | kick the cron (rate-limited per IP) |
| GET | /api/badge/:qualifiedName.svg | shields.io-style embeddable badge |
| GET | /api/card/:qualifiedName.svg | 1200×630 share card |

Quickstart

git clone <this repo>
cd mcp-tool-budget
cp .env.example .env
npm install
npm start

Then open http://localhost:4813/mcp-tool-budget/. The first refresh kicks off ~5 s after boot and
takes 2–6 minutes depending on Smithery's response time and MAX_SERVERS. While it runs you'll see
"refreshing…" in the footer.

To force a refresh: curl -X POST http://localhost:4813/mcp-tool-budget/api/refresh.

Embeds

Maintainers can paste a badge into their README so users see the footprint at a glance:

![mcp-tool-budget](https://holyai.me/mcp-tool-budget/api/badge/<qualifiedName>.svg)

A 1200×630 share card is also available at /api/card/<qualifiedName>.svg for social posts.

License

MIT.