Merchant setup
Expose to agents
Choose the surfaces each resource is reachable on: HTTP, MCP, A2A and ACP checkout.
Two switches decide where a resource appears: the protocol must be enabled under protocols, and the resource must name it in expose. Naming a disabled protocol fails validate, so the two can never drift apart silently.
protocols:
http: { enabled: true }
mcp: { enabled: true, mountPath: /mcp }
a2a: { enabled: false, mountPath: /a2a }
acp: { enabled: false, mountPath: /acp }
resources:
premium_report:
# …
expose: [http, mcp]Protocols
Native routes. Every resource exposed over http is invocable at POST /api/resources/:id/invoke with a JSON body as input.
# free resource
curl -s http://localhost:8080/api/resources/basic_weather/invoke \
-X POST -H 'content-type: application/json' -d '{"city":"berlin"}'
# paid resource without a proof -> 402 Payment Required
curl -i http://localhost:8080/api/resources/premium_report/invoke -X POSTAn x402 proof goes in PAYMENT-SIGNATURE, an MPP credential in Authorization: Payment …. Reference: Invoke a resource.
MCP Streamable HTTP at mountPath. Each resource becomes a tool named by its id; a paid tool shows its price in the description and gains an optional _payment argument.
curl -s http://localhost:8080/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Serves MCP 2026-07-28 and 2025-era clients, and needs the @modelcontextprotocol/server peer. A paid tool also accepts the rail's own _meta proof. Reference: MCP.
Experimental A2A v1.0.1. Enabling it serves the Agent Card at /.well-known/agent-card.json and JSON-RPC SendMessage at mountPath. Each exposed resource becomes a skill, and at least one must be exposed.
protocols:
a2a:
enabled: true
mountPath: /a2a
resources:
market_report:
# …
expose: [http, mcp, a2a]Clients send A2A-Version: 1.0. The x402 A2A extension stores up to 256 unpaid tasks in the receipt database; at capacity, new purchases get retryable GATEWAY_BUSY. Serving A2A needs no SDK. See A2A.
Experimental ACP 2026-04-17. Unlike the others, ACP is a fixed checkout lifecycle: you map each of its five operations to one free resource that fronts your existing checkout API, and mark those resources expose: [acp].
protocols:
acp:
enabled: true
mountPath: /acp
auth:
type: bearer
token: ${ACP_BEARER_TOKEN}
idempotency:
retentionHours: 24
checkout:
operations:
createCheckoutSession: acp_checkout_create
updateCheckoutSession: acp_checkout_update
getCheckoutSession: acp_checkout_get
completeCheckoutSession: acp_checkout_complete
cancelCheckoutSession: acp_checkout_cancelA complete, validating config is in ACP checkout; the wire contract is in the ACP reference.
Discovery
Whatever the protocol, two public routes describe what this gateway offers:
| Route | Returns |
|---|---|
GET /.well-known/agent-commerce | merchant, enabled protocols, adapter descriptors with pinned specs, each rail's settlement terms and payment flow |
GET /api/resources | every resource with its input schema, pricing, exposure and payment methods |
Mount paths
A2A and ACP default to /a2a and /acp. MCP requires protocols.mcp.mountPath. Validation rejects overlapping enabled mounts and conflicts with public or ledger routes, including /health, /api/receipts, the A2A Agent Card and ACP discovery paths. Avoid /api mounts, where the gateway serves its own routes.