Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 152 additions & 9 deletions examples/mcp-paid-tool/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,176 @@
# paid MCP tool pattern
# Paid MCP tool guide: sell one MCP/API call with x402 + Pyrimid

Best fit: MCP servers with expensive data, scraping, enrichment, analytics, compliance checks, search, or model calls.
This guide shows a reproducible pattern for turning one valuable MCP tool into a paid
HTTP/x402 product that buyer agents can discover through the Pyrimid catalog.

## Tool design
Best fit: MCP servers with expensive data, scraping, enrichment, analytics,
compliance checks, search, or model calls.

- Free tool: `preview_*` returns schema, price, sample output, and payment requirement.
- Paid tool: `buy_*` returns HTTP 402/x402 requirement until paid.
- Discovery: publish server card, `llms.txt`, `agents.txt`, and Pyrimid catalog entry.
## What you are building

A paid MCP tool should expose two surfaces:

1. **Free preview/discovery**: schema, price, sample output, and payment metadata.
2. **Paid execution**: returns HTTP `402 Payment Required` until the buyer retries
with `X-PAYMENT` or `X-PAYMENT-TX` proof.

Pyrimid handles discovery and affiliate routing by making the product visible to
agents through the catalog and by standardizing the x402 payment requirement.

```text
MCP client asks for tool → server returns price + product_id → buyer pays on Base
→ buyer retries with payment proof → server returns the paid result
```

## Working endpoint to copy

This repository already ships seed paid endpoints under:

```text
GET https://pyrimid.ai/api/v1/paid/{product_id}
```

Use the MCP monetization audit seed product as the smallest complete example:

```bash
curl -i 'https://pyrimid.ai/api/v1/paid/mcp-server-audit?url=https://example.com/mcp'
```

Expected unauthenticated response shape:

```http
HTTP/2 402
content-type: application/json
x-payment-required: {"x402Version":2,"scheme":"exact","network":"base",...}
x-pyrimid-vendor: pyrimid-growth
x-pyrimid-product: mcp-server-audit
```

```json
{
"error": "payment_required",
"message": "Pay $0.10 USDC on Base through Pyrimid, then retry with X-PAYMENT or X-PAYMENT-TX.",
"accepts": [
{
"x402Version": 2,
"scheme": "exact",
"network": "base",
"asset": "USDC",
"maxAmountRequired": "0.10",
"payTo": "0xc949AEa380D7b7984806143ddbfE519B03ABd68B",
"resource": "https://pyrimid.ai/api/v1/paid/mcp-server-audit?url=https://example.com/mcp",
"vendorId": "pyrimid-growth",
"productId": "mcp-server-audit",
"affiliateBps": 4000,
"protocol": "pyrimid"
}
],
"docs": "https://pyrimid.ai/quickstart",
"catalog": "https://pyrimid.ai/api/v1/catalog?source=pyrimid-seed"
}
```

A real buyer agent should read `accepts[0]`, pay exactly the requested Base USDC
amount to the Pyrimid router, then retry:

```bash
curl -s \
-H 'X-PAYMENT-TX: 0x_YOUR_BASE_PAYMENT_TX_HASH' \
'https://pyrimid.ai/api/v1/paid/mcp-server-audit?url=https://example.com/mcp'
```

Successful paid responses include the product IDs, verified payment transaction,
paid payload, and Pyrimid links for proof/stats/catalog.

## Minimal product metadata

Publish catalog metadata for the paid tool so buyer agents can find it before
calling the endpoint:

```json
{
"vendor_id": "your-mcp-server",
"vendor_name": "Your MCP Server",
"product_id": "paid_search",
"description": "Paid MCP search result with enriched citations",
"category": "search-scraping",
"tags": ["mcp", "search", "x402", "paid-tools"],
"price_usdc": 50000,
"price_display": "$0.05",
"affiliate_bps": 3000,
"endpoint": "https://your-service.com/api/paid/search",
"method": "GET",
"network": "base",
"asset": "USDC"
"asset": "USDC",
"output_schema": {
"type": "object",
"properties": {
"results": { "type": "array" },
"routed_by": { "const": "pyrimid" }
}
}
}
```

Keep `price_usdc` in USDC base units (`50000` = `$0.05`) and keep
`product_id` stable. Buyer agents will use `product_id`, `endpoint`, and
`output_schema` to decide whether the tool is worth buying.

## MCP tool design

Expose a free preview tool and a paid tool in your MCP server:

```json
{
"tools": [
{
"name": "preview_paid_search",
"description": "Show price, schema, and sample output for paid_search",
"inputSchema": { "type": "object", "properties": { "query": { "type": "string" } } }
},
{
"name": "buy_paid_search",
"description": "Run the paid search after x402 payment proof is available",
"inputSchema": {
"type": "object",
"required": ["query", "payment_tx"],
"properties": {
"query": { "type": "string" },
"payment_tx": { "type": "string", "description": "Base tx hash or x402 proof" }
}
}
}
]
}
```

The preview tool can return the same `accepts[]` object that the HTTP endpoint
returns with status `402`. The paid tool should call your paid endpoint with
`X-PAYMENT-TX` and return the JSON result only after verification succeeds.

## Agent reproduction checklist

A buyer-agent demo is considered reproducible when it can show all of these:

- catalog discovery: `GET /api/v1/catalog?source=pyrimid-seed` or your listing URL;
- unpaid probe: paid endpoint returns HTTP `402` and an `accepts[]` payment requirement;
- payment retry shape: command or code retries with `X-PAYMENT`/`X-PAYMENT-TX`;
- paid output schema: response includes stable `product_id`, payload, and proof links;
- public metadata: server card, `llms.txt`, `agents.txt`, or README links back to Pyrimid.

## Why route through Pyrimid?

- Agents can find your tool in one catalog.
- Agents can find your tool in one catalog instead of scraping ad hoc docs.
- Buyer agents get a standard x402 payment flow.
- Affiliates can route demand to your tool.
- Affiliates can route demand to your tool with explicit `affiliate_bps`.
- Vendor, affiliate, and protocol fees are visible onchain.
- MCP servers can keep their core tools read-only/free while charging only for
high-cost calls.

## Common mistakes

- Returning only a prose payment error instead of machine-readable `accepts[]`.
- Changing `product_id` after agents have cached or indexed it.
- Charging before the preview tells the agent the exact price and output schema.
- Omitting `Cache-Control: no-store` on paid/proof-sensitive responses.
- Treating social posts as proof of payment; use Base transaction/proof links instead.