jegamboafuentes

x402dispatcher

Community jegamboafuentes
Updated

x402 Bazaar aggregator MCP server — discover paid APIs, settle USDC micropayments, return data to agents

x402dispatcher

Local x402 Bazaar Aggregator for AI agents: discover paid APIs from the Coinbase x402 Bazaar, wrap them as Model Context Protocol (MCP) tools, settle micropayments from a CDP treasury wallet, and return the upstream data to the agent.

This repo is currently at V4.

Why this exists

AI agents are good at reasoning and tool use, but bad at paying for APIs. The x402 protocol turns HTTP 402 Payment Required into a programmable stablecoin micropayment rail (typically USDC).

x402dispatcher sits in the middle as a solo-operator friendly aggregator:

Idea What it means
Discovery Query the public Coinbase x402 Bazaar catalog
MCP integration Expose discovered APIs as MCP tools for Cursor / agents
Dispatch Sign and settle payment from a treasury wallet via @coinbase/cdp-sdk
Monetization Apply a micro-markup on top of upstream cost and retain the spread

Funds move wallet → merchant. The platform does not custody buyer funds.

Roadmap

Version Status Goal
V1 Done Manually wrap one paid-style flow (MBTA demo + $0.01 USDC testnet settle)
V2 Done Auto-discover Base Sepolia Bazaar APIs and wrap many as MCP tools with real x402 payment
V3 Done Smart arbitrage: search, compare prices, pick cheapest API for a task (with failover)
V4 Current Track success/latency; economy vs verified routing tiers
V5 Planned Cloud host, public registries, agent.json for crawlers

What V4 does

On top of V3 routing, V4 records every paid call’s success and latency in data/api-stats.json, then offers two tiers:

Tier Behavior
economy Cheapest first (V3 behavior)
verified Only APIs with enough successful history; ranked by reliability/latency/price score

Thresholds (env): VERIFIED_MIN_SAMPLES (default 2), VERIFIED_MIN_SUCCESS_RATE (default 0.8).

New tools: get_api_stats, list_verified_apis. quote_route / route_and_call accept optional tier.

What V3 does

On top of V2 discovery + payment, V3 adds a router:

  1. quote_route — search Bazaar for a natural-language task, rank candidates by total price (upstream + markup), return the plan without paying
  2. route_and_call — same ranking, pay and call the cheapest; on failure, try the next-cheapest (up to max_attempts)

All spends remain gated by MAX_PRICE_USD.

What V2 does

On startup the MCP server:

  1. Loads credentials from .env
  2. Resolves a CDP Treasury payer wallet
  3. Searches / lists the Coinbase Bazaar for Base Sepolia (eip155:84532) HTTP resources priced at or below MAX_PRICE_USD
  4. Registers each match as an MCP tool
  5. Also registers helper tools: search_bazaar, list_discovered_apis, call_x402_api
  6. Keeps the V1 demo tool get_mbta_predictions

When an agent calls a discovered tool (or call_x402_api):

  1. Enforce MAX_PRICE_USD on upstream price + markup
  2. Pay the real x402 endpoint with CdpX402Client + wrapFetchWithPayment from @x402/fetch
  3. Collect the markup spread (Treasury → Merchant USDC transfer when possible)
  4. Return { payment, data } to the agent

V1 get_mbta_predictions still proves a fixed $0.01 USDC Base Sepolia transfer, then fetches free public MBTA prediction data.

Architecture

Agent / Cursor
    │  MCP (stdio)
    ▼
x402dispatcher MCP server (src/index.ts)
    │
    ├─ Discovery  → listX402DiscoveryResources / searchX402Resources (@coinbase/cdp-sdk)
    ├─ Payment    → CdpX402Client + wrapFetchWithPayment (@coinbase/cdp-sdk/x402, @x402/fetch)
    ├─ Routing    → economy (price) / verified (stats score) with failover
    ├─ Stats      → data/api-stats.json success + latency history
    ├─ Guardrails → MAX_PRICE_USD (+ SDK spend controls)
    └─ Markup     → MARKUP_BPS applied; optional USDC transfer to Merchant account
    │
    ▼
Upstream x402 HTTP API (Bazaar listing)

Key packages

  • @coinbase/cdp-sdk — wallets, Bazaar discovery, CdpX402Client
  • @x402/fetch / @x402/core / @x402/evm — HTTP 402 payment loop
  • @modelcontextprotocol/sdk — MCP server + tools
  • dotenv, zod, viem

Requirements

  • Node.js 19+ (CDP SDK requirement; 22 LTS recommended)
  • Coinbase Developer Platform credentials:
    • CDP_API_KEY_ID
    • CDP_API_KEY_SECRET
    • CDP_WALLET_SECRET (Wallet Secret from CDP Portal → Non-custodial Wallet → Security — not a MetaMask private key)
  • Base Sepolia USDC (+ a little ETH for gas) on the Treasury address

Setup

git clone https://github.com/jegamboafuentes/x402dispatcher.git
cd x402dispatcher
npm install
cp .env.example .env
# edit .env with your CDP credentials

Environment variables

Variable Required Description
CDP_API_KEY_ID Yes CDP API key ID
CDP_API_KEY_SECRET Yes CDP API key secret
CDP_WALLET_SECRET Yes CDP Wallet Secret (base64 P-256 key from Portal)
MAX_PRICE_USD Recommended Hard cap before any automated spend (e.g. 0.01)
MARKUP_BPS Optional Markup in basis points (default 1000 = 10%)
DISCOVERY_LIMIT Optional Max Bazaar tools to register at startup (default 40, max 100)
VERIFIED_MIN_SAMPLES Optional Min successful-history calls for Verified (default 2)
VERIFIED_MIN_SUCCESS_RATE Optional Min success rate 0–1 for Verified (default 0.8)
CDP_PRIVATE_KEY Optional Only if you import a specific EOA into CDP (not used by default V2+ payer path)

Never commit .env. Only .env.example is tracked.

Fund the treasury

npx tsx -e "import 'dotenv/config'; import { CdpX402Client } from '@coinbase/cdp-sdk/x402'; const c = new CdpX402Client({ environment: 'development', walletConfig: { type: 'eoa', accountName: 'Treasury' } }); console.log(await c.getAddresses());"

Send Base Sepolia USDC (and a little ETH) to the printed evmAddress.

Run

MCP server (stdio)

npm start

Cursor MCP config

Project file: .cursor/mcp.json (already included). Cursor should spawn:

{
  "mcpServers": {
    "x402dispatcher": {
      "command": "npx",
      "args": ["tsx", "src/index.ts"],
      "cwd": "${workspaceFolder}"
    }
  }
}

Reload MCP in Cursor after clone/install. If ${workspaceFolder} is not expanded on your Cursor build, set cwd to the absolute path of this repo and optionally point command at your Node 22 binary.

MCP tools

Core

Tool Purpose
quote_route Rank matching APIs; tier=economy|verified; no payment
route_and_call Pay/call best match for tier; failover; records stats
get_api_stats V4 — local success/latency history
list_verified_apis V4 — APIs that currently qualify as Verified
search_bazaar Semantic/text search of Base Sepolia Bazaar APIs under MAX_PRICE_USD
list_discovered_apis List APIs currently cached/registered
call_x402_api Pay + call by tool_name or full resource URL
get_mbta_predictions V1 demo: $0.01 USDC settle + live MBTA predictions

Dynamic tools

At startup, x402dispatcher also registers one MCP tool per discovered Bazaar resource (names like x402_<host>_<path>_<n>). Each accepts optional query / body and pays the upstream URL.

Testing

V4 end-to-end (recommended)

Seeds two economy weather calls, promotes the winner into Verified, then quotes/routes with tier=verified:

npm run test:v4

Expect: V4 SMOKE TEST PASSED

Earlier versions

npm run test:v3
npm run test:v2

Manual checks in Cursor

  1. Reload the x402dispatcher MCP server
  2. Ask for weather with economy routing a couple of times (builds stats)
  3. Ask: “List verified APIs” / “Get API stats”
  4. Ask: “Use the verified tier to get weather for Boston”
  5. Confirm chosen.verified is true and data/api-stats.json grew

Guardrail check

Set MAX_PRICE_USD below a listing’s total and confirm quote/route refuse or return zero candidates.

Project layout

x402dispatcher/
├── src/
│   ├── index.ts       # MCP server, tool registration
│   ├── discovery.ts   # Bazaar list/search → DiscoveredApi
│   ├── payment.ts     # CdpX402Client, markup, MBTA settle
│   ├── routing.ts     # quote + economy/verified route + failover
│   ├── stats.ts       # V4 local success/latency store
│   └── config.ts      # MAX_PRICE_USD, MARKUP_BPS, verified thresholds
├── scripts/
│   ├── v4-smoke-test.ts
│   ├── v3-smoke-test.ts
│   ├── v2-smoke-test.ts
│   ├── mcp-test.ts
│   └── smoke-test.ts
├── data/              # local api-stats.json (gitignored)
├── .cursor/
│   ├── mcp.json
│   └── rules/         # security + x402-stack agent rules
├── AGENTS.md          # product / roadmap context for agents
├── .env.example
└── package.json

Security notes

  • Wallet credentials load only from .env — never hardcode secrets.
  • Every automated spend is gated by MAX_PRICE_USD before signing.
  • V2 also configures CDP x402 spend controls (maxAmountPerPayment + Base Sepolia network allowlist).
  • Treat the Bazaar as a catalog, not an endorsement. Prefer small caps on testnet first.
  • CDP_WALLET_SECRET must be the Portal Wallet Secret (long base64), not a MetaMask hex key.

Stack references

License

ISC

MCP Server · Populars

MCP Server · New

    PSU3D0

    agent-spreadsheet

    MCP server for spreadsheet analysis and editing. Slim, token-efficient tool surface designed for LLM agents.

    Community PSU3D0
    pitiflautico

    NeoBrowser

    MCP server that drives real Chrome with your real logged-in sessions — genuine fingerprint (passes bot.sannysoft), human-like input, bot-wall aware. 43 tools, single static Rust binary.

    Community pitiflautico
    aeonfun

    Aeon MCP Server

    The most autonomous AI agent framework: runs unattended on GitHub Actions, self-healing skills, drives Claude Code, Grok, Codex & more. No approval loops. Configure once, forget forever.

    Community aeonfun
    nhadaututtheky

    NeuralMemory

    NeuralMemory stores experiences as interconnected neurons and recalls them through spreading activation, mimicking how the human brain works. Instead of searching a database, memories are retrieved through associative recall - activating related concepts until the relevant memory emerges.

    Community nhadaututtheky
    norrietaylor

    Distillery

    Team knowledge evaporates daily — pairing sessions, debugging context, architectural rationale lost to Slack. Distillery captures it at the point of creation, connects it into a living graph, and surfaces it conversationally. It monitors feeds, tracks what matters to your projects, and alerts you before you know to ask. A team brain that learns.

    Community norrietaylor