Skip to content

CLI ​

The CLI embeds the same runtime as the server. It is useful for one-shot tasks, machines without a browser, and CI jobs that should not open a port.

bash
pnpm --filter @kestrel/cli build
node apps/cli/dist/index.js --help

Commands ​

CommandDescription
kestrel serveStart the HTTP + SSE server (same as kestrel-server).
kestrel run <prompt...>Run one task, stream output, exit.
kestrel chatInteractive session with /new, /cancel, /help, /exit.
kestrel pluginsList discovered plugins with state and errors.
kestrel modelsList registered models; marks the default.
kestrel sessionsList persisted sessions.
kestrel sessions resume <id>Continue an interrupted session.
kestrel sessions rewind <id> <messageId>Drop a user turn, and restore the files it started from.
kestrel skills [show <name>]List workspace skills, or print one body.
kestrel skills lintValidate every skill file; exits 1 on errors.
kestrel skills new <name>Scaffold skills/<name>/SKILL.md without overwriting.

Options ​

FlagApplies toMeaning
-c, --config <path>allConfiguration file (default kestrel.config.json).
--workspace <dir>run, chat, serve, skillsWorkspace root for tools, new sessions and skill discovery.
--model <id>run, chat, serveDefault model for new sessions.
--host <host>serveBind address.
--port <port>serveBind port.
--token <token>serveRequire a bearer token.
--role <role>users createadmin or member (default member).
--tenant <id>users createTenant id (default default).
--email <address>users createOptional contact address.
--description <text>skills newFrontmatter description for the scaffold.
--when <text>skills newOptional whenToUse hint for the scaffold.
--jsonrun, skillsPrint raw event envelopes (run) or a JSON document (skills, skills lint).
-h, --helpallHelp.
-v, --versionallVersion.

Examples ​

bash
# read-only analysis
kestrel run "Map this repository. Do not modify anything." --workspace .

# machine-readable stream for another tool
kestrel run "Run the test suite and summarise failures" --json | jq -r 'select(.event.type=="message.delta") | .event.delta'

# pin a model and a workspace
kestrel run "Add a healthcheck endpoint" --model gpt-4o-mini --workspace /srv/app

# inspect the procedures available to a workspace
kestrel skills --workspace /srv/app
kestrel skills show release-checklist --workspace /srv/app
kestrel skills lint --workspace /srv/app
kestrel skills new release-checklist --description "Publish a release safely." --workspace /srv/app

# serve with authentication
kestrel serve --host 0.0.0.0 --port 7331 --token "$(openssl rand -hex 24)"

run and chat raise the log level to warn so the transcript stays readable; set KESTREL_LOG_LEVEL=info (or debug) to see plugin activation and session lifecycle lines. serve logs at info by default.

--json output is the same ServerEventEnvelope shape the API sends, without the SSE framing:

json
{"seq":12,"at":"2026-01-01T10:00:04.000Z","event":{"type":"tool.started","sessionId":"...","call":{"id":"call_1","name":"read_file","arguments":{"path":"README.md"}}}}

Approvals in the terminal ​

run and chat install an interactive approval prompt. When a tool asks for permission, the CLI prints the tool name and arguments and asks for y/n. This is a local decision; it does not touch the HTTP approval endpoint.

In non-interactive contexts, prefer shellPermission: "auto" inside a disposable sandbox, or implement a policy plugin with a resolvePermission function.

Exit codes ​

CodeMeaning
0Run completed (including a run stopped by the finish tool).
1Run failed, or startup/configuration failure.
2Invalid arguments or unknown command.

A cancelled run exits 0. In --json mode the failure is present in the stream even when the process exits 1, so pipelines can parse and gate on either signal.

Released under the MIT License.