Commands
The mage CLI is one binary with two audiences. There are verbs you type —
init, connect, skills, dream, dashboard, and friends — and there is
hidden plumbing that mage’s hooks and mage:* skills run for you. You never
type the plumbing by hand; it is listed below for transparency so you can see
exactly what the machinery does on your behalf.
The full inventory at the bottom of this page is generated straight from the CLI definition and guarded by a drift test, so it can never fall out of sync with the code. The hand-written examples here cover the verbs you actually run; everything else is reference.
Every command accepts --help:
mage --helpmage init --helpThe three channels
Section titled “The three channels”The mage binary above is only part of the surface — there are agent skills too. Sorting every name into one of three channels is the fastest way to keep them straight:
A · Agent skills — invoked inside your coding agent as mage:<name>, not in a terminal. These are the verbs of everyday use; each one orchestrates plumbing calls for you. There are exactly five:
| Skill | What you get |
|---|---|
mage:guide | orient in the knowledge base — navigate notes and decisions |
mage:learn | capture a note now, or bulk-import a folder (--from) |
mage:groom | turn captured scratch into notes — accept or reject the batch |
mage:graduate | elevate a proven procedural note into a loadable skill |
mage:optimize | sharpen a skill’s trigger — reword or demote weak ones |
B · CLI commands you type — the terminal verbs for setup and housekeeping that doesn’t belong inside the agent (init, link, connect, doctor, dashboard, dream, and friends). The rest of this page is their reference.
C · Plumbing — hidden CLI verbs you never type by hand (observe, distill, promote, stage, index, nudge, memory-hook, redact, ingest, flatten, and friends). A skill or a host hook runs them for you; the complete, generated set is in the full inventory — that table, not this list, is the authoritative roster.
The rhythm: skills (A) when you curate · CLI (B) at setup and check-ups · plumbing (C) never by hand. The one hybrid: groom is both the mage:groom skill (what you use) and a hidden mage groom CLI verb (what the skill calls) — every other name is cleanly one channel.
flowchart LR setup["set up — CLI<br/>init · link · connect"] --> work["work — automatic<br/>observe · Gate-0 · nudge"] work --> curate["curate — skills<br/>mage:groom · mage:learn"] curate --> health["check up — CLI<br/>doctor · dashboard · dream"] health --> work
Setting up a knowledge base
Section titled “Setting up a knowledge base”mage init creates a knowledge base. With no arguments it detects what you want
from where you run it: inside a git repo it scaffolds an in-repo knowledge
base under mage/; otherwise it creates a standalone hub. You can force
either shape.
# In-repo: a knowledge base under mage/, committed alongside the codemage init --in-repo
# Hub: a standalone knowledge base that can span many repos.# A bare name creates ./<name>, like `git init`.mage init <your-hub> --hubBy default an in-repo init also wires the capture hooks for you. Pass
--no-connect to skip that and run mage connect yourself later. For the full
walkthrough see Install and Quickstart. For when to
pick in-repo, hub, or hybrid, see Modes.
Wiring up capture
Section titled “Wiring up capture”mage connect opts this repo into capture by writing mage’s hooks into Claude
Code’s per-repo .claude/settings.local.json (which is personal and gitignored).
It is idempotent and backs up the file before touching it. mage disconnect
removes exactly what connect added.
# Wire capture hooks into this repo (.claude/settings.local.json)mage connect
# Wire them into your personal settings instead (~/.claude/settings.json)mage connect --user
# Remove mage's capture hooks again (host hooks stay intact)mage disconnectCapture is strictly opt-in — it is not bundled with the skills plugin. For what the hooks actually capture, see Capture and the Hooks reference.
Reaching a knowledge base outside the repo
Section titled “Reaching a knowledge base outside the repo”When your KB lives in a hub (external or hybrid mode), it sits outside the
repo your agent was launched in — and agent harnesses confine file access to the
project root. mage connect therefore also grants access to the hub, by adding it
to permissions.additionalDirectories in the same local settings file. Without
that grant the agent is pointed at a knowledge base it cannot read, and every note
read becomes a permission prompt.
This is independent of everything else connect wires: turning off your harness’s
own auto-memory does not revoke it. mage records exactly which entries it added, so
mage disconnect removes those and leaves any you added yourself untouched.
Two cases worth knowing:
- The hub isn’t on this machine. No grant is written (there is nothing to grant
yet). Clone the hub, then re-run
mage connect. - A new worktree. Local settings are gitignored, so a fresh worktree starts
without them. Run
mage connectin it.
mage doctor reports the grant under KB access grant — a failing check when the
hub is present but ungranted, and a skip when the hub simply isn’t cloned here.
Changing in 0.0.18: per ADR-0043 an external hub will be addressed by its remote
(hub_repo) and located by derivation at ~/.mage/hubs/<host>/<owner>/<repo>,
cloned on demand — deprecating hub_path and the “isn’t on this machine” case
above. See Modes and storage.
Regenerating the index and skills
Section titled “Regenerating the index and skills”Two generated artifacts keep agents oriented. mage index rebuilds both recall
surfaces — mage/INDEX.md, the full one-line-per-note index of every
memory-genre note, and mage/MEMORY.md, the ranked, budget-bounded roster
the host pushes at session launch (idempotent — never hand-edit either output;
see The two recall surfaces).
mage skills regenerates the per-wing mage-wing-* skills — one
auto-loaded skill per wing, into .claude/skills/ and .agents/skills/ — so agents
discover your knowledge base.
There are two classes of generated skill, and only one of them is mage skills’
business:
- Per-wing skills (
mage-wing-*) are derived from your notes, exactly like the index.mage skillsis their writer; re-running it rebuilds them from the current wings, deterministically. - Graduated skills (
mage-skill-*) come out of the grooming loop, when a proven procedural note earns its own skill.mage dream --applyis the single writer that mints those, and the ceilings it enforces are the reason it is the only one.mage skillsnever creates, edits, or deletes a graduated skill. See Promote and graduate.
Each generated wing skill includes a “Governing decisions” section listing the accepted, non-superseded decision records (ADRs) that the wing’s memory-genre notes link to — per-ADR recall rides linking memories, so an ADR reachable only from another ADR’s Relations list does not govern (ADR-0041 §4). The section is capped at the 12 most recent decisions, with the remainder folded into one “…and N more in decisions/” line; the recall/footprint ceilings stay as a whole-file backstop (use mage footprint/mage doctor to diagnose breaches).
# Rebuild both recall surfaces after adding or editing notesmage index
# Regenerate the per-wing skills (run this after a new wing appears)mage skillsAt a hub root, index fans out
Section titled “At a hub root, index fans out”Run against a single knowledge base, mage index writes that one pair. Run at a
hub root, it writes the hub’s own INDEX.md + MEMORY.md and regenerates
each registered project’s own projects/<name>/INDEX.md + MEMORY.md in place
(a project whose directory is not on disk is skipped). Each project’s pair is
scoped to that project’s notes; the hub’s own pair spans the fleet.
This is not cosmetic: an external-mode code repo’s autoMemoryDirectory points
at projects/<name>/, so that is where its session-launch recall has to be. The
fan-out is one level deep only — run at a project root, mage index writes that
project’s pair and nothing else (no recursion, and it never reaches back up to
the hub root). See Set up a hub and external
mode.
mage/INDEX.md (along with MEMORY.md, and Dashboard.md from mage dashboard) is generated and committed, so on a team it will sometimes
conflict on a merge — that is expected, not a mistake. Treat these like build
output: after merging a branch that touched notes, re-run mage index (and
mage dashboard, if you use it) to regenerate the file rather than
hand-resolving the conflict. That goes double for MEMORY.md: its roster order
consults local usage metrics, so two machines with identical notes can
legitimately produce different orderings — regenerate, never hand-merge.
mage index is plumbing — the hooks and the mage:learn flow (the
deliberate-capture skill that drafts a note for you and writes it after you
confirm) run it for you — but it is safe to run yourself. mage skills also carries a read-only metrics
mode that reports context-match (whether the skills that auto-loaded matched the
work that followed):
# Read-only context-match report for your generated skillsmage skills --metrics
# Same report as JSON, for toolingmage skills --metrics --jsonSee Optimize for how those match rates drive reword and demote decisions, and Thresholds and the dial for the rates involved.
Checking knowledge-base health
Section titled “Checking knowledge-base health”mage dream reports knowledge-base health, read-only: stale notes,
superseded-but-active notes, dangling links, and orphans. It writes nothing.
(When validating links, dream parses standard [text](path) links and [[wikilinks]], correctly resolves #fragment anchors to their files, and explicitly skips external URLs like http:// or mailto: to keep the report focused on your local graph.)
# Read-only health reportmage dream
# Flag notes whose last_reviewed is older than 90 days (default is 180)mage dream --stale-days 90
# Exit non-zero if there are any findings (useful in CI or a hook)mage dream --strictmage dream also carries the --apply and --reject plumbing flags — the
single-writer seam the grooming skills drive. You do not type those by hand; they
are covered under the plumbing table below and in
Promote and graduate.
mage footprint reports your context footprint and recall economics. It measures the byte and line occupancy of the generated auto-memory file against the host agent’s recall budget (e.g., 25,600 bytes or 200 lines). A recall-budget breach means the host will silently truncate the file, dropping your earliest memories. When this happens, mage doctor will point you at mage footprint to investigate.
# Report context footprint and pointer leveragemage footprint
# Output as JSON for toolingmage footprint --json
# Suppress output; for a failing exit code on breach, use `mage doctor` insteadmage footprint --quietLinking to a hub
Section titled “Linking to a hub”If your durable knowledge lives in a hub, mage link <hub-path> registers this
code repo with it. mage unlink removes the linkage again.
# Register this repo's knowledge base with an existing hubmage link /path/to/hub
# Use a different project name inside the hubmage link /path/to/hub --project my-service
# Remove the linkagemage unlinkmage list, mage verify, and mage status are the read-only companions: list
the projects in a hub, sanity-check a hub’s structure, and check per-machine link
health for one or more code repos.
# List the projects registered in a hubmage list --hub /path/to/hub
# Sanity-check a hub's structuremage verify --hub /path/to/hub
# Check link health for one or more code reposmage status /path/to/repoGenerating the dashboard
Section titled “Generating the dashboard”mage dashboard renders the knowledge base for a human — without a server. It is
a generated artifact, not a service.
# Generate Dashboard.md + an Obsidian-core Knowledge.basemage dashboard
# Also generate the self-contained dashboard.html cockpitmage dashboard --html
# Print the command to open the generated htmlmage dashboard --openDiagnosing and migrating
Section titled “Diagnosing and migrating”mage doctor diagnoses environment, knowledge-base, and connection health, including read-only genre-tell annotations (memory-genre over-cap size, done-state vocabulary, issue-ref density, checkboxes).
--fix repairs missing capture-sink ignore rules; --report prints a redacted,
content-free support bundle to attach to bug reports. mage migrate upgrades a
knowledge base’s metadata to the current schema (idempotent; it never commits).
Whenever you link a hub (mage link) or wire up capture for a single repo (mage connect), mage runs a fast readiness check and prints a readiness footer. This serves as a mini-doctor report to confirm your environment is ready to capture and recall notes without requiring a full manual mage doctor run.
# Diagnose env + KB + connection healthmage doctor
# Repair any missing capture-sink ignore rulesmage doctor --fix
# Print a redacted, content-free support bundle for an issuemage doctor --report
# Upgrade this KB's metadata to the current schemamage migrateThe full inventory
Section titled “The full inventory”Every command, alias, and flag below is generated from the CLI itself. The
plumbing (hidden) commands carry a plumbing badge — those are run by mage’s
hooks and mage:* skills, not typed by hand.
mage init
Initialize mage: an in-repo knowledge base, or a standalone hub
| Flag | Description |
|---|---|
--in-repo | scaffold the knowledge base inside this code repo's mage/ |
--hub | create a standalone hub (vs an in-repo KB) at the current dir or <name> |
--external | removed in 0.0.10 — use --hub |
--name <name> | deprecated: pass the hub name as the positional argument instead |
-d, --dir <path> | hub mode: explicit hub directory (overrides <name>) |
--private | hub mode: create as private GitHub repo (requires gh) |
--public | hub mode: create as public GitHub repo (requires gh) |
--local | hub mode: skip GitHub — local-only hub |
--owner <user> | hub mode: GitHub owner (auto-detected via `gh api user`) |
--project <name> | in-repo mode: project name (default: basename of code repo) |
-y, --yes | non-interactive: use defaults (detect in-repo vs hub from the cwd) |
--no-connect | skip auto-wiring capture hooks after an in-repo init |
mage index
(Re)generate INDEX.md + the Claude Code MEMORY.md roster — the always-loaded index of notes (idempotent; roster order consults local metrics when present)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
mage skills
(Re)generate one auto-loaded skill per wing into .claude/skills/ and .agents/skills/
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
--metrics | read-only: fold the context-match rollup and report skill-load match rates (never regenerates skills) |
--json | metrics mode: emit the rows as JSON instead of a table |
--quiet | metrics mode: fold + write the rollup silently (the Stop-hook path) |
mage footprint
report mage's context-window cost: launch surfaces, yield, pointer leverage
| Flag | Description |
|---|---|
--json | emit the measurement as JSON instead of the table |
--quiet | render nothing but still return the result |
mage dream
Report knowledge-base health (default), or apply a grooming proposal via stdin (--apply)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
--stale-days <n> | flag notes whose last_reviewed is older than N days (default 180) |
--strict | exit non-zero if any findings (for hooks/CI) |
--json | emit the health report as JSON to stdout (machine-readable) |
--apply | apply ONE confirmed Proposal JSON from stdin (the single writer; never commits) |
--reject | append ONE Proposal JSON from stdin to the rejected-edit buffer (back off) |
mage link
Link this code repo to an existing hub (auto-detects storage based on mage/ content)
| Flag | Description |
|---|---|
--project <name> | project name in the hub (default: basename of code repo) |
--storage <kind> | override auto-detected storage: 'repo-owned' (hybrid; the repo keeps its docs) or 'hub-owned' (the hub owns the docs) |
-y, --yes | non-interactive: auto-confirm prompts |
--no-connect | skip auto-wiring capture hooks after link |
mage unlink
Remove a mage linkage from this code repo (updates both metadata files)
| Flag | Description |
|---|---|
--hub <path> | specific hub to unlink from (default: primary hub or the only hub_ref) |
--delete-hub-side | for hub-owned slots: also delete <hub>/projects/<project>/ dir |
-y, --yes | non-interactive: auto-confirm prompts |
mage verify
Sanity-check a hub's structure (and optionally linked code repos)
| Flag | Description |
|---|---|
--hub <path> | hub root (default: cwd) |
mage list
List the projects in this hub
| Flag | Description |
|---|---|
--hub <path> | hub root (default: cwd) |
mage migrate
Upgrade this KB's metadata to the current schema (idempotent; never commits)
| Flag | Description |
|---|---|
--dir <path> | where to look for the knowledge base (default: cwd; walks up) |
mage adopt
Onboard pre-existing Claude Code memories into this KB's capture inbox: place in-shape captures, report out-of-shape to distill (plan-first; never commits)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
--all | whole-machine sweep: adopt memories for every KB they belong to, not just this one |
--dry-run | stop at the plan; write nothing |
-y, --yes | non-interactive: skip the confirmation prompt |
mage status
Check per-machine link health for one or more code repos
No options.
mage autonomy
Show or set this KB's opt-in grooming autonomy level (operator | approver | overseer; ADR-0030; never commits)
| Flag | Description |
|---|---|
--dir <path> | where to look for the knowledge base (default: cwd; walks up) |
mage doctor
Diagnose env + KB, connection, and recall readiness; --fix repairs ignores; --report bundles logs
| Flag | Description |
|---|---|
--hub <path> | hub root (default: cwd if it looks like a hub) |
--fix | add any missing capture-sink ignore rules |
--report | print a redacted, content-free support bundle for issues |
mage dashboard
Generate this KB's dashboard (Dashboard.md + Knowledge.base; --html adds the interactive cockpit)
| Flag | Description |
|---|---|
--html | also generate the self-contained dashboard.html cockpit |
--hub <path> | hub root |
--open | print the command to open the html |
--open-with <target> | where clicking a note opens it: file (relative link, works anywhere) | obsidian | vscode |
mage connect
Wire mage capture hooks into this repo's Claude Code settings (.claude/settings.local.json; personal + gitignored)
| Flag | Description |
|---|---|
--user | target the personal ~/.claude/settings.json instead of the repo-local file |
--all-projects | from a hub: wire every registered project's code repo (repo-local each) |
--no-git-hook | skip installing the redaction pre-commit hook |
-y, --yes | non-interactive: skip the confirmation prompt |
mage disconnect
Remove mage's capture hooks from this repo's Claude Code settings (leaves host hooks intact)
| Flag | Description |
|---|---|
--user | target the personal ~/.claude/settings.json instead of the repo-local file |
--no-git-hook | skip removing the redaction pre-commit hook |
-y, --yes | non-interactive: accepted for symmetry (no destructive prompt) |
Plumbing (hidden) commands
mage ingestplumbing
Enumerate + classify ingestable sources under <dir> (read-only) — what `mage:learn --from` distills.
| Flag | Description |
|---|---|
--json | emit the manifest as JSON to stdout (machine-readable) |
mage distillplumbing
Read observed .mage/learnings into note candidates (plumbing behind mage:groom Phase 1)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
--json | emit the candidate manifest as JSON |
--seen <session:offset> | advance the distill watermark after a batch is dispositioned |
mage promoteplumbing
Fold note-read usage into graduate proposals (plumbing behind mage:graduate)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
--json | emit the graduate proposals as JSON |
--seen <session:offset> | advance the promote offset after a batch is dispositioned |
mage stageplumbing
Stage a short lesson draft into .mage/staging/ (frictionless inline capture — the organic grooming loop)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
-t, --title <title> | lesson title (required — drives the H1 and slug) |
--type <type> | note type (default: gotcha) |
--tags <wing/room,...> | comma-separated wing/room tags |
--wing <wing> | convenience wing (prepended as a tag when none homes there) |
--body <text> | lesson body (else read from stdin) |
--json | emit the result as JSON |
mage groomplumbing
Surface / accept / reject the staged lesson batch (plumbing behind the mage:groom skill)
| Flag | Description |
|---|---|
-d, --dir <path> | where to look for the knowledge base (default: cwd; walks up for in-repo) |
--json | emit the batch / disposition as JSON |
--accept <slugs|all> | promote these staged drafts to notes/ and re-index |
--reject <slugs|all> | discard these staged drafts and record their keys |
mage observeplumbing
Hook-fired capture seam: read a Claude Code hook JSON on stdin and append one event to .mage/learnings/ (ADR-0015; never blocks the host)
| Flag | Description |
|---|---|
--session <id> | session id (overrides the session field in the hook JSON) |
--event <type> | force the event type (session_start|user_prompt|assistant_msg|skill_load|tool_use|compact|session_end); default: inferred from the hook payload |
--cwd <dir> | working directory used to locate the knowledge base (overrides the hook JSON cwd; defaults to it, then process.cwd()) |
mage nudgeplumbing
Hook-fired boundary nudge: on a SessionStart (compact/startup/resume), surface the closed chapter's earned-signal digest plus the autonomy-scaled grooming backlog for the agent to mine and `mage stage`/`mage:groom` (ADR-0029/0030; never blocks the host)
| Flag | Description |
|---|---|
--cwd <dir> | working directory used to locate the knowledge base (overrides the hook JSON cwd; defaults to it, then process.cwd()) |
mage memory-hookplumbing
Hook-fired Claude Code Gate-0 capture gate: on PreToolUse, redirect + scrub a native-memory write into mage's note schema (or deny a write to a generated index); on PostToolUse, nudge `mage groom` (ADR-0032/0033; never blocks the host)
| Flag | Description |
|---|---|
--cwd <dir> | working directory used to locate the knowledge base (overrides the hook JSON cwd; defaults to it, then process.cwd()) |
mage redactplumbing
Deterministically scan a file or stdin for secrets/PII (ADR-0014 Gate 2); --strip emits redacted text
| Flag | Description |
|---|---|
--strip | print the redacted text to stdout (secret values → [REDACTED:<kind>]) |
--quiet | suppress the findings report |
--staged | scan staged git changes (the pre-commit gate) |
--check | report-only intent for hooks |
mage flattenplumbing
Normalize harness-shaped (Claude Code) notes to mage's flat schema (ADR-0035): --staged flattens staged blobs at the commit boundary; --all sweeps every note under the docs root regardless of git state (the backfill for notes committed before flatten existed); default sweeps the working tree (the Stop hook). Never blocks.
| Flag | Description |
|---|---|
--staged | flatten staged git changes (the pre-commit guarantee) |
--all | flatten every note under the docs root, regardless of git state (backfill; takes precedence over --staged) |
--quiet | suppress the report |