Local working memory for coding agents outside the product repository. Version 0.26.0.
Documentation Website Β· Architecture & Specs Β· Changelog
Product git repositories should contain product code: source, tests, and shipped documentation. Agent working stateβanti-regression traps, architecture decisions, feature specifications, implementation plans, execution state, and changelogsβbelongs in a curated vault outside the product repository, queried through an MCP server and matching CLI.
spec-memo includes both the Model Context Protocol (MCP) server for AI coding environments and the memo CLI for interactive terminal usage and agent execution.
# Global install via npm from GitHub (adds `memo` to your npm global bin)
npm install -g github:jpolvora/spec-memo
# Or build from source clone
git clone https://github.com/jpolvora/spec-memo.git
cd spec-memo
npm install
npm run build
npm linkThe package.json declares "bin": { "memo": "./dist/cli.js" } and dist/cli.js includes the #!/usr/bin/env node shebang. Choose the method that best matches your workflow:
When actively developing spec-memo or working from a local clone:
cd /path/to/spec-memo
npm install
npm run build
npm link- How it works: npm creates a global symlink/shim (
memoon Unix;memo,memo.cmd,memo.ps1on Windows) in your global npm prefix directory (e.g.,%AppData%\Roaming\npmon Windows,/usr/local/binor~/.nvm/versions/node/<ver>/binon Linux/macOS). - Live Rebuild Invariant: The link points directly to
dist/cli.js. Whenever you compile changes withnpm run build, your globalmemocommand reflects the latest code immediately without needing to re-link or re-install.
# Point npm install directly to your local clone directory
npm install -g "/path/to/spec-memo"- Installs a packaged copy to your npm global directory. Re-run this command after major rebuilds to refresh the global binary.
If you prefer not using npm global link or want a standalone wrapper script:
-
Linux / macOS: Create
~/.local/bin/memo(or/usr/local/bin/memo):#!/usr/bin/env bash exec node "/path/to/spec-memo/dist/cli.js" "$@"
Make it executable:
chmod +x ~/.local/bin/memo -
Windows (Command Prompt / PowerShell): Create
memo.cmdin a folder that is in your system or userPATH(e.g.C:\bin\memo.cmdor%USERPROFILE%\bin\memo.cmd):@echo off node "C:\path\to\spec-memo\dist\cli.js" %*
(Optionally create
memo.ps1for PowerShell:& node "C:\path\to\spec-memo\dist\cli.js" @args)
-
Verify Binary Resolution:
# Open a new shell/terminal session and run: memo --help memo check-version -
If
memo: command not foundpersists:- Restart terminal: Fresh environment variables (like PATH changes) require a new shell or terminal window.
- Check global npm PATH on Windows: Ensure
%AppData%\Roaming\npm(or your customnpm config get prefix) is in your User or SystemPATHvariable. - Check global npm PATH on Linux/macOS: Ensure
~/.local/binor$(npm config get prefix)/binis in your shell profile (~/.bashrc,~/.zshrc).
-
IDE MCP vs Terminal CLI:
- Your AI editor (Cursor, VS Code, Claude Desktop, Antigravity) configures stdio MCP via
memo setup --write-mcpornode /path/to/dist/cli.js serve. - Putting
memoon your systemPATHensures that interactive terminal commands and AI agents executing shell scripts can callmemo bootstrap,memo doctor --fix,memo search, etc. anywhere on your machine.
- Your AI editor (Cursor, VS Code, Claude Desktop, Antigravity) configures stdio MCP via
-
After upgrading Node.js (FTS empty /
GC_FAILED/ ABI mismatch):better-sqlite3is a native addon. A Node upgrade (for example 22 β 24) leaves the oldNODE_MODULE_VERSIONbinding in place. Search may error or look empty,gcreturnsGC_FAILED, anddoctormust report unhealthy with rebuild steps rather than a stale healthy count.# Debian/Ubuntu (needed when no prebuild exists for your Node version) sudo apt install build-essential npm rebuild better-sqlite3 memo doctor --rebuildspec-memo requires Node.js 22+ (
package.jsonengines.node). CI runs the test suite on Node 22 and Node 24. FTS still usesbetter-sqlite3(notnode:sqlite); rebuild after every Node upgrade.
spec-memo supports three operational deployment modes configured via memo setup:
- Local Mode (Default): All memory records, indexing, and queries run directly on the local machine in
~/.spec-memo/. Zero network dependencies. - Hybrid Mode: Local vault remains the primary low-latency cache; transparently pulls updates from a shared daemon during
bootstrapand debounces pushes on mutating operations (upsert,append,forget,gc). Manual sync viamemo sync. Works offline seamlessly (fails open). WhenvaultGit.enabledis also set,memo syncruns hybrid HTTP and vault-git in parallel. - Remote Mode: Agent hosts run a local stdio MCP proxy (
memo serve) that forwards all 11 tools to a central remote daemon. Zero memory records stored on local disk. Fails closed with structured errors when unreachable.
# Configure Local mode (default)
memo setup --mode local
# Configure Hybrid mode with a remote SSE daemon
memo setup --mode hybrid --url http://daemon.internal:3000
# Configure Remote mode with a remote SSE daemon
memo setup --mode remote --url http://daemon.internal:3000Note on Authentication: Bearer tokens are read exclusively from environment variables (
SPEC_MEMO_AUTH_TOKENorSPEC_MEMO_SSE_TOKEN).memo setupverifies token presence in your environment without storing secrets in plain text on disk.
All agent hosts (Cursor, VS Code, OpenCode, Antigravity, Claude Desktop) use the same uniform stdio MCP wiring (memo serve). Mode switching is controlled entirely via ~/.spec-memo/config.json.
# Print MCP configuration snippet for your editor
memo setup --host cursor --print-mcp
memo setup --host vscode --print-mcp
memo setup --host opencode --print-mcp
memo setup --host claude --print-mcp
# Automatically write/merge MCP configuration directly to your editor's config file
memo setup --host cursor --write-mcp
memo setup --host vscode --write-mcpAdd to claude_desktop_config.json:
{
"mcpServers": {
"spec-memo": {
"command": "memo",
"args": ["serve"]
}
}
}Add to ~/.cursor/mcp.json or open Cursor Settings > MCP:
{
"mcpServers": {
"spec-memo": {
"command": "memo",
"args": ["serve"]
}
}
}Add to ~/.gemini/config/mcp_config.json or active workspace config:
{
"mcpServers": {
"spec-memo": {
"command": "memo",
"args": ["serve"]
}
}
}Add to your extension's MCP configuration settings:
{
"mcpServers": {
"spec-memo": {
"command": "memo",
"args": ["serve"]
}
}
}Add to ~/.config/opencode/config.json (type is local, command is an array β args is not valid here):
{
"mcp": {
"spec-memo": {
"type": "local",
"command": ["memo", "serve"],
"enabled": true
}
}
}Day-to-day vault ops (all 10 MCP tools + CLI extras) are documented as a project skill:
Preferred install into a consumer repo:
memo install-skills --product-root /path/to/consumer
memo install-skills --global --force
# or MCP tool: install_skills { "productRoot": "/path/to/consumer" }
# install_skills { "global": true, "force": true }Manual copy/symlink of .agents/skills/ws-memo/ remains a fallback. Setup of specMemo.enabled in workflow-skills consumers remains ws-spec-memo β do not duplicate that bridge here.
Audience: operators and humans. Agents: see AGENTS.md.
All daemon ports are fully configurable via ~/.spec-memo/config.json under the "ports" section (with aliases mcp for sse, ui for status):
{
"ports": {
"sse": 3123,
"status": 3124,
"canvas": 3125
}
}| Service | Default URL | Start |
|---|---|---|
| MCP SSE transport | http://127.0.0.1:3123 (/sse, /message, /health) |
memo serve --sse |
| Status monitor | http://127.0.0.1:3124/ |
co-starts with --sse (disable: --no-status; override: --status-port) |
| Canvas graph viewer | http://127.0.0.1:3125 |
memo canvas |
# After global install or npm link
memo bootstrap
memo search "database lock" --kind trap
memo doctorFrom a source checkout:
npm install
npm run build
node dist/cli.js bootstrap
# or: npm link β memo β¦Vault root defaults to ~/.spec-memo/ ($SPEC_MEMO_ROOT to override). You can also persist a default vault path in bootstrap ~/.spec-memo/config.json:
{
"vaultRoot": "/var/lib/spec-memo"
}Resolution order: --vaultRoot flag β $SPEC_MEMO_ROOT β bootstrap config.json vaultRoot β current directory when it contains config.json + projects/ β ~/.spec-memo/.
Unusable candidates (not a directory, missing read/write permission, or not creatable) are skipped. Export, import/restore, backups, and reset always resolve through this same path and print the vault root they used.
One-time setup:
memo setup --vault-root /var/lib/spec-memo| Mode | Command | When to use |
|---|---|---|
| Stdio (default) | memo serve |
Cursor / Claude Desktop / Gemini host spawns the process (see MCP configs above) |
| HTTP / SSE | memo serve --sse |
Shared lab daemon, remote MCP URL, or bookmarkable status page |
# Loopback SSE + status monitor
memo serve --sse
# β MCP SSE: http://127.0.0.1:3123/sse
# β Health: http://127.0.0.1:3123/health
# β Status UI: http://127.0.0.1:3124/
memo serve --sse --port 3123 --status-port 3124
memo serve --sse --no-status # MCP only
memo serve --sse --json # machine metadata (includes statusUrl)Flags: --host (default 127.0.0.1), --port, --status-port, --no-status, --auth-token, --vaultRoot.
spec-memo secures non-loopback HTTP/SSE daemon traffic and status monitor access using a single shared Bearer token.
- Zero Secrets on Disk: Tokens are never stored in vault
config.json, product files, or Git repositories. They are resolved at runtime from environment variables or command-line flags. - Non-Loopback Safety: Binding beyond loopback (
127.0.0.1,localhost,::1) strictly refuses to start without a token. - Supported Environment Variables:
SPEC_MEMO_AUTH_TOKEN(recommended) orSPEC_MEMO_SSE_TOKEN(alias).
# Linux / macOS
openssl rand -hex 32
# Windows (PowerShell)
[guid]::NewGuid().ToString('N')# Via Environment Variable (recommended)
export SPEC_MEMO_ROOT=/var/lib/spec-memo
export SPEC_MEMO_AUTH_TOKEN="your_generated_token_here"
memo serve --sse --host 0.0.0.0 --port 3000
# Or via CLI flag
memo serve --sse --host 0.0.0.0 --port 3000 --auth-token "your_generated_token_here"For systemd autoboot, configure Environment=SPEC_MEMO_AUTH_TOKEN=your_generated_token_here in /etc/systemd/system/spec-memo.service (see systemd setup).
Export the token in your shell environment (~/.bashrc, ~/.zshrc, or Windows Environment Variables):
export SPEC_MEMO_AUTH_TOKEN="your_generated_token_here"
memo setup --mode hybrid --url http://daemon.internal:3000 --host cursor --write-mcpIf connecting your IDE (Cursor, VS Code, Claude Desktop, Antigravity) directly to the remote SSE endpoint, provide the Authorization header in your MCP configuration:
{
"mcpServers": {
"spec-memo": {
"url": "http://daemon.internal:3123/sse",
"headers": {
"Authorization": "Bearer your_generated_token_here"
}
}
}
}- Status Monitor Web UI (Port 3124): Open
http://daemon.internal:3124/β when a token is configured, the UI redirects to/login(password-manager-friendly token field). The session is an HttpOnly cookie; the browser does not put the token in the address bar or API URLs. - Health & API Verification:
# Check MCP daemon health (port 3123) curl -s -H "Authorization: Bearer your_generated_token_here" http://daemon.internal:3123/health # Check status monitor API (port 3124) curl -s -H "Authorization: Bearer your_generated_token_here" http://daemon.internal:3124/api/status
Run memo doctor on the client or server to verify whether the deployment mode detects an active token in the environment:
memo doctor- Start
memo serve --sse(status companion on by default). - Open http://127.0.0.1:3124/ in a browser (favorite that URL).
- Confirm health cards (MCP host/port, vault count, uptime) and the live activity log (tool + HTTP events).
- Filter by vault/project via the page control or
?project=<projectId>.
Quick machine checks:
curl -s http://127.0.0.1:3123/health
curl -s http://127.0.0.1:3124/api/status
curl -s http://127.0.0.1:3124/api/vaults
# JSON array of `{ id, displayName }` β the monitor sidebar and vault selectors use this array (not `{ vaults: [...] }`).
# Live stream (SSE): GET http://127.0.0.1:3124/api/events/streamWhen a token is set, send Authorization: Bearer <token> (or a session cookie from /login). Diagnostic routes are read-only except explicit operator writes: backup/reset HTTP endpoints and POST /api/wiki/regenerate. Canvas remains a separate graph UI.
The status monitor includes a dedicated Backups tab (?tab=backups or #tab-backups) for vault snapshot management:
- Create Backup β persists a timestamped
.zipunder$SPEC_MEMO_ROOT/backups/. With All vaults selected, a confirmation dialog is required (confirmFullBackup: trueon the API). A selected project vault creates a single-project snapshot. - Inventory β lists saved archives with filename, size, entry counts, scope (
full/project), and encryption status. Filter by filename, scope, project, kinds present, date range, and encryption. - Row actions β Restore (
POST /api/vaults/restore), Download (GET /api/vaults/backups/{filename}), and Delete (DELETE /api/vaults/backups/{filename}with{ confirm: true }). Click a row to open the details drawer (GET /api/vaults/backups/{filename}/inspect). - Complete archives β backups include all durable record kinds (
trap,decision,spec,plan,state,log,scratch,review,prompt,session). Restore rebuilds FTS automatically.
HTTP routes:
| Method | Path | Role |
|---|---|---|
POST |
/api/vaults/backups |
Persist snapshot (projectId or confirmFullBackup: true) |
GET |
/api/vaults/backups |
List inventory (optional q, scope, projectId, encrypted, since, until, kind, size filters) |
GET |
/api/vaults/backups/{filename} |
Download archive |
GET |
/api/vaults/backups/{filename}/inspect |
Details drawer metadata |
DELETE |
/api/vaults/backups/{filename} |
Remove archive file ({ confirm: true }) |
POST /api/vaults/export remains for scripted browser zip download (full vault requires confirmFullBackup: true when projectId is omitted).
Tip
CLI parity: memo backups, memo restore --backup β¦, and memo export-vault operate on the same backups/ folder. UI zips contain vault-backup.json β extract and run memo import-vault --archive vault-backup.json for CLI restore.
The Vaults tab (?tab=vaults) lists vault projects from GET /api/vaults (JSON array with id, displayName, aliasOf, recordCount). Operators can create projects, set aliases, merge sources into a canonical id (optional copyRecords), edit display names, and delete with confirmation. Mutating routes use the same auth and path sanitization as backup/reset.
CLI extra (not an MCP tool): memo vault list|alias|merge|create|update|delete (see Command Reference).
The Wiki tab (?tab=wiki or ?tab=wiki&project={id}) shows the vault file projects/{projectId}/WIKI.md. It is not the consumer product README.
- Select a project (All vaults is refused). Missing
WIKI.mdshows an empty state; Regenerate stays available. - Regenerate posts
POST /api/wiki/regeneratewith{ "projectId" }(collect β filltemplate.mdβ persist). Optional AI polish is off by default; setwiki.aiEnabledin vaultconfig.jsonorSPEC_MEMO_WIKI_AI=1. Polish failures still save the deterministic page (aiPolished: false). - CLI extra (not an MCP tool):
memo wiki --project <id>andmemo wiki --project <id> --regenerate. Unavailable in remote mode.
HTTP routes:
| Method | Path | Role |
|---|---|---|
GET |
/api/wiki?project= |
Current markdown (exists false when missing) |
GET |
/api/wiki/section?project=&id= |
One h2 section by slug |
POST |
/api/wiki/regenerate |
Collect, render, persist WIKI.md |
memo doctor # vault + FTS + in-repo pollution scan
memo doctor --json
memo doctor --rebuild # rebuild SQLite FTS5 from markdown
memo doctor --fix # delete leftover in-tree workflow residue
memo doctor --check-capture <path> # verify CAPTURED vs IGNORED exclusion boundaryAlso useful: memo rank (trap recurrence), memo wiki --regenerate (vault project page), memo gc --dry-run, and the status page live log while the SSE daemon is up.
Use this so the MCP SSE daemon (and status monitor) start on boot. Prefer a durable vault directory (not a login-user ~/.spec-memo unless intentional).
sudo mkdir -p /var/lib/spec-memo
# Install Node 22+ + clone/build to /opt/spec-memo (or npm i -g spec-memo and point ExecStart at `memo`)/etc/systemd/system/spec-memo.service:
[Unit]
Description=spec-memo MCP SSE
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/spec-memo
Environment=SPEC_MEMO_ROOT=/var/lib/spec-memo
# Auth token (SPEC_MEMO_AUTH_TOKEN or SPEC_MEMO_SSE_TOKEN)
Environment=SPEC_MEMO_AUTH_TOKEN=replace-me
ExecStart=/usr/bin/node /opt/spec-memo/dist/cli.js serve --sse --host 0.0.0.0 --port 3000
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now spec-memo.service
sudo systemctl status spec-memo.service
curl -s -H "Authorization: Bearer replace-me" http://127.0.0.1:3000/health
# Status UI: http://<host>:3001/ (also requires the bearer when a token is set)
# Inspect configured environment variables on service:
systemctl show spec-memo.service --property=Environment
# Or inspect live environment variables of the running process:
sudo cat /proc/$(pgrep -f "spec-memo" | head -n 1)/environ | tr '\0' '\n' | grep SPEC_MEMO- Install Node 22+ and
npm install -g github:jpolvora/spec-memo(or build this repo and use the full path tonode+dist\cli.js). - Create a vault dir, e.g.
C:\spec-memo-vault. - Task Scheduler β Create Task:
- Trigger: At log on (or At startup with a service account).
- Action: Start a program
- Program:
node(full path if needed) - Arguments:
"C:\Users\<you>\AppData\Roaming\npm\node_modules\spec-memo\dist\cli.js" serve --sse --host 127.0.0.1 --port 3000
(ormemo.cmd serve --sse β¦ifmemois on PATH)
- Program:
- Start in: vault-friendly working directory.
- Add environment variables on the task (or a wrapper
.cmd):SPEC_MEMO_ROOT=C:\spec-memo-vault, andSPEC_MEMO_SSE_TOKEN=β¦if binding off loopback. - Optional: NSSM / WinSW to wrap the same command as a Windows Service with restart-on-failure.
Verify: open http://127.0.0.1:3001/ and curl http://127.0.0.1:3000/health.
Shared-lab note: project identity comes from the git remote of the tool cwd / projectId. Laptop paths do not exist on the server β pass a stable projectId (e.g. github.com-jpolvora-spec-memo) or a server-side clone path as cwd. One bearer token = shared vault (no per-user ACL).
Zero setup required in product repos.
spec-memo requires no configuration files, no .spec-memo directory, and no committed pointers in your project.
- Automatic Project Identity: When an agent works in any project directory,
spec-memodetects the git remoteorigin(e.g.github.com/org/repo) and maps all memory to that project's external vault. All clones of the same repository automatically share the exact same working memory. - Prevent Accidental In-Repo Memory Commits: Install the pre-commit write-block hook in any consumer repository:
(Blocks accidental commits of
cd /path/to/your-product-repo memo hook install.agents/plans/,MEMORY.md,memory/*.md, and.state.md)
ββββββββββββββββββββββββββββββββββββββββββββββββ
β AI Agent Session β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββ
β
1. Session Start β 2. During Work
ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββ
βΌ βΌ
memo bootstrap memo upsert / append
(Returns token-budgeted brief: (Saves traps, decisions,
Traps, Decisions, Live Slug, Drift) specs, plans, logs to vault)
β
β 3. Query on Demand
ββββββββββββββββββββββββββββΊ memo search / get
β
βΌ 4. Session Finish / Housekeeping
memo gc
(Purges expired scratch,
compacts completed plans)
-
Session Start (
bootstrap): At the start of a prompt or task, the agent invokesbootstrap:memo bootstrap
Returns a token-budgeted brief (default 8 KB; raise via
~/.spec-memo/config.jsonbootstrap.maxBytesor--maxBytes) containing top ranked anti-regression traps for relevant files, open architecture decisions, active spec/plan slice, and code drift alerts. -
During Work (
upsert&append):- Record newly discovered bug traps or anti-regression lessons:
memo upsert --kind trap --title "SQLite WAL Lock on Windows" --severity high --path-patterns "src/db/*.ts" --body "Always close statements before closing connection."
- Record an architectural decision:
memo upsert --kind decision --title "Use SQLite FTS5 for Search" --body "ADR: FTS5 provides fast local indexing with zero external daemons."
- Append an audit or task event:
memo append --event "Refactored vault locking mechanism and passed all 178 tests"
- Record newly discovered bug traps or anti-regression lessons:
-
Query Memory (
search&get):- Filtered full-text search:
memo search "database lock" --kind trap
- Fetch a specific record by ID or slug:
memo get --id trap-sqlite-wal-lock-on-windows
- Filtered full-text search:
-
Finishing & Housekeeping (
gc&promote):- Run garbage collection to apply TTL retention (purges 7-day scratch, 14-day review records, and compacts completed plans):
memo gc
- If a human explicitly wants a decision or spec recorded in product documentation, promote it into the product repository:
memo promote trap-sqlite-wal-lock-on-windows --to docs/adr/002-sqlite-locking.md
- Run garbage collection to apply TTL retention (purges 7-day scratch, 14-day review records, and compacts completed plans):
All memory is stored in $SPEC_MEMO_ROOT (defaults to ~/.spec-memo/):
~/.spec-memo/
βββ config.json # Global vault configuration (TTL, budget, enableTelemetry, git sync)
βββ memo.sqlite # Disposable SQLite FTS5 search index
βββ telemetry/ # Append-only daily rolling usage logs (telemetry-YYYY-MM-DD.part-N.jsonl)
βββ projects/
βββ <projectId>/ # Hash derived from git remote origin
βββ project.json # Project metadata, remote URL, display name
βββ TRAPS.md # Auto-compiled markdown view of active traps
βββ DECISIONS.md # Auto-compiled markdown view of architecture decisions
βββ INDEX.md # Auto-compiled markdown view of all project specs & plans
βββ traps/ # Individual *.md records with YAML frontmatter
βββ decisions/ # Architecture decisions (ADRs)
βββ specs/ # Feature specifications
βββ plans/ # Implementation plans and execution state
βββ logs/ # Append-only chronological run logs & roll-ups
βββ reviews/ # Code review and audit notes (14-day TTL)
βββ scratch/ # Temporary scratchpad notes (7-day TTL)
- Markdown Source of Truth: Every record is a human-readable Markdown file with structured YAML frontmatter.
- Disposable SQLite FTS5 Index:
memo.sqliteprovides instant Porter-stemmed search, tag filtering, and path pattern globbing. If deleted or corrupted, it is automatically rebuilt from the Markdown files. - Automatic Project Identity: Repositories are identified by normalized remote URL (
git@github.com:org/repo.gitβgithub.com/org/repo). Multiple clones on the same machine share the same memory without conflicts. - Operational Telemetry & Usage Analytics: Built-in rolling JSONL telemetry records tool latencies, endpoints, duration, and error codes under
~/.spec-memo/telemetry/(enableTelemetry: true). Asynchronously batched with zero disk blockages and secret redaction. - Secret Redaction & Safety: Built-in pattern filters automatically redact API keys, JWTs, private keys, and bearer tokens from memory records before writing. Writes directed to the product repository root are rejected by default.
- Automatic Trap Deduplication: When saving a new trap,
spec-memochecks token overlap against existing traps with matching path patterns. If overlap exceeds 70%, the older trap is automatically marked assuperseded. - Spec Code Drift Detection: When specifications declare
linkedPathsandverifiedAtSha,bootstrapcompares git status and file contents against the verified commit SHA, warning the agent if the product code drifted from the specification.
Inspect running daemons, deployment mode, socket reachability, project bindings, and storage metrics with a single read-only command. memo status never creates or rewrites vault files (config.json, projects/, telemetry/). Malformed config.json reports CONFIG_ERROR. Remote /health 401/403 fails --check (exit 1).
# Display colorized status dashboard (aliases: memo info, memo state)
memo status
# Health check mode for CI/CD or scripts (exits 0 if healthy, 1 if issues exist)
memo status --check
# Machine-readable JSON output
memo status --jsonInspect vault integrity, SQLite FTS index status, and detect leftover in-repo workflow pollution. (Also see Run, serve, status monitor & autoboot for live SSE status checks.)
# Check vault health and scan product repository for residue
memo doctor
# Check and automatically clean up in-tree workflow pollution files
memo doctor --fix
# Rebuild the SQLite FTS5 index from vault markdown records
memo doctor --rebuildOne-shot migration of existing .agents/specs/, memory/*.md, MEMORY.md, .agents/plans/, and CHANGELOG.md files into the external vault:
memo import --from /path/to/legacy-repoManage backups, restore full ZIP archives, or reset the memory store with automatic safety snapshots:
# List available timestamped backups
memo backups
# Restore the most recent backup
memo restore --latest
# Restore from a specific backup archive (.zip or .json)
memo restore --backup ~/.spec-memo/backups/2026-08-31-14-30-45-backup.zip
# Reset vault records and SQLite databases with a mandatory pre-wipe backup
memo reset --all --force
# Export encrypted vault archive
memo export-vault --password "my-secure-password" -o ~/spec-memo-backup.json
# Restore encrypted vault archive on another machine
memo restore ~/spec-memo-backup.json --password "my-secure-password"Enable automatic private git remote backup on the vault root (~/.spec-memo/):
In ~/.spec-memo/config.json:
{
"bootstrap": {
"maxBytes": 8192
},
"vaultGit": {
"enabled": true,
"atomic": false,
"remoteUrl": "git@github.com:my-user/my-private-memory-vault.git",
"branch": "main"
}
}bootstrap.maxBytes is the default UTF-8 session brief budget (8192). Increase it to return a larger memo bootstrap payload; per-call --maxBytes / MCP maxBytes still overrides this value.
vaultGit.atomic defaults to false (batched): mutations write markdown only; git commit + remote pull/push run on memo sync, MCP/CLI session_end, or graceful memo serve shutdown. Set "atomic": true for per-mutation commit and push (fail-open; errors go to error.logs).
When both mode: hybrid and vaultGit.enabled are set, memo sync dispatches hybrid HTTP and vault-git in parallel. Either channel can fail without crashing the MCP/SSE server. CLI one-shot memo upsert in batched mode does not flush git on process exit; run memo sync.
Vault records can be selectively promoted into the product repository with ADR templates:
memo promote decision-sqlite-fts5 --to docs/adr/001-sqlite-fts5.md --format adrResolve synchronization differences between local and remote vaults with automatic semantic auto-merging:
# Preview reconciliation changes (dry-run)
memo reconcile --dry-run
# Reconcile preferring local vault as the authoritative source of truth
memo reconcile --prefer local
# Reconcile preferring remote daemon
memo reconcile --prefer remote
# Automatic cleanup of identical conflict sidecars
memo reconcile --clean-sidecars- Smart Auto-Merge (
smart-merge): When record bodies match, divergent retrieval counts (hits,lastHit,occurrences,tags,linkedPaths) merge cleanly in place with zero conflict files generated. - Single Sidecar Cap: If true body conflicts exist under
--strategy sidecar, a single deterministic${slug}.conflict.mdsidecar is maintained rather than proliferating timestamped files. - Doctor Cleanup:
memo doctor --fixautomatically cleans obsolete sidecars whose bodies match the base record. - Transactional Rollback: Multi-record changeset applications use copy-on-write staging rollback journals; errors cleanly revert state without partial writes.
| Command / Tool | Role | Key Options |
|---|---|---|
status |
Query read-only operational dashboard, daemon reachability, configuration, and storage statistics (aliases: info, state, setup --check) |
--check, --cwd, --vaultRoot, --json |
setup |
Configure deployment mode & agent host MCP wiring | --mode, --url, --host, --print-mcp, --write-mcp, --json |
bootstrap |
Compile token-budgeted session brief | --maxBytes (overrides config.json bootstrap.maxBytes, default 8192), --query, --path, --slug, --session-id, --explain |
search |
Filtered FTS5 retrieval across records | --kind, --tags, --path, --all, --sort (relevance|occurrences|updated|hits), --hit-ids, --session-id, --explain, --include-expired, --as-of |
get |
Read one record by id or kind+slug (eligible kinds bump hits) |
--id or --kind+--slug, --session-id |
upsert |
Create or update typed memory record | --kind, --title, --severity, --path-patterns, --body |
append |
Append chronological event log | --event, --kind |
forget |
Archive or permanently delete record | --id, --purge |
gc |
Apply TTL retention and compact plans | --dry-run, --project, --purge |
promote |
Safe export of record to product repo | --id, --to, --format (raw/adr/madr/skill), --force, --limit |
check_version / check-version |
Compare running version to npm latest | --json |
install_skills / install-skills |
Install ws-memo / ws-session-tracking into a consumer repo or global skills roots |
--product-root, --global, --skill, --force, --json |
install_hooks / install-hooks |
Optional agent lifecycle hooks for Antigravity, OpenCode, Cursor, Claude (CLI-only) | --host, --global, --apply, --dry-run, --force, --remove, --json |
prompt / prompts |
Ingest & query prompt history; derive rules; export stories; record memory feedback | record/list/search/show/session/export/derive-rules/feedback |
session |
Start/end/inspect work sessions (alias into prompt) |
start/end/handoff/show/export, --summary, --pr, --handoff-steps, --shared, --objective |
activity |
Timesheet / invoicing activity report | --since, --until, --client, --json |
feedback |
Submit helpful/stale/wrong feedback on a memory record (CLI extra) | <id>, --helpful/--stale/--wrong, --comment |
rank |
List traps by recurrence (CLI-only) | --layer, --limit, --backfill, --json |
doctor |
Diagnose health, mode, conflict sidecars, semantic contradictions, stale traps, and fix repo pollution | --fix, --rebuild, --json |
sync |
Synchronize vault records (hybrid HTTP, vault-git, or both in parallel) | --all, --dry-run, --prefer (local|remote), --strategy, --clean-sidecars, --force, --json |
reconcile |
Reconcile sync conflicts, apply smart semantic auto-merge, and clean conflict sidecars | --prefer (local|remote), --strategy (smart-merge|local-wins|remote-wins|sidecar), --clean-sidecars, --dry-run, --all, --json |
import |
Import legacy .agents tree to vault |
--from, --vaultRoot |
export-vault |
Export encrypted portable archive | --password, --output, --project |
import-vault / restore |
Restore portable archive (.zip or .json) into vault | <file>, --backup, --latest, --password |
backups |
List available timestamped backups in $SPEC_MEMO_ROOT/backups/ |
--vaultRoot, --json |
reset |
Reset vault database and clear files with mandatory pre-wipe backup | --all, --project, --force, --password |
hook install |
Install pre-commit write-block hook | --productRoot |
wiki |
Print or regenerate vault projects/{id}/WIKI.md (CLI extra; not an MCP tool) |
--project, --regenerate, --json |
vault |
Manage vault projects (alias redirect, merge, CRUD; CLI extra; not an MCP tool) | list, alias --from --to, unalias --from, merge --source --target [--copy-records], create, update, delete --confirm |
serve |
Run stdio or SSE MCP server for agent hosts (SSE co-starts status on :3124; stdio opt-in via --status) |
--sse, --port, --status, --status-port, --no-status, --auth-token |
How do I check if I am on the latest spec-memo?
memo check-version --jsonCompare current to latest. When the registry is unreachable, updateAvailable is "unknown" and latest is null.
How do I install the ws-memo skill into a consumer project?
memo install-skills --product-root /path/to/consumer
# Global (Cursor/agents + Antigravity if ~/.gemini/config exists):
memo install-skills --global --forceUse --force only when overwriting a diverged destination. MCP hosts can call install_skills with the same arguments (global: true for global roots).
How do I make the memo command available on my PATH (Windows / Linux / macOS)?
Run npm link inside your spec-memo clone directory. This links the package bin ("memo": "./dist/cli.js") to your npm global directory (e.g. %AppData%\Roaming\npm on Windows or /usr/local/bin on Linux). After running npm run build, memo is immediately accessible in any new terminal session without re-linking. See Making memo Available Globally on PATH for manual shim alternatives and PATH troubleshooting.
MIT