Skip to main content
Glama
Himess

x402-defillama-mcp

by Himess
README.md
# x402-defillama-mcp

An **x402 pay-per-call proxy in front of DefiLlama's agent MCP.** An AI agent with a funded Base
wallet uses DeFi data with **no account, no subscription, no browser login** — it pays USDC per
tool call. Proxies **10 of DefiLlama's 23 MCP tools** as a proof-of-concept.

Verified end-to-end on **Base mainnet** — real USDC settlement, on-chain.

## Problem

DefiLlama runs a live 23-tool agent MCP (`mcp.defillama.com/mcp`). Today an agent can only use it
with a DefiLlama account + active API subscription + browser login. An autonomous agent with a
wallet but no account can't onboard. x402 (HTTP 402 + EIP-3009 USDC settlement) fixes exactly this:
pay-per-call, no account. This repo proves the flow, and proposes it as an **alternative** auth to
the existing API-key/credit rail — **dual-auth, not a replacement.**

## Demo

![demo](demo/demo.gif)

The recording is a **deterministic replay of a real Base-mainnet run** (`demo/demo.tape`,
regenerate with `vhs demo.tape`). The settlement it shows is a real on-chain transaction — see below.

### Verify it yourself

Three independent ways to check this is real, not a mock:

1. **On-chain proof.** The settlement tx is on Base mainnet:
   [`0xe58ae46d…abe7`](https://basescan.org/tx/0xe58ae46d92f8920df8a134c2220274c123eda682a31ce60eaf099dda9be0abe7).
   `status: success` · USDC transfer **payer → payTo, 0.001 USDC** · gas paid by the facilitator
   (the payer's ETH is untouched — EIP-3009 is gasless for the payer). from / to / amount / status
   match the demo exactly.

2. **Run it live against your own wallet.** The video is a replay; here's the live path:
   ```bash
   git clone <repo> && cd x402-defillama-mcp && npm i
   cp .env.example .env
   npm run wallets:gen                 # generates burners; or paste your own
   # set PAY_TO_ADDRESS = your treasury, CLIENT_PRIVATE_KEY = your funded burner in .env
   # fund the client with a little USDC on Base (mainnet) or Base Sepolia (testnet)
   npm run dev                         # start the proxy
   npm run demo:script                 # agent pays per call → gets data → prints the settlement tx
   ```
   Testnet (Base Sepolia, `NETWORK=base-sepolia`, public facilitator, no keys) proves the identical
   mechanism with zero mainnet spend.

3. **Real data.** The figures returned are live DefiLlama data — e.g. Binance CEX ~$137.7B TVL —
   independently checkable on [defillama.com](https://defillama.com). The proxy is a pass-through to
   DefiLlama's REST API, not a mock.

## Architecture

```mermaid
flowchart LR
  A["AI agent<br/>(MCP client + Base wallet)"] -- "MCP tools/call" --> P["x402-defillama-mcp<br/>/mcp"]
  P -- "rail A · no key" --> X["402 + accepts[] → agent signs EIP-3009<br/>→ facilitator verifies + settles USDC on Base"]
  X -- "settled" --> P
  P -- "rail B · DefiLlama API-key header" --> S["skip 402 → serve via pro backend<br/>(existing subscription rail)"]
  P -- "resolves tool" --> D["DefiLlama REST<br/>api.llama.fi | pro-api.llama.fi/{KEY}"]
```

- **Rail A (x402 pay-per-call):** built on Coinbase's `@x402/mcp` (`createPaymentWrapper` on the MCP
  SDK). No payment → in-protocol **402** with an `accepts[]` (scheme `exact`, network, USDC, `payTo`,
  amount = the tool's price). The agent signs **EIP-3009 `transferWithAuthorization`**; the
  **facilitator verifies + settles** on-chain, then the tool runs. Facilitator = public facilitator
  on testnet (no keys); **Coinbase CDP facilitator** on mainnet.
- **Rail B (dual-auth):** a request carrying a DefiLlama API-key header **skips the 402** and serves
  via the `pro` backend with that key. One server, two rails.
- **Data-driven registry:** each tool is one declarative row (`name → endpoint → price → params`);
  adding a tool = adding a row. The remaining 13 of DefiLlama's 23 tools drop in as rows (some need the
  Pro backend).
- **Discovery:** `/.well-known/x402` (advertised networks) + `/catalog` (tools, prices, params).
- **Price-sanity guard:** the server refuses to start if any per-call price exceeds a ceiling
  (default `$0.05`) — protects against a decimals/units bug.

## Run (2-minute quickstart)

```bash
npm i
cp .env.example .env
npm run wallets:gen        # fresh burners; funds/keys stay in .env (gitignored)
npm run dev                # proxy on http://localhost:4021  (POST /mcp)
```

No-spend checks: `npm run backend:check` (data layer), `npm run smoke` (MCP + the 402 gate),
`npm run dualauth-check` (API-key rail skips the 402).

Config (`.env`): `NETWORK` (`base-sepolia`|`base`) · `PAY_TO_ADDRESS` · `FACILITATOR`
(`public`|`cdp`) · `DATA_BACKEND` (`free`|`pro`) · `PRICE_MODE` (`tiered`|`flat`) ·
`ALLOW_APIKEY_PASSTHROUGH` · `SESSION_TOKEN_MODE`.

## Production mapping

This is a PoC of a feature that would live in DefiLlama's own stack, not a data reseller:

- **`payTo` = DefiLlama's treasury.** In the demo it's a burner; in production the settlement USDC
  lands in your wallet.
- **Backend is a one-env swap.** The demo runs on the free public API to stay costless; in
  production `DATA_BACKEND=pro` points at your own gated Pro data over the identical path
  (`pro-api.llama.fi/{KEY}/…`). The x402 payment layer is byte-identical either way.
- **Dual-auth = additive.** x402 is an *alternative* auth to the API-key/credit flow, so existing
  keys keep working while agents onboard without a subscription. Nothing is removed.

## Design decisions / FAQ

- **Why a demo, not a PR?** DefiLlama's MCP server and Pro-API billing are closed-source — there's
  no public file to patch. The credible move is a working proxy + the dual-auth recommendation.
- **Doesn't this resell DefiLlama's data?** No. It's a PoC of DefiLlama's own future feature; in
  production it fronts *their* gated data and the settlement goes to *their* treasury. The open free
  API stays open.
- **Pay-per-call vs session tokens.** Per-call is the demo (clearest: pay each call, no
  subscription). x402 V2 reusable session tokens (amortize per-call overhead) are scaffolded behind
  `SESSION_TOKEN_MODE`, default off.
- **Multi-chain / CCTP.** On mainnet the `accepts[]` can advertise Base + other chains so an agent
  pays where its treasury sits. Consolidating multi-chain revenue into one treasury is where CCTP
  would slot in as an optional sweep — noted, **not built** (Base-only needs none).

## Extensions

Payments are rail-agnostic (`src/payments/provider.ts`) — a second rail drops in behind the same
interface. `src/payments/mpp.ts` (Machine Payments Protocol — Stripe + Tempo's open, IETF-proposed
agent-payment standard) is stubbed **for now** to keep this PoC's single thesis (x402 on the MCP)
focused — **not** for any technical barrier. MPP is open (Apache-2.0/MIT, implementable via the
`mppx` SDK; only Stripe's optional fiat/card path is gated, not the crypto rail) and a **planned
fast-follow** — adding it makes the MCP monetizable on both leading agent-payment rails. Peers are
already split across the two: CoinGecko shipped x402, Dune Analytics is on MPP. `ACP` slots in the
same way.

## Provenance

x402 API verified against Coinbase's `coinbase/x402` examples; `@x402/mcp` / `@x402/core` /
`@x402/evm` on the MCP SDK; CDP facilitator via `@coinbase/x402`. DefiLlama endpoints are live
public API. DefiLlama already tracks x402 as a category (`dimension-adapters#6181`, merged).