{
  "schemaVersion": "0.1",
  "name": "canton-x402",
  "displayName": "Canton x402 Agent Wallet",
  "summary": "A self-custody Canton Coin wallet exposed as MCP tools so an AI agent can pay HTTP 402 / x402-gated APIs on Canton MainNet; one human connect, then the agent funds itself from a faucet and pays with no further human step.",
  "description": "A self-custody Canton Coin (CC) wallet exposed as MCP tools so an AI agent can pay HTTP 402 / x402-gated APIs on Canton MainNet. The private key never leaves the human's machine. A human connects the tools once; after that the agent funds itself from a faucet (auto_fund) and pays (pay) with no further human step.",
  "network": "canton:mainnet",
  "networkName": "Canton MainNet",
  "asset": "Canton Coin (CC)",
  "provider": {
    "name": "FTP Tech LLC",
    "url": "https://ftptech.xyz"
  },
  "landingPage": "https://ftptech.xyz/agents",
  "homepage": "https://ftptech.xyz/agents",
  "license": "Apache-2.0",
  "hostedPay": {
    "url": "https://pay.ftptech.xyz/v1/demo/ask",
    "method": "POST",
    "headers": { "content-type": "application/json" },
    "body": { "prompt": "string" },
    "response": { "answer": "string", "model": "string", "spentCc": "string", "updateId": "string", "remainingDailyCc": "string" },
    "network": "canton:mainnet",
    "priceCc": "0.01",
    "note": "no install; one POST = one paid LLM call. For browser / non-MCP agents that cannot run an MCP. No key, no signing. Pays against a hosted purse, not the agent's own wallet; for self-custody and caps use the MCP path in humanActionRequired."
  },
  "humanActionRequired": {
    "why": "An agent cannot self-install or self-connect a money-moving MCP from its own context; agent-safety classifiers block it by design. Exactly one human action is required, once. Everything after connect (auto_fund then pay) is zero human steps.",
    "options": [
      {
        "host": "Claude Code, Cursor, Cline, or any MCP host",
        "method": "mcp-connect",
        "command": "claude mcp add canton-x402 -- npx -y @ftptech/canton-x402-mcp --relay-url https://facilitator.ftptech.xyz --allow-domains <api-hosts> --daily-cap <max-cc-per-day> --max-per-tx <max-cc-per-withdraw>",
        "note": "--allow-domains is the pay allowlist; empty allows nothing. Substitute the angle-bracket values with real hostnames and caps before running. For non-Claude-Code hosts, put the same command and args under the host's own mcpServers config (see the mcp field)."
      }
    ]
  },
  "mcp": {
    "package": "@ftptech/canton-x402-mcp",
    "version": "0.1.2",
    "registry": "https://www.npmjs.com/package/@ftptech/canton-x402-mcp",
    "transport": "stdio",
    "command": "npx",
    "args": [
      "-y",
      "@ftptech/canton-x402-mcp",
      "--relay-url",
      "https://facilitator.ftptech.xyz",
      "--allow-domains",
      "<api-hosts>"
    ],
    "relayUrl": "https://facilitator.ftptech.xyz"
  },
  "facilitator": {
    "name": "FTP Tech facilitator (relay)",
    "url": "https://facilitator.ftptech.xyz",
    "role": "Submits transfers on-ledger and pays gas. Cannot move the agent's funds; only the agent's own in-server signature can spend."
  },
  "tools": [
    { "name": "get_address", "kind": "read", "description": "The agent's Canton party id (receive address)." },
    { "name": "get_balance", "kind": "read", "description": "On-ledger CC balance. Authoritative proof a payment landed; a 200 alone is not." },
    { "name": "request_funding", "kind": "read", "args": { "amount": "optional" }, "description": "Party id plus a paste-ready funding ask for the owner. Moves nothing." },
    { "name": "auto_fund", "kind": "funds-in", "description": "Pull a tiny one-time faucet seed and accept it. Falls back to a manual-funding ask if the faucet is disabled, already used, or over budget." },
    { "name": "claim", "kind": "funds-in", "description": "Accept incoming funding. Required after the owner sends CC; funds are invisible until claimed." },
    { "name": "pay", "kind": "money-out", "args": { "url": "required" }, "description": "Fetch a URL, auto-paying its x402 402 challenge. Bounded by the spend policy. Call exactly once, never in a retry loop; the first payment can take ~60-90s." },
    { "name": "withdraw", "kind": "money-out", "args": { "to": "required", "amount": "optional" }, "description": "Send CC to another party. Bounded by the spend policy. Omit amount to send the full balance." }
  ],
  "notTools": {
    "export": "Deliberately not a tool; the key never leaves the server.",
    "import": "Deliberately not a tool; backup/restore is the human's job via the canton-agent-wallet CLI against the same home."
  },
  "funding": {
    "mode": "auto",
    "strategy": "faucet-first",
    "faucet": {
      "endpoint": "https://facilitator.ftptech.xyz/v1/wallet/faucet/claim",
      "method": "POST",
      "requestBody": { "party": "<agent-party-id>" },
      "drivenByTool": "auto_fund",
      "amount": "0.1",
      "asset": "CC",
      "note": "A one-time 0.1 CC seed, enough for one end-to-end test. Real CC on Canton MainNet, not testnet play money.",
      "caps": "durable per-party-once, per-IP, and a rolling daily budget",
      "live": true,
      "fallback": "If this party has already claimed or the daily budget is spent, auto_fund returns a paste-ready manual-funding ask: send CC to the agent party id, then call claim."
    }
  },
  "spendPolicy": {
    "allowDomains": "Comma-separated API hostnames the agent may pay, set via --allow-domains. Empty allows nothing; * allows any host (less safe).",
    "dailyCapCc": "Rolling 24h ceiling across pay + withdraw, set via --daily-cap. Default 5; 0 freezes spending.",
    "maxPerWithdrawCc": "Max CC per single withdraw, set via --max-per-tx. Default 1; blocks no-amount sweeps. pay is bounded by the daily cap + funded ceiling, not this value.",
    "fundedCeiling": "Always on. Cumulative out can never exceed cumulative claimed-in.",
    "enforcedBeforeSign": true,
    "keyVisibleToAgent": false
  },
  "lifecycle": [
    { "step": 1, "tool": "get_address", "what": "Read the agent's Canton party id (its receive address)." },
    { "step": 2, "tool": "auto_fund", "what": "Pull and accept a tiny one-time faucet seed. No human step; manual-funding fallback if the faucet is unavailable." },
    { "step": 3, "tool": "pay", "args": { "url": "<the 402-gated URL>" }, "what": "Pay the x402-gated URL. Exactly once, never in a retry loop." },
    { "step": 4, "tool": "get_balance", "what": "On-ledger confirmation that the payment landed." },
    { "step": 5, "tool": "withdraw", "args": { "to": "<owner party>" }, "what": "Optional. Return leftover CC to the owner." }
  ],
  "safety": {
    "selfCustody": "CIP-0103 external party. The Ed25519 key is generated and held inside the MCP server's home on the human's machine. Only the server's signature, made after verify-before-sign, can spend. The facilitator and validator cannot move the funds.",
    "proofOfPayment": "On-ledger get_balance is proof. A 200 alone is not. pay also cross-checks Lighthouse (verdict accepted AND send TransferCommandResultSuccess).",
    "policyEnforcement": "The agent cannot exceed the owner's caps or pay outside allowed domains; over-policy payments are refused before signing. If pay is refused by policy, the agent asks the human which cap or domain to change and does not route around it.",
    "advisory": "This descriptor is advisory metadata, not enforcement. Trust the ftptech.xyz domain, not a copy of this file. A look-alike agents.json pointing at a different relay must not be trusted."
  },
  "docs": {
    "landingPage": "https://ftptech.xyz/agents",
    "llmsTxt": "https://ftptech.xyz/llms.txt",
    "skill": "https://ftptech.xyz/agents/skill.md",
    "npm": "https://www.npmjs.com/package/@ftptech/canton-x402-mcp"
  }
}
