A terminal-based AI agent. Supports Anthropic, OpenAI-compatible, and GLM providers. Runs on Linux, macOS, and Windows.
curl -fsSL https://raw.githubusercontent.com/Coremail/cmagent/main/install.sh | shInstalls to ~/.local/bin/cmagent. If that directory is not in your PATH, the
installer will tell you what to add to your shell profile.
Run in PowerShell:
irm https://raw.githubusercontent.com/Coremail/cmagent/main/install.ps1 | iexInstalls to %LOCALAPPDATA%\cmagent\cmagent.exe and adds it to your user PATH.
Download the binary for your platform directly from the Releases page, extract the archive, and place the binary somewhere on your PATH.
| Platform | File |
|---|---|
| Linux x86_64 | cmagent-linux-x86_64.tar.gz |
| macOS aarch64 | cmagent-macos-aarch64.tar.gz |
| Windows x86_64 | cmagent-windows-x86_64.zip |
Each archive contains a single binary (cmagent or cmagent.exe) and a
.sha256 checksum file.
# First time only: configure a provider (e.g. Anthropic)
cmagent init
# Most common: launch the full-screen TUI
cmagent tui
# Run without args to get a menu (TUI / line chat / gateway / config / status)
cmagent
# One-shot: send a single message and exit (non-interactive)
cmagent -m "Explain this codebase"
# Pick an agent profile (default reads from ~/.cmagent/config.toml)
cmagent tui --agent codingcmagent updateChecks GitHub for a newer release, downloads the correct binary for your
platform, verifies the checksum, and replaces the running executable in place.
Add --yes to skip the confirmation prompt.
Config lives in ~/.cmagent/. Run cmagent init to set up providers and
preferences interactively, or cmagent config to edit settings at any time.
Provider credentials are stored as environment variables. For Anthropic:
export ANTHROPIC_API_KEY="sk-ant-..."If you already use the OpenAI Codex CLI,
cmagent config provider -> Import from Codex CLI re-uses the credentials
already in ~/.codex/auth.json (both API-key and ChatGPT-account OAuth
flows are supported). See docs/codex-import.md.
See cmagent doctor to verify your setup.
With no arguments, opens a menu picker (TUI / Chat / Gateway / Config / Status / Doctor). Useful when you want to switch interaction modes without remembering the subcommand. On first launch this also triggers the setup wizard.
The primary interactive mode. Renders a scrollable chat pane, live tool/thinking tree, status bar, and rich input with paste folding, slash commands, and per-turn editing. This is the mode most users want day-to-day.
cmagent tui # default workspace + agent
cmagent tui --agent coding # pick an agent
cmagent tui -c # continue the most recent session
cmagent tui --session <id> # resume a specific session
cmagent tui --remote http://host:3100 --token <tk> # connect to a remote gatewaycmagent ships two interactive front-ends. Both speak to the same
agent, share /slash commands, sessions, and config; they differ
only in how they paint the screen.
| Variant | What it is | When to pick it |
|---|---|---|
canvas (default) |
ratatui-based, multi-pane (transcript / sidebar / input). Mouse selection, in-place permission modals, live activity tree, sidebar showing tokens / context / git branch / MCP / plan / todos / goal / agent activity. | Local terminal, fast tty. Best at-a-glance signal density. |
streaming |
Print-based, prints into the terminal's native scrollback. No alt-screen takeover; selection works via the terminal's normal copy/paste. | High-latency SSH, very wide remote sessions, recording demos with script(1), terminals that mangle alt-screen. |
Selection priority:
- CLI flags
--canvas/--streaming— force the named variant for this session. Mutually exclusive. - Config
[general] default_tui—"canvas"(default) or"streaming". - Built-in fallback —
"canvas".
Change the default via cmagent config → Defaults → Default TUI,
or edit ~/.cmagent/config.toml directly:
[general]
default_tui = "streaming"cmagent (no args) and cmagent tui (no flag) both honour the
config. cmagent tui --canvas or cmagent tui --streaming
override it for one session.
Plain stdin/stdout REPL with no fullscreen takeover. Useful inside
restricted terminals, log scrapers, or when piping output. No mouse, no
panels — just > prompt + response.
cmagent chat --agent coding
cmagent chat -cNon-interactive one-shot: send the message, print the agent's reply, exit with a non-zero code on tool/policy errors. Ideal for scripts, cron, and CI hooks.
cmagent -m "Summarize CHANGELOG.md" --agent docs
echo "review this diff" | cmagent -m "$(cat -)"Local HTTP server (default port 3100) exposing REST + WebSocket so other tools, scripts, or web frontends can drive the agent.
cmagent gateway --port 3100
cmagent tui --remote http://host:3100 --token <token> # remote TUI clientUser accounts and bearer tokens are managed with cmagent gateway user add.
Stdio-based JSON-RPC 2.0 server speaking the Agent Client Protocol. Use this to embed cmagent as a subprocess inside another application or IDE extension.
cmagent acp --agent codingRuns a long task as a series of short, independent iterations. Each
iteration spawns a fresh agent session that reads the workspace, takes
one small step, updates STATUS.md, and exits. The loop continues until
the agent writes a done sentinel or max_iter is reached.
Use it for tasks too large for a single conversation — bulk refactors, language ports, multi-step migrations.
cmagent ralph new "Port http client from reqwest to ureq"
# (edit ~/.cmagent/ralph/<id>/prompt.md)
cmagent ralph run <id>
cmagent ralph status <id> | tailcmagent init # first-time setup wizard
cmagent config # interactive config editor
cmagent doctor # diagnostics (providers, sandbox, skill deps, ...)
cmagent workspace # browse / delete / rename saved sessions
cmagent skill <cmd> # list / install / setup / enable / disable skills
cmagent brain <cmd> # inspect long-term memory
cmagent mcp <cmd> # manage MCP servers
cmagent update # update the binary in placeInside a session (TUI or chat) the agent keeps three kinds of
progress state. All three persist per session — they survive process
restart and /switch, and are stored in the session's SQLite DB. In
the canvas TUI each one renders as a status-bar chip (when the sidebar
is hidden) or a sidebar panel (when it's open, toggle with Ctrl+B).
A short roadmap (typically 3–8 coarse steps) the agent commits to at
the start of a multi-step task. The agent drives it as a side effect of
working (via its update_plan tool); each step is pending,
in progress, done, or skipped. This is not a control loop —
it just shows you what the agent intends to do and where it is.
/plan # show the current plan (or note none is active)
/plan clear # drop the active plan
/plan run [N] # re-enter the agent to work the next pending step,
# repeating until the plan is complete or N
# iterations elapse (default 10, max 50). Ctrl+C
# cancels mid-loop.
Completion is structural: the plan is done when no step is pending or in progress.
An unbounded, granular checklist for the small tasks within a logical
work batch (the agent adds and completes items via its todo tool).
Each item is simply done or not done. The sidebar shows pending items
with a count.
/todos # show the list (also /todo)
/todos clear # wipe all todos
Set a goal and the agent runs toward it on its own. After each turn a
judge LLM reads the recent transcript and decides whether the goal's
success criteria are visibly met; if not, its feedback is injected and
the agent takes another turn. Unlike /plan, this does recurse
automatically — it stops when the judge confirms completion or after a
turn cap (50 by default).
/goal <text> # e.g. /goal ship v0.3.0 with green tests
/goal # show the current goal and how many turns it has run
/goal clear # cancel the active goal
Per-agent [goal] config (in the agent's config.toml) can route the
judge to a separate cheaper model (judge_provider / judge_model)
and override the iteration cap (max_iterations).
- No runtime dependencies — single static binary.
- Browser tools (
browser_query,browser_act,browser_eval) require a Chromium-family browser on the host. See below.
The three browser tools drive any CDP-speaking browser. cmagent detects
Chrome, Chromium, Microsoft Edge, Brave, Vivaldi, and Opera on PATH and
launches a headless instance automatically (launch mode, default).
Run cmagent doctor to see whether the tools are currently enabled.
If you want cmagent to attach to a browser you already have open —
typical case: Windows + Edge — switch to connect mode:
- Start the browser with the debug port:
msedge.exe --remote-debugging-port=9222 # Windows / Edge google-chrome --remote-debugging-port=9222 # Linux / Chrome
- Fetch the WebSocket URL:
Copy the
curl http://127.0.0.1:9222/json/version
webSocketDebuggerUrlfield from the response. - Run
cmagent config→ Browser Tool Configuration → setmode = "connect"and paste the URL intoconnect_url. - Restart cmagent.
cmagent doctorshould reportBrowser tools: ENABLED.
Only loopback URLs (127.0.0.1, [::1], localhost) are accepted in
connect_url. Remote CDP endpoints are rejected at config time.
cmagent splits state between a global install directory (one per user, holds all config, credentials, long-term memory, logs) and a workspace directory (one per project, holds per-project sessions, brain, scratch files).
Root is ~/.cmagent/ on Linux/macOS, %USERPROFILE%\.cmagent\ on
Windows. Override with the CMAGENT_HOME environment variable.
~/.cmagent/
├── config.toml # [general] defaults, [security], [browser], ...
├── providers/ # one .toml per provider (anthropic, glm, openai-compat, ...)
│ └── claude-default.toml
├── agents/ # agent profiles
│ └── <name>/
│ ├── config.toml # profile (presets, tools, prompt_threshold, ...)
│ ├── AGENT.md # the agent's system-prompt body
│ └── brain.db # (optional) agent-private long-term memory
├── presets/ # shared agent baselines (sys-default, ...)
├── skills/ # installed skills (one dir per skill)
├── channels/ # channel adapter configs (lunkr, telegram, slack, ...)
├── mcp/
│ └── servers.toml # MCP server registry
├── plugins/ # installed Claude Code plugin bundles
├── adapters/ # legacy adapter shims
├── cron/ # cron-schedule TOMLs
├── ralph/<task-id>/ # Ralph loop task state (prompt.md, STATUS.md, iter logs)
├── sessions/<id>/ # global (non-workspace) session JSON
├── data/
│ ├── brain.db # global long-term memory (SQLite + FTS5)
│ ├── audit.db # channel inbound audit log (when enabled)
│ ├── ralph.db # Ralph task index
│ └── logs/
│ ├── cmagent.log.YYYY-MM-DD # daily rolling app log
│ └── panics.log # panic backtraces (TUI mode)
├── workspaces.toml # registry of known project workspaces
├── remotes.toml # saved `--remote` gateway URLs + tokens
├── gateway.toml # gateway server config
├── gateway.pid # gateway process PID (when running)
├── stt.toml / tts.toml / vision.toml # media backend configs
└── .env # provider credentials (ANTHROPIC_API_KEY, ...)
Logs: text logs land in ~/.cmagent/data/logs/cmagent.log.YYYY-MM-DD
(daily rotation, kept indefinitely — clean up by hand). Console only
shows WARN+. Run with --debug to bump the file level to DEBUG; set
RUST_LOG=cmagent_core=trace for finer per-module control.
Credentials: never commit .env. The installer / cmagent init
sets the right permissions; if you copy this directory between
machines, copy .env separately and out-of-band.
Created lazily the first time you launch cmagent inside a directory. Everything here is scoped to that one project.
<project>/.cmagent/
├── workspace.toml # workspace defaults (temp_provider / temp_model overrides,
│ # known sessions, display preferences like show_activity)
├── brain.db # workspace-scoped long-term memory
├── sessions/
│ ├── <uuid>.db # one SQLite DB per session (transcript + tool calls)
│ └── telegram-<chat>.db # channel-bound sessions use a stable id, not UUID
├── tmp/ # agent scratch space (file_write to relative paths, etc.)
├── tool-output/ # overflow storage for large tool outputs the chat
│ # transcript truncated (referenced via file://...)
├── screenshots/ # `screenshot` tool drops PNGs here
├── dl/ # channel adapters store downloaded attachments here
└── skills/ # workspace-local skill overlays (optional)
The tmp/ directory is the agent's safe scratch area. The sandbox's
default policy whitelists writes inside the workspace; paths outside
(/tmp/..., ~/Documents/...) get rejected.
Add .cmagent/ to your project's .gitignore unless you want sessions
and brain DBs in version control.
MIT