Skip to content

MCP Configure

canviq mcp configure registers Canviq as an MCP server in the config files for Claude Code and Cursor. After running it, those tools can call Canviq APIs through natural language.

Run the command

canviq mcp configure

The command checks for ~/.claude/ and ~/.cursor/ directories (or, failing that, whether the tool's config file already exists on its own). For each tool it finds, it merges the Canviq server entry into that tool's config file, reads that file back, and reports what is actually in it:

Claude Code: updated (claude mcp add-json), verified in /Users/you/.claude.json
Cursor: skipped, not detected: no /Users/you/.cursor and no /Users/you/.cursor/mcp.json

You always get one line per tool, with one of four statuses:

Status Meaning
written No entry was there before. One is there now, and it matches.
updated An entry was already there. It now matches.
failed The write errored, or the entry is not in the file afterward.
skipped Nothing was attempted: the tool isn't installed, or you passed --print.

Every status comes from the read-back, not from the write returning without an error. If any tool comes back failed, that line goes to stderr and the command exits 1, so a run that configured nothing never looks like a success.

Claude Code writes to ~/.claude.json, under the top-level mcpServers key. This is Claude Code's own live session-state file, not a plain settings file, so if you have a Claude Code session open while you run the command, quit and relaunch it afterward: a running session can overwrite what was just written the next time it saves.

If you set CLAUDE_CONFIG_DIR, Claude Code keeps its config in $CLAUDE_CONFIG_DIR/.claude.json instead, and the command follows the variable: detection, the write, the delegated claude calls and the read-back all use the same resolved path. Nothing under $HOME is touched in that case, and the paths printed in the report and in --json are the resolved ones.

When the claude CLI is on your PATH, the command hands the write to it (claude mcp remove, then claude mcp add-json --scope user) so the merge happens inside the process that owns the file. The remove step is what makes a re-run work: claude mcp add-json refuses when a server of that name already exists, so without it every re-run would drop back to editing the file directly. remove reports its own failure when there is nothing to remove, which the command ignores. If add-json refuses after the remove went through, the entry you had is written back before anything else is tried, so a failed run never leaves you with less config than you started with. If claude isn't on your PATH, or it refuses, the command edits the config file itself.

Neither path is taken on trust. After either one the command re-reads the same file it wrote, and reports failed if the canviq entry isn't there. If you see failed for Claude Code, quit Claude Code and run the command again.

Cursor writes to ~/.cursor/mcp.json.

What it writes

Claude Code and Cursor expect slightly different shapes for a remote server entry, so each gets its own:

// ~/.claude.json
{
  "mcpServers": {
    "canviq": {
      "type": "http",
      "url": "https://canviq.app/api/mcp",
      "headers": {
        "Authorization": "Bearer ${CANVIQ_API_KEY}"
      }
    }
  }
}
// ~/.cursor/mcp.json
{
  "mcpServers": {
    "canviq": {
      "url": "https://canviq.app/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:CANVIQ_API_KEY}"
      }
    }
  }
}

Claude Code requires "type": "http" on a remote server entry, without it the entry is read as a broken stdio server and skipped. Cursor's documented shape omits type entirely. The two also expand their header environment variable differently: Claude Code reads ${CANVIQ_API_KEY}, Cursor reads ${env:CANVIQ_API_KEY}.

Both are written as literal strings; the command never substitutes your actual key into either file. Each tool reads the CANVIQ_API_KEY environment variable at launch time and substitutes it into the header when making requests. This prevents your API key from being committed if the config file lands in a dotfiles repo.

If CANVIQ_API_KEY is not set when the tool launches, the config still loads, but the tool sends the literal, unexpanded ${CANVIQ_API_KEY} string as the Authorization header. Every request then fails with a 401, and claude mcp list shows a missing-variable warning next to the canviq entry. Set the variable below before you troubleshoot anything else.

Set the environment variable

After running the command, add your API key to your shell profile:

# ~/.zshrc or ~/.bashrc
export CANVIQ_API_KEY=pk_live_...

The key must be agent-backed, generated from Settings → Agents (/admin/settings/agents). An SDK key or a key created via the generic API Keys wizard shares the same pk_live_/pk_test_ prefix but is not linked to an agent; Claude Code or Cursor will connect but every tool call will fail with an auth error. See Getting an agent-backed key.

Reload your profile or restart your terminal:

source ~/.zshrc

Preview the config without writing

Use --print to see a human-readable, labeled config block per client without touching any files:

canviq mcp configure --print

This is useful for manual configuration or to verify what would be written. Add the global --json flag for the machine-parseable form of the same preview:

canviq mcp configure --print --json | jq '."claude-code".mcpServers.canviq'

Both clients come back with "status": "skipped" and "reason": "print", so a script can't read a preview as a configured machine. reason is not-detected when the tool isn't installed, which is the other way a client can be skipped. Branch on reason, not on the prose in detail.

Machine-readable results

On a real run, --json configures your tools and prints the outcome as one JSON document keyed by client:

canviq mcp configure --json
{
  "claude-code": {
    "name": "Claude Code",
    "path": "/Users/you/.claude.json",
    "status": "updated",
    "method": "claude-cli",
    "verified": true,
    "mcpServers": {
      "canviq": {
        "type": "http",
        "url": "https://canviq.app/api/mcp",
        "headers": { "Authorization": "Bearer ${CANVIQ_API_KEY}" }
      }
    }
  }
}

verified is true only when the read-back found the entry, in the file named by path. method is claude-cli, direct, or none. reason appears on skipped results only, as not-detected or print. detail appears when there is a reason worth reading: why a client was skipped, or why it failed. The exit code is 1 if any client came back failed.

Manual configuration

If the command finds neither tool (no ~/.claude/ directory or ~/.claude.json file, and no ~/.cursor/ directory or ~/.cursor/mcp.json), it prints the config block and instructions instead of writing anything. Copy the output into your tool's MCP server list by hand. The message lists the exact locations it checked, so with CLAUDE_CONFIG_DIR set it names that directory rather than your home directory.

Verify the connection

After restarting Claude Code or Cursor, run a natural language query to confirm the integration works:

List my Canviq surveys

If the tool returns a list of surveys, the MCP server is configured. If it returns an auth error, confirm that CANVIQ_API_KEY is set in the environment where the tool launches.

!!! note Some tools read shell profiles only from login shells. If your key is set in ~/.zshrc but the tool launches from a GUI, you may need to set CANVIQ_API_KEY in the tool's own environment settings instead.

Global flags

canviq mcp configure reads the global --json flag as described above. Like every other command, --json changes how the result is rendered, not what the command does: the files are written either way. Use --print when you want a run that writes nothing. --quiet is accepted without erroring but ignored. See Scripting and CI for the full global-flags contract.