Shared memory and context tools for agentic work.
Code Rooms
// === m1nd-mcp CLI argument parsing ===
//
// Clap derive struct for m1nd-mcp binary modes.
// Replaces manual std::env::args() parsing in main.rs.
use clap::Parser;
/// `--version` string: semantic version + embedded git sha, e.g. `1.1.0 (50385cd)`.
/// The sha is `unknown` on builds without a `.git` (crates.io / vendored). This
/// makes the binary declare exactly what it is — the first layer of the
/// version-honesty moat (see `build.rs` / `session::binary_version_info`).
const LONG_VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), " (", env!("M1ND_GIT_SHA"), ")");
#[derive(Parser, Debug)]
#[command(
name = "m1nd-mcp",
about = "Neuro-symbolic connectome engine",
version,
long_version = LONG_VERSION
)]
pub struct Cli {
/// Start HTTP server with embedded web UI
#[arg(long)]
pub serve: bool,
/// HTTP server port
#[arg(long, default_value = "1337")]
pub port: u16,
/// Bind address override (default: 127.0.0.1). A non-loopback bind (e.g.
/// 0.0.0.0 or a concrete LAN IP) exposes graph mutation to the network and is
/// REFUSED at startup unless `--allow-remote` is also given — there is no
/// authentication yet, so an unguarded remote bind must be an explicit,
/// deliberate opt-in, never the default.
#[arg(long, default_value = "127.0.0.1")]
pub bind: String,
/// Explicitly allow binding the HTTP server to a non-loopback address.
/// Without this flag a non-loopback `--bind` is refused at startup (there is
/// no auth: an open bind would expose graph mutation to the LAN). With it the
/// bind proceeds and a strong unauthenticated-exposure warning is printed.
pub allow_remote: bool,
/// Serve frontend from disk instead of embedded (dev mode)
pub dev: bool,
/// Also run JSON-RPC stdio server alongside HTTP
pub stdio: bool,
/// Auto-open browser on startup
pub open: bool,
/// Path to config JSON file
pub config: Option<String>,
/// Graph source path override
pub graph: Option<String>,
/// Plasticity state path override
pub plasticity: Option<String>,
/// Runtime directory override for instance sidecar state
pub runtime_dir: Option<String>,
/// Global registry directory override
pub registry_dir: Option<String>,
/// Domain: code, music, memory, generic
#[arg(long, default_value = "code")]
pub domain: String,
/// Disable auto-launching the HTTP GUI in stdio mode (for CI, headless servers)
pub no_gui: bool,
/// Path to event log file (append-only JSON lines). Enables cross-process SSE via file bus.
pub event_log: Option<String>,
/// Watch an event log file and broadcast new events via SSE (HTTP-only mode).
/// Use when a separate stdio process writes events to this file.
pub watch_events: Option<String>,
/// Attach read-only: load the snapshot and serve queries, but never write to
/// disk and never take an exclusive lease. Mutation tools are disabled.
/// Also honored via env `M1ND_READ_ONLY=1`.
pub read_only: bool,
/// Attach to a running `--serve` owner as a thin stdio↔HTTP MCP bridge.
/// Takes the owner's base URL (e.g. `http://127.0.0.1:1337`), or the literal
/// `auto` to auto-discover the live serve ReadWrite owner for this client's
/// runtime_root via the instance registry (read-only, NO lease). The env var
/// `M1ND_ATTACH_URL`, when set, overrides both and wins. The bridge loads NO
/// graph, builds NO engines, and takes NO lease: it speaks stdio MCP to the
/// host (Claude Code), forwards every JSON-RPC frame to the owner's
/// `POST /mcp`, and relays the owner's server→client SSE push notifications
/// (`notifications/m1nd/graph_changed`) back to stdout. Multiple `--attach`
/// clients pointed at one owner share that owner's single live graph.
/// Requires the `serve` feature.
pub attach: Option<String>,
/// One-shot triage: distribute the field-report spool into per-project boxes
/// (`<repo>/.m1nd/inbox.jsonl`) + the medulla box, then print the cross-box
/// sweep (spool ∪ every known box, de-duplicated by content id) as JSON and
/// exit. Idempotent (append-with-dedup), LOCAL, safe to re-run — it is
/// telemetry, not memory (MEDULLA-PRD §9.2). Add `--no-distribute` to sweep
/// the EXISTING boxes without filing anything new first.
pub inbox_sweep: bool,
/// With `--inbox-sweep`: skip the distribution pass and only read the current
/// spool + boxes (a pure, read-only view).
pub no_distribute: bool,
/// One-shot MEDULLA storage-split migration (MEDULLA-PRD §4.2, slice M5a).
/// Takes one required verb (no default):
/// `plan` — print the dry-run plan JSON (enumerate + classify + the
/// count-conservation gate) WITHOUT mutating anything;
/// `apply` — backup-first, then move repo-fact claims into the project
/// brain store, stamp `Origin-Brain`, prune ghost ingest-root
/// pointers, and verify count- AND content-conservation; prints
/// the receipt (incl. the authoritative `moved_files` list). It
/// REFUSES on any destination name collision (never overwrites)
/// and writes a `manifest.json` + an `ingest_roots.json` copy
/// into the backup dir;
/// `rollback` — restore the medulla store (and `ingest_roots.json`) from the
/// most recent backup, removing exactly the files named in that
/// backup's manifest (never scanning the destination store), and
/// snapshotting the live state first so a mid-restore failure
/// stays recoverable.
/// Derives every path from the runtime root exactly like `--inbox-sweep`,
/// runs offline, prints JSON, and exits. `apply`/`rollback` mutate the store —
/// intended for the maintainer, never an agent (the CODE-LAND-ONLY posture) —
/// and REFUSE while a served owner is up (stop the owner first: the offline
/// migration must not race a live owner).
#[arg(long, value_name = "plan|apply|rollback")]
pub medulla_migrate: Option<MedullaMigrateMode>,
/// The destination project brain for `--medulla-migrate`, named EXPLICITLY
/// as a repo root path — the brain that repo-fact claims move into and whose
/// root is stamped as their `Origin-Brain`. It is NEVER derived from the
/// ambient session binding: a second agent that bound the owner to an
/// unrelated repo once caused the migration to move legacy memories into the
/// wrong brain's store (field bug 2026-07-05). REQUIRED for `apply` (and for
/// `rollback`, which must locate the same store); recommended for `plan`,
/// which otherwise falls back to the ambient binding and loudly flags that
/// destination as unsafe in its JSON.
#[arg(long, value_name = "PATH")]
pub migrate_project_root: Option<String>,
}
/// The verb for `--medulla-migrate` (MEDULLA-PRD §4.2). No default: the flag
/// requires one of these values, so a bare `--medulla-migrate` is a usage error.
#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
#[value(rename_all = "lower")]
pub enum MedullaMigrateMode {
/// Pure dry-run: print the plan, mutate nothing (§11 M5a default).
Plan,
/// The gated executor: backup-first split + stamp + prune (mutates).
Apply,
/// Restore the medulla store from the most recent backup (mutates).
Rollback,