Canvass CLI
Install, connect, operate, automate, troubleshoot, and safely update Canvass from terminal agents and background workers.
The Canvass CLI is the preferred way to give Claude Code, Codex, Cursor, Grok Bot, Hermes, or a background worker governed access to Canvass. It handles enrollment, keeps credentials out of chat, and exposes the same live catalog and governed actions as the product UI. Tenant, campaign, policy, approval, pause, audit, and idempotency checks remain server-enforced.
The CLI owns connection lifecycle and local secret handling. MCP is the tool transport the CLI installs for compatible agent clients; it does not replace the CLI's enrollment, keychain, diagnostics, or recovery work. Use direct authenticated HTTP or remote MCP only when the runtime cannot execute the CLI, or when the generated handoff says an exact custom permission set cannot be represented by a CLI preset.
The one-minute path
- In Canvass, choose Connect an agent.
- Name the agent, choose the smallest job it needs, and create the pairing message.
- Give the complete generated message to the agent unchanged. It contains the selected role, campaign scope, connection lifecycle, and operating rules. Pairing codes are single-use and expire after 24 hours.
- In the agent's private terminal, run:
printf '%s' "$GTM_PAIRING_CODE" | gtm connect --code-stdin- Review the request in Approvals. An administrator may approve or narrow it.
- The CLI claims the credential into the OS keychain and verifies the granted catalog. It never prints the credential.
- Connect the local MCP bridge, restart the agent, and ask it to call
get_catalog:
gtm agents detect
gtm agents install autoA good first prompt is “Show our ICPs.”
Keep the secret out of chat
Never paste GTM_AGENT_KEY, keychain contents, claim secrets, or status secrets into a prompt.
The CLI stores and supplies the registration credential without showing it to the model.
Install
macOS and Linux:
curl -fsSL https://canvass.fabric.pro/install.sh | sh
gtm versionWindows PowerShell:
irm https://canvass.fabric.pro/install.ps1 | iex
gtm versionThe Unix installer defaults to ~/.local/bin/gtm; set GTM_CLI_INSTALL_DIR to choose another location.
Official releases cover macOS, Linux, and Windows on amd64 and arm64. Installers verify SHA-256 before
replacing the executable. Releases also include an SBOM and GitHub build-provenance attestation.
Connect safely
Interactive use:
gtm connect GTM-7K4Q-9H2MFor agents and shell history, prefer stdin:
printf '%s' "$GTM_PAIRING_CODE" | gtm connect \
--code-stdin \
--name "Campaign copy assistant"The default request is Plan across workspace. It reads approved GTM workspace context and proposes drafts for review, but it cannot run live campaign actions. Ask for another certified preset only when the job needs narrower or executable access:
printf '%s' "$GTM_PAIRING_CODE" | gtm connect \
--code-stdin \
--name "Workspace planning assistant" \
--request workspace-planner \
--non-interactive \
--jsonFor lead-only research:
printf '%s' "$GTM_PAIRING_CODE" | gtm connect \
--code-stdin \
--name "Lead research worker" \
--request lead-researcher \
--non-interactive \
--jsonUse --campaigns <id[,id...]> to limit access to specific campaigns. Proposal-only copy and research
requests do not require a live campaign. While approval is pending, leave the command running or resume
the exact enrollment with gtm status --json. Status never mints a replacement key.
For an autonomous campaign builder, request the complete reviewed campaign surface and bind it to the exact campaign IDs it may operate. The administrator still reviews the action set, and prospect-visible delivery remains governed by the campaign's human-approval policy:
printf '%s' "$GTM_PAIRING_CODE" | gtm connect \
--code-stdin \
--name "Campaign operator" \
--request campaign-operator \
--campaigns <campaign-id> \
--non-interactive \
--jsonConnect an agent client
gtm agents detect --json
gtm agents install autoOr choose one explicitly:
gtm agents install claude
gtm agents install codex
gtm agents install cursorClaude Code and Codex use their official MCP commands. Cursor receives a managed gtm stdio entry.
For another standards-compatible client, run gtm agents instructions --json and configure the shown
command. The local server is simply:
gtm mcpThe bridge forwards JSON-RPC to the registration-bound remote MCP endpoint. It suppresses notification responses, converts malformed or empty upstream responses into explicit errors, and never widens the server catalog.
Command reference
| Command | Purpose | Changes GTM state? |
|---|---|---|
gtm setup | Diagnose the machine and show the next connection step | No |
gtm connect | Submit or resume pairing and claim approval | Creates a reviewed request |
gtm status | Resume pending approval or verify the connection | No |
gtm catalog | Show only resources and actions currently granted | No |
gtm capabilities | Explain available, denied, and UI-only typed commands | No |
gtm workspace show/status/activity | Inspect tenant-scoped operational projections | No |
gtm context show/list | Read approved account and knowledge context | No |
gtm icp, companies, people, lists | Use friendly governed strategy and record commands | Depends on subcommand |
gtm campaigns, artifacts, messaging | Prepare and review a governed campaign package | Depends on subcommand |
gtm approvals, inbox, meetings | Review and operate exact approval/conversation records | Depends on subcommand |
gtm providers, instantly | Reconcile and activate only through approved workflows | Consequential commands |
gtm run <action> | Invoke one granted governed action | Yes; idempotency key required |
gtm operations get <id> | Inspect a durable invocation | No |
gtm mcp | Run the local stdio bridge | Depends on the invoked tool |
gtm agents detect/install/instructions | Configure a local agent | Local configuration only |
gtm credentials exec -- <command> | Supply credentials to one child process | No GTM mutation by itself |
gtm doctor | Check secret storage, registration, and catalog health | No |
gtm disconnect | Remove local credentials and pending state | Local only |
gtm commands --json | Discover the machine-readable surface | No |
gtm update --check | Show the verified update path | No |
Use --profile <name> for multiple workspaces or agent identities. Use --json for automation.
Every typed mutation accepts --input <file|->, repeatable --set key=JSON, --dry-run, an optional
--idempotency-key, and --wait or --no-wait. When no key is supplied, the CLI derives a stable key
from the exact action and canonical JSON parameters, so repeating the same logical command is safe.
The server catalog still decides whether the action is available and whether approval is required.
Inspect the current registration before automation:
gtm capabilities --json
gtm campaigns launch --dry-run --input campaign-pass.json --json
gtm campaigns launch --wait --input campaign-pass.json --json
gtm operations watch <operation-id> --timeout 10m --jsonThe stable process exit contract is 0 for success and 1 for usage, authorization, approval,
availability, validation, transport, or operation failure. Structured failures include a stable code
and human-actionable message; automation should branch on code, not localized prose.
Read the live catalog first
gtm catalog --jsonThe catalog is the truth for this registration now. It advertises only granted resources and actions.
A paused, expired, disabled, or campaign-less registration returns non-retryable recovery guidance and
the setup deep link instead of pretending that zero tools is success. Agents should call get_catalog
at the beginning of every session and after an administrator changes access.
From ICP to governed delivery
Use this sequence for autonomous campaign work. Friendly commands are conveniences over the same catalog resources and Platform actions exposed through MCP and authenticated HTTP:
- Run
gtm catalog --json, then inspectgtm workspace show,gtm icp list, andgtm campaigns list. - Create or revise the campaign's ICP with
gtm icp createorgtm icp update, then usegtm icp activatefor the intended version. A new ICP does not replace or rebind existing campaigns; each campaign retains its exact versioned audience context. - Import or update qualified companies and people using only commands reported available by
gtm capabilities --json. Provider search and list membership reads remain unavailable until the live catalog exposes privacy-safe projections. - Use
gtm messaging policy-saveandgtm messaging policy-activate, create or update the campaign, then persist its working copies withgtm artifacts draftorgtm artifacts update. - Run
gtm campaigns check, resolve every named blocker, and perform a dry run. - Run
gtm campaigns launch --no-waitonly when the operator intends to request governed delivery. Instantly activation and prospect-visible sending remain subject to the exact campaign grant, suppression checks, delivery authorization, and human approval. - Follow the returned operation with
gtm operations watch <operation-id>to a terminal status and report the campaign name, outcome, and next human action. Use IDs only in structured receipts or to disambiguate names.
See Agent capability parity for generated coverage and explicit exceptions. Never improvise a substitute command for an unavailable capability.
Invoke a governed action
gtm run gtm.save_reply_draft \
--input request.json \
--idempotency-key draft-acme-followup-v1 \
--jsonEvery mutation requires a caller-stable idempotency key. If a response is interrupted or ambiguous, retry with the same key and equivalent input. Never create a new key merely because the first response was lost. Inspect durable work with:
gtm operations get <action-invocation-id> --jsonThe CLI cannot bypass proposal-only access, human approval, suppression, campaign scope, tenant pause, or delivery policy.
Background workers and CI
printf '%s' "$GTM_PAIRING_CODE" | gtm connect \
--code-stdin \
--profile nightly-research \
--name "Nightly research worker" \
--request lead-researcher \
--non-interactive \
--jsonRun gtm doctor --json before consuming a one-time pairing code. The OS keychain is the default. On a
headless server without one, explicitly opt into the permission-checked 0600 fallback with
--allow-file-secret-store only when the runtime has a private, persistent home directory. File fallback
is never implicit and must not be used on shared or ephemeral storage. Disconnect fails closed if secret
deletion cannot be confirmed.
Supply credentials to one legacy child without exporting them into the parent shell:
gtm credentials exec --profile nightly-research -- ./workerTroubleshooting
Start with:
gtm doctor --json
gtm status --json
gtm catalog --json| Symptom | Meaning | What to do |
|---|---|---|
not_connected | This profile has no credential | Create a connection and run gtm connect |
pending_review | No admin decision yet | Review it in Approvals |
activation_pending | Approved catalog is still activating | Keep waiting or retry gtm status |
| Paused or disabled catalog | The key is valid but authority is off | Enable it in Team & agents → Agents |
| No campaign resources | The grant has no usable campaign | Add a campaign or use a campaign-free preset |
idempotency_key_required | A mutation lacks its stable command ID | Choose one key and reuse it for exact retries |
| Secret-store error | Keychain use or deletion failed | Restore it, or explicitly use file fallback on a headless host |
| Invalid pairing code | It may be unknown, expired, consumed, or throttled | Create a fresh pairing message |
Public pairing failures are deliberately generic to prevent code enumeration.
Disconnect, pause, revoke, and replace
gtm disconnect --profile nightly-research --jsonDisconnect removes local state only. An administrator pauses or revokes server access in Team & agents. If a reveal-once credential is lost, replace the connection; replay recovers the receipt, not the key.
Update and verify
gtm update --check
curl -fsSL https://canvass.fabric.pro/install.sh | shVersioned archives are immutable under /releases/gtm-cli/v<version>/; latest.txt moves only after all
six archives and checksums exist. Installers reject checksum mismatches, unsafe version paths, and
unapproved alternate origins.
Security model
- Pairing codes are single-use, expire after 24 hours, and resolve through a high-entropy secret.
- The agent asks; the administrator may approve or narrow, never silently widen.
- Credentials are reveal-once, tenant-bound, hashed server-side, and stored in the OS keychain by default.
- GTM rechecks registration, grant, scope, pause, policy, and action constraints at execution time.
- Prospect-visible work remains proposal-only until human approval and delivery checks pass.
- Credentials and enrollment secrets are excluded from normal output, durable action parameters, logs, and MCP errors.
Next: Connect outside agents, Team & agents, and Approvals.