Skip to main content
Glama

AI Agent Hub

x402-compliant marketplace for AI agents. Agents pay USDC (on Base) directly over HTTP — no API keys, no signup, no invoices — to buy:

  • Data queries (/api/queries) — paid: mode: "fetch" for title/description/text, "links" for outbound links, "images" for image sources + alt text, "metadata" for meta tags + response headers

  • Storage (/api/storage) — paid file upload / download

  • Ads (/api/ads) — paid ad impressions/clicks for agent-facing surfaces

  • Agent registry (/api/agents) — agents register themselves, free tier

Every paid route returns HTTP 402 Payment Required with x402 payment requirements when called without payment. An x402-aware client — e.g. a CdpX402Client wrapped with @x402/fetch's wrapFetchWithPayment — signs a USDC payment and retries the request with a PAYMENT-SIGNATURE header. The server, built with the CDP SDK's createX402Server, verifies

  • settles the payment through the CDP hosted facilitator, then serves the resource.

The same paid capabilities are also exposed as MCP tools, so any MCP-capable agent (Claude, etc.) can discover and call them directly — the MCP tool calls proxy into the same x402-protected routes.

Quick start

cp .env.example .env
# edit .env: set X402_PAY_TO_ADDRESS to your wallet

docker compose up --build

Related MCP server: UnifyAPI

Without Docker

cd backend && npm install && npm run dev
cd frontend && npm install && npm run dev

How the x402 flow works

  1. Agent calls POST /api/queries with no payment.

  2. Server (an X402Server from createX402Server) responds 402 Payment Required with the accepted payment options — price, asset (USDC), network, and the receiving address.

  3. Agent's client signs a payment (EIP-3009 exact/upto, or the Solana equivalent) and retries with a PAYMENT-SIGNATURE header.

  4. @x402/express's paymentMiddlewareFromHTTPServer calls the CDP hosted facilitator to verify the payment, runs the route handler, then calls the facilitator to settle it on-chain.

  5. Server responds 200 OK with the data, plus a settlement receipt.

See backend/src/middleware/x402Payment.js and backend/src/x402.js. Route pricing lives in x402.js's routeConfig map — everything else (wallet provisioning, scheme registration, facilitator auth, Bazaar discovery metadata) is handled by createX402Server.

Project structure

ai-agent-hub/
├── .vscode/                     # debug/run configs for VS Code
├── backend/
│   ├── src/
│   │   ├── index.js             # Express app entrypoint
│   │   ├── config.js            # env config loader
│   │   ├── x402.js              # builds the CDP-backed X402Server + route pricing
│   │   ├── db.js                # Postgres (pg) connection pool + schema
│   │   ├── routes/
│   │   │   ├── agents.js        # agent registration (free)
│   │   │   ├── storage.js       # paid upload/download
│   │   │   ├── queries.js       # paid data queries
│   │   │   └── ads.js           # paid ad impressions
│   │   ├── middleware/
│   │   │   └── x402Payment.js   # per-route x402 payment wrapper
│   │   └── mcp/
│   │       └── server.js        # MCP server exposing the same tools
│   ├── uploads/                 # file storage (docker volume)
│   ├── package.json
│   └── Dockerfile
├── frontend/                    # static dashboard (agents, revenue, ads)
├── client/                      # paying buyer scripts (proves the buy side)
│   ├── generate-wallet.mjs
│   ├── payForQuery.mjs
│   ├── payForUpload.mjs
│   ├── payForDownload.mjs
│   └── package.json
├── docker-compose.yml
├── deploy/
│   └── akash/
│       ├── deploy.yaml          # SDL manifest (fill in before deploying)
│       └── README.md            # step-by-step Akash deployment guide
├── .env.example
└── README.md

Networks & facilitator (CDP SDK)

This scaffold uses the CDP (Coinbase Developer Platform) SDK's x402 primitives (@coinbase/cdp-sdk/x402) rather than wiring a facilitator URL by hand. createX402Server() in backend/src/x402.js:

  • reads CDP_API_KEY_ID / CDP_API_KEY_SECRET from env and authenticates with the CDP hosted facilitator (JWT-authenticated, no facilitator URL to configure);

  • registers exact + upto payment schemes for EVM routes and exact for Solana;

  • settles into X402_PAY_TO_ADDRESS directly if set, or otherwise provisions and manages its own CDP wallet (needs CDP_WALLET_SECRET in that case);

  • picks its default networks from CDP_X402_SERVER_ENVIRONMENT: development → Base Sepolia + Solana Devnet, production → Base mainnet + Solana mainnet.

Create an API key at https://portal.cdp.coinbase.com, drop it into .env, and you're set — no manual scheme registration or facilitator auth-header wiring needed. On the client side, CdpX402Client (from the same SDK) provisions a CDP-managed paying wallet with no private keys to store, and supports client-side spend controls (per-payment caps, rolling caps, network/asset/payee allowlists) if you build a buyer alongside this seller.

Funding a test wallet

On Base Sepolia, fund your receiving/paying address with test USDC via the CDP faucet — either the portal (Onchain Tools → Faucet at https://portal.cdp.coinbase.com) or programmatically with cdp.evm.requestFaucet({ address, network: "base-sepolia", token: "usdc" }).

Fallback path: vanilla @x402/express (no CDP SDK)

This scaffold defaults to the CDP SDK's createX402Server because it handles wallet provisioning, scheme registration, and facilitator auth for you. If you'd rather not depend on the CDP SDK at all — e.g. you're managing your own signing keys, or want a facilitator other than Coinbase's — you can drop down to the vanilla x402 packages instead. This is a documented, supported path (from x402's own "Quickstart for Sellers"), not a hack:

import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { ExactSvmScheme } from "@x402/svm/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";

const app = express();
const evmAddress = "0xYourEvmAddress";
const svmAddress = "YourSolanaAddress";

// Testnet facilitator — free, no API key, Base Sepolia + Solana Devnet only.
// Confirmed explicitly NOT for production use.
const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://x402.org/facilitator",
});

// Mainnet: swap in the CDP hosted facilitator's REST endpoint directly
// (this is the underlying URL createX402Server calls for you — useful if
// you want CDP's facilitator without pulling in the rest of the CDP SDK):
//
// const facilitatorClient = new HTTPFacilitatorClient({
//   url: "https://api.cdp.coinbase.com/platform/v2/x402",
//   // still needs CDP_API_KEY_ID / CDP_API_KEY_SECRET auth — see the
//   // CDP facilitator docs for how to attach auth headers to this client.
// });
//
// Alternative third-party mainnet facilitator (no CDP account needed):
// const facilitatorClient = new HTTPFacilitatorClient({
//   url: "https://facilitator.payai.network",
// });

app.use(
  paymentMiddleware(
    {
      "POST /api/queries": {
        accepts: [
          {
            scheme: "exact",
            price: "$0.01",
            network: "eip155:84532", // Base Sepolia — use eip155:8453 for mainnet
            payTo: evmAddress,
          },
        ],
        description: "Run a single data query",
      },
    },
    new x402ResourceServer(facilitatorClient).register(
      "eip155:84532",
      new ExactEvmScheme()
    ),
  ),
);

If you go this route, replace backend/src/x402.js and backend/src/middleware/x402Payment.js with this pattern instead of createX402Server — the route handlers in routes/*.js don't change, since req.payment is populated the same way either way.

Facilitator URLs, confirmed:

Facilitator

URL

Networks

Auth

x402.org (testnet)

https://x402.org/facilitator

Base Sepolia, Solana Devnet

none

CDP hosted (mainnet)

https://api.cdp.coinbase.com/platform/v2/x402

Base, Solana, Polygon, Arbitrum, World mainnets

CDP_API_KEY_ID / CDP_API_KEY_SECRET

PayAI (mainnet, third-party)

https://facilitator.payai.network

check their docs for current coverage

varies

Never point production traffic at the x402.org testnet facilitator — it's explicitly documented as testnet-only.

Buying from your own server (the client side)

Everything above is the seller. client/ is a separate, minimal buyer — a script that actually completes a payment against this server, proving the full loop rather than just the 402 half.

cd client
npm install
cp .env.example .env
npm run generate-wallet

Copy the printed private key into client/.env as EVM_PRIVATE_KEY, then fund that address with Base Sepolia testnet USDC via the CDP faucet (portal.cdp.coinbase.com → Onchain Tools → Faucet). Wait ~30-60 seconds for the faucet transaction to confirm, then:

npm run pay-for-query -- https://example.com

This pays $0.01, then prints back the extracted page title/description/text from routes/queries.js's real fetch logic. A payment-response header in the output is your on-chain settlement receipt.

Storage round-trip (upload, then download the same file):

npm run pay-for-upload
# prints a fileId — pay to download it back:
npm run pay-for-download -- <fileId>

This is also the only way to fully test /api/storage/upload — a plain curl can't complete an x402 payment, so any curl-only test of a paid route will only ever get you the 402 response, never the real result.

Bazaar discovery — already on, needs a public URL to matter

Every route's 402 response already includes a "bazaar" block (you can see it in the decoded PAYMENT-REQUIRED header on any paid request) — createX402Server auto-injects the Bazaar discovery extension for every route in routeConfig, with discoverable metadata generated from each route's description. There's no extra code needed on your end; this is different from the vanilla @x402ResourceServer path, which requires manually setting extensions: { bazaar: { discoverable: true, ... } } per route.

What listing actually requires beyond that:

  1. A payment has to settle through the facilitator for a route to appear in the catalog — declaring the route isn't enough by itself. You've already cleared this: the client/ payments earlier settled real transactions through the CDP facilitator on Base Sepolia.

  2. A public URL. The resource.url in every 402 response is currently http://localhost:4021/... — not reachable by anyone but you. An external agent finding your listing in the Bazaar catalog still needs to actually call that URL to use it, so this only becomes meaningful once the backend is deployed somewhere with a real domain (see the deployment step in the mainnet checklist below).

  3. To enrich what shows up in search/browsing (beyond the minimal auto-generated metadata), you can pass a bazaar block to declareDiscoveryExtension per route in x402.js — see the example in docs.x402.org's seller quickstart, under "Enhance Discovery with Metadata."

You can browse the CDP facilitator's live catalog yourself once deployed: GET https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources?payTo=<your address>.

Mainnet checklist

Once you've verified the full buy/sell loop on testnet with client/:

  1. Deploy the backend somewhere with a public URL and a static IP — a VPS, a container host, anything reachable from the internet. localhost can't be called by real agents or appear meaningfully in Bazaar. Once deployed, add that server's IP to your CDP API key's allowlist (portal.cdp.coinbase.com → the same screen where you opted out of allowlisting for local dev earlier).

    If deploying to Akash Network: a ready-to-fill SDL manifest and full step-by-step guide live in deploy/akash/ — including the architecture decision to use a managed Postgres provider instead of self-hosting it on Akash, since Akash's persistent storage is tied to the lease and is lost on redeploy/migration. See deploy/akash/README.md before deploying.

  2. Flip CDP_X402_SERVER_ENVIRONMENT=production in the backend's .env.

  3. Point X402_PAY_TO_ADDRESS at a real mainnet wallet you control — double check this address before deploying; mainnet transactions are real money.

  4. Fund a buyer wallet with real mainnet USDC if you're also testing the client against production — never reuse a testnet-only throwaway key from generate-wallet.mjs for this.

  5. If you ever swap the CDP SDK for the vanilla @x402/express fallback above, use https://api.cdp.coinbase.com/platform/v2/x402 — never leave https://x402.org/facilitator wired up for production traffic.

  6. Expand routes/queries.js's data source beyond single-page fetches if your catalog grows — rate limiting, caching, and a real allowlist of fetchable domains are worth adding before this is public-facing.

  7. Re-run the SDK verification step from earlier (node -e "import('@coinbase/cdp-sdk/x402').then(m => console.log(Object.keys(m)))") against whatever version npm install actually pulled — latest in package.json means it can drift between your dev machine and a fresh production deploy.

Notes / next steps

  • Dependencies for @coinbase/cdp-sdk and the @x402/* packages are pinned to latest in backend/package.json since this ecosystem moves fast — run npm install then check npm list if you want to pin exact versions for reproducible builds.

  • db.js uses pg against Postgres — docker-compose runs a postgres:16-alpine service alongside the backend automatically; for local (non-Docker) dev, point DATABASE_URL at any Postgres instance you have running. Schema is created automatically on boot via initDb() (CREATE TABLE IF NOT EXISTS, safe to run on every startup).

  • routes/queries.js fetches a single URL and extracts title/description/ text via cheerio — swap fetchPageData for a real scraper, search API, or automation job runner as the catalog grows beyond simple fetches.

  • For an MCP server that also pays for x402-protected APIs (rather than just gating its own), see the CDP docs' MCP Server guide — account.signX402Payment() signs a payment directly for non-HTTP transports like MCP, no client wrapper needed.

  • backend/src/mcp/server.js currently gates paid MCP tools by proxying each tool call into the x402-protected REST routes above (verified, working). There's a more "native" option — @x402/mcp's createPaymentWrapper — but its exact API for attaching to McpServer.registerTool isn't documented publicly as of this writing. Before switching to it, inspect the type declarations yourself: npm install @x402/mcp @x402/core @x402/evm @x402/extensions, then grep -A 15 "createPaymentWrapper" node_modules/@x402/mcp/dist/*.d.ts.

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • AgisHub — pay-per-call tools for AI agents over x402 (USDC on Base). No API key.

  • Pay-per-use weather, environment, finance, and on-chain intelligence tools for AI agents via x402.

  • 63 pay-per-call tools for agents: vision, text, data, web, blockchain. USDC on Base via x402.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/justuncase1210-del/AI-Agent-Hub'

If you have feedback or need assistance with the MCP directory API, please join our Discord server