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_xxxxxxxxxxxxxxxxIf 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:
- Confirm your code reached
pay()/ping()(add a log line) - Confirm the request didn't 401 — check your API key + agent ID
- Confirm you're hitting the right
baseUrl(production vs local dev) - 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.
- Confirm the config file path is correct for your platform (see Connect MCP hosts)
- Restart the host fully (quit, don't just reload)
- Confirm the URL
https://mcp.trycanopy.ai/mcpis reachable from the host's network (no corporate proxy / firewall blocking it) - Check the host's MCP logs for HTTP errors against the
canopyserver 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.