Skip to main content
Glama
README.md
# Citely-x402

An open **MCP server that gates content & tools behind [x402](https://x402.org) stablecoin micropayments** — with a pluggable content provider and a pluggable payment network (**Base** today, **[GOAT Network](https://www.goat.network)** as the headline integration).

Most "agent payments" demos rebuild x402 from scratch. This repo extracts a clean, reusable gateway: an MCP server exposing `search_articles` + `get_article`, gated by a free-quota entitlement and then x402 pay-per-call. Two seams keep it generic and keep any proprietary data out.

## Quickstart

```bash
pnpm install
cp .env.example .env      # defaults to base-sepolia
pnpm example              # boots the gateway on http://localhost:3402
pnpm tsx scripts/agent-client.ts   # discovers → hits the 402
```

The 402 → pay → 200 flow, end to end:

```bash
# 1) No payment → 402 with the x402 payment requirements
curl -i http://localhost:3402/api/read/stablecoin-licensing-basics
#   HTTP/1.1 402
#   [{"scheme":"exact","network":"eip155:84532","maxAmountRequired":"300000",
#     "asset":"0x036CbD…","payTo":"0x…","resource":"/read/stablecoin-licensing-basics"}]

# 2) With an X-PAYMENT proof → 200 with the body
curl -H "x-payment: <proof>" http://localhost:3402/api/read/stablecoin-licensing-basics
```

## Architecture

```
                 x-citely-account (ERC-8004 id)
   AI agent ───────────────────────────────────────┐
      │  MCP: search_articles / get_article         │
      │  or   GET /api/read/:slug                    ▼
      │                                     ┌──────────────────┐
      └────────────────────────────────────▶│  gateway         │
                                             │  1. entitlement  │  free quota per account
                                             │  2. x402 paywall │  402 → USDC → 200
                                             │  3. ContentProvider ─▶ your catalog/body
                                             └──────────────────┘
```

Two seams isolate everything specific to your deployment:

- **`ContentProvider`** (`src/content/provider.ts`) — `listCatalog()` / `getContent(slug)`. The repo ships `sampleContentProvider` with dummy public content. Bring your own by implementing the interface.
- **`PaymentNetwork`** (`src/payment/network.ts`) — `{ id, caip2, usdcAddress, buildResourceServer() }`. Ships a Base-Sepolia adapter and a GOAT adapter.

## Swap the payment network

Set `X402_NETWORK` (see `.env.example`):

| `X402_NETWORK` | CAIP-2 | Facilitator / token |
|---|---|---|
| `base-sepolia` (default) | `eip155:84532` | Coinbase CDP (`CDP_API_KEY_ID` / `_SECRET`); USDC `0x036CbD…` |
| `goat-testnet` | `eip155:48816` | `GOAT_FACILITATOR_URL` + `GOAT_USDC_ADDRESS` |
| `goat-mainnet` | `eip155:2345` | `GOAT_FACILITATOR_URL` + `GOAT_USDC_ADDRESS` |

GOAT is an EVM-compatible, Bitcoin-secured L2, so the same `ExactEvmScheme` (EIP-3009 USDC) applies. See [`docs/goat-integration.md`](docs/goat-integration.md) and [`docs/erc-8004-identity.md`](docs/erc-8004-identity.md).

## Bring your own content

```ts
import { createGatewayMcpHandler } from "citely-x402";
import type { ContentProvider } from "citely-x402";

const myProvider: ContentProvider = {
  listCatalog: (q) => /* your catalog */ [],
  getContent: (slug) => /* your body + provenance */ null,
};

const handler = createGatewayMcpHandler({
  provider: myProvider, store: myUsageStore, freeLimit: 3, subscribeUrl: "https://…",
});
export { handler as GET, handler as POST };
```

## Relation to Citely

This is the open x402/MCP gateway. [Citely](https://citely.info) (private) plugs its own provenance-backed content provider into these same interfaces — the proprietary content, on-chain (EAS) provenance, and expert-review pipeline stay private. Nothing in this repo is Citely content; the shipped provider is dummy sample data.

## License

MIT — see [LICENSE](./LICENSE).