A Go CLI for a locally running Kanna. It is designed for agents: exact IDs are never truncated, live provider/model discovery prevents broken turns, compact transcript commands avoid loading unnecessary history, and every command documents itself with --help.
Requirements: Go 1.26.5+ and a running local Kanna instance.
Install the latest version directly from GitHub:
go install github.com/dbpprt/kannacli@latestGo installs binaries into $(go env GOPATH)/bin (~/go/bin by default). Add
that directory to PATH if kannacli is not found:
export PATH="$(go env GOPATH)/bin:$PATH"To persist it for zsh, add the same line to ~/.zshrc, then open a new shell.
Verify the installation:
command -v kannacli
kannacli --version
kannacli pingBuild from a clone instead:
git clone https://github.com/dbpprt/kannacli.git
cd kannacli
go install .The repository ships a concise agent skill at
skills/kannacli. For Codex:
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
cp -R skills/kannacli "${CODEX_HOME:-$HOME/.codex}/skills/"Restart the agent environment, then invoke $kannacli. Other skill-compatible
agents can copy the same folder into their configured skills directory.
kannacli [command] [flags]Start with these discovery commands instead of guessing IDs or models:
kannacli project list
kannacli chat list --project .
kannacli chat models --provider pi
kannacli chat send "explain this codebase" --project-id . \
--provider pi --model qwen3_6_27b --wait--project-id accepts an exact project ID, exact path, or unique title. If it
is omitted for a new chat, the deepest registered project containing the
current directory is used. New chats require --provider; the CLI looks up
that provider's live model catalog before creating the turn. Pi models outside
the configured favorites can be sent explicitly with --no-validate, while
provider-level capabilities remain validated. --wait is bounded to 30 minutes
by default and returns on completion, failure, or an actionable user-input tool;
override the bound with --wait-timeout.
| Flag | Description |
|---|---|
-a, --addr |
Kanna WebSocket address (default: ws://127.0.0.1:3210/ws) |
-p, --password |
Kanna password; prefer KANNA_PASSWORD |
Set KANNA_ADDR to change the default address. Keep credentials out of shell
history and process arguments:
export KANNA_PASSWORD='your-local-kanna-password'
export KANNA_ADDR='ws://127.0.0.1:3210/ws'| Command | Description |
|---|---|
kannacli ping |
Health check |
kannacli status |
Auth status for all services |
kannacli sidebar |
View projects and chats with emoji status |
kannacli sidebar --watch |
Live-watch sidebar changes |
kannacli usage |
Show rate limits and credit usage |
| Command | Description |
|---|---|
kannacli project open <path> |
Open a project directory |
kannacli project list |
List exact project IDs, titles, and paths |
kannacli project create <path> |
Create and open a new project |
kannacli project clone <url> --title <title> |
Clone a repo and open as project |
kannacli project remove <project> |
Remove by exact ID, path, or unique title |
kannacli project rename <project> |
Rename by exact ID, path, or unique title |
| Command | Description |
|---|---|
kannacli chat list |
List all chats |
kannacli chat create <projectId> |
Create a new chat |
kannacli chat send "msg" -c <id> |
Send a message to a chat |
kannacli chat send "msg" -P <proj> -r claude |
Start a validated chat and message |
kannacli chat models -r pi |
Read the live provider-specific model catalog |
kannacli chat tail <id> -n 10 |
Read only recent transcript entries |
kannacli chat search <id> -q term |
Search transcript text/tool inputs locally |
kannacli chat tools <id> --pending |
Inspect tool calls awaiting a response |
kannacli chat respond <id> -t <toolId> --approve |
Respond to an approval/question tool |
kannacli chat queue list <id> |
Inspect messages queued behind a running turn |
kannacli chat queue steer <id> <queueId> |
Interrupt and run a queued message now |
kannacli chat rename <id> -t "title" |
Rename a chat |
kannacli chat archive <id> |
Archive a chat |
kannacli chat unarchive <id> |
Restore a chat |
kannacli chat delete <id> |
Delete a chat permanently |
kannacli chat cancel <id> |
Cancel a running agent turn |
kannacli chat fork <id> |
Fork a chat |
kannacli chat export <id> |
Export as standalone HTML |
| Command | Description |
|---|---|
kannacli git init <chatId> |
Initialize git in project |
kannacli git branches <chatId> |
List branches |
kannacli git checkout <id> -b <branch> |
Checkout a branch |
kannacli git create-branch <id> -n <name> |
Create a new branch |
kannacli git merge <id> -b <branch> |
Merge a branch |
kannacli git sync <id> --action push |
Sync (fetch/pull/push/publish) |
kannacli git publish <id> -o owner -n repo |
Publish to GitHub |
| Command | Description |
|---|---|
kannacli diff refresh <chatId> |
Refresh diff snapshot |
kannacli diff commit <projId> -s "msg" --paths file1 --paths file2 |
Commit changes |
kannacli diff discard <chatId> --path <path> |
Discard file changes |
kannacli diff ignore <chatId> --path <path> |
Add to .gitignore |
| Command | Description |
|---|---|
kannacli settings show |
Show current settings |
kannacli settings set --theme dark |
Update settings |
kannacli settings keybindings |
Show keybindings |
kannacli settings llm-provider --action show |
Show LLM provider config |
KANNA_LLM_API_KEY=... kannacli settings llm-provider --action set --provider openrouter --model <model> |
Set LLM provider |
| Command | Description |
|---|---|
kannacli auth status |
Show auth status |
kannacli auth install -s claude |
Install a CLI |
kannacli auth login -s claude |
Start login flow |
| Command | Description |
|---|---|
kannacli skills search "query" |
Search marketplace |
kannacli skills install -s github -i owner/repo |
Install a skill |
kannacli skills uninstall <id> |
Uninstall a skill |
kannacli skills list |
List installed skills |
kannacli skills list -s global |
List global skills |
| Command | Description |
|---|---|
kannacli terminal create -P <project> |
Create a project terminal |
kannacli terminal view <termId> -n 20 |
Read bounded terminal output |
kannacli terminal input -t <termId> -d "ls" |
Send input |
kannacli terminal close -t <termId> |
Close a terminal |
| Command | Description |
|---|---|
kannacli fs list [path] |
List directory |
kannacli fs mkdir <path> |
Create directory |
| Command | Description |
|---|---|
kannacli system status |
Health check |
kannacli system ping |
Ping |
kannacli system update |
Check for updates |
kannacli system update --action install |
Install update |
# Quick health check
kannacli ping
# View all projects and chats
kannacli sidebar
# Send a message to an existing chat
kannacli chat send "fix the login bug" --chat-id abc123
# Start a new chat in a project with Claude
kannacli chat send "review my code" --project-id . --provider claude --model sonnet
# Pipe content from stdin
echo "refactor the auth module" | kannacli chat send --chat-id abc123
# Search and install a skill
kannacli skills search "docker"
kannacli skills install --source github --skill-id owner/repo
# Check usage limits
kannacli usage
# Set the LLM provider for Pi without exposing the key in process arguments
KANNA_LLM_API_KEY='<api-key>' kannacli settings llm-provider \
--action set --provider openrouter --model qwen/qwen3-coder
# Clone a GitHub repo as a project
kannacli project clone https://github.com/user/repo.git --title "My Repo"
# Publish to GitHub
kannacli git publish <chatId> --owner myuser --name myrepo --visibility privatekannacli (Go CLI)
↕ WebSocket (JSON protocol)
Kanna Server (localhost:3210)
├── WSRouter — subscription & command routing
├── AgentCoordinator — multi-provider turn management
├── EventStore — JSONL persistence
└── ReadModels — derived views
↕ stdio
Claude Code / Codex / Cursor / Pi
The CLI speaks the same WebSocket protocol as the Kanna frontend, sending
{v:1, type:"command", id:..., command:{...}} envelopes and receiving
{v:1, type:"ack", id:..., result:{...}} responses.
The WebSocket client has one connection reader that dispatches command replies,
snapshots, and concurrent subscriptions by envelope ID. Do not add per-command
ReadMessage loops: Gorilla WebSocket supports only one concurrent reader.
gofmt -d .
go test -race ./...
go vet ./...
go build ./...
gitleaks git --redactMIT