MCP tools reference
Canopy's remote MCP server exposes payment and discovery capabilities as tools inside any MCP-compatible host. See Connect MCP hosts for claude.ai, ChatGPT, Claude Desktop, Cursor, VS Code, Zed, Cline, and Windsurf, or Connect Claude Agent SDK for SDK apps.
In Claude Agent SDK, MCP tools require explicit permission. With the server named canopy, use allowedTools: ["mcp__canopy__*"] or list individual tool names like mcp__canopy__canopy_pay.
All tools share the same outcome model as pay(): structured results, never errors, for allowed / pending_approval / denied.
canopy_pay
Send a USD payment from the org treasury. Subject to the agent's spending policy.
// Arguments
{ "to": "0x1234567890abcdef1234567890abcdef12345678", "amountUsd": 0.10 }
// Returns
{ "status": "allowed", "txHash": "0x...", "transactionId": "...", "costUsd": 0.10 }Other outcomes the LLM needs to handle:
{ "status": "pending_approval", "approvalId": "appr_...", "reason": "Amount $7.50 exceeds approval threshold of $5" }
{ "status": "denied", "reason": "Spend cap exceeded: $8.00 + $5.00 > $10 / 24h" }canopy_preview
Dry-run policy evaluation without signing or charging. Same arguments as canopy_pay. Returns the same shape with "dryRun": true.
canopy_check_url
URL-driven dry run. Probes the URL, parses the 402 (x402 or MPP), and returns the parsed offer plus an allowed / pending_approval / denied verdict — without signing. Cached per-(org, url) for 60 seconds.
// Arguments
{ "url": "https://feed.example/depth/btc-usd" }
// Returns
{
"status": "allowed",
"rail": "x402",
"chainId": 8453,
"amountUsd": 0.10,
"recipient": { "address": "0x...", "slug": "feed-example", "name": "Feed Example" },
"resourceUrl": "https://feed.example/depth/btc-usd",
"scheme": "exact",
"network": "base",
"realm": null,
"cached": false
}Pending and denied results carry the same offer fields plus a reason.
canopy_get_approval_status
Poll the current state of an approval request after canopy_pay returns pending_approval.
// Arguments
{ "approvalId": "appr_..." }
// Returns
{ "status": "pending", "decidedAt": null, "expiresAt": "2026-04-27T10:45:00Z", "transactionId": "..." }status is one of "pending", "approved", "denied", "expired".
canopy_wait_for_approval
Block until an approval is decided, or up to 60 seconds. For longer waits, poll canopy_get_approval_status instead.
// Arguments
{ "approvalId": "appr_...", "timeoutMs": 30000 }timeoutMs is capped at 60 000 to prevent holding the MCP transport.
canopy_discover_services
List paid services the agent can call (x402-on-Base + MPP-on-Tempo). Filtered by category/query.
// Arguments
{ "category": "data", "query": "orderbook", "limit": 5 }Returns an array of:
{
"slug": "...",
"name": "...",
"description": "...",
"category": "...",
"logoUrl": "...",
"docsUrl": "...",
"paymentMethods": [{ "realm": "...", "baseUrl": "...", "protocol": "x402" }],
"endpoints": [{ "method": "GET", "path": "/...", "description": "...",
"priceAtomic": "10000", "currency": "USDC",
"pricingModel": "fixed", "protocol": "x402" }],
"preferredBaseUrl": "...",
"policyAllowed": true
}preferredBaseUrl is the rail picked by treasury balance — concatenate with an endpoint path and pass to canopy.fetch().
canopy_ping
Verify the API key + agent are valid. Returns agent and org details plus latency.
// Arguments: none
// Returns
{
"ok": true,
"agent": { "id": "agt_...", "name": "Trader", "status": "active", ... },
"org": { "name": "Acme", "treasuryAddress": "0x..." },
"latencyMs": 84
}canopy_get_budget
Cap snapshot for the current period.
// Returns
{ "capUsd": 10, "spentUsd": 5.70, "remainingUsd": 4.30, "periodHours": 24, "periodResetsAt": "..." }canopy_approve / canopy_deny
Mark a pending approval as approved or denied (for chat-gated approvals where the host can decide via a tool call).
// Arguments
{ "approval_id": "appr_..." }These tools are typically only used in MCP hosts where the human runs the chat — they let the LLM render an approval prompt and the human's choice resolves it. Most agent integrations use canopy_get_approval_status / canopy_wait_for_approval to wait on a dashboard decision instead.