feat(mcp): the paid-depth seam and its structured refusal - #11218
feat(mcp): the paid-depth seam and its structured refusal#11218JSONbored wants to merge 1 commit into
Conversation
Tier gates DEPTH, never visibility. Every tool stays listed and callable at every tier; a call past a paid boundary answers a structured `payment_required` naming the boundary, the tier that clears it, and where to get one -- so an agent relays an actionable upgrade path instead of reporting a dead end. A paid tool hidden from free callers is a tool nobody discovers or upgrades for, which is the same absence-reads-as-nonexistence failure this repo measured twice in #11146 and #11148. The tier resolver already existed at the MCP dispatch seam (authTier has ridden every $mcp_tool_call since #8967), so the seam is the refusal plus the first boundary: history windows on get_economics_trends. That surface was CHOSEN FROM USAGE -- over the 30 days to 2026-08-14 the economics family carried the most distinct callers of any tool (get_subnet_economics: 52, above get_subnet_health's 47 on a third the volume). Effectively all traffic is anonymous, so the free depth stays a real product: 7d/30d/90d are open to everyone and only `1y` and `all` -- the two whole-rollup scans -- need a key. An unrecognised tier clears nothing, and an unbounded window crosses every finite ceiling. The `payment` block is shaped so an x402 challenge later joins it rather than introducing a second error vocabulary. Closes #11179
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
metagraphed-data-api | d1e1669 | Aug 14 2026, 01:07 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
metagraphed-registry-sync-api | d1e1669 | Aug 14 2026, 01:07 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
metagraphed-wss-lb | d1e1669 | Aug 14 2026, 01:07 PM |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #11218 +/- ##
==========================================
- Coverage 95.51% 95.51% -0.01%
==========================================
Files 742 743 +1
Lines 45308 45330 +22
Branches 16648 16659 +11
==========================================
+ Hits 43277 43298 +21
Misses 526 526
- Partials 1505 1506 +1
🚀 New features to boost your workflow:
|
|
Closing on red |
Closes #11179.
Tier gates depth, never visibility. Every tool stays listed and callable at every tier; what a key buys is how far back a call may read. A paid tool hidden from free callers is a tool nobody discovers or upgrades for — the same absence-reads-as-nonexistence failure measured twice already (unregistered mutations in #11146, empty captured schemas in #11148).
What shipped
Phase 1 was already in place and is verified, not rebuilt:
applyTieredRateLimitresolves the tier at the MCP dispatch seam, andauthTierhas ridden every$mcp_tool_callsince #8967 — which is exactly why phase 3 could be decided from data.Phase 2 — the structured refusal.
payment_requiredrides the existing tool-error path with apaymentblock:tier,required_tier,boundary,limit,requested,upgrade_url. The message carries the upgrade URL too, so a client that renders only prose still shows its human something actionable. The block is shaped so an x402 challenge later joins it rather than introducing a second error vocabulary. Published where agents read: the tool description andpublic/skills/bittensor/SKILL.md.Phase 3 — the first boundary, chosen from usage. Over the 30 days to 2026-08-14, the economics family carried the most distinct callers of any tool (
get_subnet_economics: 52 callers, aboveget_subnet_health's 47 on a third the volume) — economic history is the demand centre the issue predicted. Effectively all measured traffic is anonymous, so the free depth stays a real product rather than a teaser:7d/30d/90dare open to every caller, and only1yandall— the two whole-rollup scans — require a paid key.Phase 4 (x402) is explicitly the evaluate-after step in the issue; the seam it needed now exists, and the refusal shape is the place a challenge will live.
Two traps closed by tests
"enterprise","__proto__",""all rank below free — otherwise a typo in an account record becomes free access to every paid depth.allparses todays: null; treating null as "no request" would have made the deepest read the one thing that passed free.Validation
typecheck,lint,format:check,validate:mcp(240 tools),validate:unreferenced-exports(731, at the ceiling — not raised),validate:module-state-resetssrc/mcp-tier-gate.tsand the changedsrc/mcp-server.tslinestools/call: anonymous1y→payment_requiredwith the block; the same anonymous caller at30d→ never gated; the gated tool still appears intools/list