Kenso
Kenso CLI

Coding agents

Kenso CLI pages

The CLI is built to be driven by a coding agent: Claude Code, Codex, Cursor, Gemini CLI or anything else that runs shell commands. An agent learns it from the Agent Skill, kenso --help and kenso describe, and never needs these web pages.

Set up an agent in three steps

  1. Install the CLI where the agent runs: npm i -g kenso (Node 22 or newer).
  2. Give it a key. Either set KENSO_API_KEY (and KENSO_WORKSPACE_ID when the key reaches several workspaces) in the agent's environment, or log in once on that machine:
echo $KEY | kenso auth login --with-key
kenso workspace use 1234
  1. Install the Agent Skill, so the agent knows the rules before its first command:
kenso skill install

The Agent Skill

kenso skill install writes the skill kenso-cli (one SKILL.md) where each agent looks for skills:

Agent--clientFolder
Claude Codeclaude-code~/.claude/skills/kenso-cli/
Codexcodex~/.agents/skills/kenso-cli/
Cursorcursor~/.cursor/skills/kenso-cli/

Without --client, it installs for the agent that runs it when that is Claude Code, Codex or Cursor (detected from the environment, see below), else for all three. It prints what it wrote:

{"installed":[{"client":"claude-code","path":"/home/you/.claude/skills/kenso-cli/SKILL.md","status":"created"}]}
kenso skill install --client claude-code
kenso skill install --client all
kenso skill install --dir .claude/skills/kenso-cli
kenso skill install --force
  • --dir writes the skill into that folder instead, for example a project's own skills folder. Name the folder kenso-cli, as agents expect the folder to match the skill name.
  • A different SKILL.md already in a target folder is replaced only with --force; without it the command exits 7, writes nothing, and its next adds --force. The same file is left alone ("status":"unchanged").
  • --dry-run writes nothing and exits 0. It prints each target's status (replaced marks a different file there) and a next that applies it, with --force when a file would be replaced.
  • Cursor also reads ~/.claude/skills/ and ~/.agents/skills/, so after a default install for all three it may list kenso-cli more than once. To avoid that, install with --client cursor only, or remove the copies you do not need.

The skill also ships in the Kenso plugin for Claude Code (Ken-Technology/ken-ai-plugin), so npx skills add Ken-Technology/ken-ai-plugin installs it along with the MCP skills. To read it without installing, open skill/kenso-cli/SKILL.md in the package.

Rules the skill teaches

  • Data is on stdout, as JSON when piped. Progress, warnings and errors are on stderr. Parse stdout; read stderr when the exit code is not 0.
  • Plan, then apply. Run a write with --dry-run, read the plan, then run the exact command in its next (the same command with --yes).
  • Pass files, not rows. Never paste a CSV into the conversation. Write the file, pass its path with --file, and read the summary.
  • Read failures only. If the summary's failed, notFound and invalid are 0, the work is done. Otherwise read just the problem rows from results.csv or invalid.csv.
  • Follow next. Every error with a known fix carries the exact command to run.
  • Branch on the exit code: 0 ok, 2 fix the command, 3 fix the key, 5 some rows failed, 6 wait or raise a limit, 130 resume.
  • Look things up, do not guess. kenso describe <resource> <action> prints any command's flags and body schema as JSON.

The token-saving pattern

Adding 5,000 leads through the MCP sends every lead through the model, hundreds of thousands of tokens. Through the CLI it is two commands and two short JSON objects:

kenso contacts import --campaign 812 --file leads.csv --dry-run
kenso contacts import --campaign 812 --file leads.csv --yes

Then, only if the summary shows failures:

grep -E '^[0-9]+,(failed|not_found|invalid),' ~/.kenso/runs/r_tdi5cdnx/results.csv | head -50

Environment variables

VariableWhat it does
KENSO_API_KEYThe API key. Wins over any saved profile
KENSO_WORKSPACE_IDThe workspace for every command. --workspace wins over it
KENSO_PROFILEThe saved profile to use. --profile wins over it
KENSO_API_URLThe API, default https://api.ken.so
KENSO_CONFIG_DIRWhere the config file and cache live, default ~/.kenso
KENSO_RUNS_DIRWhere run folders live, default <config dir>/runs
KENSO_MCP_URLThe MCP for kenso mcp, default https://mcp.ken.so/mcp

Cloud sandboxes

Cloud agents (Claude Code on the web, Codex cloud, Cursor background agents and similar) often run with a network allowlist. Allow:

  • api.ken.so: every command
  • mcp.ken.so: only kenso mcp tools and kenso mcp call
  • registry.npmjs.org: to install the CLI with npm

Store the key as the platform's secret and expose it as KENSO_API_KEY. Run kenso doctor as the first command: it checks Node, the config, that the API is reachable and that the key works, and exits 0 when all four pass.

kenso doctor

Point the run folders at the workspace if the home folder does not persist between sessions: KENSO_RUNS_DIR=./.kenso-runs. Keep that folder out of git.

How Kenso knows an agent ran a command

The CLI checks these environment variables, in this order: CLAUDECODE and CLAUDE_CODE_ENTRYPOINT (Claude Code), CODEX_SANDBOX and CODEX_THREAD_ID (Codex), CURSOR_AGENT (Cursor), GEMINI_CLI (Gemini CLI), OPENCODE (OpenCode), then AI_AGENT, a free-form name any other agent can set. When one is set:

  • every request carries X-Ken-Client: Kenso CLI via <agent>, and writes carry X-Ken-Actor: agent, so Kenso shows the change as made by you through that agent;
  • help ends with a short "For agents" block;
  • browser login never opens a browser itself: it prints the link for you to open.

kenso doctor shows the agent it detected.

MCP-only tools

A few Kenso MCP tools have no API route, such as the skills Kenso's own agents use. Reach them from the shell with the same key:

kenso mcp tools
kenso mcp call skills --operation list
kenso mcp call contacts --operation list --args '{"limit":5}'

mcp call prints the tool's structured result, else its text parsed as JSON, else the text. A tool error exits 1 with mcp_tool_error.