A role-based terminal agent harness. Seven built-in personas — senior developer, analyst, reviewer, planner, researcher, assistant, and a coding agent with sub-agents — shared core tools, different judgment. Runs on any OpenAI-compatible model, including the one on your own hardware.
A cast, not a coder. Seven built-in personas change the agent's role while keeping the normal tool surface familiar. Senior developer for root-cause fixes, reviewer for functional checks, analyst for product and project decisions, planner for execution plans, and researcher for source-backed investigations — same core tools, different judgment. coder-with-subagents additionally enables delegation; custom personas can narrow capabilities. Add your own with a markdown file or build one through chat.
Real tools, real work. It reads files, writes code, runs shell commands, searches your codebase — and does it all in parallel. Delegates sub-tasks to isolated sub-agents. Rules, skills, and MCP servers extend capabilities without touching the codebase.
Runs where your code runs. vLLM, Ollama, your own inference server, or any OpenAI-compatible API. No account, no telemetry, no cloud dependency.
Ink TUI. A proper terminal interface with multiline paste, image attachments, smooth animations.
Web UI. cast web (also available as cast server) launches a browser-based control room — background agents, token-by-token streaming, diff viewer, and chat commands with account/project controls in Settings. Same sessions as the TUI.
Point a generic coding agent and a role-specific one at the same file, and they look for different things. An analyst persona surfaces gaps and acceptance criteria; a qa persona treats an untested edge case as unfinished work. A pm persona turns settled decisions into milestones and tasks, while a researcher checks claims against sources.
Personas are role prompts first: they steer what the agent investigates, prioritizes, and treats as done. Each persona is defined by markdown frontmatter (~/.cast/personas/*.md or .cast/personas/*.md) that can also constrain available built-in tools (tools), skills (skills), MCP servers (mcp), and sub-agent delegation (subagents, subagentTypes). Those capability limits are enforced at runtime, not merely described in the prompt.
Capability scoping is opt-in. The shipped personas deliberately retain the common tool, skill, and MCP surface so changing a role does not unexpectedly remove a workflow; only coder-with-subagents exposes delegation. Define allowlists on a custom persona when least privilege or a smaller prompt surface matters — for example, a documentation-only role that cannot call shell or database tools. This reduces instruction clutter and prevents accidental or misrouted invocations; it is not an automatic property of every role.
For empirical research on role prompting and tool-agent behavior, see docs/persona-research.md.
macOS / Linux:
curl -fsSL https://aa-blinov.github.io/cast/install | bashWindows (PowerShell):
irm https://aa-blinov.github.io/cast/install.ps1 | iexRequires Node.js 22+. Self-contained bundle — no npm packages needed at runtime.
Pin a version: CAST_VERSION=0.1.0 curl ... | bash
Upgrade later: cast upgrade
# Launch — prompts for provider URL + API key on first run, remembers after
cast
# One-shot prompt
cast "explain what this project does"
# Specific model + reasoning
cast -m qwen/qwen3-235b-a22b -r high "refactor this function"
# Resume last session
cast -cbash read write edit glob grep ls task ssh web_search web_fetch — the agent has full filesystem, shell, SSH remote, and web access. Multiple tools run in parallel. The task tool delegates work to isolated sub-agents (with their own persona and context) and returns only the final result. Image files (jpg/png/gif/webp) are sent directly to vision-capable models. Web tools are off by default — toggle with /web (persists to settings).
Project-specific instructions in .cast/rules/*.md — Cursor-compatible format with four modes: always (injected every turn), auto (attached when matching files enter context), lazy (model reads on demand), and manual (via @mention or /rule:name). Nested .cast/rules/ directories in subdirectories scope rules to that subtree.
Drop an AGENTS.md or CLAUDE.md in your repo root — cast picks it up automatically and injects it into the system prompt. Walks every ancestor directory up to /, so org-wide guidelines in a parent folder apply to all projects beneath it. The file in cwd itself is trust-gated; files above load without prompting. No special syntax, no config — just the file.
Self-contained instruction packages loaded on demand from ~/.cast/skills/ / .cast/skills/, plus skills.sh universal paths (.agents/skills/, ~/.agents/skills/, and the compatible ~/.config/agents/skills/). Follows the Agent Skills spec. The agent sees what's available and loads the right one automatically.
Connect any Model Context Protocol server — local (stdio) or remote (streamable HTTP). Uses the common mcpServers JSON config shape. Their tools appear alongside the built-in ones.
Swap the agent's role — and optionally which built-in tools that role may use:
| Persona | What it does |
|---|---|
senior (default) |
Lazy senior dev — root-cause fixes, deletion over addition |
coder-with-subagents |
Delegates work to sub-agents via the task tool for parallel exploration |
analyst |
Product, analytical, and project work — hypotheses, decisions, requirements, priorities, and plans |
pm |
Turns settled decisions into clear project plans, milestones, dependencies, and actionable tasks |
qa |
Functional review — requirements, regressions, scenarios, and actionable findings |
researcher |
Source-backed investigations with searches, cross-checks, and citations |
assistant |
Everyday help, planning, writing, and quick lookups; uses tools when needed |
Add your own in ~/.cast/personas/ (global) or .cast/personas/ (project), or ask the agent in chat to create/customize one. The constructor can configure behavior, built-in tools, skills, MCP servers, sub-agents, and agentsMd. It shows the proposed change before writing. If you customize the active persona, the current turn stays unchanged and the override applies automatically on the next message; /reload is not required.
Plan mode is user-owned: /plan switches the agent to read-only exploration, and /build returns to implementation. The agent writes execution-spec plans with - [ ] checklists to <project>/.cast/plans/<session-id>/. Once it calls plan_done, choose to keep refining, implement in the current context, or implement in a clean model context while retaining the visible thread. An approved plan is re-read into build-mode context across compaction and restarts; its checklist is projected into the task list. Each phase can run its own model — see /plan-model.
When the conversation gets too long, the agent automatically summarizes older messages — keeps the context window useful without losing important details.
Reasoning controls combine provider model metadata with the configured provider dialect. Supported providers expose either off/on or effort levels such as low/medium/high; configure them with --reasoning, /reasoning, and /reasoning-format when an endpoint needs an explicit protocol.
Every conversation auto-saves. Resume with --continue, pick from a list with --resume, or switch mid-session with /sessions.
cast web launches a browser-based control room — same sessions as the TUI, with a diff viewer, background agents, and token-by-token streaming. The file reader previews text and code with wrapped lines and source-line numbers; Markdown, tables, images, and PDFs keep their document-specific previews. The TUI is still the default for local interactive use; the Web UI is the answer when you want to share a session, keep one running in the background, or drive cast from a browser/phone. cast server is an equivalent command for daemon-oriented scripts and integrations.
# Start (default 127.0.0.1:1337)
cast web
# Start on a different port
cast web --port 8080
# Bind 0.0.0.0 so it's reachable from other machines on the network
cast web --public
# Lifecycle
cast web status
cast web stopFor local development, run the browser UI in the foreground with npm run dev:web. Pass server options after --, for example npm run dev:web -- --port 8080.
On first start, cast auto-generates a password and saves it to serverToken in ~/.cast/settings.json. The login is always cast. Cast serves its own themed sign-in screen and keeps the resulting session in an HttpOnly, SameSite cookie; API responses are never cached. The password is shown in the terminal on first run so you can copy it; after that, look it up in ~/.cast/settings.json.
The --public flag exposes plain HTTP. It is suitable only for a trusted LAN; it cannot protect the password or session from a network observer. For remote access without a domain or HTTPS, keep Cast on its default loopback address and use an SSH tunnel: ssh -L 1337:127.0.0.1:1337 user@host. Do not expose it directly on a public address.
The daemon records its bound address, a local-only TUI token, and a per-process identity in ~/.cast/server.json. A TUI on the same machine connects to 127.0.0.1 even when the daemon uses --public; the token is accepted only from a loopback socket. Idle sessions without an attached client are released from daemon memory after five minutes and are lazily reloaded from the session store when opened again.
cast upgrade verifies the daemon identity before restarting it and preserves its host and port. A foreground daemon is left running: restart that one manually after the upgrade, so its terminal-owned work is never interrupted automatically.
Env vars: CAST_SERVER_PORT (default 1337), CAST_SERVER_HOST (default 127.0.0.1).
| Command | Description |
|---|---|
| Any text | Send a prompt to the agent |
/model [name] |
Show/change model |
/subagent-model [name] |
Show/change sub-agent model |
/plan-model [name|off] |
Show/change the plan-mode model |
/plan-model-provider [name|off] |
Set the provider for the plan-mode model |
/plan |
Enter plan mode (explore + plan only) |
/build |
Exit plan mode, restore full toolset |
/reasoning |
Change reasoning level |
/reasoning-format |
Select the provider reasoning protocol |
/persona [name] |
Show/change persona |
/provider |
Change provider endpoint and API key |
/permissions [default|bypass] |
Show/change bash confirmation mode |
/web |
Toggle web tools (web_search, web_fetch) |
/web-fetch-provider |
Select Jina Reader or direct local fetch |
/sessions |
List/switch/delete saved sessions |
/fork |
Branch the current safe context into a new session |
/skills |
List loaded skills |
/skill:name [args] |
Force-load and run a skill |
/mcp |
Toggle MCP servers on/off |
/plugin |
Install, enable, disable, and remove marketplace plugins |
/hooks |
List and enable/disable lifecycle hooks |
/reload |
Re-scan skills, rules, MCP, and personas for cwd |
/rules |
List loaded rules |
/rule:name |
Invoke a rule by name |
/steer <msg> |
Inject message while agent is working |
/s <msg> |
Alias for /steer |
/queue <msg> |
Queue message for after agent stops |
/q <msg> |
Alias for /queue |
/queue-reset |
Clear the message queue |
/qr |
Alias for /queue-reset |
/abort, /stop |
Stop current agent run |
/compact |
Force context compaction |
/new |
Start a new session (autosaves current) |
/copy |
Copy last assistant response to clipboard |
/current |
Show all status bar data |
/clear |
Clear conversation context |
/ssh |
Manage SSH hosts (list, add, remove) |
/statusbar |
Toggle and reorder status bar segments |
/theme |
Change color theme |
/usage |
Show session token/cost usage |
/repo |
Show cwd and git branch |
/quit, /exit |
Save and exit |
/keys |
List all keybindings |
/help |
Show this command list |
cast [options] [prompt]
cast run [options] <message> Non-interactive mode (stream to stdout, exit)
cast run --interactive Persistent JSONL session for programmatic clients
cast upgrade [version] [--force]
Re-run installer to update
Options:
-m, --model <model> Model name
-r, --reasoning <level> off / low / medium / high / max
-p, --persona <name> Persona to use
-c, --continue Resume most recent session
--resume Pick which session to resume (numbered list)
--resume=<id> Resume specific session by id
-s, --session <id> Resume specific session (alias for --resume=<id>)
--bypass-permissions Skip dangerous-command confirmation
--skill <path> Load extra skill (repeatable)
--no-skills Skip project/agents/global/plugin/builtin skill discovery
--mcp <path> Load extra MCP config (repeatable)
--no-mcp Skip global/project MCP server discovery
-v, --version Show version
-h, --help Show help
run subcommand:
--format <default|json> Output format
--interactive Persistent JSONL session protocol
(also accepts: -m, -r, -p, -c, -s, --bypass-permissions, --skill, --mcp)
On first run, cast asks for your provider URL and API key, then saves both to ~/.cast/settings.json. No .env file needed.
Other environment variables (provider credentials live in the settings file, not env):
| Variable | Description |
|---|---|
CAST_CWD |
Override working directory |
CAST_BASH |
Bash executable for the bash tool (Windows: non-standard Git Bash / msys2) |
CAST_VERSION |
Pin install version (installer) |
CAST_SERVER_PORT |
Server daemon port (default 1337) |
CAST_SERVER_HOST |
Server daemon bind address (default 127.0.0.1; use 0.0.0.0 or --public for LAN) |
CAST_SESSIONS_DB |
Override SQLite session database path |
Works with anything that speaks the OpenAI API: OpenRouter, OpenAI, Ollama (http://localhost:11434/v1), vLLM, LiteLLM, Azure OpenAI, etc.
src/
core/ Agent logic (no UI dependency)
loop.ts Agent loop — streaming, tool dispatch, compaction
tools.ts Tool definitions (OpenAI function calling format)
tools/ Tool executors: bash, files, search, web, task
llm.ts LLM interaction, streaming, retry, prompt caching
session.ts Session persistence, token estimation, compaction
mcp.ts MCP server connection (stdio + streamable HTTP)
personas.ts Persona loading (project > global > builtin)
rules.ts Cursor-compatible rule system (always/auto/lazy/manual, nested rules, @mentions)
skills.ts Agent Skills spec implementation
config.ts AppConfig, model validation, onboarding
project.ts System prompt assembly, trust gating
startup.ts Unified startup orchestration
runner.ts Queue management (steering, follow-ups)
run.ts Non-interactive runner (cast run)
vendors.ts Reasoning metadata, think-block parsing
upgrade.ts Self-update via GitHub releases
...
ui/ Ink TUI components
App.tsx Top-level layout
Composer.tsx Input with autocomplete, image paste
ChatLog.tsx Message rendering
commands.ts Slash command handlers
...
pickers/ Onboarding pickers (model, persona, reasoning)
index.ts CLI entry point
prompts/ System prompts, persona files, compaction templates
test/ Vitest unit tests
scripts/ esbuild bundle step
dist/ Compiled single-file bundle
npm install --ignore-scripts
npm start # Run from source (tsx)
npm run check # Type check + lint (tsc + biome)
npm test # Unit tests (vitest)
npm run build # Bundle into dist/index.js (esbuild)
npm run format # Auto-format (biome)
npm run e2e:plan # Plan-mode e2e smoke via tmux (real provider, costs tokens)