C CORTANADocumentation › Guides

Using the CLI

The cortana command is a local coding and personal assistant. Its commands and keys follow Claude Code and the Codex CLI, and it works with Ollama, Docker Model Runner, or llama.cpp.

Launching

cortana                         # full-screen TUI; the current directory is the workspace
cortana --plain                 # line REPL (automatic when stdin/stdout isn't a terminal)
cortana --model qwen3:8b        # a different model for this session
cortana --add-dir ~/notes       # let tools also use another folder
cortana --listen                # start in hands-free voice mode

Without the symlink, run scripts/cortana from the repository or uv run python main.py. Every option is listed under Command-line flags.

MCP servers, the knowledge graph and other slow services connect in the background after the UI opens, so you can start typing straight away. /doctor checks the configured model server and reports model capabilities.

The terminal UI

The TUI is a scrolling transcript with • replies and tool calls, a Working (12s • esc to interrupt) status line and a › composer. Tool calls show what they do: a red/green diff with line numbers for edits, the start of a new file, the command for shell calls. When they finish, a one-line summary replaces the raw output, such as "Read 120 lines", "Updated app.py · +3 −1" or "Found 14 matches".

KeyAction
EnterSend. Prompts typed while a turn runs are queued.
↑ / ↓Recall earlier prompts, or move through the / command popup
/ then TabComplete a slash command
EscInterrupt the running turn (or stop a spoken reply)
Shift+TabCycle permission mode: auto → plan → ask
← on an empty promptLive view of subagents and background tasks
Ctrl+TFull transcript: complete tool output and reasoning
Ctrl+RToggle hands-free voice mode
Ctrl+C / Ctrl+DQuit

Set OLLAMA_CONTEXT_WINDOW to your server's context size to see context-used percentages. At 90% the conversation is summarized automatically and the turn continues; see Context compaction.

Permission modes

The mode decides which tool calls need your approval. Switch with Shift+Tab or /permissions auto|plan|ask, and set the default with agent.permission_mode.

ModeBehavior
autoTools run freely, except the always-ask calls below.
planRead-only. Edits, commands, downloads, browser clicks and generation are refused. The agent investigates and writes a plan for you to review.
askEvery tool that changes something (writes, commands, non-read-only MCP tools, browser actions) asks first.

In every mode, the CLI asks before a destructive or outward-facing shell command (rm, sudo, git push, git reset --hard, curl … | sh, DROP TABLE, …) and before creating or running a tool the model wrote. Answering always approves only that exact command or tool for the rest of the session. Turn this off with agent.confirm_destructive: false.

Plan, review, then build

  1. Switch to plan and describe the change. The agent reads and searches, writes a plan with update_plan and summarizes it, leaving the steps open.
  2. Read it with /plan (or open the Markdown file under .cortana/plans/), edit it if you like, and ask for changes until it's right.
  3. Switch back to auto and say "go ahead". The agent carries the saved plan out step by step, and a turn can't end with steps left undone.

See Planning & verification for how plans and the verifier work.

Slash commands

Read-only commands (/status, /context, /usage, /diff, /plan, …) run immediately, even while a turn is in progress. Others queue behind it.

Session and model

CommandAction
/helpCommands and keyboard shortcuts
/statusModel, context window, token usage, MCP and session status
/model [name]List installed models, or switch
/config [key value]Show settings, or change reasoning and UI preferences (thinking on|off|auto, reasoning low|medium|high|…, show-thinking, recaps, tips, recap-after <seconds>)
/doctorCheck the configured model server, tool support, and context size
/permissions [auto|plan|ask]Show or change the permission mode (also /approvals)
/exit, /quitQuit

Conversations and context

CommandAction
/clear (/new)Start a new conversation; the old one stays in /resume
/resume [id]List saved conversations, or resume one (also /threads)
/forgetPermanently delete the current conversation
/compact [focus]Summarize the conversation to free context. With memory, continue in a new thread seeded with the summary.
/contextWhat is filling the context window
/usage (/cost)Session token totals
/plan [clear]Show this conversation's saved plan, or delete it
/memoryShow working memory
/reindexRebuild semantic-recall vectors from saved history
/export [file]Save the conversation as Markdown in the workspace

Working on code

CommandAction
/initHave the agent create or improve AGENTS.md
/review [focus]Have the agent review uncommitted changes (read-only)
/diffShow uncommitted changes, including new files
/mention <path>Attach a workspace file to your next message
/add-dir [path]Let tools read and write another folder this session

Tools, agents and media

CommandAction
/toolsCore tools and on-demand tool groups
/skills [query]List or search skills
/agentsSubagent profiles and this session's subagents
/tasks [cancel <id>]Running and recent background tasks, or cancel one
/mcpMCP servers, their status and tools
/voice [on|off]Listen continuously and speak replies (also Ctrl+R)
/image <prompt>Generate an image without going through the model (also /imagine)
/image edit <change>Edit the last image; each edit becomes the new last image
/image qwen|ollamaSwitch image provider; /image alone shows status

Learning

CommandAction
/good, /badRate the last answer, so its recipe is reused or dropped
/learned [delete <id>]List learned recipes and stats, or delete one
/teach …Record a task you demonstrate and turn it into a skill (below)

Shell & teach mode

Start a line with ! to run a shell command in the workspace yourself. The output is shown and sent along with your next message, so you can say "fix this" after a failing test run:

› !python -m unittest tests.test_calc
› the divide test fails, fix it

Teach mode turns a task you do yourself into a reusable skill:

› /teach release-notes write release notes from git
› !git log --oneline v1.2..HEAD
› /teach note fixes go before features
  … edit files in your editor …
› /teach stop          # shows the drafted SKILL.md
› /teach save          # keeps it under skills/learned/ (or /teach discard)

Only ! commands and file changes inside the workspace are recorded; nothing watches in the background. /teach cancel stops without drafting.

Command-line flags

FlagEffect
--model NAMEOverride OLLAMA_MODEL
--config PATHYAML settings file (default CORTANA_CONFIG or ./cortana.yml)
--workspace PATHWorkspace for tools, skills, personality and outputs (default: current directory)
--add-dir DIRAlso let tools use DIR (repeatable)
--plainLine REPL instead of the TUI
--no-streamWait for each complete model response
--think / --no-thinkEnable or disable model reasoning
--quietHide progress and metrics
--memory none|local|qdrantMemory provider (default MEMORY_PROVIDER)
--resource-id IDIdentity that scopes long-term memory (default local-user)
--thread-id IDConversation identity (default default)
--listenStart in hands-free voice mode
--tts local|httpSpeak with local weights or the voice.http server
--no-audio, --no-images, --no-videosLeave out voice, image generation or video generation
--browser / --no-browserLet the assistant drive a real browser
--heartbeat / --no-heartbeatSelf-started check-ins
--experience / --no-experienceLearn recipes from finished tasks

scripts/cortana adds two launcher flags: --kokoro-tts (default environment, Kokoro active) and --qwen-tts (the .venv-qwen environment, Qwen active). Everything else is passed on to main.py.

Managing MCP servers

Add Model Context Protocol servers the same way as claude mcp or codex mcp. Servers connect the next time Cortana starts.

# stdio: everything after -- is the command line
cortana mcp add playwright -- npx -y @playwright/mcp@latest
cortana mcp add -e API_KEY='${MY_KEY}' myserver -- uvx my-mcp-server

# remote (Streamable HTTP by default; --transport sse for legacy servers)
cortana mcp add --transport http postman https://mcp.postman.com/minimal \
    --header 'Authorization: Bearer ${POSTMAN_API_KEY}'

cortana mcp list            # connects to each server and reports ✓/✗
cortana mcp get postman
cortana mcp remove postman

Put single quotes around ${VAR} so your shell doesn't expand it; the config then stores the reference, not the secret. Other options: --scope project|user, --description, --always-loaded and --force. See MCP servers for the config files and per-server options.