Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Koda 🐻

Koda is a terminal-native AI coding agent. It runs locally, keeps all data on your machine, and connects to any LLM provider you choose.

Modes at a glance

ModeHow to invokeBest for
Interactive TUIkoda (no args)Long sessions, iterative coding
Headlesskoda "prompt" or echo … | kodaScripts, CI, one-shot tasks
ACP serverkoda server --stdioEditor plugins (VS Code, Zed, …)

Quick start

# 1. Open the interactive TUI
koda

# 2. Ask something at the prompt
#    > explain why the auth tests are failing

# 3. Type /help inside for keybindings and commands

First run triggers onboarding: Koda looks for a running local model (LM Studio, Ollama) and falls back to prompting for a cloud API key.

What’s next

CLI reference

Flags

FlagEnv varDescription
-p, --prompt <PROMPT>Run a single prompt and exit (headless). Use "-" for stdin
<PROMPT> (positional)Same as -p β€” koda "fix the bug" works
-a, --agent <NAME>Agent definition to use (JSON in agents/, default: default)
-s, --resume <ID>Resume a previous session by ID prefix
--model <NAME>KODA_MODELModel name or alias (e.g. claude-sonnet, gemini-flash)
--provider <NAME>KODA_PROVIDERLLM provider (anthropic, gemini, openai, ollama, …)
--base-url <URL>KODA_BASE_URLOverride the provider’s API base URL
--max-tokens <N>Maximum output tokens
--temperature <F>Sampling temperature (0.0–2.0)
--thinking-budget <N>Anthropic extended thinking budget (tokens)
--reasoning-effort <L>OpenAI reasoning effort (low, medium, high)
--sandbox <MODE>KODA_SANDBOXBash tool sandbox: none (default), project (restrict writes to project dir + /tmp), or strict (project + deny reads of credential dirs: ~/.ssh, ~/.aws, ~/.gnupg, ~/.kube, ~/.azure, ~/.config/gcloud)
--output-format <FMT>Headless output format: text (default) or json
--project-root <DIR>Project root (defaults to cwd)

Subcommands

CommandDescription
koda server --stdioStart ACP server over stdin/stdout (for editors)
koda server --port <N>WebSocket ACP server on port N (not yet implemented)

Headless mode

Headless mode runs a single prompt, prints the answer, and exits. No TUI β€” the assistant’s reply streams to stdout; tool status goes to stderr.

# Positional prompt (shortest form)
koda "what does this codebase do?"

# Explicit -p flag
koda -p "fix the failing tests"

# Read prompt from stdin (use "-" literally)
koda -p - < my_question.txt

# Pipe into koda β€” stdin is auto-detected when not a TTY
git diff HEAD~1 | koda
cat error.log | koda
echo "review auth.rs" | koda

# With a model override
koda "explain this" --model gemini-flash

# Capture just the assistant reply (tool status stays on stderr)
koda "list exported functions in lib.rs" > functions.txt

Exit codes

CodeMeaning
0Turn completed successfully
1Error (API failure, bad config, …)

Approval in headless mode

There is no human to approve tool calls. Koda automatically:

  • Approves read-only tools: Read, Grep, Glob, WebFetch
  • Approves safe write tools: Write, Edit (files only)
  • Rejects destructive Bash commands (rm -rf, git push --force, …)
  • Skips AskUser questions (prints to stderr, continues with empty answer)

Rejected actions are printed to stderr. The turn still completes with exit code 0 unless the API itself errors.

Output formats

--output-format text (default) β€” streams the assistant’s reply to stdout exactly as typed. Tool call summaries go to stderr.

--output-format json β€” emits a single JSON object after the turn ends:

{
  "success": true,
  "response": "The exported functions are …",
  "session_id": "a3f8bc12-…",
  "model": "claude-sonnet-4-6"
}

File attachment in headless mode

The @file syntax works in headless mode too:

koda "review @src/auth.rs and @tests/auth_test.rs"

Resuming a session in headless mode

# Note the session ID shown in the TUI status bar, then continue from a script
koda -s a3f8bc "run the failing tests and fix them"

Interactive TUI

Run koda with no arguments to open the full-screen TUI.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  [conversation history β€” scrollable with PgUp/PgDn]                     β”‚
β”‚                                                                          β”‚
β”‚  ⚑ Bash   cargo test                                                    β”‚
β”‚  β”‚ running 42 tests …                                                   β”‚
β”‚  βœ“ Bash (exit 0)                                                         β”‚
β”‚                                                                          β”‚
β”‚  All tests pass! Here's what I changed in `auth.rs` …                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ claude-sonnet Β· auto Β· 34% Β· 8s ────────────────────────────
β”‚  > _                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The status bar shows: model Β· approval mode Β· context % Β· elapsed

Layout

  • Top panel β€” conversation history. Scrollable; supports syntax-highlighted code blocks, rendered markdown, and collapsible tool-call summaries.
  • Status bar β€” live view of model, approval mode, context usage, and inference time.
  • Input β€” multi-line editor with history, tab-completion for slash commands and @file paths, and reverse-search (Ctrl+R).

Starting a conversation

Just type and press Enter. Koda streams the response in real time. While inference is running, Esc or Ctrl+C cancel the current turn.

See slash commands for all in-session commands and keybindings for the full keyboard reference.

File & image attachments

Attaching files

Type @ anywhere in your message to attach files as context:

> explain @src/auth.rs
> compare @old_impl.rs and @new_impl.rs
> what's wrong with @error.log

As you type after @, a fuzzy file picker appears. Press Tab to cycle through matches or select with Enter. The file’s full contents are injected into the message before it’s sent to the model.

Images

For vision-capable models (Claude, Gemini, GPT-4o), attach images directly:

> what does @screenshot.png show?
> explain the architecture in @diagram.png

Supported formats: PNG, JPEG, GIF, WEBP. Images are base64-encoded and sent inline to the model API.

Non-image files (SVG, PDF, etc.) attached via @ are sent as text content, not as vision input.

Large pastes

Pasting more than ~500 characters into the input is automatically wrapped in a reference block to keep prompts clean:

> [pasted 1,234 chars β€” attached as reference]
> what's the bug in this code?

The paste is still sent to the model; it just doesn’t clutter the display.

Slash commands

Type in the TUI input. Tab-completion is available for all commands.

/help

Shows the quick-reference keybinding card inside the TUI. This docs site is the full reference; /help is the in-session reminder.

/model [<alias-or-id>]

Without an argument: opens an interactive picker listing all model aliases and any locally running models detected via LM Studio or Ollama.

With an argument: switches immediately.

/model gemini-flash        ← switch by alias
/model claude-opus         ← switch by alias
/model local               ← auto-detect from LM Studio
/model gpt-4o              ← literal model ID (no alias needed)
/model llama3.2            ← any model name your provider understands

The new model is persisted to the keystore and used for all future sessions until changed again. See Providers & model aliases.

/provider [<name>]

Without an argument: opens a two-step picker β€” choose provider, then browse and pick one of its available models.

With an argument: jumps straight to that provider’s model list.

/provider                  ← open the picker
/provider anthropic        ← go straight to Anthropic models
/provider ollama           ← browse locally running Ollama models

/key

Opens the API key manager. Select a provider, then type or paste your key. Keys are stored in the local SQLite keystore (file mode 0600) and injected as environment variables at every startup.

Shell env vars always win over stored keys β€” so export ANTHROPIC_API_KEY=… in your shell or .envrc is always a clean override.

/compact

Summarises old conversation history to free context tokens. Koda auto-compacts when the context window hits 85% full, but you can trigger it manually at any time:

  • All but the last 4 messages are summarised by the model
  • The summary replaces the old messages in the DB
  • The compressed session continues normally
  • Use /purge later to clean up the archived messages

/purge [<age>]

Deletes compacted (archived) message history. Does not touch the live messages in your current session.

/purge        ← delete all archived messages (prompts for confirmation)
/purge 90d    ← only messages archived more than 90 days ago
/purge 30d    ← only messages archived more than 30 days ago

Requires y to confirm. Deleted messages are gone permanently.

/undo

Reverts all file mutations from the previous inference turn β€” Write, Edit, and Delete tool calls. One /undo per turn; call again to go back another turn. Bash commands (e.g. cargo build) are not undoable.

# Koda wrote bad code in the last turn
/undo    ← all file changes from that turn are reverted
/undo    ← undo the turn before that

/diff

Shows a summary of uncommitted git diff in the project root. Then offers:

  • Review β€” sends the diff to the model for code review comments
  • Commit β€” asks the model to write a conventional commit message and runs git commit -m "…"

/sessions [<sub-command>]

/sessions              ← open the session picker (shows last 100 sessions)
/sessions resume abc   ← resume the session whose ID starts with "abc"
/sessions delete abc   ← permanently delete that session

Session IDs are UUIDs; you only need 6–8 characters to be unambiguous. On resume, Koda shows an away-summary: idle time, message count, token usage, and a banner if the previous turn was interrupted mid-inference.

/memory [save]

/memory        ← show the paths to project and global memory files
/memory save   ← ask the model to summarise the session and append to MEMORY.md

See Memory for the full memory system.

/skills [<query>]

/skills              ← list all built-in and custom skills
/skills security     ← filter by name or description

/agent <name>

Switches to a named sub-agent for the current session. The agent’s system prompt, model, and allowed tools replace the current defaults.

/agent testgen     ← use the "testgen" agent definition

/expand [<n>]

Shows the full, untruncated output of a recent tool call. Useful when Koda collapsed a long cargo build or grep result during streaming.

/expand      ← show full output of the most recent tool call
/expand 3    ← show full output of the 3rd most recent tool call

/copy [<n>]

Copies the Nth-most-recent assistant response to the system clipboard. Defaults to the most recent response (n=1).

/copy      ← copy the last response
/copy 2    ← copy the second-to-last response
/copy 5    ← copy the fifth-to-last response

Reads from the full session DB, so compacted (summarised) responses are included in the count. A one-line preview is shown in the confirmation.

/export [<file.md>]

Exports the full session transcript as a Markdown document.

/export                    ← auto-named file in the current directory
/export notes/session.md   ← write to a specific relative path

Paths must be relative to the current directory. Absolute paths and .. traversal are rejected.

When no path is given, the filename is derived from the first user message and the current UTC time:

koda-20260410-143022-refactor-the-auth-module.md

The transcript includes all user messages, assistant responses, and a summary of every tool call. System prompts are excluded.

/verbose [on|off]

Toggles verbose tool output. By default Koda collapses long outputs during streaming. Verbose mode shows every line in real time.

/verbose      ← toggle
/verbose on   ← enable explicitly
/verbose off  ← disable explicitly

/exit

Quit Koda. Equivalent to Ctrl+D.

Keybindings

Input

KeyAction
EnterSend message
Alt+EnterInsert newline (multi-line input)
TabAutocomplete slash commands and @file paths
Shift+TabToggle approval mode (auto ↔ confirm)
↑ / ↓Cycle through input history
Ctrl+RReverse history search
KeyAction
PgUp / PgDnScroll history one page up / down
HomeJump to top of history
EndJump to bottom (latest output)
Mouse scrollScroll conversation history

Session control

KeyAction
EscCancel current inference
Ctrl+CCancel current inference
Ctrl+DQuit koda

Approval prompt

These keys appear when the agent asks to execute a tool:

KeyAction
yApprove this action
nReject this action
aApprove and switch to auto mode (no more confirmations this session)
fReject and type written feedback explaining why
EscReject (same as n)

Approval modes

Koda has two approval modes, toggled with Shift+Tab (current mode shown in the status bar):

Auto β€” safe tools run without confirmation. Destructive shell commands (rm -rf, sudo, git push --force, etc.) still require explicit y. Read-only tools (Read, Grep, Glob, WebFetch) are always auto-approved.

Confirm β€” every write or mutation requires explicit y before executing. Read-only tools are still auto-approved.

The mode is persisted per session β€” if you approve with a (auto), that session remembers it even after resuming.

In headless mode, there is no human to prompt. Destructive Bash commands are silently rejected; all other tools proceed automatically.

Approval keys

KeyEffect
yApprove this one action
nReject this one action
aApprove and enable auto mode for the rest of the session
fReject and provide written feedback the model can act on
EscReject (same as n)

Session management

Koda stores every conversation in a local SQLite database, organised by project root. Each session gets a UUID that you can use to resume it.

# List and pick a session interactively
/sessions

# Resume by ID prefix from the TUI
/sessions resume a3f8bc

# Resume from the command line (headless or interactive)
koda -s a3f8bc
koda -s a3f8bc "continue where we left off"

# Delete a session permanently
/sessions delete a3f8bc

Away summary

When you resume a session that was idle, Koda shows:

  • How long you were away
  • Message and tool-call counts
  • Total tokens used
  • A banner if the previous turn was interrupted mid-inference

Session title

Koda auto-generates a short title after the first exchange. The title is shown in /sessions and the status bar.

Context management

Every provider has a context window limit (measured in tokens). The status bar shows current usage as a percentage (e.g. 34%).

Auto-compact

When usage reaches 85%, Koda automatically compacts the session:

  1. All but the last 4 messages are summarised by the model
  2. The summary is stored in the DB (recoverable with /purge)
  3. A status line appears: 🐻 Context at 85% β€” auto-compacting…

Auto-compact is skipped if there are pending tool calls (it waits for the turn to finish cleanly).

Manual compact

Run /compact at any time to compact early, e.g. before starting a large refactor so you have the full context window available.

Purging archived history

/compact keeps summaries in the DB. Use /purge to delete them:

/purge        ← prompt and delete all archived messages
/purge 90d    ← delete only archived messages older than 90 days

Memory

Memory files persist facts and preferences across sessions.

Project memory β€” MEMORY.md in the project root (Koda also reads CLAUDE.md and AGENTS.md for compatibility). Injected into every system prompt for that project.

Global memory β€” ~/.config/koda/memory.md. Injected into every system prompt across all projects.

/memory        ← show the paths to both memory files
/memory save   ← ask the model to summarise and append to MEMORY.md

MemoryWrite tool

The MemoryWrite tool lets the model append facts to memory directly during a conversation:

> Remember that we use tabs not spaces in this project

Koda will call MemoryWrite automatically when you ask it to remember.

File precedence

FileScopePriority
.koda/MEMORY.mdProjectHighest
MEMORY.mdProject rootHigh
CLAUDE.mdProject rootHigh (compatibility)
AGENTS.mdProject rootHigh (compatibility)
~/.config/koda/memory.mdGlobalBase

Providers & model aliases

Supported providers

Provider name--provider valueAPI key env varDefault modelNeeds key
AnthropicanthropicANTHROPIC_API_KEYclaude-sonnet-4-6βœ“
OpenAIopenaiOPENAI_API_KEYgpt-4oβœ“
Google GeminigeminiGEMINI_API_KEYgemini-flash-latestβœ“
GroqgroqGROQ_API_KEYllama-3.3-70b-versatileβœ“
Grok / xAIgrokXAI_API_KEYgrok-3βœ“
DeepSeekdeepseekDEEPSEEK_API_KEYdeepseek-chatβœ“
MistralmistralMISTRAL_API_KEYmistral-large-latestβœ“
MiniMaxminimaxMINIMAX_API_KEYminimax-text-01βœ“
OpenRouteropenrouterOPENROUTER_API_KEYanthropic/claude-3.5-sonnetβœ“
Together AItogetherTOGETHER_API_KEYLlama-3.3-70B-Instruct-Turboβœ“
Fireworks AIfireworksFIREWORKS_API_KEYllama-v3p3-70b-instructβœ“
LM Studiolm-studioβ€”auto-detectβœ—
Ollamaollamaβ€”auto-detectβœ—
vLLMvllmβ€”auto-detectβœ—

Local providers (LM Studio, Ollama, vLLM) are auto-detected on first run and require no API key. The model is discovered from the running server.

Model aliases

Aliases let you switch models without memorising exact IDs. They’re shown in the /model picker and accepted by --model and /model.

AliasProviderExact model ID
gemini-flash-liteGeminigemini-flash-lite-latest
gemini-flashGeminigemini-flash-latest
gemini-proGeminigemini-pro-latest
claude-haikuAnthropicclaude-haiku-4-5-20251001
claude-sonnetAnthropicclaude-sonnet-4-6
claude-opusAnthropicclaude-opus-4-6
localLM Studioauto-detect at runtime

You can also use any literal model ID your provider supports β€” aliases are just shortcuts. koda --model gpt-4o-mini or /model o3 both work.

Configuration

Precedence

When multiple sources specify the model, provider, or API key, the highest-priority source wins:

1. CLI flags          --model, --provider, --base-url        (highest)
       ↓
2. Shell env vars     KODA_MODEL, KODA_PROVIDER, KODA_BASE_URL
       ↓
3. Keystore / DB      saved by /model, /provider, /key (injected at startup)
       ↓
4. Built-in defaults  Claude Sonnet via Anthropic              (lowest)

API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, …) follow the same chain. Keys saved with /key are injected at startup β€” but a key already in the shell environment takes precedence and is never overwritten.

# Per-call override (doesn't change saved config)
koda "review auth.rs" --model o3

# Per-project via direnv (.envrc)
export KODA_MODEL=gemini-2.5-pro

# CI / GitHub Actions
ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_KEY }} koda -p "check types"

Config files

Everything lives in ~/.config/koda/:

PathContent
db/koda.dbSQLite β€” sessions, messages, settings, API keys, input history
logs/koda.logRolling daily tracing log (not shown in the TUI)
agents/Global custom agent JSON definitions
skills/Global custom skill markdown files
memory.mdGlobal memory (injected into all system prompts)

Project-level overrides live in .koda/ at your project root and take priority over global config:

PathContent
.koda/agents/Project-specific agent definitions
.koda/skills/Project-specific skills
MEMORY.mdProject memory (also checks CLAUDE.md, AGENTS.md)

Custom agents

Place JSON files in .koda/agents/ (project-local) or ~/.config/koda/agents/ (global):

{
  "name": "testgen",
  "system_prompt": "You are a test generation specialist. When asked to write tests, always use the project's existing test patterns.",
  "model": "gemini-2.5-flash",
  "allowed_tools": ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
}

Agent fields

FieldRequiredDescription
nameβœ“Identifier used with /agent <name> and InvokeAgent
system_promptβœ“The agent’s persona and instructions
modelModel alias or ID (defaults to current saved model)
allowed_toolsSubset of tools the agent can call (defaults to all)

Using agents

/agent testgen     ← switch to a named agent for the current session

The main model dispatches to sub-agents via the InvokeAgent tool. Each sub-agent runs in its own worktree with its own model, tools, and session.

Built-in agents

AgentPurpose
guideDocumentation assistant β€” answers questions about Koda
defaultGeneral-purpose coding assistant

Skills

Skills are reusable expertise modules β€” markdown files loaded into the system prompt on demand.

/skills                  ← list all available skills
/skills security         ← filter by name or description

The model can also activate skills automatically via the ActivateSkill tool when it determines a skill is relevant.

Creating custom skills

Place a SKILL.md file inside a named directory under .koda/skills/ (project-local) or ~/.config/koda/skills/ (global). The directory name becomes the skill name.

.koda/
  skills/
    my-checklist/
      SKILL.md        ← skill content goes here

SKILL.md format

Frontmatter is YAML between --- fences; the body is the skill prompt:

---
name: my-checklist
description: One-line summary shown in ListSkills output.
tags: [review, quality]
when_to_use: Use when the user asks to review a pull request or a diff.
allowed_tools: [Read, Grep, Glob]
user_invocable: true
argument_hint: <file_or_pr_url>
---

# My Review Checklist

When reviewing code, always check:
- [ ] No hardcoded secrets
- [ ] Error handling covers all paths
- [ ] Tests cover the new logic
FieldRequiredDescription
nameβœ”Skill identifier (used with ActivateSkill)
descriptionrecommendedOne-line summary shown in ListSkills
tagsoptionalSearchable tags: [tag1, tag2]
when_to_userecommendedGuidance for the model on when to activate
allowed_toolsoptionalRestrict tools during activation (empty = all)
user_invocableoptionalfalse = model-only, hidden from /skills
argument_hintoptionalUsage hint (e.g. <file_path>)

Note: Both underscore (allowed_tools) and hyphenated (allowed-tools) field names are accepted for CC compatibility.

How allowed_tools enforcement works

When a skill with allowed_tools is activated:

  1. Tool definitions are filtered β€” only the listed tools (plus meta-tools like ActivateSkill, ListSkills, ListAgents, InvokeAgent, AskUser) are sent to the LLM on subsequent turns.
  2. Blocked tool calls are rejected β€” if the model still attempts a blocked tool (e.g., from cached context), the call returns an error explaining the scope restriction.
  3. Scope clears automatically when a different skill without allowed_tools is activated.

Scope transitions are logged as info events (πŸ”’ scope activated / πŸ”“ scope cleared).

Skill lookup order

  1. .koda/skills/ (project-local, highest priority)
  2. ~/.config/koda/skills/ (global)
  3. Built-in skills bundled with the binary

Project-local skills shadow global ones with the same name.

Tools reference

Koda exposes these tools to the model. In Confirm approval mode you’ll be prompted before each mutating call. In Auto mode, only destructive Bash commands require confirmation.

ToolEffectDescription
ReadRead-onlyRead a file (with optional line range)
WriteMutatingCreate or overwrite a file
EditMutatingTargeted text replacement within a file
DeleteMutatingDelete a file or directory
BashVariesRun a shell command
GrepRead-onlySearch for patterns across files (ripgrep)
GlobRead-onlyList files matching a glob pattern
WebFetchRead-onlyFetch a URL and return its text content
WebSearchRead-onlySearch the web via DuckDuckGo
ThinkInternalExtended reasoning step (no side effects)
MemoryReadRead-onlyRead from project or global memory
MemoryWriteMutatingAppend a fact to a memory file
TodoReadRead-onlyRead the session task list
TodoWriteMutatingUpdate the session task list
RecallContextRead-onlySearch session history for past context
ListSkillsRead-onlyList available skills
ActivateSkillInternalLoad a skill’s instructions into context
InvokeAgentVariesDelegate a task to a named sub-agent
ListFilesRead-onlyList directory contents
AskUserInteractiveAsk the user a clarifying question

Approval behaviour by tool

CategoryToolsAuto modeConfirm mode
Read-onlyRead, Grep, Glob, ListFiles, WebFetch, WebSearch, TodoRead, RecallContextβœ… Autoβœ… Auto
InternalThink, ActivateSkillβœ… Autoβœ… Auto
Safe writesWrite, Edit, Delete, MemoryWrite, TodoWriteβœ… Auto⏸ Prompt
Agent callsInvokeAgentβœ… Auto⏸ Prompt
User interactionAskUser⏸ Prompt⏸ Prompt
Destructive shellrm -rf, sudo, git push --force, …⏸ Prompt⏸ Prompt

ACP server (editor integration)

Koda implements the Agent Client Protocol over stdio JSON-RPC 2.0. This lets editors connect to Koda as a local agent without network setup.

# Start the server (editors launch this automatically)
koda server --stdio

Protocol lifecycle

Editor β†’ initialize           (negotiate protocol version)
Koda   ← InitializeResponse

Editor β†’ session/new          (create a session)
Koda   ← NewSessionResponse   (returns session_id)

Editor β†’ session/prompt       (send a user message)
Koda   ← [stream of session/update events]
Koda   ← PromptResponse       (turn complete)

Editor β†’ Cancel               (optional β€” aborts the running turn)

Each line on stdin/stdout is a complete, self-contained JSON-RPC object.

Editor setup

For VS Code, Zed, and other editors, see your editor’s extension docs for how to configure a local ACP agent. The command to register is:

koda server --stdio

No ports, no tokens, no network configuration required.

Privacy & data

Koda has zero telemetry. No usage data, crash reports, or analytics are collected or transmitted anywhere.

What stays local

  • Conversations are stored only in your local SQLite database
  • API keys are stored locally in the same database (file mode 0600)
  • The only network traffic is your LLM API calls to the provider you chose
  • Version checks query crates.io only (no Koda-specific server)
  • You can audit every byte sent to the model by reading the DB directly

Database location

~/.config/koda/db/koda.db

The database is a standard SQLite file. You can inspect it with any SQLite browser or the sqlite3 CLI.

Deleting your data

# Delete all sessions
rm ~/.config/koda/db/koda.db

# Or selectively from the TUI
/sessions delete <id>

There is no cloud backup. Deleted data is gone.