# GEDX402 — MCP builder setup

Wire GEDX402 MCP in Cursor for **operator testing** — list paid tools and settle x402 USDC from the CDP buyer wallet.

**Customer pay path:** [EXTERNAL-PAYER.md](./EXTERNAL-PAYER.md) — `@x402/fetch` primary; awal optional (no MCP, no API keys). See [INTEGRATOR-QUICKSTART.md](./INTEGRATOR-QUICKSTART.md).

**Agentic Wallet path:** [AGENTIC-WALLET.md](./AGENTIC-WALLET.md) — `npx skills add coinbase/agentic-wallet-skills`, fund USDC on Base, then direct x402 or `gedx402_list_tools` / `gedx402_call`.

**Operator testing (hosted MCP):** Cloudflare Worker at `https://mcp.gedx402.com/mcp` — signs via CDP secrets (`CDP_API_KEY_ID`, `CDP_API_KEY_SECRET`, `CDP_WALLET_SECRET`). Not the primary customer integration.

Hub: `https://gedx402.com` · Manifest: `/.well-known/agents.json` · Hosted MCP: `https://mcp.gedx402.com/mcp`

---

## 1. Cursor MCP (hosted — recommended)

Add one URL to `.cursor/mcp.json` in **ged** or **ged-x402** (merge with other servers such as `superlocalmemory`):

```json
{
  "mcpServers": {
    "ged-x402": {
      "url": "https://mcp.gedx402.com/mcp"
    }
  }
}
```

Restart MCP / reload the Cursor window after editing. **No `npm run mcp` process** — Cursor talks directly to the Worker.

| Item | Value |
| --- | --- |
| Endpoint | `https://mcp.gedx402.com/mcp` (Streamable HTTP — GET/POST) |
| Tools | `code` (Code Mode — orchestrate via JS) when `CODE_MODE=true`; else `gedx402_list_tools`, `gedx402_call`, … |
| Payment | **Server-side** x402 via CDP buyer secrets on the `ged-x402-mcp` Worker |
| Fund buyer | Fund the CDP `ged-x402-buyer` wallet with USDC on Base (and Solana if enabled) |

**Operator deploy:** `npm run deploy -- --shard=mcp` (sets CDP secrets from `../ged/.env`). Smoke: `npm run mcp:smoke`.

**Without server-side CDP secrets:** `gedx402_list_tools` and `gedx402_health` work; `gedx402_call` returns a clear error. For laptop-signed payments, use the optional local bridge (§3).

Discovery: hub `/.well-known/x402` includes `remote_mcp`.

### Operator prod testing

`gedx402_call` on the hosted MCP pays from the **operator** CDP buyer wallet (`ged-x402-buyer`), not customer wallets. Use this for prod smoke and agent testing only.

| Check | How |
| --- | --- |
| Wallet balance | MCP tool `gedx402_balances` (USDC per enabled network) |
| Per-call spend | Worker logs `type=mcp_settlement` JSON (route, shard, amount_usd, network, tx, buyer_suffix) |
| Dashboard | `mcp_operator_spend` on revenue API — separate from customer `estimated_gross_usd` |

Fund the buyer with USDC on Base (and Solana if enabled). Cap per call: `GEDX402_MAX_PAYMENT_USD` (default 5).

### Code Mode (orchestrate tools via code)

[Cloudflare Code Mode](https://blog.cloudflare.com/code-mode/) wraps all GEDX402 MCP tools behind a single **`code`** tool. The model writes JavaScript that calls `codemode.gedx402_*` methods; the mcp Worker runs it in an isolated dynamic Worker (`LOADER` binding). Use for multi-step x402 flows instead of one tool call per LLM turn.

| Item | Value |
| --- | --- |
| Enabled | `CODE_MODE=true` on `ged-x402-mcp` (default) |
| MCP tool | `code` — pass async arrow function body as string |
| Disable | `CODE_MODE=false` + redeploy mcp shard |
| Verify | `npm run ged:codemode-setup` (ged repo) |
| Prod beta | [Worker Loader signup](https://forms.gle/MoeDxE9wNiqdf8ri9) if deploy fails on LOADER |

---

## 2. CDP credentials (operator deploy / optional local bridge)

Create or extend the sibling **ged** repo `.env` (loaded automatically by `src/load-env.js`):

| Variable | Purpose |
| --- | --- |
| `CDP_API_KEY_ID` | Coinbase Developer Platform API key |
| `CDP_API_KEY_SECRET` | CDP API secret |
| `CDP_WALLET_SECRET` | CDP wallet secret (buyer signing) |
| `X402_NETWORK` | `base` (mainnet) or `base-sepolia` (testnet) |

One-time buyer setup:

```bash
npm run buyer:setup
```

Fund the printed EVM address with enough USDC on Base for starter calls (`worst_case_price_usd` from manifest).

Portal: https://portal.cdp.coinbase.com/

---

## 3. Local MCP bridge (optional — dev only)

Use only when you need your **laptop** to sign x402 payments (e.g. hosted Worker lacks CDP secrets, or shard filtering via env). **Not required** for normal Cursor use — prefer §1 hosted URL.

Do **not** add `command`/`args` to `.cursor/mcp.json` for production; keep hosted `url` only.

Smoke the bridge from a terminal (not Cursor MCP):

```bash
npm run mcp
```

Optional env (shell or `.env`):

| Variable | Default | Purpose |
| --- | --- | --- |
| `GEDX402_HUB` | `https://gedx402.com` | Hub origin |
| `GEDX402_SHARD` | — | Filter manifest to one shard (e.g. `search`) |
| `GEDX402_MAX_PAYMENT_USD` | `5` | Per-call USDC cap |

Local Cursor wiring (dev only — spawns `node scripts/ged-x402-mcp.mjs`):

```json
{
  "mcpServers": {
    "ged-x402-local": {
      "command": "node",
      "args": ["scripts/ged-x402-mcp.mjs"]
    }
  }
}
```

Open the **ged-x402** folder as the Cursor workspace. Requires `../ged/.env` CDP creds on your machine.

---

## 4. MCP tools

| Tool | Use |
| --- | --- |
| `gedx402_health` | Hub health, tool count, CDP buyer status |
| `gedx402_list_shards` | Modality shards + origin URLs |
| `gedx402_list_tools` | Paid routes (name, shard, price, endpoint) |
| `gedx402_call` | Invoke any tool by name with JSON body |
| `gedx402_balances` | Buyer USDC on all enabled networks |
| `gedx402_poll_job` | Poll async browser jobs (free, after submit) |

When `GEDX402_SHARD` is set, per-route tools (e.g. `gedx402_chat_micro`) are also registered.

### `gedx402_list_tools`

Returns tools in **outcome-first order**: browser extract → managed RAG session → image → voice → chat tiers last.

Optional `shard` filter — `browser`, `aisearch`, `media`, `chat`, `search`, `jobs`, `llm`, `embed`, `image`, etc.

Returns JSON array: `name`, `shard`, `price`, `endpoint`, `description`.

### `gedx402_call`

| Field | Required | Notes |
| --- | --- | --- |
| `tool` | yes | Name from `gedx402_list_tools` |
| `body` | yes | POST JSON for the route |
| `wait` | no | For async jobs: poll until done (default follows tool `async` flag) |

**Example — cheap chat probe:**

```json
{
  "tool": "gedx402_chat_micro",
  "body": {
    "messages": [{ "role": "user", "content": "Say hi." }],
    "max_tokens": 16
  }
}
```

**Example — vector search:**

```json
{
  "tool": "gedx402_search_query",
  "body": {
    "namespace": "demo",
    "query": "edge inference",
    "top_k": 3
  }
}
```

**Example — Scrape Lite (browser hero):**

```json
{
  "tool": "gedx402_firecrawl_scrape",
  "body": { "url": "https://example.com" }
}
```

---

## 5. Starter tools (cheap probes)

Outcome-first — browser and RAG heroes before chat tiers. These map to per-shard starter routes (`starter:true` in agents.json) from `SHARD_STARTER_ROUTES`:

| Tool | Shard | Starter route | Task |
| --- | --- | --- | --- |
| `gedx402_embed_ping` | embed | `POST /v1/embed/ping` | entry probe |
| `gedx402_firecrawl_scrape` | browser | `POST /v1/firecrawl/scrape` | Scrape Lite hero |
| `gedx402_aisearch_outcome_answer` | aisearch | `POST /v1/aisearch/outcome/answer` | RAG answer hero |
| `gedx402_images_transform` | images-api | `POST /v1/images/transform` | resize/fit/transcode |
| `gedx402_image_flux_1_schnell` | image | `POST /v1/image/flux-1-schnell` | fast image gen |
| `gedx402_voice_sessions` | media | `POST /v1/voice/sessions` | voice session hero |
| `gedx402_jobs_browser` | jobs | `POST /v1/jobs/browser` | async browser submit |
| `gedx402_chat_micro` | chat | `POST /v1/chat/micro` | lowest chat tier |
| `gedx402_llm_qwen3_30b_a3b_fp8` | llm | `POST /v1/llm/qwen3-30b-a3b-fp8` | raw LLM route |
| `gedx402_agents_sessions` | agents | `POST /v1/agents/sessions` | hosted agent session |
| `gedx402_memory_sessions` | d1 | `POST /v1/memory/sessions` | memory session hero |
| `gedx402_unified_run` | gateway | `POST /v1/unified/run` | unified catalog chat |
| `gedx402_objects__key` | storage | `PUT /v1/objects/:key` | artifact upload |
| `gedx402_turnstile_verify` | turnstile | `POST /v1/turnstile/verify` | Turnstile verify |

Run `gedx402_list_tools` (no filter) for the live outcome-first list with price and endpoint.

### Bundle starter examples

**Voice** (`GET /v1/models?bundle=voice`):

```json
{
  "tool": "gedx402_voice_sessions",
  "body": { "budget": { "duration_minutes": 5, "max_turns": 30 } }
}
```

**Browser** (`GET /v1/models?bundle=browser`):

```json
{
  "tool": "gedx402_firecrawl_scrape",
  "body": { "url": "https://example.com" }
}
```

**RAG** (`GET /v1/models?bundle=rag`):

```json
{
  "tool": "gedx402_embed_small",
  "body": { "text": "Workers AI runs at the edge." }
}
```

**Managed RAG** (`GET /v1/models?bundle=managed-rag`):

```json
{
  "tool": "gedx402_aisearch_sessions",
  "body": { "initial_index": { "url": "https://example.com/docs" }, "budget": { "max_index_ops": 1, "max_queries": 1 } }
}
```

**Search** (`GET /v1/models?bundle=search`):

```json
{
  "tool": "gedx402_exa_search",
  "body": { "query": "x402 agent marketplace APIs", "num_results": 5, "type": "auto" }
}
```

---

## 5. BYOK operator MCP (ged repo — research only)

Customers pay x402 on shard URLs. For **operator** research in Cursor, wire upstream MCP from the sibling **ged** repo (vault-bootstrap — no local key files; `GED_CF_API_TOKEN` in `ged/.env` only):

| Provider | Setup | MCP package |
| --- | --- | --- |
| Firecrawl | `npm run ged:firecrawl-setup` | `firecrawl-mcp` |
| Tavily | `npm run ged:tavily-setup` | remote `mcp.tavily.com` |
| Exa | `exa-mcp` in `ged/.cursor/mcp.json` | remote Exa MCP |
| SociaVault | `npm run ged:sociavault-setup` | `sociavault-mcp` |

Agents: `ged/.cursor/agents/firecrawl.md`, `tavily.md`, `exa.md`, `sociavault.md`. Restart Cursor after setup.

---

## 6. CLI buyer demo (no MCP)

Paid fetch without Cursor — optional CDP Bazaar search or direct chat call:

```bash
npm run x402:buyer-demo              # POST chat.gedx402.com/v1/chat/micro
npm run x402:buyer-demo -- --search  # Bazaar NL search, then pay discovered URL
```

Logs `payment-response` settlement header. See [DISTRIBUTION.md](./DISTRIBUTION.md) §5 for Bazaar indexing.
