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
- Install the CLI where the agent runs:
npm i -g kenso(Node 22 or newer). - Give it a key. Either set
KENSO_API_KEY(andKENSO_WORKSPACE_IDwhen 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
- 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 | --client | Folder |
|---|---|---|
| Claude Code | claude-code | ~/.claude/skills/kenso-cli/ |
| Codex | codex | ~/.agents/skills/kenso-cli/ |
| Cursor | cursor | ~/.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
--dirwrites the skill into that folder instead, for example a project's own skills folder. Name the folderkenso-cli, as agents expect the folder to match the skill name.- A different
SKILL.mdalready in a target folder is replaced only with--force; without it the command exits 7, writes nothing, and itsnextadds--force. The same file is left alone ("status":"unchanged"). --dry-runwrites nothing and exits 0. It prints each target's status (replacedmarks a different file there) and anextthat applies it, with--forcewhen a file would be replaced.- Cursor also reads
~/.claude/skills/and~/.agents/skills/, so after a default install for all three it may listkenso-climore than once. To avoid that, install with--client cursoronly, 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 itsnext(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,notFoundandinvalidare 0, the work is done. Otherwise read just the problem rows fromresults.csvorinvalid.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
| Variable | What it does |
|---|---|
KENSO_API_KEY | The API key. Wins over any saved profile |
KENSO_WORKSPACE_ID | The workspace for every command. --workspace wins over it |
KENSO_PROFILE | The saved profile to use. --profile wins over it |
KENSO_API_URL | The API, default https://api.ken.so |
KENSO_CONFIG_DIR | Where the config file and cache live, default ~/.kenso |
KENSO_RUNS_DIR | Where run folders live, default <config dir>/runs |
KENSO_MCP_URL | The 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 commandmcp.ken.so: onlykenso mcp toolsandkenso mcp callregistry.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 carryX-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.