koala73 / koala73/worldmonitor

feat(mcp): free-tier MCP teaser quota (cache tools, 5/day) + MCP registry listings

Open
#4,277 0 comments 0 reactions 0 assignees View on GitHub
agent-readiness area: API feature P1 seo
Dominant language
TypeScript
Stars
86.6k
Forks
13.1k
Avg merge
8h 4m
Merged PRs (30d)
825

Description

## Summary

Open a **free-tier MCP teaser**: per-tier `mcpDailyQuota` in the product catalog (free = 5 calls/day, **cache tools only**; Pro = 50 incl. LLM-backed RPC tools), replace the hardcoded quota constant and the `tier < 1` auth rejection with entitlement-driven checks, and list the server on the major MCP registries (mcp.so, Smithery, Glama, awesome-mcp-servers).

## Why (evidence)

- The MCP ecosystem is at ~9,400 public servers, +38% in 4 months, with Data & Search ~18% of the category — and **no dominant geopolitical-data MCP server exists yet**. First-mover slot is open and cheap to claim.
- Today `FREE_FEATURES.mcpAccess: false` means a developer who finds WorldMonitor in a registry **cannot try a single call without paying $39.99/mo** — which kills directory listings as a channel entirely (registries surface servers people can actually connect).
- Honest caveat from the research: MCP→paying-user conversion is unproven anywhere. So this is deliberately scoped as a low-cost optionality bet: quota plumbing + listings, no new tool development.
- Restricting the free quota to **cache tools** (edge-cached reads) keeps free-tier COGS ≈ 0; the LLM-backed RPC tools (`get_world_brief`, `get_country_brief`, `analyze_situation`, …) stay Pro — they're also the strongest upgrade reason.

## Current state (verified anchors)

- `api/mcp/auth.ts:186-238` `runProPreChecks()` — rejects unless `ent && tier >= 1 && mcpAccess === true && validUntil >= Date.now()`; 401 JSON-RPC error `-32001 "Subscription not active."` No anonymous path; auth = OAuth bearer or `X-WorldMonitor-Key`.
- `server/_shared/pro-mcp-token.ts` — `PRO_DAILY_QUOTA_LIMIT = 50` **hardcoded**, same for all paid tiers, not sourced from `productCatalog`.
- `api/mcp/quota.ts` — Redis daily counter (`dailyCounterKey(userId)`, INCR+EXPIRE, 48h TTL, fail-closed, rollback + counter-clamp). Mechanism is sound; only the limit needs to become per-caller.
- `api/mcp/constants.ts` — `SERVER_NAME 'worldmonitor'`, `SERVER_VERSION '1.10.0'`; server card at `public/.well-known/mcp/server-card.json` (kept in version sync).
- Registry split already exists: `api/mcp/registry/cache-tools.ts` (29 cached tools) vs `rpc-tools.ts` (12 LLM/dynamic tools) — the free/paid tool boundary maps onto an existing structural line.
- Per-minute rate limit (60/min) independent of daily quota — keep as-is.

## Proposed design

| Tier | `mcpDailyQuota` | Tool surface |
|---|---|---|
| Free (signed-in) | 5 | cache tools only (+ quota-exempt `describe_tool`, `prompts/*`) |
| Pro | 50 | all tools |
| API Starter/Business | 200 (proposal — confirm pricing fit) | all tools |
| Enterprise | custom | all tools |

- Quota-exceeded and rpc-tool-denied responses include a machine-readable upgrade hint (`data: { reason, upgradeUrl, dailyQuota, used }`) — the error message *is* the marketing surface for agents.
- Sign-in still required (OAuth flow exists via `mcp-grant.html`); no anonymous access — quota abuse stays bounded by account creation.

## Implementation plan

**Phase 1 — per-tier quota plumbing**
- [ ] `mcpDailyQuota: number` on `PlanFeatures` in `convex/config/productCatalog.ts`; `FREE_FEATURES: { mcpAccess: true, mcpDailyQuota: 5 }`; populate all tiers
- [ ] `api/mcp/auth.ts`: drop the `tier < 1` condition; gate on `mcpAccess === true` (+ keep validUntil check for paid rows; define free-row semantics — users without an entitlement row resolve through `FREE_TIER_DEFAULTS`, verify `resolveBearerToContext` carries entitlements for them)
- [ ] `api/mcp/quota.ts` / `server/_shared/pro-mcp-token.ts`: limit becomes a parameter from auth context entitlements; keep `50` as defensive fallback; counter-clamp uses the caller's limit
- [ ] Tests: per-tier quota tests, entitlement parity/watchdog, free-tier 6th-call rejection shape

**Phase 2 — free/paid tool boundary**
- [ ] Tool dispatch: free-tier callers invoking RPC-registry tools get the structured upgrade error (not a silent 401); `tools/list` still advertises all tools with an annotation (agents should see what exists)
- [ ] Update server instructions text in `api/mcp/constants.ts` to state tiering plainly

**Phase 3 — conformance & card**
- [ ] Update `public/.well-known/mcp/server-card.json` (bump version with `SERVER_VERSION`); run/extend MCP conformance suite (#3876) for the new auth outcomes
- [ ] ⚠️ `tests/mcp.test.mjs` is the long pole in the pre-push battery — run targeted first, full battery before merge

**Phase 4 — listings & docs (no code)**
- [ ] Submit to mcp.so, Smithery, Glama, punkpeye/awesome-mcp-servers (PR)
- [ ] README: "Use with Claude Desktop / AI agents" section with copy-paste config; docs quickstart page
- [ ] Blog: update the existing MCP-agents post with the free-tier hook; track signups with `utm_source=mcp-registry`

## Acceptance criteria

- A signed-in free user connects from Claude Desktop and successfully calls cache tools 5×/day; 6th call returns the structured quota error with upgrade hint
- Free call to an RPC tool returns the upgrade error; Pro behavior unchanged (50/day, all tools)
- Conformance suite green; server card version-synced; fail-closed Redis behavior preserved
- Listed and discoverable on ≥3 registries with working install instructions

## Out of scope

- Anonymous/keyless MCP access
- New MCP tools; usage-based billing
- MCP-specific onboarding UI beyond docs/README

## Effort

~2–4 days code + listing submissions. Cheapest option-value item in the 2026-06-10 research ranking.

Contributor guide

Open the contributing guide

Research direction

Start with convex/config/productCatalog.ts, api/mcp/auth.ts, api/mcp/quota.ts, and server/_shared/pro-mcp-token.ts to trace entitlements through authentication and quota enforcement. Run the targeted MCP tests before the full tests/mcp.test.mjs battery. Done means the stated free and paid tool behavior, quota errors, conformance checks, synchronized server card, and registry install instructions all meet the acceptance criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
redis, typescript
Domain
api, authentication, backend, databases, documentation, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.