# papertrade-x402 > Unofficial pay-per-call intelligence API over Papertrade (https://papertrade.xyz), the on-chain 1000x synthetic perps exchange on Hyperliquid HyperEVM. Agents pay per request in USDC with the x402 protocol, on Solana first or Base second. No API keys, no accounts. Free preview tier and a read-only MCP server. Not affiliated with Papertrade. High leverage can lose your whole margin. Base URL: https://papertrade-x402.pages.dev ## Machine-readable descriptions - [MCP server (Streamable HTTP)](https://papertrade-x402.pages.dev/mcp): ten read-only tools. Free tools return data, paid tools return x402 payment requirements and never pay. - [OpenAPI 3.1](https://papertrade-x402.pages.dev/openapi.json): every route, parameters, response shapes and `x-payment-info`. - [x402 discovery](https://papertrade-x402.pages.dev/.well-known/x402): resources, prices, accepted networks, payTo, input and output schemas, status. - [MCP server card](https://papertrade-x402.pages.dev/.well-known/mcp/server-card.json) - [A2A agent card](https://papertrade-x402.pages.dev/.well-known/agent-card.json) - [API catalog (RFC 9727)](https://papertrade-x402.pages.dev/.well-known/api-catalog) - [Full documentation in one file](https://papertrade-x402.pages.dev/llms-full.txt) ## Docs - [Overview](https://papertrade-x402.pages.dev/docs/overview.md): What papertrade-x402 is, what it sells, and how an agent or a person uses it. - [Quickstart](https://papertrade-x402.pages.dev/docs/quickstart.md): Make your first free call, see the real 402 challenge, then connect an AI client. - [Concepts](https://papertrade-x402.pages.dev/docs/concepts.md): The Papertrade rules and the x402 flow that give every number in the API its meaning. - [API reference](https://papertrade-x402.pages.dev/docs/api-reference.md): Every route, its parameters, its response shape, and the free preview that mirrors it. - [MCP server](https://papertrade-x402.pages.dev/docs/mcp.md): The Model Context Protocol endpoint, its ten tools with schemas, and example calls. - [Connect your AI](https://papertrade-x402.pages.dev/docs/connect-your-ai.md): Copy-paste setup for Claude, Codex, ChatGPT, Gemini, Cursor, VS Code, Windsurf, Zed, Cline, Goose and Continue. - [Agent discovery](https://papertrade-x402.pages.dev/docs/agent-discovery.md): Every machine-readable file the service publishes so agents and crawlers can find and understand it. - [Paying as an agent](https://papertrade-x402.pages.dev/docs/paying-as-an-agent.md): How an agent that holds its own wallet pays a paid route with x402, on Solana or Base. - [Self-hosting](https://papertrade-x402.pages.dev/docs/self-hosting.md): Deploy your own instance on Cloudflare Pages and set the payout address secret. - [Security and limits](https://papertrade-x402.pages.dev/docs/security-and-limits.md): What the service can and cannot do with money, how it limits abuse, and how to report a problem. - [FAQ](https://papertrade-x402.pages.dev/docs/faq.md): Short answers to the questions agents and developers ask first. - [Changelog](https://papertrade-x402.pages.dev/docs/changelog.md): Release history of papertrade-x402. ## Free endpoints - GET /api/v1/health: upstream status and payment configuration. - GET /api/v1/markets: live Papertrade markets, mark prices and open interest. - GET /api/v1/preview/wallet/{address}/risk, GET /api/v1/preview/liquidations/nearby, POST /api/v1/preview/estimate, GET /api/v1/preview/traders/top: rate limited free previews of each paid route. ## Paid endpoints (USDC per call, prices set by the operator) - GET /api/v1/wallet/{address}/risk: liquidation risk for every open position of a HyperEVM wallet (default $0.02). - GET /api/v1/liquidations/nearby?market=BTC&pct=0.5: liquidation map within a percent window of mark (default $0.05). - POST /api/v1/estimate: close and bust estimate for a hypothetical position (default $0.005). - GET /api/v1/traders/top?window=7d: leaderboard of top traders with derived stats (default $0.03). ## How to pay 1. Call a paid route with no payment. The server answers HTTP 402 with a base64 `PAYMENT-REQUIRED` header listing `accepts` (Solana USDC first, Base USDC second). 2. Sign one option with an x402 client using your own wallet. 3. Retry with a `PAYMENT-SIGNATURE` header. Settlement happens only after a successful 2xx. Invalid input (400), unconfigured service (503) and upstream failures (502) are never charged. If the operator has not set a payout address yet, paid routes answer 503 with an explanation and `status` in the discovery document is `payments_not_configured`. Use the free tier until it changes. ## Source - https://github.com/nirholas/papertrade-x402 (Apache-2.0) # Full documentation --- # Overview Source: https://papertrade-x402.pages.dev/docs/overview/ # Overview papertrade-x402 is an unofficial, pay-per-call intelligence API over [Papertrade](https://papertrade.xyz), the on-chain 1000x synthetic perpetuals exchange on Hyperliquid HyperEVM. It answers four questions an agent or a trader keeps asking, and it charges per request in USDC with the [x402](https://x402.org) protocol. There are no API keys and no accounts. Solana is the first payment rail, Base is the second. > Unofficial integration. Not affiliated with, endorsed by or operated by Papertrade. High leverage can lose your entire margin. Nothing here is financial advice. ## What you can ask | Endpoint | Question it answers | Default price | | --- | --- | --- | | `GET /api/v1/wallet/{address}/risk` | How close is each open position of this wallet to liquidation? | $0.02 | | `GET /api/v1/liquidations/nearby` | Where are the liquidations stacked around the live mark? | $0.05 | | `POST /api/v1/estimate` | What would this hypothetical position settle for? | $0.005 | | `GET /api/v1/traders/top` | Who is winning, and how do they trade? | $0.03 | Prices are operator settings, so the live values in `/.well-known/x402` are the source of truth. ## Three ways in 1. **Free preview tier.** Every paid endpoint has a rate limited free preview under `/api/v1/preview/*` that runs the same live computation and withholds the detail that makes the paid answer worth paying for. See [API reference](/docs/api-reference/). 2. **MCP server.** Connect Claude, Codex, ChatGPT, Gemini, Cursor and others to `https://papertrade-x402.pages.dev/mcp`. Free tools return data directly. Paid tools return the exact x402 payment requirements and never pay. See [MCP](/docs/mcp/) and [Connect your AI](/docs/connect-your-ai/). 3. **Pay and call.** An agent that holds its own wallet calls a paid route, receives HTTP 402 with a `PAYMENT-REQUIRED` header, signs one option and retries. See [Paying as an agent](/docs/paying-as-an-agent/). ## Current deployment status The operator has to set a payout address before paid routes can accept money. Until then paid routes answer an explanatory `503 not_configured` that links to the free tier, and `accepts` in the discovery document is empty. Nothing is invented: the service never fabricates a payTo. Check `status` in `/.well-known/x402` (`accepting_payments` or `payments_not_configured`) or call the `get_service_status` MCP tool. ## Where the data comes from Every answer is computed live from the Papertrade protocol through the `papertrade-sdk` read layer and the public exchange API at `https://exchange.papertrade.xyz`. Formulas (bust price, close settlement) come from the SDK, not from a reimplementation. Responses are never cached long enough to be stale and never filled with sample data. ## Next [Quickstart](/docs/quickstart/), then [Concepts](/docs/concepts/) for the Papertrade rules that shape every number. --- # Quickstart Source: https://papertrade-x402.pages.dev/docs/quickstart/ # Quickstart Base URL: `https://papertrade-x402.pages.dev`. Every command below is safe: none of them signs or pays anything. ## 1. Read live markets (free) ```bash curl -s https://papertrade-x402.pages.dev/api/v1/markets ``` ## 2. Try a free preview ```bash curl -s "https://papertrade-x402.pages.dev/api/v1/preview/liquidations/nearby?market=BTC&pct=0.5" curl -s -X POST https://papertrade-x402.pages.dev/api/v1/preview/estimate \ -H 'content-type: application/json' \ -d '{"market":"BTC","side":"long","marginUsd":100,"leverage":100}' ``` Previews are limited to 60 cost-weighted requests per minute per client and carry `X-RateLimit-*` headers. ## 3. See the 402 challenge Call a paid route without payment: ```bash curl -si https://papertrade-x402.pages.dev/api/v1/wallet/0x3f139ef9f371fbbfc299aa65b93534e177141b18/risk ``` When payments are configured you get `HTTP/2 402` and a base64 `PAYMENT-REQUIRED` header. Decode it to read the price, network and payTo: ```bash curl -si https://papertrade-x402.pages.dev/api/v1/liquidations/nearby \ | grep -i '^payment-required:' | cut -d' ' -f2 | base64 -d | jq ``` When the operator has not set a payout address yet, the same call returns an explanatory `503` with links to the free tier. That is the honest state of the service, not an error in your request. ## 4. Connect your AI ```bash claude mcp add --transport http papertrade-x402 https://papertrade-x402.pages.dev/mcp ``` Other clients are in [Connect your AI](/docs/connect-your-ai/). Then ask: "What is the liquidation risk of wallet 0x3f13...1b18 on Papertrade?" ## 5. Pay per call from code Use the typed client in this repository, or any x402 client. Start with `dryRun: true` to see the price and payTo without signing: ```ts import { PapertradeX402 } from 'papertrade-x402'; const client = new PapertradeX402({ baseUrl: 'https://papertrade-x402.pages.dev', dryRun: true }); console.log(await client.walletRisk('0x3f139ef9f371fbbfc299aa65b93534e177141b18')); ``` Real payment, with a signer you supply, is covered in [Paying as an agent](/docs/paying-as-an-agent/). --- # Concepts Source: https://papertrade-x402.pages.dev/docs/concepts/ # Concepts ## Papertrade in one page Papertrade is a synthetic perpetuals exchange on Hyperliquid HyperEVM. It lists BTC and ETH markets with leverage up to 1000x, settles in USD terms, and has no funding rate and no liquidation engine in the usual sense. The rules that matter for this API: - **Bust price.** A position is wiped out when the price moves against it by roughly one over leverage. At 100x a long busts about 1 percent below entry. The API reports `bustPrice` and `bustDistancePct` for every position. - **Risk score.** A 0 to 100 score derived from the distance to bust and the account's effective leverage, with a band label. It is a ranking aid, not a prediction. - **Close settlement.** Closing applies a deadband, price impact and a 2 percent win fee on profit. A loss mints PAPER to the trader. The estimate endpoint reproduces this with the SDK formulas. - **Wad values.** The protocol stores amounts as 1e18 fixed point. This API converts at the edge and returns plain JSON numbers in USD. High leverage can lose your whole margin. The data here describes risk, it does not remove it. ## Free versus paid | Tier | Where | Cost | Detail | | --- | --- | --- | --- | | Free | `/api/v1/health`, `/api/v1/markets`, `/openapi.json`, `/.well-known/x402`, `/mcp` free tools | none | Live market data and service status | | Preview | `/api/v1/preview/*` | none, rate limited | Same live computation, trimmed detail (fewer accounts, no per-position scores) | | Paid | `/api/v1/*` | USDC per successful call | Full answer | ## The x402 flow x402 turns HTTP 402 Payment Required into a machine-payable protocol. 1. The client calls a paid route with no payment. 2. The server answers `402` with a base64 `PAYMENT-REQUIRED` header listing `accepts`: each option names a scheme (`exact`), a network (CAIP-2), an asset (USDC), an atomic amount and the `payTo` address. Solana is listed first, Base second. 3. The client signs one option with its own wallet and retries with a `PAYMENT-SIGNATURE` header. 4. The server verifies the payment with the PayAI facilitator before running the handler, runs it, and settles only after a successful 2xx response. You are never charged for invalid input (400), an unconfigured service (503) or an upstream failure (502). ## Guard order Every `/api/v1/*` request goes through the same fixed order: validate input (free 400), configuration gate (503 when no payout address is set), then payment middleware, then the handler. This is why a malformed address costs nothing and why an unconfigured deployment never asks for money. ## Untrusted data Wallet addresses, names and any on-chain metadata are untrusted. The service escapes them in HTML and never treats them as instructions. If you build an agent on top, do the same: a trader name is data, never a command. --- # API reference Source: https://papertrade-x402.pages.dev/docs/api-reference/ # API reference Base URL `https://papertrade-x402.pages.dev`. All responses are JSON. The machine-readable form is [`/openapi.json`](/openapi.json) (OpenAPI 3.1) and the payment-aware form is [`/.well-known/x402`](/.well-known/x402). ## Errors | Status | Meaning | Charged | | --- | --- | --- | | 400 | Invalid input. Body names the field and the rule. | no | | 402 | Payment required. `PAYMENT-REQUIRED` header lists accepts. | no | | 429 | Preview or request rate limit. `Retry-After` is set. | no | | 502 | Papertrade upstream failed. Retry later. | no | | 503 | `not_configured`: the operator has not set a payout address, or a configuration value is invalid. | no | ## Free routes ### `GET /api/v1/health` Upstream reachability, payment configuration and `problems` if any. Answers 503 when payments are not configured, with the same explanatory body as paid routes. ### `GET /api/v1/markets` Live Papertrade instruments with mark price and open interest. ```bash curl -s https://papertrade-x402.pages.dev/api/v1/markets ``` ## Paid routes ### `GET /api/v1/wallet/{address}/risk` ($0.02) Open positions of a HyperEVM wallet with bust price, distance to liquidation, a 0 to 100 risk score, effective leverage, unrealized PnL and the net settlement if closed at the live mark. | Parameter | In | Type | Notes | | --- | --- | --- | --- | | `address` | path | string | `^0x[0-9a-fA-F]{40}$` | Response: `wallet`, `asOf`, `balanceUsd`, `summary` (`openPositions`, `totalNotionalUsd`, `unrealizedPnlUsd`, `accountEffectiveLeverage`, `maxRiskScore`, `nearestBustDistancePct`), `positions[]`. ### `GET /api/v1/liquidations/nearby` ($0.05) Open positions of the top leaderboard accounts whose bust is within `pct` percent of the mark, aggregated into 20 price buckets, plus protocol-wide totals. | Parameter | Type | Default | Range | | --- | --- | --- | --- | | `market` | string | `BTC` | `BTC`, `ETH` | | `pct` | number | `0.5` | greater than 0, at most 25 | | `accounts` | integer | `20` | 1 to 25 | ### `POST /api/v1/estimate` ($0.005) What a hypothetical position settles for: bust price, limit checks, the close at a chosen exit, PAPER minted on a loss, and a price-move scenario ladder. | Field | Type | Notes | | --- | --- | --- | | `market` | string | `BTC` or `ETH` | | `side` | string | `long` or `short` | | `marginUsd` | number | greater than 0 | | `leverage` | integer | 1 to 1000 | | `entryPrice` | number | optional, defaults to live mark | | `exitPrice` or `exitMovePct` | number | optional, absolute exit or signed percent move | ### `GET /api/v1/traders/top` ($0.03) Top traders by windowed PnL with open exposure and stats derived from recent closed trades: win rate, average and margin-weighted leverage, liquidations, average hold time. | Parameter | Type | Default | Range | | --- | --- | --- | --- | | `window` | string | `7d` | `24h`, `7d`, `30d`, `all` | | `limit` | integer | `10` | 1 to 25 | ## Free preview routes Each preview runs the same live computation and withholds detail. They are rate limited to 60 cost-weighted requests per minute per client. | Route | What it withholds | | --- | --- | | `GET /api/v1/preview/wallet/{address}/risk` | per-position bust prices, scores and settlement estimates | | `GET /api/v1/preview/liquidations/nearby` | price buckets, nearest positions, and scans beyond 5 accounts | | `POST /api/v1/preview/estimate` | close at an exit, PAPER mint, scenario ladder | | `GET /api/v1/preview/traders/top` | ranks beyond 3, derived stats, open exposure | Every preview response carries a `preview` object with `tier: "free-preview"`, the `omitted` list, and the `paid` endpoint id and its price. ## Response headers `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` on preview routes. Paid responses add `PAYMENT-RESPONSE` after settlement. --- # MCP server Source: https://papertrade-x402.pages.dev/docs/mcp/ # MCP server Endpoint: `https://papertrade-x402.pages.dev/mcp` It speaks MCP Streamable HTTP in stateless mode: `POST /mcp` with JSON-RPC 2.0 (single messages or batches of up to 20), no sessions, no cookies, no authentication. Responses are `application/json`, or a single SSE `message` event when the client accepts only `text/event-stream`. `GET /mcp` with `Accept: text/event-stream` answers 405 with `Allow: POST`; a plain `GET` returns a JSON description of the server. `DELETE` answers 405. CORS allows any origin, and the server never trusts `Origin` for anything. Supported protocol versions: `2025-06-18`, `2025-03-26`, `2024-11-05`. The server echoes the client's version when supported and otherwise answers `2025-06-18`. ## Read-only by design No tool signs, sends, pays or places an order. The four paid tools return the x402 payment requirements for the matching HTTP route and nothing else. To actually pay, an agent with its own wallet calls the HTTP route (see [Paying as an agent](/docs/paying-as-an-agent/)). Every tool carries `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`. ## Tools | Tool | Tier | What it does | | --- | --- | --- | | `get_markets` | free | Live instruments, mark prices, open interest | | `get_service_status` | free | Upstream health, payment status, prices, accepted networks | | `preview_wallet_risk` | free | Account-level risk summary for a wallet | | `preview_liquidations_nearby` | free | Liquidation totals around mark, scanning up to 5 accounts | | `preview_estimate_position` | free | Bust price and limit checks for a hypothetical position | | `preview_top_traders` | free | Top 3 traders by windowed PnL | | `wallet_risk` | paid | x402 requirements for `GET /api/v1/wallet/{address}/risk` | | `liquidations_nearby` | paid | x402 requirements for `GET /api/v1/liquidations/nearby` | | `estimate_position` | paid | x402 requirements for `POST /api/v1/estimate` | | `top_traders` | paid | x402 requirements for `GET /api/v1/traders/top` | Input schemas mirror the HTTP parameters in the [API reference](/docs/api-reference/): `address` (0x plus 40 hex), `market` (`BTC` or `ETH`), `pct` (0 to 25), `accounts` (1 to 25), `side`, `marginUsd`, `leverage` (1 to 1000), `exitPrice`, `exitMovePct`, `window` (`24h`, `7d`, `30d`, `all`), `limit` (1 to 25). Unknown fields are rejected. The complete JSON Schemas, `outputSchema` included, are returned by `tools/list` and listed in the [server card](/.well-known/mcp/server-card.json). ## Examples Initialize: ```bash curl -s https://papertrade-x402.pages.dev/mcp \ -H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' ``` List tools: ```bash curl -s https://papertrade-x402.pages.dev/mcp -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' ``` Call a free tool with real data: ```bash curl -s https://papertrade-x402.pages.dev/mcp -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_markets","arguments":{}}}' ``` Ask for payment requirements of a paid tool: ```bash curl -s https://papertrade-x402.pages.dev/mcp -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"wallet_risk","arguments":{"address":"0x3f139ef9f371fbbfc299aa65b93534e177141b18"}}}' ``` The result's `structuredContent` has `status` (`ready` or `payments_not_configured`), `x402Version`, `accepts`, `price`, the exact `request` to send, `howToPay` and a `note`. Inspect with the official inspector: ```bash npx @modelcontextprotocol/inspector --cli https://papertrade-x402.pages.dev/mcp --transport http --method tools/list ``` ## Errors Protocol errors use JSON-RPC codes: `-32700` parse error (HTTP 400), `-32600` invalid request, `-32601` unknown method, `-32602` invalid params or unknown tool. Tool failures return a normal result with `isError: true` and a message the model can act on. Unexpected exceptions return a generic message and never leak internals. ## Limits Request bodies are capped at 64 KB. Each client is limited per isolate to 120 requests per minute, and tool calls are cost-weighted at 40 per minute (live-data tools cost more than status calls). Exceeding a limit returns HTTP 429 with `Retry-After`, or `isError` for a tool call. --- # Connect your AI Source: https://papertrade-x402.pages.dev/docs/connect-your-ai/ # Connect your AI The MCP endpoint is `https://papertrade-x402.pages.dev/mcp` (Streamable HTTP, no authentication). It exposes free tools directly. Paid tools return x402 payment requirements and never pay, so connecting an assistant cannot spend money. Client configuration formats change quickly; each snippet below was checked against the client's current documentation, and if a client moves a setting, its own docs win. ## Claude Code ```bash claude mcp add --transport http papertrade-x402 https://papertrade-x402.pages.dev/mcp ``` Add `--scope user` to make it available in every project, or commit a project-level `.mcp.json`: ```json { "mcpServers": { "papertrade-x402": { "type": "http", "url": "https://papertrade-x402.pages.dev/mcp" } } } ``` ## Claude Desktop and claude.ai Open Settings, then Connectors, then Add custom connector, and paste `https://papertrade-x402.pages.dev/mcp`. No sign-in is needed. Claude Desktop can also reach remote servers through the `mcp-remote` stdio bridge in `claude_desktop_config.json`: ```json { "mcpServers": { "papertrade-x402": { "command": "npx", "args": ["-y", "mcp-remote", "https://papertrade-x402.pages.dev/mcp"] } } } ``` ## Claude API (MCP connector) The connector is a beta. Current header: `mcp-client-2025-11-20`. Declare the server in `mcp_servers` and enable it with an `mcp_toolset` entry: ```bash curl https://api.anthropic.com/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \ -H "anthropic-beta: mcp-client-2025-11-20" -H "content-type: application/json" \ -d '{ "model": "claude-opus-5-5", "max_tokens": 1000, "messages": [{"role": "user", "content": "What is the BTC liquidation picture on Papertrade right now?"}], "mcp_servers": [{"type": "url", "url": "https://papertrade-x402.pages.dev/mcp", "name": "papertrade-x402"}], "tools": [{"type": "mcp_toolset", "mcp_server_name": "papertrade-x402"}] }' ``` ## OpenAI Codex CLI Add a Streamable HTTP server to `~/.codex/config.toml`: ```toml [mcp_servers.papertrade-x402] url = "https://papertrade-x402.pages.dev/mcp" ``` Or from the shell: ```bash codex mcp add papertrade-x402 --url https://papertrade-x402.pages.dev/mcp ``` ## OpenAI Responses API ```bash curl https://api.openai.com/v1/responses \ -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" \ -d '{ "model": "gpt-5", "tools": [{ "type": "mcp", "server_label": "papertrade_x402", "server_url": "https://papertrade-x402.pages.dev/mcp", "require_approval": "never" }], "input": "Estimate a 100x BTC long with 100 USD margin on Papertrade." }' ``` `require_approval: "never"` is safe here because every tool is read-only. Use `"always"` if your policy requires approval for all tool calls. ## ChatGPT Enable developer mode (Settings, Apps and Connectors, Advanced), then create a connector with the URL `https://papertrade-x402.pages.dev/mcp` and authentication set to none. ## Gemini CLI In `~/.gemini/settings.json` (or the project `.gemini/settings.json`): ```json { "mcpServers": { "papertrade-x402": { "httpUrl": "https://papertrade-x402.pages.dev/mcp" } } } ``` Or: `gemini mcp add --transport http papertrade-x402 https://papertrade-x402.pages.dev/mcp`. ## Cursor `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` globally: ```json { "mcpServers": { "papertrade-x402": { "url": "https://papertrade-x402.pages.dev/mcp" } } } ``` ## VS Code `.vscode/mcp.json`: ```json { "servers": { "papertrade-x402": { "type": "http", "url": "https://papertrade-x402.pages.dev/mcp" } } } ``` ## Windsurf `~/.codeium/windsurf/mcp_config.json`: ```json { "mcpServers": { "papertrade-x402": { "serverUrl": "https://papertrade-x402.pages.dev/mcp" } } } ``` ## Zed In Zed `settings.json`: ```json { "context_servers": { "papertrade-x402": { "url": "https://papertrade-x402.pages.dev/mcp" } } } ``` ## Cline In `cline_mcp_settings.json`: ```json { "mcpServers": { "papertrade-x402": { "url": "https://papertrade-x402.pages.dev/mcp", "type": "streamableHttp" } } } ``` ## Goose Run `goose configure`, choose Add Extension, then Remote Extension (Streaming HTTP), and enter the endpoint. Or in `~/.config/goose/config.yaml`: ```yaml extensions: papertrade-x402: enabled: true type: streamable_http name: papertrade-x402 uri: https://papertrade-x402.pages.dev/mcp timeout: 300 ``` ## Continue `.continue/mcpServers/papertrade-x402.yaml`: ```yaml name: Papertrade x402 version: 0.0.1 schema: v1 mcpServers: - name: papertrade-x402 type: streamable-http url: https://papertrade-x402.pages.dev/mcp ``` ## Any other agent framework Anything that speaks OpenAPI can import [`/openapi.json`](/openapi.json). Anything that speaks x402 can read [`/.well-known/x402`](/.well-known/x402). Frameworks that take a plain tool list can read `tools/list` from the MCP endpoint and map each `inputSchema` to a function definition. ## Try it After connecting, ask: "Use Papertrade to show current markets, then preview the liquidation map around BTC." Both calls are free and return live data. Paying for the full answer is a separate, explicit step you or your agent take with your own wallet: see [Paying as an agent](/docs/paying-as-an-agent/). --- # Agent discovery Source: https://papertrade-x402.pages.dev/docs/agent-discovery/ # Agent discovery Everything an agent needs to find, understand and call this service is published as a real file or endpoint. | URL | Format | Purpose | | --- | --- | --- | | `/.well-known/x402` | JSON | x402 and bazaar discovery: resources, prices, accepted networks, payTo, input and output schemas with examples, preview routes, status | | `/openapi.json` | OpenAPI 3.1 | Every route including previews and `/mcp`, with `x-payment-info` | | `/mcp` | MCP Streamable HTTP | Tool server, see [MCP](/docs/mcp/) | | `/.well-known/mcp/server-card.json` | JSON (SEP-1649) | Server info, transport endpoint, capabilities, tool list. Alias at `/.well-known/mcp.json` | | `/.well-known/agent-card.json` | JSON (A2A) | Agent card with one skill per tool. Alias at `/.well-known/agent.json` | | `/.well-known/api-catalog` | `application/linkset+json` (RFC 9727) | Catalog linking the OpenAPI document, MCP endpoint, docs and llms.txt | | `/llms.txt` | text | Short index for language models | | `/llms-full.txt` | text | Full documentation inlined | | `/docs/*.md` | markdown | Raw markdown twin of every docs page | | `/robots.txt` | text | Crawl policy with Content-Signal and explicit AI bot allowances | | `/sitemap.xml` | XML | All pages | The landing page also sends `Link` headers: `rel="service-desc"` for the OpenAPI document, `rel="api-catalog"`, `rel="mcp-server"`, `rel="service-doc"` for the docs and `rel="describedby"` for llms.txt. ## x402 bazaar discovery `/.well-known/x402` follows the convention x402 crawlers read: `version` plus absolute `resources`, and the richer `x402Version` 2 body with `endpoints`. Each endpoint carries `accepts` (empty until the operator sets a payout address), a `bazaar` entry in `extensions` with the input example, input schema, output example and output schema, plus the free `preview` route. The 402 responses embed the same bazaar extension so a facilitator can catalog the resource after the first settled payment. ## Status field `status` is `accepting_payments` or `payments_not_configured`. A crawler or agent should treat the second as "free tier only for now" and not as an outage. ## Crawl policy `robots.txt` allows the open web, disallows `/api/` for generic crawlers, and explicitly allows GPTBot, ClaudeBot, Claude-User, OAI-SearchBot, Google-Extended and PerplexityBot, with `Content-Signal: search=yes, ai-input=yes, ai-train=no`. --- # Paying as an agent Source: https://papertrade-x402.pages.dev/docs/paying-as-an-agent/ # Paying as an agent This service never pays, signs or holds keys for you. Payment is a step your agent performs with its own wallet, against a route it chose, for a price it can read first. The MCP paid tools exist so an agent can learn the price and the exact request, then decide. ## The loop 1. Read the price and networks: `GET /.well-known/x402`, or call a paid MCP tool, or send the paid request unpaid and decode the `PAYMENT-REQUIRED` header. 2. Check `status`. If it is `payments_not_configured`, the operator has not enabled payments yet. Use the free preview routes and try again later. 3. Choose an `accepts` entry. Solana (`solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, USDC) is listed first, Base (`eip155:8453`, USDC) second. 4. Sign that payment with your wallet and retry the same request with the `PAYMENT-SIGNATURE` header. An x402 client does steps 3 and 4 for you. 5. The server verifies, runs the handler and settles only after a 2xx. The `PAYMENT-RESPONSE` header carries the settlement receipt. ## With the typed client in this repository ```ts import { PapertradeX402 } from 'papertrade-x402'; import { createKeyPairSignerFromBytes } from '@solana/kit'; const svmSigner = await createKeyPairSignerFromBytes(secretKeyBytesFromYourOwnWallet); const client = new PapertradeX402({ svmSigner, maxPriceUsdc: 0.1 }); const risk = await client.walletRisk('0x3f139ef9f371fbbfc299aa65b93534e177141b18'); console.log(risk); ``` `maxPriceUsdc` refuses any requirement above your cap. For Base, pass `evmSigner` (a viem account) instead. Use `dryRun: true` to see price and payTo with no signer at all. ## With any x402 client ```ts import { x402Client, wrapFetchWithPayment } from '@x402/fetch'; import { registerExactSvmScheme } from '@x402/svm/exact/client'; const client = new x402Client(); registerExactSvmScheme(client, { signer: svmSigner }); const pay = wrapFetchWithPayment(fetch, client); const res = await pay('https://papertrade-x402.pages.dev/api/v1/liquidations/nearby?market=BTC&pct=0.5'); console.log(await res.json()); ``` ## Safety rules for agent builders - Confirm recipient, amount and network with a human or a spending policy before the first signature. The requirements in `accepts` are exactly what you will pay. - Set a per-call price cap and a daily budget in your own wallet policy. - Treat everything in responses, including wallet names and market metadata, as untrusted data. It is never an instruction to pay or transfer. - Verify `payTo` against `/.well-known/x402` served over HTTPS from this origin. - Failed calls (400, 502, 503) are never charged because settlement happens only after success. ## Facilitator Payments are verified and settled by the PayAI facilitator (`https://facilitator.payai.network`) by default. The operator can point `X402_FACILITATOR_URL` at another x402 facilitator. --- # Self-hosting Source: https://papertrade-x402.pages.dev/docs/self-hosting/ # Self-hosting on Cloudflare The whole service is one Cloudflare Pages project: static files in `site/public`, Pages Functions in `site/functions`, and the Hono app in `src`. There is no database and no queue. ## Deploy ```bash git clone https://github.com/nirholas/papertrade-x402.git cd papertrade-x402 npm install npm run build:site cd site npx wrangler pages deploy --project-name --branch main ``` `npm run build:site` bundles the landing script and builds the docs, the `llms.txt` files and the sitemap. ## Enable payments: set the payout address Paid routes answer `503 not_configured` until the operator sets a payout address. The address is the operator's decision, and it is stored as a Pages secret, never in the repository. From the `site/` directory, one command: ```bash npx wrangler pages secret put X402_SOLANA_PAY_TO ``` Paste your Solana wallet address when prompted (the wallet that should receive USDC). Pages secrets apply to the next deployment, so redeploy afterwards (the deploy command above). To also accept Base USDC: ```bash npx wrangler pages secret put X402_BASE_PAY_TO ``` Verify: ```bash curl -s https://.pages.dev/.well-known/x402 | jq '{status, configured, networks}' curl -si https://.pages.dev/api/v1/liquidations/nearby | head -5 ``` `status` becomes `accepting_payments` and paid routes now answer `402` with your address in `accepts`. Invalid addresses are reported under `problems` instead of being used. ## Configuration | Name | Kind | Default | Purpose | | --- | --- | --- | --- | | `X402_SOLANA_PAY_TO` | secret | unset | Solana address that receives USDC. Required for Solana. | | `X402_BASE_PAY_TO` | secret | unset | EVM address for Base USDC. Optional. | | `X402_FACILITATOR_URL` | var | `https://facilitator.payai.network` | x402 facilitator | | `PAPERTRADE_API_URL` | var | `https://exchange.papertrade.xyz` | Papertrade exchange API | | `PRICE_WALLET_RISK` | var | `0.02` | USDC per call | | `PRICE_LIQUIDATIONS_NEARBY` | var | `0.05` | USDC per call | | `PRICE_ESTIMATE` | var | `0.005` | USDC per call | | `PRICE_TRADERS_TOP` | var | `0.03` | USDC per call | Vars live in `site/wrangler.toml`. Prices are validated: a value that is not a positive USDC amount is reported in `problems` and the default is kept. ## Local development ```bash cp .dev.vars.example site/.dev.vars npm run dev:site ``` `site/.dev.vars` is git-ignored. Use throwaway addresses locally, never a key. ## Embedding The landing page can be framed by `https://papertrade-os.pages.dev` and any `*.pages.dev` origin (`frame-ancestors` in `site/public/_headers`). Add `?embed=1` to hide the marketing chrome. Documentation pages are never frameable. --- # Security and limits Source: https://papertrade-x402.pages.dev/docs/security-and-limits/ # Security and limits ## Money safety - The server never holds a private key and never signs, sends, swaps, bridges or mints anything. The only value that moves is the USDC payment you sign yourself, to the `payTo` shown in `accepts`. - The MCP server is read-only. Paid tools return requirements, not payments. - Settlement happens only after a successful 2xx. Invalid input, an unconfigured service or an upstream failure is never charged. - Payout addresses come from the environment only. No address is hardcoded in the repository or invented when missing. ## Untrusted data Wallet addresses, trader names and any on-chain metadata are data. The landing page sets them with `textContent`, the API escapes them, and agents must not interpret them as instructions. ## Rate limits | Surface | Limit | Scope | | --- | --- | --- | | `/api/v1/preview/*` | 60 cost-weighted requests per minute | per client IP, per isolate | | `/mcp` requests | 120 per minute | per client IP, per isolate | | `/mcp` tool calls | 40 cost-weighted per minute | per client IP, per isolate | | `/mcp` request body | 64 KB | per request | | Batch size | 20 messages | per request | Limits use in-memory counters inside each Cloudflare isolate, so they bound abuse but are not a global quota. Upstream Papertrade calls are capped in concurrency, with timeouts and bounded retries, so a burst cannot fan out without limit. Paid routes are limited by payment itself. ## Browser protections The site sends a strict Content-Security-Policy (`script-src 'self'; style-src 'self'`), `nosniff`, a strict referrer policy and a locked permissions policy. Only the landing page may be framed, and only by `https://papertrade-os.pages.dev` and `*.pages.dev`. ## Not financial advice Papertrade is a 1000x synthetic perpetuals exchange. High leverage can lose your entire margin. Risk scores, bust prices and estimates describe the protocol rules at a moment in time, they are not predictions or advice. This is an unofficial integration, not affiliated with Papertrade. ## Reporting a vulnerability See [SECURITY.md](https://github.com/nirholas/papertrade-x402/blob/main/SECURITY.md) in the repository and `/.well-known/security.txt`. Please do not open public issues for exploitable bugs. --- # FAQ Source: https://papertrade-x402.pages.dev/docs/faq/ # FAQ ## Why do paid routes return 503? The operator has not set a payout address yet, so the service cannot accept money. It says so instead of pretending: the 503 body explains it and links the free preview tier, the MCP server and these docs. Once `X402_SOLANA_PAY_TO` is set, the same routes answer 402. See [Self-hosting](/docs/self-hosting/). ## Is the free preview real data? Yes. A preview runs the same live computation as the paid route against the live Papertrade API, then withholds detail (fewer accounts, no per-position scores). Nothing is sampled or canned. ## Do I need an API key or account? No. The only credential is a signed x402 payment, from your own wallet, per call. ## Will connecting Claude or ChatGPT spend my money? No. The MCP tools are read-only. Paid tools return the payment requirements and stop. Paying is a separate action you or your agent perform with a wallet. ## Which networks and tokens? USDC on Solana mainnet first, USDC on Base second. ## What if a call fails after I pay? Settlement happens only after a successful 2xx response, so a failed call is not charged. Errors 400, 429, 502 and 503 never settle. ## How fresh is the data? Computed per request from the live Papertrade protocol. Each response has an `asOf` timestamp. ## Can I run my own instance and keep the revenue? Yes. It is Apache-2.0. Deploy to Cloudflare Pages and set your own payout address: [Self-hosting](/docs/self-hosting/). ## Is this official? No. It is an unofficial integration and not affiliated with Papertrade. ## Where is the OpenAPI spec, the llms.txt, the MCP card? [Agent discovery](/docs/agent-discovery/) lists every file. ## How do I report a bug? Open an issue at https://github.com/nirholas/papertrade-x402/issues. For security problems see [Security and limits](/docs/security-and-limits/). --- # Changelog Source: https://papertrade-x402.pages.dev/docs/changelog/ # Changelog ## Unreleased - Read-only MCP server at `/mcp` (Streamable HTTP, stateless, batches, SSE framing, CORS) with ten tools: six free, four paid tools that return x402 requirements and never pay. - Free preview tier under `/api/v1/preview/*`, rate limited, running the same live computation with detail withheld. - Paid routes answer an explanatory 503 (with links to the free tier and the operator command) until a payout address is set. No address is ever invented. - Discovery: x402 bazaar extensions with input and output schemas and real examples, MCP server card, A2A agent card, RFC 9727 api-catalog, OpenAPI preview and MCP paths, `Link` headers, robots with Content-Signal, sitemap, `server.json`, `glama.json`. - Documentation site at `/docs/` generated from `docs/*.md` with search, markdown twins, `llms.txt` and `llms-full.txt`. - Landing page: Connect your AI, MCP tools, works-with strip, live "Try it" with a free preview mode, `?embed=1` and an "Open in Papertrade OS" link, `frame-ancestors` for the OS. ## 0.1.0 - 2026-10-10 Initial release. - Four paid endpoints: wallet liquidation risk, nearby liquidation map, close/bust estimate, top traders. - Free endpoints: health, markets, OpenAPI 3.1, x402 discovery. - x402 v2 with the PayAI facilitator: USDC on Solana first, Base second. Verify before the handler, settle only after a 2xx. - Operator-configurable prices through wrangler vars; payTo addresses from environment only, 503 when unset. - `PapertradeX402` typed client with a dry-run mode, publishable from `src/client.ts`. - Landing page with live markets, endpoint catalog, curl examples and an interactive "Try the 402" form. - Tests against recorded real Papertrade fixtures, x402 schema validation of the 402 shape, and facilitator rejection of malformed payments.