roam-code is the local CLI that runs pre-change gates before every agent edit
and compiles tamper-evident, content-hashed evidence packets after every change.
Local analysis, no API keys, and no automatic source-code or telemetry upload.
A cold parser cache retrieves one checksum-verified grammar bundle; prewarm it
before air-gap use. Explicit network features are inventoried in
docs/network-boundary.md.
281 commands, 244 MCP tools, 28 languages, local analysis, zero API keys.
CLAUDE.md— codebase/agent rules: quality discipline, 12 behavioral laws, adding commands, schema/test discipline. Read first when modifying roam-code itself.AGENTS.md— sister file to this one for tools using the AGENTS.md convention.README.md— human-facing overview, install matrix, headline counts.- Live docs: https://roam-code.com/docs/getting-started, https://roam-code.com/docs/command-reference, https://roam-code.com/docs/architecture.
pip install "roam-code[mcp]" # CLI + FastMCP server (recommended for agents)
pip install roam-code # CLI only
pipx install "roam-code[mcp]" # isolated env
uv tool install "roam-code[mcp]"Requirements: Python 3.10+. No native deps. Linux / macOS / Windows.
cd /path/to/your/project
roam init # index + fitness rules (creates .roam/; CI is opt-in)
roam health # 0-100 sanity check
roam understand # one-screen tour of the codebaseroam init creates .roam/index.db (the codebase graph), .roam/fitness.yaml
(architectural rules). Add --with-ci=github to create
.github/workflows/roam.yml, or run
roam ci-setup --platform github --write later.
roam mcp-setup <platform> is the canonical onramp — it prints (or writes
with --write) the exact config block for your tool. Supported platforms:
claude-code, codex-cli, cursor, gemini-cli, vscode, windsurf.
roam mcp-setup claude-code # Claude Code CLI
roam mcp-setup cursor --write # Cursor IDE; writes the file in place
roam mcp-setup vscode --preset full # VS Code Copilot Agent Mode
roam --json mcp-setup codex-cli # structured envelopePresets (env var ROAM_MCP_PRESET): core, review, refactor, debug,
architecture, compliance, compile-curated, full. core is the narrow
default; use roam_expand_toolset to inspect the live contents of any preset.
Fallback manual config (any MCP client that accepts a JSON command block):
{
"mcpServers": {
"roam-code": {
"command": "roam",
"args": ["mcp"],
"env": { "ROAM_MCP_PRESET": "core" }
}
}
}After setup, run roam doctor to verify the server is registered and reachable.
roam mode read_only # read-only analysis
roam mode safe_edit # edits + finding records allowed
roam mode migration # schema / data migrations allowed
roam mode autonomous_pr # stage + commit + open PRs allowedModes are cumulative: each tier adds capabilities to the previous one. The
MCP boundary enforces the active mode on every tool call (see "MCP runtime
security"); pick the lowest tier that lets the agent finish: read_only for
analytics / retrieval copilots, safe_edit for AI-assisted PR drafting,
migration for schema runs, autonomous_pr for hands-off agents. The
active mode rides on every McpDecisionReceipt for post-run audits.
1. roam runs start open run; sets ROAM_RUN_ID (HMAC-chained ledger)
2. roam mode safe_edit declare action surface
3. roam pr-bundle init start proof bundle
4. roam preflight <sym> gate before edit (auto-logs to active run)
5. roam impact <sym> blast radius (auto-logs)
6. <edit>
7. roam diff | roam critique review (auto-logs); exit 5 on high severity
7a. roam findings list cross-detector findings on the workspace
8. roam pr-bundle emit close bundle with proofs
9. roam runs end --with-pr-bundle-emit
10. roam replay <id> narrate the run
11. roam agent-score score the agent on 0..100 composite
In CI, --ci (or ROAM_CI=1) on pr-bundle emit/validate implies both
--strict and --strict-resolved — gates on structural completeness AND on
the absence of unresolved blast-radius symbols.
Repo-local state, zero network:
.roam/constitution.yml— unified laws + rules + memory + gates..roam/runs/— per-run HMAC-chained event ledger (roam runs verify)..roam/leases/— multi-agent claims (roam lease claim/release/list)..roam/memory.jsonl— portable agent memory (roam memory ...)..roam/pr-bundles/— proof-carrying PR packets (roam pr-bundle ...)..roam/laws/— mined invariants (roam laws mine/check)..roam/index.db— SQLite codebase graph (symbols, edges, findings, git).
roam findings list / show / count queries a normalized cross-detector
registry persisted in the index DB. 28+ detectors emit findings today
(clones, dead, complexity, smells, n1, missing-index, over-fetch,
bus-factor, auth-gaps, vulns, invariants/laws, hotspots, taint, vibe-check,
orphan-imports, conventions, pr-risk, duplicates, audit-trail-conformance,
audit-trail-verify, boundary, test-hermeticity, plus consumer/aggregator
commands). Each row is confidence-tagged: static_analysis (deterministic
AST/CFG + taint/dataflow), structural (graph/edge patterns), heuristic
(name patterns, thresholds, statistical outliers), or runtime (requires
ingested traces).
Every change emits a portable ChangeEvidence packet (see
src/roam/evidence/) with schema_version, content hash, redaction
metadata, and links to the run ledger. From one packet roam projects SARIF,
in-toto/CGA attestations, OSCAL-ish control maps, OTel/GenAI traces,
CycloneDX/VEX, and Markdown reports. Every sensitive MCP tool call also
emits a McpDecisionReceipt (src/roam/evidence/mcp_receipt.py) — actor
id, tool id, input hash, policy decision, output hash, with redact-on-egress
for secrets, PII, and machine-local paths.
Roam maps to and supports evidence for compliance controls. It does not certify or make compliant.
Every sensitive MCP tool call passes through a wrapper layer that enforces
the active mode, scrubs secrets from the response payload before it reaches
the host LLM context, and emits a local McpDecisionReceipt. When a valid run
is active, the receipt is HMAC-anchored into that run's signed ledger; calls
without an active valid run remain explicitly unlinked.
- Egress redaction. Secret patterns are scrubbed at the wrapper layer
before responses return to the host. Lineage is stamped on the receipt
(
redactions[]carries reasons from a closed enum:secret,pii,sensitive_content,size_limit,policy,user_opt_in_required,machine_local_path,schema_strict,producer_not_available,prompt_injection_marker). - Policy enforcement. The 4 modes are enforced at the MCP boundary.
Each receipt records a
policy_decisionfrom the closed enumallow/deny/escalate/redact/not_evaluated/would_deny_dry_run. - Receipt integrity. Receipts under an active valid run are HMAC-linked to
ledger events; other receipts report the unlinked state explicitly.
verify_chain_with_receipts()returns areceipt_integrityvalue from the closed enumok/missing/tampered/not_linked.
The full pattern library (egress regex sources, gateway integration notes,
Interlock / Lasso / Portkey hooks) lives in dev/MCP-SECURITY-POSTURE.md.
Roll enforcement out without blocking traffic by setting
ROAM_MODE_DRY_RUN=1. The gate evaluates normally, the tool call still
proceeds, and the receipt records policy_decision: "would_deny_dry_run"
plus extra.shadow_mode = true and extra.would_deny_reason. Walk teams
through it:
- Set
ROAM_MODE_DRY_RUN=1in the MCP host environment. - Run the agent workload for a representative window.
- Query
roam findings list(or grep receipts under.roam/mcp_receipts/) forwould_deny_dry_rundecisions. - Tune mode / rules until the unexpected-deny count is zero.
- Unset
ROAM_MODE_DRY_RUNto switch to hard enforcement.
After a run completes, a host can verify the receipt chain end-to-end:
from pathlib import Path
from roam.runs.signing import verify_chain_with_receipts, ensure_ledger_key
from roam.runs.ledger import read_run_events
repo_root, run_id = Path.cwd(), "run_2026_05_19_abc123"
events = read_run_events(repo_root, run_id)
key = ensure_ledger_key(repo_root)
result = verify_chain_with_receipts(events, key, repo_root, run_id)
# result["receipt_integrity"] -> closed enum:
# "ok" every receipt-bearing event resolves to an on-disk receipt
# whose sha256 matches the chain-baked hash
# "missing" a receipt was deleted after signing
# "tampered" a receipt was edited after signing
# "not_linked" no sensitive tool fired a receipt this run (advisory)The McpDecisionReceipt dataclass lives at
src/roam/evidence/mcp_receipt.py. Gateways pin the receipt shape via the
JSON Schema Draft 2020-12 emitter:
python scripts/export_mcp_receipt_schema.py > mcp-receipt.schema.jsonClosed-enum vocabulary is pulled by reference at build time, so a vocabulary edit propagates without a schema re-roll.
| Command | Reports |
|---|---|
roam side-effects ensure_index |
io_read, io_write, mutation, process, or none |
roam idempotency ensure_index |
idempotent, non_idempotent, or unknown |
roam causal-graph ensure_index |
Param-to-sink dependency edges |
roam tx-boundaries |
Begin/commit/rollback regions and unsafe mutations outside transactions |
| Command | Purpose |
|---|---|
roam understand |
One-screen codebase briefing |
roam search <pattern> |
Find symbols by name |
roam retrieve "<task>" |
Graph-aware FTS5 + structural rerank for free-form tasks |
roam context <symbol> |
Exact files + line ranges to read before changing |
roam preflight <symbol> |
Blast radius + tests + fitness gate |
roam impact <symbol> |
What breaks if this symbol changes |
roam diagnose <symbol> |
Root-cause ranking for failing behaviour |
roam diff |
Blast radius of uncommitted changes |
git diff | roam critique |
Patch verifier (clones-not-edited, blast radius; exit 5 on high severity) |
roam adversarial |
Architectural challenges on changed files (composes cycles + clusters + layers + catalog + dead + complexity) |
roam grep <pattern> |
Index-aware text search (reachability, PageRank, clones, bridges) |
roam refs-text <string> |
String audit: SAFE-TO-REMOVE / REVIEW / LOAD-BEARING |
Run roam --help for the 5-verb core, roam --help-all for every command,
and roam surface --json for the machine-readable inventory.
roam --json <cmd>— structured envelope (default for MCP), schema-versioned.roam --sarif <cmd>— SARIF 2.1.0 for GitHub Code Scanning / CI (health, debt, complexity, smells, vulns, …).
dev/MCP-SECURITY-POSTURE.md— gateway-integrator companion: egress redaction pattern library, mode-gate enforcement, receipt-chain invariants, Interlock / Lasso / Portkey hooks.src/roam/evidence/mcp_receipt.py— canonicalMcpDecisionReceiptshape.scripts/export_mcp_receipt_schema.py— Draft 2020-12 schema emitter.- MCP runtime security design discussion: #37 (comment)
Run roam --help-all for all 281 commands (+ alias pairs).