Skip to content
Docs / Use with coding agents

Use with coding agents

Coding agents like Claude Code, Cursor and Codex can use Canonopy Decisions directly: build your own model from the JSON your code sends Jev, switch the code over once it's ready, show you how it decides if you ask, and improve it later, without you writing the calls. Connect them to the hosted MCP connector, which needs nothing installed, add the skill so they know when and how to use it, or point them at these docs.

The hosted MCP connector

The connector runs on our servers at https://api.canonopylabs.com/mcp (MCP Streamable HTTP). There's nothing to install: your agent needs an API key from the console, sent in an Authorization header like any API call.

Claude Code

bash
claude mcp add --transport http canonopy https://api.canonopylabs.com/mcp --header "Authorization: Bearer cnp_…"

Add --scope user to have it in every project. Check it with claude mcp list, or /mcp inside a session.

Cursor

.cursor/mcp.json in your project, or ~/.cursor/mcp.json for every project:

json
{
  "mcpServers": {
    "canonopy": {
      "url": "https://api.canonopylabs.com/mcp",
      "headers": { "Authorization": "Bearer cnp_…" }
    }
  }
}

Codex

~/.codex/config.toml, with your key in the CANONOPY_API_KEY environment variable:

toml
[mcp_servers.canonopy]
url = "https://api.canonopylabs.com/mcp"
bearer_token_env_var = "CANONOPY_API_KEY"

Any other MCP client

Add a Streamable HTTP server with the URL https://api.canonopylabs.com/mcp and the header Authorization: Bearer cnp_…. It's JSON-RPC 2.0 over POST, answered with JSON; there's no session to keep and no stream to open (GET answers 405). To see it work with curl:

bash
curl https://api.canonopylabs.com/mcp \
  -H "Authorization: Bearer $CANONOPY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2025-06-18" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'

A missing or refused key gets 401 with a JSON error. Protocol versions 2025-06-18, 2025-03-26 and 2024-11-05 are supported.

Every tool call is an API call

Each tool call is a normal call to the API with your key: the same fair-use limit (50 requests per second per key), the same errors, the same plan. Nothing is billed per tool call.

What the hosted connector doesn't do

It runs on our servers, so it never reads or writes files, and never reads environment variables:

  • upload_history and replace_history take past cases inline: rows (a list of cases), or a file's contents as text (CSV with a header row, JSONL, or a JSON list), up to about 2 MB per call. Your agent reads the file and sends its text; split bigger files, or use canonopy upload.
  • build_model takes past cases inline as history rows; reading them from a file on disk (history_file) is the local server's.
  • download_model returns a link that works for 10 minutes without a key, and the curl line to save it.
  • set_day_one_fallback takes no keys: add your Jev or OpenAI-compatible key once in the console (open the decision model, then Day one). local and none need no key.

For those on your own machine, use the local MCP server.

The local MCP server

canonopy mcp runs the same tools on your machine, over stdio, from the canonopy-cli package. Use it when you want the agent to upload files straight from disk, save downloaded models to disk for offline use, or read a day-one backend's key from an environment variable. It needs Python 3.9 or later and nothing else.

bash
pip install https://canonopylabs.com/dl/canonopy_cli-0.6.2-py3-none-any.whl

The key goes in the server's environment, never in the chat.

Claude Code

bash
claude mcp add canonopy --env CANONOPY_API_KEY=cnp_… -- canonopy mcp

Cursor

json
{
  "mcpServers": {
    "canonopy": {
      "command": "canonopy",
      "args": ["mcp"],
      "env": { "CANONOPY_API_KEY": "cnp_…" }
    }
  }
}

Codex

toml
[mcp_servers.canonopy]
command = "canonopy"
args = ["mcp"]
env = { CANONOPY_API_KEY = "cnp_…" }

Any other MCP client

Run canonopy mcp as a stdio server (JSON-RPC 2.0, one message per line). If canonopy isn't on the client's PATH, give the full path (which canonopy) or run python -m canonopy_cli mcp.

CANONOPY_API_KEYenvironment variablerequired
Your API key. Sent only to the API; no tool ever prints or returns it.
CANONOPY_BASE_URLenvironment variable
The API. Default https://api.canonopylabs.com.
CANONOPY_DOCS_URLenvironment variable
The docs the docs tool reads. Default https://canonopylabs.com.

Tools

The hosted connector and the local server have the same 47 tools, in the order you'd usually use them. A decision model is called a domain in the API; the tools say decision model.

From the JSON you send Jev (Start with no data):

  • build_model: your own model from a Jev request: state (one real example), questions (as you send them to Jev), and optionally rules in plain words, name, description and history rows (your past cases). The local server also takes history_file, a .csv, .jsonl or .json file on disk. JSON first: without state and questions it builds nothing and says how to get them (ask you to paste the request you send Jev, or draft it from your code and confirm it with you). It asks a few questions about the JSON first by default (interview, answer_timeout_seconds); it returns when the model is ready, or sooner if those questions wait for your answers. See Build with your coding agent.
  • draft_request_help: the JSON's shape, an example and a checklist for getting it.
  • get_build_questions, answer_build_questions: the build's questions about your JSON (build_id or model), and your answers (answers: each id with the keys its answer_with lists, or skip; done).
  • get_build: where a build is (build_id, or model for its latest build): the phases, what it read, the quality check, the examples once it's ready, rules found and flagged cases. With wait: true it returns once the build is ready (or needs attention, failed, or waits for answers); if the answer has still_working, call it again. Nothing is needed from you meanwhile.
  • confirm_found_rules: confirm or reject the rules found in your history (build_id or model; rules: each id, decision and hard).
  • review_flagged_history: past cases that contradict your rules (build_id or model). With no decisions it lists the pending ones; rows (each id and decision: follow_rule, keep or drop) or all decide them.
  • get_advice: what would improve the model most, in plain words (model).
  • change_rules: new rules in plain words (model, rules, mode: add or replace). It retrains straight away, and the build says what changed.
  • mark_decision_wrong: the right answer for a decision (decision_id, answers or action, note); the next retrain learns it.
  • shadow_mode, send_shadow_cases, review_shadow_disagreements: shadow mode: your model beside your current decisions on real requests, without acting, and the short review list.
  • report_play_results: a playtest's results (canonopy playtest sends them for you).
  • spot_checks: this week's optional spot-check card (model), or the setting (set: off, light, thorough).

On a built model, train starts a targeted retrain and returns its build id. get_examples shows how it decides on about 20 situations, and correct_examples retrains with your corrections: both optional.

Every model:

  • list_decision_models, get_decision_model: what exists, and where each stands (status, actions, rules, fields, serving version).
  • create_decision_model: start one, with a name and optionally a plain-words description.
  • describe_decision_model: the set-up conversation (describe the decision, answer open questions, refine it).
  • update_decision_model: exact changes to questions, rules or fields; archive or restore.
  • get_examples, correct_examples: optional, any time: about 20 example cases showing how it decides, and your corrections (corrections, and retrain, true by default, to retrain with them now). The old name sign_off_examples still works.
  • upload_history, history_summary: past cases and how each was resolved: inline rows or a file's text (hosted), or a local .csv, .jsonl or .json file (local server).
  • list_uploads, delete_upload, replace_history, clear_history: see each upload, delete one, swap every uploaded case for new ones, or delete them all, then train for the next version of the same model. These delete permanently, so each needs confirm set to the decision model's name.
  • train, get_job: a new version in about a minute, with its report.
  • get_report, list_versions, promote_version: read reports, see versions, promote or roll back.
  • get_progress: what's waiting for the next retrain, every version's accuracy, and advice.
  • decide: a decision in Jev's format, with the rules applied and act / review / ask.
  • report_outcome: what really happened, for the next version.
  • list_unsure, answer_unsure: the unsure queue.
  • list_decisions, get_decision, export_decisions: the decision log: past decisions with filters and search, one in full, or a CSV or JSONL file (saved to disk by the local server; a short-lived link from the hosted connector).
  • add_option: a new option or action, with a before/after report.
  • get_day_one_fallback, set_day_one_fallback: the backend for questions not learned yet.
  • usage: plan, decisions this month and the monthly price.
  • download_model: a finished version, to run yourself: a short-lived link (hosted) or a zip saved to disk (local server).
  • docs: these docs (the index, one page, a search, or one API endpoint explained), and the skill with page=skill.

Errors come back as readable tool errors with the API's message, like 409 conflict: A domain with that name already exists, so the agent can fix the call.

Skill

The Canonopy Decisions skill is a packaged instruction file your agent loads when a task calls for it: when a decision model fits and when it doesn't, every step of the workflow with its tool and API call, how to read source, route and decision, switching from Jev, pricing, and what to do about each error. It's plain Markdown: SKILL.md, plus reference/ and examples/ files the agent reads only when it needs them.

Claude Code

With the CLI (canonopy-cli 0.3.1 and later):

bash
canonopy skill install              # for you, in every project: ~/.claude/skills/canonopy-decisions/
canonopy skill install --project    # this project only: .claude/skills/canonopy-decisions/

It prints where it went, and never replaces an installed copy unless you add --force. Without the CLI, unzip the skill into your skills folder:

bash
curl -fsSL -o canonopy-decisions-skill.zip https://canonopylabs.com/dl/canonopy-decisions-skill.zip
unzip canonopy-decisions-skill.zip -d ~/.claude/skills/

Claude Code picks it up in new sessions, and uses it whenever you ask about repeated decisions, switching from Jev, or Canonopy itself.

Other agents

  • The files: canonopylabs.com/skill/SKILL.md, with its supporting files next to it (for example /skill/reference/troubleshooting.md), or the whole canonopy-decisions/ folder as a zip. Put the folder where your agent reads skills (canonopy skill install --dir PATH copies it there), or tell it to read SKILL.md first.
  • Through MCP: the hosted connector and the local server both offer it as the resource canonopy://skill/SKILL.md (its supporting files are resources too), and their instructions point agents to it. The docs tool returns it with page=skill, for clients that don't read resources.

What to ask

  • "Build a Canonopy model from the Jev request in src/refunds.py, with our refund rules, and switch the code over once it's ready."
  • "Here are our past refunds in data/refunds.csv: rebuild refunds with them and walk me through the rules it found."
  • "What does the advice for refunds say? Retrain it if it's a weak spot, and show me the before and after."
  • "Set up a decision model for refund requests: approve, escalate or decline. Never approve over $500; fraud-flagged accounts always go to a person."
  • "Show me how refunds decides on the example cases, correct the ones I say are wrong, and retrain."
  • "Upload data/past_refunds.csv to refunds and train it. What does the report say would help most?"
  • "Decide this case with refunds@latest and explain the answer."
  • "Go through the unsure queue for refunds with me."
  • "How do I switch our Jev code over?"

Keys stay out of the chat

  • Your API key lives in the connector's configuration (the Authorization header) or the local server's environment. It's sent only to the API, and no tool returns it.
  • Your day-one backend's key (a Jev or OpenAI-compatible key) goes in the console. With the local server, it can instead come from an environment variable you name: add it to the server, for example --env TYPESAFE_API_KEY=…, and ask the agent to "use TYPESAFE_API_KEY".
  • The tools that change what production answers (correct_examples, promote_version, answer_unsure) tell the agent to check with you first. So does the skill for those that change what your model learns: confirm_found_rules, review_flagged_history, change_rules and mark_decision_wrong. The tools that delete cases (delete_upload, replace_history, clear_history) say they delete permanently and won't run until the agent passes the decision model's name as confirm.

Point your agent at the docs

  • llms.txt: an index of every docs page as Markdown, with a line about each.
  • llms-full.txt: every docs page in one file.
  • The skill: when and how to use Canonopy Decisions, step by step (see Skill).
  • Markdown pages: add .md to any docs URL, like https://canonopylabs.com/docs/quick-start.md. The introduction is /docs.md.
  • The API description: every endpoint and field, with examples and a "start here" workflow. Browse it at api.canonopylabs.com/docs.

A prompt that works: "Read https://canonopylabs.com/llms.txt, then call our refunds decision model before a refund is issued, and hand ask decisions to a person."

Without MCP

Everything is plain HTTP. Any agent that can run curl can follow the "start here" workflow at the top of the API description, or the API reference.