Canopy

Troubleshooting

401 Invalid API key

The API key you're using is missing, malformed, or has been revoked.

Fix. Go to Dashboard → Settings → API Keys, revoke the current key if needed, and generate a new one. Update your environment variable:

export CANOPY_API_KEY=ak_live_xxxxxxxxxxxxxxxx

If you're using a test key (ak_test_…) against a production endpoint, or vice versa, you'll also get a 401. Make sure the key matches the environment you're targeting.

agentId is required for pay()

You called pay(), preview(), fetch(), discover(), ping(), or budget() without an agent ID configured.

Fix. Pass agentId to the constructor, or set the CANOPY_AGENT_ID environment variable.

const canopy = new Canopy({
  apiKey: process.env.CANOPY_API_KEY!,
  agentId: process.env.CANOPY_AGENT_ID!, // ← add this
});
canopy = Canopy(
    api_key=os.environ["CANOPY_API_KEY"],
    agent_id=os.environ["CANOPY_AGENT_ID"],  # ← add this
)

Find your agent ID in Dashboard → Agents. It starts with agt_.

denied: Recipient not in allowlist

The agent's policy has a recipient allowlist, and the address or slug you passed to pay() isn't on it.

Fix. Go to Dashboard → Agents → [your agent] → Policy and add the recipient. Or choose a different recipient your policy already permits.

discover() respects the same allowlist — services blocked by your policy are filtered out by default. Pass includeBlocked: true (TS) or include_blocked=True (Py) to see blocked services with policyAllowed: false.

denied: Spend cap exceeded

The agent has spent its budget for the current cap window.

Fix. You have two options:

  • Wait for the cap window to reset. Call budget() to see when:
    const b = await canopy.budget();
    console.log(`$${b.remainingUsd} left, resets at ${b.periodResetsAt}`);
  • Raise the cap in Dashboard → Agents → [your agent] → Policy.

Empty discover() results

Most likely the agent's policy has an allowlist that filters out everything in the requested category.

Fix. Pass includeBlocked: true to see blocked services and inspect why each is blocked. You can also pass includeUnverified: true to surface long-tail entries that haven't yet been reviewed by Canopy.

Agent shows as not connected after running

The dashboard's "connected" badge flips on the first successful request to /api/sign or /api/ping. If it doesn't flip:

  1. Confirm your code reached pay() / ping() (add a log line)
  2. Confirm the request didn't 401 — check your API key + agent ID
  3. Confirm you're hitting the right baseUrl (production vs local dev)
  4. Check the dashboard's Activity tab — even denied / pending payments register the agent as connected

MCP tools don't appear in Claude Desktop / Cursor

The host hasn't picked up your mcpServers config block.

Fix.

  1. Confirm the config file path is correct for your platform (see Connect MCP hosts)
  2. Restart the host fully (quit, don't just reload)
  3. Confirm the URL https://mcp.trycanopy.ai/mcp is reachable from the host's network (no corporate proxy / firewall blocking it)
  4. Check the host's MCP logs for HTTP errors against the canopy server URL

Claude Agent SDK sees tools but will not call them

Claude Agent SDK requires explicit MCP tool permissions. Without them, Claude can see that Canopy tools exist but cannot call them.

Fix. Add allowedTools to your query() options:

allowedTools: ["mcp__canopy__*"]

You can also allow only specific tools, such as mcp__canopy__canopy_pay and mcp__canopy__canopy_get_budget.