# MCPay docs

Commerce layer for AI agents on MultiversX. Everything you need to
call a paid MCP or publish one of your own — and, for agents, how to
pay us via open protocols with no signup.

## Start here (AI agents, no signup needed)

MCPay turns any HTTP API into a paid MCP server. An autonomous agent
that understands the x402 protocol can discover our services, call
them, and pay per-request entirely on-chain. Three steps:

```bash
# 1. Discover — list every paid MCP on this gateway
curl {{GATEWAY}}/api/catalog

# 2. Call — unauth'd POST returns a 402 payment challenge
curl -X POST {{GATEWAY}}/mcp/mvx-chain-data/getBlockHeight \
  -H 'content-type: application/json' \
  -d '{}'
# → HTTP 402 with a body matching /.well-known/x402.json `challenge_schema`

# 3. Pay + retry — broadcast an MVX tx matching accepts[0], then retry
#    with x-payment: base64(JSON({ tx_hash, nonce, from }))
```

Full machine-readable profile: `{{GATEWAY}}/.well-known/x402.json`
contains JSON Schemas for both the challenge and the x-payment
envelope. No prose required; a JSON-Schema validator is enough.

This is the recommended path for agents that find MCPay through
search, referrals, or crawlers. No API key to manage, no human in the
loop, no SDK install.

## Start here (agent owners — pre-paid balance)

If you're building an agent that calls MCPay many times on your own
behalf, a pre-paid owner balance is usually cheaper and faster than
an x402 tx per call. Connect a MultiversX wallet at <{{SITE}}>, top up
with EGLD, and use the API key on every call:

```bash
pnpm add @mcpay/sdk
```

```ts
import { McpayClient } from '@mcpay/sdk';

const mcpay = new McpayClient({
  gatewayUrl: '{{GATEWAY}}',
  apiKey:     process.env.MCPAY_API_KEY!,
  network:    '{{NETWORK}}', // client throws if gateway reports a different net
});

const account = await mcpay.call('mvx-chain-data', 'getAccount', {
  address: 'erd1…',
});
console.log(account.data.balance);
```

No `MCPAY_API_KEY` yet? Connect a MultiversX wallet at
<{{SITE}}> — we auto-provision a deterministic API key from your address.

## For agent owners

### Get an API key

Connect any MultiversX wallet (xPortal, DeFi Wallet, Ledger). MCPay
upserts your agent-owner row keyed by wallet address and returns a
deterministic API key (sent as `x-mcpay-key` on every request). Same
wallet → same key, reusable across sessions. It&apos;s an off-chain
bearer string on MCPay — not an on-chain ESDT token.

### Check your balance

```bash
curl -H "x-mcpay-key: $MCPAY_API_KEY" \
  {{GATEWAY}}/api/agents/$OWNER_ID/balance
# → {"ownerId":"ao_…","balanceX10k":0,"monthlyBudgetX10k":null}
```

Balance is an integer of ten-thousandths of USD. `1 = $0.0001`,
`10000 = $1`.

### Call a tool

```bash
curl -X POST {{GATEWAY}}/mcp/mvx-chain-data/getAccount \
  -H 'content-type: application/json' \
  -H 'x-mcpay-key: mcpay_w_…' \
  -d '{"address":"erd1…"}'
```

Response:

```jsonc
{
  "ok": true,
  "data": { "balance": "8…", "nonce": 335, /* … */ },
  "meta": {
    "call_id":    "c_xxxxxxxx",
    "latency_ms": 403,
    "price_x10k": 8,
    "cache_hit":  false,
    "upstream_status": 200
  }
}
```

### Failed calls do not deduct

Upstream 4xx/5xx or rate-limited → MCPay returns 502/503 **without
touching your balance**. A refund row is created; for wallet-connected
agents an on-chain `refund()` fires through the escrow contract.

### Sign + broadcast OAuth 2.1 bearer (autonomous agents)

```bash
# 1. Register a client
curl -X POST {{GATEWAY}}/oauth/register \
  -H 'content-type: application/json' \
  -d '{"client_name":"my-agent","scope":"mcp:call"}'
# → {"client_id":"mcpay_cl_…","client_secret":"mcpay_sec_…", …}

# 2. Exchange for an access_token
curl -X POST {{GATEWAY}}/oauth/token \
  -d 'grant_type=client_credentials' \
  -d 'client_id=…' -d 'client_secret=…'
# → {"access_token":"mcpay_oauth_…","token_type":"Bearer", …}

# 3. Use it — both headers work
curl -H "Authorization: Bearer $ACCESS_TOKEN" {{GATEWAY}}/api/catalog
```

## For providers

Upload an OpenAPI 3 spec, set a price per call, pick accepted tokens,
deploy. MCPay hosts the MCP server on Cloudflare Workers and settles
earnings daily to your MultiversX wallet.

- **Take rate** — 10% of every successful call. 90% to your wallet.
- **Rolling escrow** — 10% platform cut doubles as refund reserve.
  7-day bucket. Funds > 7 days auto-release via `releaseExpired()`.
- **Auto-disable** — 10 consecutive failures → MCP disabled until ack.
- **Pricing floor** — min $0.0001/call. No cap.
- **Edit after create** — `/p/mcps/:slug/edit` to re-price, swap
  upstream, flip cache policy, edit per-tool descriptions.

Onboarding wizard: `/p/mcps/new`.

## Networks

Three fully-independent gateways. Tokens don't cross.

| Network | URL | chainId | Status |
|---|---|---|---|
| mainnet | `mcpay.network` | 1 | planned |
| devnet  | `devnet.mcpay.network` | D | planned |
| testnet | `testnet.mcpay.network` | T | live |

Testnet runs on Supernova (0.6 s blocks).

## Contracts (testnet)

| Contract | Role | Address |
|---|---|---|
| payment-splitter | accumulate + 90/10 split | `erd1qqqqqqqqqqqqqpgq8k70hcdk3yu3hlquf7xe8cnp2u8y4ad97qtsazw8d5` |
| rolling-escrow   | 7-day refund pool | `erd1qqqqqqqqqqqqqpgqjcxayluj72f07tvvp4s4hvq6kvqstnxm7qtsjy4scf` |
| event-log        | per-call audit + aggregate counters | `erd1qqqqqqqqqqqqqpgqs8vpl76hjxj3m0dnaqqccwlkvgnwzjl77qts49mstv` |

Rust, `multiversx-sc` 0.65, upgradeable via `#[upgrade]`.

## Protocols

Shipped:

- **MCP** (Anthropic) — the tool interface. **live**
- **x402** (Coinbase) — HTTP 402 wire, on-chain tx-hash proof. **live** · profile at `/.well-known/x402.json`
- **OAuth 2.1 + DCR** (IETF) — MCP-over-HTTP compliance. **live**
- **AP2** (Google) — signed spend mandates, Ed25519-verified per-call. **live**
- **MPP** (Coinbase) — machine-payment tx-data tagging for audit trail. **live** · profile at `/.well-known/mpp.json`
- **Agent-as-Provider** (MCPay) — composite MCPs with revenue split. **live**

Tracking (spec not stable enough to implement — deliberately):

- **UCP** (Google) — universal commerce discovery. Catalog is UCP-shaped by convention; full profile lands when Google finalises.
- **ACP** (OpenAI + Stripe) — counter-offer / negotiation. Ships when real agents want to haggle.
- **MX-8004** (MultiversX) — agent identity NFTs + reputation registry. Following the spec to final before minting a contract.

## Error codes

| Code | HTTP | Meaning |
|---|---|---|
| `invalid_token` | 401 | token missing / revoked / wrong network |
| `payment_required` | 402 | no token supplied; challenge emitted |
| `insufficient_balance` | 402 | balance < tool price |
| `mandate_revoked` | 403 | mandate referenced by x-mcpay-mandate is revoked |
| `mandate_expired` | 403 | mandate passed expires_at |
| `mandate_mcp_not_allowed` | 403 | MCP slug not in mandate's allowlist |
| `mandate_exceeded` | 403 | next call would push spent_x10k past max |
| `mcp_not_found` | 404 | slug doesn't match any published MCP |
| `network_mismatch` | 409 | client-declared network ≠ gateway `/health` |
| `upstream_failed` | 502 | upstream 4xx/5xx; no balance deducted |
| `upstream_rate_limited` | 503 | MVX public API 429 us; SDK retries |
| `invalid_client` | 401 | OAuth client_id / client_secret mismatch |

---

Repo: <https://github.com/morfestboy/MCPay> · Brief: `docs/project-brief.md`
