# MCP server

Last updated: 2026-10-10

`quoteproof-mcp` is an MCP server (stdio) that gives an agent one tool per route. It needs Node.js 20.3 or later and has no install scripts.

| Tool | Route | Price |
|---|---|---|
| `attestpage_verify_quote` | [POST /v1/verify/quote](/docs/verify-quote) | US$0.01 |
| `attestpage_verify_quotes` | [POST /v1/verify/quotes](/docs/verify-quotes) | US$0.08 |
| `attestpage_verify_citations` | [POST /v1/verify/citations](/docs/verify-citations) | US$0.10 |
| `attestpage_fetch` | [POST /v1/fetch](/docs/fetch) | US$0.002 |
| `attestpage_check_links` | [POST /v1/check/links](/docs/check-links) | US$0.005 |
| `attestpage_check_packages` | [POST /v1/check/packages](/docs/check-packages) | US$0.005 |
| `attestpage_attest` | [POST /v1/attest](/docs/attest) | US$0.002 |
| `attestpage_verify_receipt` | [POST /v1/receipt/verify](/docs/receipt-verify) | free |

## Install

```sh
npx -y https://vehcdj664efetfrsolne5umanq.srv.us/dl/quoteproof-mcp-0.1.25.tgz
```

[https://vehcdj664efetfrsolne5umanq.srv.us/dl/index.json](https://vehcdj664efetfrsolne5umanq.srv.us/dl/index.json) lists the current version with its sha256 and npm integrity string. `https://vehcdj664efetfrsolne5umanq.srv.us/dl/quoteproof-mcp.tgz` always redirects to the newest version.

Most MCP clients take a block like this:

```json
{
  "mcpServers": {
    "quoteproof": {
      "command": "npx",
      "args": ["-y", "https://vehcdj664efetfrsolne5umanq.srv.us/dl/quoteproof-mcp-0.1.25.tgz"],
      "env": { "QUOTEPROOF_URL": "https://vehcdj664efetfrsolne5umanq.srv.us", "QUOTEPROOF_X402_KEY": "0x..." }
    }
  }
}
```

## Paying

There are two ways to pay: x402 (USDC, `QUOTEPROOF_X402_KEY`) and L402 (sats, `QUOTEPROOF_NWC_URL`). Set either or both.

With `QUOTEPROOF_X402_KEY` set to a wallet private key, paid tools pay the 402 with x402 (see [Payments](/docs/payments)). The key stays in the process and is never logged. Before signing, the server checks the offer against local limits: `QUOTEPROOF_MAX_USD` per call (default 0.10; each tool also pays no more than its listed price), `QUOTEPROOF_SESSION_USD` per process (default 1) and `QUOTEPROOF_NETWORKS` (default `eip155:84532`, Base Sepolia; Base mainnet `eip155:8453` only when you list it). An offer over a limit, or with no amount, fails with `payment_refused_locally` and nothing is signed. A paid result carries the settlement in `_meta["x402/payment-response"]`.

Without a key, paid tools use the free trial where it is on, and fail with `trial_exhausted` once it is used up. A trial call to `attestpage_verify_citations` or `attestpage_check_links` takes at most 3 items. Set `QUOTEPROOF_TRIAL=0` to turn the trial off.

With `QUOTEPROOF_NWC_URL` set to a Nostr Wallet Connect connection string (Node.js 22 or later), paid tools pay in sats with L402 where the service offers it (see [Payments](https://vehcdj664efetfrsolne5umanq.srv.us/docs/payments.md)). Create a wallet connection just for this server that may only pay invoices, with a small daily budget. The connection string is a secret and is never logged or returned. Before paying, the server checks the invoice and its token against `QUOTEPROOF_MAX_SATS` per call (default 100; each tool also pays no more than its listed sats), `QUOTEPROOF_SESSION_SATS` per process (default 1000; routing fees are counted after each payment, so one payment can go over this by its fee; the wallet's own budget is the hard limit) and `QUOTEPROOF_LN_NETWORKS` (default `regtest,signet,testnet`; add `bitcoin` for real sats). L402 is paid before the call runs: if the call then fails, the token is kept in memory and pays your next call to the same tool. `attestpage_attest` with `idempotency_key` needs x402. When the service has too many unpaid invoices open for your address, its 402 has no invoice and the call fails with `payment_refused_locally`, saying Lightning is busy and how many seconds to wait. With only `QUOTEPROOF_NWC_URL` set, a call the service offers no L402 for uses the free trial, as with no wallet. With both a key and a wallet, `QUOTEPROOF_PAY_ORDER` (default `x402,l402`) picks the rail tried first. A paid result carries the payment in `_meta["attestpage/l402"]`.

## Remote endpoint

The same tools are served over MCP at `POST https://vehcdj664efetfrsolne5umanq.srv.us/mcp` (streamable HTTP), with nothing to install. Each POST carries one JSON-RPC message and gets one JSON answer; there are no sessions and no event stream, so GET returns 405. A tool call runs the tool's route on this server, so prices, limits and refunds are the same as calling the route.

Protocol versions: `2026-07-28` and the older `2025-11-25`, `2025-06-18`, `2025-03-26` and `2024-11-05`. A `2026-07-28` client skips `initialize`: it puts the version and its capabilities in each request's `_meta` (`io.modelcontextprotocol/protocolVersion`, `io.modelcontextprotocol/clientCapabilities`) and sends the `MCP-Protocol-Version`, `Mcp-Method` and (for `tools/call`) `Mcp-Name` headers, which must match the body (else 400 with error `-32020`, HeaderMismatch). `server/discover` returns the supported versions, capabilities and server identity; an unsupported version gets 400 with error `-32022` and the supported list. Results carry `resultType: "complete"` and `_meta["io.modelcontextprotocol/serverInfo"]`; `tools/list` adds `ttlMs` and `cacheScope`. Older clients use `initialize` as before.

The server card (SEP-2127) is at [`GET https://vehcdj664efetfrsolne5umanq.srv.us/mcp/server-card`](https://vehcdj664efetfrsolne5umanq.srv.us/mcp/server-card) (`application/mcp-server-card+json`): name, version and the remote with its supported protocol versions; it lists no tools, so call `tools/list`. The site's [AI Catalog](https://vehcdj664efetfrsolne5umanq.srv.us/.well-known/ai-catalog.json) (`application/ai-catalog+json`) points at the card, the OpenAPI document and the agent skill. `/.well-known/mcp/server-card.json` redirects to the card.

```json
{
  "mcpServers": {
    "attestpage": { "type": "http", "url": "https://vehcdj664efetfrsolne5umanq.srv.us/mcp" }
  }
}
```

To pay, put an x402 payment payload in the call's `_meta["x402/payment"]`, as `@x402/mcp` clients do. Without one, a paid tool uses the free trial where it is on, and once that is used up, or for a `verify_citations` or `check_links` call with more than 3 items (the requirements' `error` then says so), it returns a result with `isError: true` whose `structuredContent` is the x402 payment requirements; sign one of `accepts` and call again with the payload. Set `_meta["attestpage/trial"]` to `false` to get the requirements straight away. A paid result carries the settlement in `_meta["x402/payment-response"]`. The free trial and the per-address limits count the address that calls `/mcp`.

## Errors

A failed call is a tool result with `isError: true` whose text is JSON: `status`, `code`, `message` and, where useful, `details` and `hint`. The codes are the ones in [Errors](/docs/errors), plus `payment_refused_locally`, `lightning_payment_failed`, `lightning_payment_unknown`, `timeout` and `network_error` from the MCP server itself. A bad request is refused before payment and never charged.
