x402-sub-agent-mcp

x402-sub-agent-mcp

MCP server for managing x402 payment policies (rules, coupons, tiers, usage logs) conversationally via LLM and evaluating request decisions.

Category
访问服务器

README

x402-sub-agent-mcp

A Cloudflare Workers + MCP payment policy engine for the x402 protocol. Coupons, enterprise pricing tiers, internal tokens, and general pay-per-route rules — managed conversationally by an LLM, enforced by a single evaluate_request call.

Status: V1 shipped and verified end-to-end (real EIP-712 signing, real facilitator round-trips, real Cloudflare deploy). See ROADMAP.md for what's next, including the enterprise reserve membership model described below.


Table of contents


Overview & motivation

x402 lets any HTTP resource charge per request using the 402 Payment Required status code and stablecoin micropayments — no accounts, no API keys, no human checkout. The protocol itself only defines the handshake (challenge → sign → verify → settle). It doesn't define policy: who gets a free trial, who's on a negotiated enterprise rate, which routes cost what, or how you'd answer "how much has this account spent this month?"

x402-sub-agent-mcp is that policy layer. It's a single Cloudflare Worker that:

  • Owns the pricing rules, coupons, enterprise tiers, and usage log for every x402-protected route across your account (one source of truth, not one copy per Worker).
  • Exposes that as MCP tools, so an LLM (Claude, Grok, whatever) can manage pricing conversationally — "give acme-corp a flat $0.001/call rate and require Web Bot Auth" — without touching code or deploying anything.
  • Exposes a single evaluate_request tool that any protected resource Worker calls per-request to get back a structured decision: let it through, here's a 402 challenge, or here's the settlement receipt.
  • Never holds private keys. Signature verification and on-chain settlement are always delegated to an x402 facilitator — a real one for production, or the included mock facilitator for testing the whole flow without touching a blockchain.

If you're building several paywalled Workers, this is the thing they all fetch() (or service-bind to) instead of each reinventing pricing logic.

Architecture

Client ──(1) request──▶ Protected Worker ──(2) evaluate_request──▶ x402-sub-agent-mcp
                              │                                          │
                              │◀── 200 or 402 + accepts[] ───────────────┘
                              │
Client ◀── 402 { accepts } ──┘   (if payment required and none attached yet)
Client ──(3) retry + X-PAYMENT header──▶ Protected Worker ──▶ evaluate_request (again, with x_payment)
                                                                    │
                                                        facilitator /verify + /settle
                                                                    │
                              │◀── 200 + settlement ────────────────┘
Client ◀── 200 + resource ───┘

Components:

Piece What it is Repo
x402-sub-agent-mcp This repo. Policy engine + MCP server. Owns D1. you are here
A real facilitator Verifies signatures and settles on-chain. Not ours — x402.org/facilitator, Coinbase's CDP facilitator, or self-hosted. external
x402-mock-facilitator Test-only facilitator: real EIP-712 signature verification, fake settlement. No gas, no funds needed. nothinginfinity/x402-mock-facilitator
Protected resource Worker(s) Whatever you're actually charging for. Calls evaluate_request, nothing else. your other repos

The protected Worker never talks to a facilitator directly — it delegates verify/settle to this sub-agent, which also logs every outcome to usage_events.

Data model (D1)

Table Purpose
payment_rules Route pattern → price/asset/network/payTo, plus auth_required/bot_auth_required flags
coupons Free/trial/discount codes, optionally scoped to a route pattern and/or caller_id, with use limits and expiry
pricing_tiers Per-caller_id overrides: flat rate or per-compute-unit rate, plus identity/bot-auth requirements
internal_tokens Custom asset/network/scheme registrations, optionally with your own facilitator_url
usage_events Append-only log of every evaluate_request outcome — the source for get_usage_stats

Repo layout

worker.js                    single-file Worker: MCP server (/mcp) + REST fallback (/call) + policy engine
wrangler.jsonc                Cloudflare config: D1 binding, vars, service binding to the mock facilitator
migrations/0001_initial.sql   D1 schema for all five tables above
.github/workflows/deploy.yml  push-to-deploy via wrangler-action — no local CLI required
docs/DEPLOY.md                step-by-step setup, written for doing this entirely from an iPhone
docs/MCP-TOOL-CALLS.md        example tool-call payloads
README.md                     this file
ROADMAP.md                    where this is headed, including the enterprise reserve membership model

worker.js is intentionally dependency-free and single-file — same pattern as the rest of the AFO sub-agent fleet. It bundles to ~34KB.

Setup & deployment

Full step-by-step (including doing every step from an iPhone with no local terminal) lives in docs/DEPLOY.md. Summary:

  1. Create a D1 database (x402-sub-agent-db) and run migrations/0001_initial.sql against it — either via the Cloudflare dashboard's D1 console, or wrangler d1 execute if you have a CLI.
  2. Put the database ID in wrangler.jsonc under d1_databases.
  3. Add two GitHub Actions secrets to this repo: CLOUDFLARE_API_TOKEN (needs Workers Scripts: Edit + D1: Edit) and CLOUDFLARE_ACCOUNT_ID.
  4. Push to main (or run the workflow manually from the Actions tab). .github/workflows/deploy.yml runs wrangler deploy — no local npm/wrangler install needed.
  5. Verify with GET /status on the deployed URL — you want "bindings": { "DB": true }.

Service bindings (for talking to sibling Workers)

Cloudflare blocks a Worker on *.workers.dev from fetch()-ing another *.workers.dev subdomain directly (error 1042). If you're pointing facilitator_url at another Worker you own on workers.dev (like the included mock facilitator), add a Service Binding in wrangler.jsonc:

"services": [
  { "binding": "MOCK_FACILITATOR", "service": "x402-mock-facilitator" }
]

and register the hostname → binding-name mapping in the WORKERS_DEV_SERVICE_BINDINGS constant near the top of worker.js. facilitatorCall() checks that map first and falls back to a plain fetch() for anything else — which is all you need for a facilitator on the public internet or on a custom domain (custom-domain-to-custom-domain and workers.dev-to-custom-domain calls aren't affected by 1042).

Custom domains

If you'd rather avoid the service-binding dance entirely, put both Workers on a Cloudflare-managed custom domain (Workers → your worker → Triggers → Custom Domains) instead of the shared workers.dev subdomain. Fetching between two custom-domain hostnames doesn't hit error 1042.

Testing

Mock flow (no funds needed) — verified working

  1. Deploy x402-mock-facilitator alongside this worker.
  2. Register it as an internal token:
    { "name": "register_internal_token", "arguments": {
        "name": "Mock USD (test only)", "network": "base-sepolia", "asset": "MOCKUSD",
        "asset_address": "0x000000000000000000000000000000000000dEaD",
        "facilitator_url": "https://x402-mock-facilitator.<your-subdomain>.workers.dev"
    }}
    
  3. Create a rule pointed at it, sign a real EIP-712 TransferWithAuthorization payload with any throwaway keypair (no funds required — the mock facilitator never checks balance), and call evaluate_request with x_payment + facilitator_url set to the mock. You'll get a real 402 on the first call and a real signature-verified 200 paid on the retry.

This proves out rule matching, the 402 handshake, header round-tripping, and verify/settle proxying — everything except actual token custody.

Real USDC flow — verified working

  1. Fund a real wallet with testnet USDC on Base Sepolia via Circle's faucet. (Double-check the network dropdown says Base Sepolia — Circle's faucet also lists Arc and Ethereum Sepolia, and it's an easy mix-up.)
  2. Sign the same TransferWithAuthorization structure, but with the real USDC contract as verifyingContract (0x036CbD53842c5426634e7929541eC2318f3dCF7e on Base Sepolia).
  3. Point evaluate_request's facilitator_url at https://x402.org/facilitator (the default) instead of the mock.
  4. Same tool calls, same code path — only the domain and facilitator change.

Done for real: a funded wallet paid a live /api/* rule through the actual x402.org/facilitator, and the resulting 0x-prefixed settlement transaction was independently confirmed on Base Sepolia — payer balance dropped by exactly the rule's price, receiver balance rose by the same amount. This run is also what caught a real bug: the accepts[].extra field needs name/version (the EIP-712 domain Circle's USDC contract expects), not the symbol/decimals shape V1 shipped with — the mock facilitator never checks this, so it only surfaced against a real one.

Mainnet is the same again with the mainnet USDC address (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 on Base) and a production facilitator (Coinbase's CDP facilitator, or self-hosted).

MCP tools reference

All tools are available at POST /mcp (JSON-RPC 2.0, with SSE framing when the client sends Accept: text/event-stream) and as a plain REST fallback at POST /call with {"name": "...", "arguments": {...}}.

Tool Purpose
subagent_status Health check: bindings, facilitator default, tool list
create_payment_rule / list_payment_rules / update_payment_rule / delete_payment_rule Manage protected-route rules
issue_coupon / list_coupons / revoke_coupon / redeem_coupon Free/trial/discount codes
create_pricing_tier / list_pricing_tiers / update_pricing_tier Per-account enterprise pricing
register_internal_token / list_internal_tokens Custom assets/networks/facilitators
evaluate_request The one every protected Worker calls per-request
verify_payment / settle_payment Direct facilitator proxy (mostly for testing/debugging)
get_usage_stats / record_usage_event Spend and access analytics

Full input schemas are served live at GET /tools and tools/list over MCP — treat that as the source of truth over this table.

Usage examples

See docs/MCP-TOOL-CALLS.md for a fuller set. Quick taste:

Protect a route:

{ "name": "create_payment_rule", "arguments": {
    "pattern": "/api/premium/*", "price_usd": 0.01,
    "pay_to": "0xYourWalletAddress", "description": "Premium dataset access"
}}

Give one customer a negotiated rate:

{ "name": "create_pricing_tier", "arguments": {
    "name": "Acme Corp enterprise", "caller_id": "acme-corp",
    "scope_pattern": "/api/premium/*", "price_usd": 0.002, "requires_identity": true
}}

Evaluate an incoming request (called by a protected Worker):

{ "name": "evaluate_request", "arguments": {
    "path": "/api/premium/dataset.json", "method": "GET", "caller_id": "acme-corp",
    "x_payment": "<base64 X-PAYMENT header value, omit on the first attempt>"
}}

Agent operating balances & branded denomination UX (future design)

The long-term payment product has two customer funding concepts that must remain separate:

Concept Economic behavior This Worker's role
Agent operating balance A consumable prepaid balance used for tool calls, data, compute, workflows, and developer services. Spending reduces the balance. Authorize a maximum amount, meter actual usage, route x402 payment, and record a receipt from signed external balance or settlement state.
Enterprise membership reserve Refundable principal committed for a defined term to unlock fixed service entitlements and preferred overage pricing. Ordinary tool calls do not consume the reserve principal. Check the active plan and remaining entitlement, then fall through to metered overage when needed.

The settlement asset beneath an operating balance may eventually be USDC, USDT, a tokenized deposit, fiat held by an approved provider, or another asset that has passed the custody, accounting, technical, and jurisdictional gates. The asset remains external to this Worker.

A branded Penny, Nickel, Quarter, or Mill can be a human-readable pricing and marketing denomination mapped to one underlying atomic ledger. A mill is $0.001. These names should normally be display metadata, not separate transferable tokens or separate customer liabilities. Machines receive integer atomic amounts; humans may see $0.80, 80 cents, or 3 quarters + 1 nickel.

Early versions must not issue a proprietary redeemable stablecoin. They should use:

  • an approved external settlement asset;
  • an integer-based internal accounting unit;
  • signed authorization, reservation, commit, release, and receipt events; and
  • branded denomination metadata at the UI and discovery layers.

A future on-chain branded unit may be researched only through a separate issuer/custody/legal project or an approved issuing partner. Branding does not change the underlying financial classification. Product language must not call a private stablecoin government-backed, government-issued, official, insured, or deposit-protected unless that exact claim has been independently verified for the specific asset, issuer, account structure, and jurisdiction. Holding government securities in reserves is not the same as a government guarantee.

The intended architecture is an agent commerce operating system: identity, budgets, policy, metering, receipts, tool discovery, and payment routing. This repo remains its policy plane; it does not become the wallet, stablecoin issuer, custodian, treasury manager, developer bank, or payout processor.

See docs/AGENT-OPERATING-BALANCES.md for the staged architecture, terminology, accounting examples, and marketing guardrails.

Enterprise reserve membership model (design, not yet built)

This is the intended enterprise product direction (see ROADMAP.md for the build order). The model is a refundable capital reserve that unlocks discounted, metered access to AI tools, data, compute, and custom workflows. It is not an investment product and it is not a yield-sharing program.

Product definition

An enterprise customer commits a refundable reserve for a defined contract term. In exchange, the customer receives fixed service rights:

  • a negotiated set of tools, routes, datasets, seats, and workflow permissions;
  • a fixed monthly or annual included-usage entitlement;
  • a contractual discount or preferred overage rate; and
  • normal x402 billing after the entitlement is exhausted.

The customer is not promised interest, APY, a share of treasury income, profit participation, ownership, governance rights, or an entitlement that changes with investment performance. Any return earned on company-managed treasury assets belongs to the company. The company also bears treasury losses, liquidity risk, custody costs, and the obligation to return the contractual principal.

Use reserve membership or membership reserve in product and code language. Avoid presenting the enterprise customer as an investor or the reserve as an appreciating stake.

Enterprise and investor products are separate

Enterprise reserve membership Investor product
Purchases service access Supplies risk capital seeking a return
Fixed contractual entitlements Yield, equity, profit share, or governance may apply
No member-facing APY or profit expectation Requires its own legal and offering structure
Refund governed by the service contract Redemption/return governed by investment documents
Lives in this access-policy product Must use a separate entity, repo, contracts, data model, and customer flow

Combining the two would contaminate the enterprise model. Terms such as "investor," "return," "yield share," and "capital appreciation" must not appear in enterprise membership marketing or entitlement logic.

Required system boundary

The reserve product must be split into independent layers:

  1. Membership service — contracts, organizations, seats, plans, term dates, cancellation eligibility, and service entitlements.
  2. Custody or escrow provider — holds refundable principal and executes approved funding and refund instructions.
  3. Treasury service — manages company-approved cash, Treasury, money-market, or other positions; members never own portfolio shares.
  4. Accounting ledger — records principal as a refundable liability, treasury income as company income, and every movement with double-entry reconciliation.
  5. x402 policy engine — this repo; consumes signed entitlement attestations, meters usage, and charges overages.

x402-sub-agent-mcp must remain a policy and bookkeeping layer, not a wallet, bank, escrow contract, broker, investment fund, or treasury manager. It should know that an account has an active plan and a remaining entitlement. It should not know that a member "owns" vault shares or has accrued yield.

Economics

The intended pricing relationship is:

enterprise price = base service fee + metered usage - fixed reserve-tier discount

A representative contract could use a $25,000 refundable reserve, a 12- or 24-month commitment, fixed included usage, a fixed platform-fee discount, and x402 overage billing. The discount and entitlement are set by contract and do not float with Treasury rates or protocol yield.

Treasury income is a possible margin enhancer, not the economic foundation for unlimited AI usage. Refundable principal remains a liability, and the platform must be able to honor refunds even if rates fall, assets lose value, or many customers cancel together.

How x402 fits

The x402 integration is narrower and safer than the original stake proposal:

  • evaluate_request checks an active plan_entitlement before ordinary per-call pricing.
  • Entitlement-covered requests short-circuit to 200; consumption is recorded against a fixed period budget.
  • Overage falls through to the existing x402 challenge, verify, settle, and usage-log flow.
  • Membership activation is based on a signed funding attestation from the external membership/custody layer, not on this Worker receiving or controlling funds.
  • Cancellation creates a request for the external custody workflow. A refund is not the facilitator /settle operation run in reverse; it needs authenticated approvals, destination validation, idempotency, compliance checks, reconciliation, and failure recovery.

None of the reserve, custody, treasury, cancellation, or refund capabilities exist in V1. The first implementation should use synthetic or testnet funding attestations and fixed entitlements only. Real customer principal must wait for the security work, contracts, accounting, regulatory analysis, and custody structure described in the roadmap.

Security notes & limitations

  • Tool calls require a shared secret. Every tools/call (over /mcp or REST /call) needs Authorization: Bearer <token> matching the MCP_AUTH_TOKEN Cloudflare secret. Discovery endpoints (tools/list, GET /status, GET /tools) stay public since they carry no sensitive data. If MCP_AUTH_TOKEN isn't set, every call is denied by default rather than silently running open. This is a single shared secret, not per-caller auth or RBAC — anyone with the token has full access to every tool. Rotate it (set a new Cloudflare secret value) if it's ever exposed.
  • Raw SQL is never exposed as a tool. All writes go through parameterized statements in worker.js — there is no query_d1-style escape hatch.
  • pay_to and asset_address get format validation, not checksum validation. Every write path rejects anything that isn't a 0x-prefixed 40-hex-character string, and rejects the null address (0x000...000) outright. This catches typos, truncation, and garbage input. It does not verify EIP-55 mixed-case checksums (that needs Keccak-256, which isn't in Workers' Web Crypto without adding a dependency) — a single transposed character that keeps valid hex shape and case will still pass. Double-check addresses yourself before pointing a rule at a real wallet.
  • The mock facilitator never checks balance. A signature from an empty wallet passes /verify and /settle there. It proves the x402 plumbing works; it proves nothing about custody. Don't mistake a green mock-flow test for a green real-money test.
  • mode: 'upto' is stored but not yet enforced. V1's evaluate_request treats upto rules identically to exact — see the roadmap.
  • This worker holds no private keys and never will by design — signing happens client-side (or in your own signing script/service), and settlement is always delegated to a facilitator.

Contributing / extending

This is a single-file Worker on purpose — it's meant to be easy to read top-to-bottom and patch from a phone. If you're extending it:

  1. Keep new tools in the same toolSchemas + callTool() switch pattern — an LLM discovers tools generically from tools/list, so a new capability just needs a schema entry and a handler function.
  2. Any new persisted concept gets its own table in migrations/000N_*.sql, following the existing id / created_at / updated_at convention.
  3. Run node --check worker.js and an esbuild --bundle dry run before pushing — this catches syntax and bundling issues before a failed deploy does.
  4. If a new tool needs to reach another Worker you own, check whether it's workers.dev (needs a service binding, see above) or a custom domain (doesn't).

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选