Markdown-native personal context vault for AI tools. Local-first, portable, three verbs.
Overview
A portable, markdown-native, locally-owned personal context vault for AI tools. Three verbs. One vault. Any tool. Every AI coding tool eventually loses context. Sessions end. Tools change. You start fresh in Cursor on Monday, then jump to Claude Code on Tuesday, then a Claude Desktop window for planning on Wednesday - and each one needs to be told from scratch what you're working on, what's been decided, what's broken, what's next. Memcrate is a local markdown vault plus three verbs (/save, /pin, /load) that any AI tool can read and write to. Your context lives in plain .md files you own. The verbs make the rituals consistent across tools. Four files inside Core/. That's the whole verbs surface - /save, /pin, and /load only read and write within Core/. Add optional folders alongside Core/ (Projects/, Daily/, Tasks/, Inbox/) whenever you want the personal-OS scope. Read docs/overview.md for the full pitch, docs/verbs.md for the verb contracts, and docs/vault-structure.
README
Memcrate
A portable, markdown-native, locally-owned personal context vault for AI tools. Three verbs. One vault. Any tool.
What this is
Every AI coding tool eventually loses context. Sessions end. Tools change. You start fresh in Cursor on Monday, then jump to Claude Code on Tuesday, then a Claude Desktop window for planning on Wednesday - and each one needs to be told from scratch what you’re working on, what’s been decided, what’s broken, what’s next.
Memcrate is a local markdown vault plus three verbs (/save, /pin, /load) that any AI tool can read and write to. Your context lives in plain .md files you own. The verbs make the rituals consistent across tools.
What your vault looks like
~/memcrate-vault/
├── README.md
├── .memcrate # marker file (lets tools find this vault)
└── Core/
├── Context/
│ ├── Profile.md # stable: who you are, tools, anti-goals
│ ├── Projects.md # every project with status, stack
│ └── Current State.md # living: this week's focus, deadlines
└── Sessions/ # /save writes session logs here
Four files inside Core/. That’s the whole verbs surface - /save, /pin, and /load only read and write within Core/. Add optional folders alongside Core/ (Projects/, Daily/, Tasks/, Inbox/) whenever you want the personal-OS scope.
Read docs/overview.md for the full pitch, docs/verbs.md for the verb contracts, and docs/vault-structure.md for the structural details.
Why not [other thing]
- Static
CLAUDE.md/AGENTS.md/.cursorrulescapture project facts but not session state. - Cloud-backed AI memory (mem0, Letta, supermemory) is vendor-locked and not repo-scoped.
- Session-memory packs (CPR - the verb-trio inspiration here) work great for one tool but don’t span tools or carry full personal context.
- MCP memory servers are binary; humans can’t read them.
Memcrate is a personal context OS, not a memory tool. Your project catalog, daily state, decisions, and infrastructure all draw from the same vault.
Repo layout
memcrate/
├── reference-vault/ # Starter vault scaffold (Core/ + .memcrate marker) - copy anywhere
├── skills/ # Canonical SKILL.md files for each AI tool
│ └── agent/ # /save, /load, /pin as SKILL.md (Claude Code, Claude Desktop, Codex)
└── docs/ # Format spec: overview, verbs, vault structure, skills, CLI
Getting started
Install the CLI, then run memcrate. One question, then it does the rest.
$ memcrate
Where should your vault live? [~/memcrate-vault]:
>
Created your vault at ~/memcrate-vault.
Installed 3 skills for Claude Code to ~/.claude/skills
Installed 3 skills for Codex to ~/.codex/skills
You now have three verbs in Claude Code, Claude Desktop, and Codex:
load read your vault and get oriented. Run this first.
pin promote a fact into your permanent context files.
save write a session log before you finish.
Type them as /load in Claude Code and Claude Desktop, $load in Codex.
Claude Desktop needs no separate step. Its local agent mode reads the same ~/.claude/skills/ directory Claude Code does.
Re-running is safe. It reuses an existing vault and refreshes the skills.
Optionally, tell your tools who you are:
memcrate profile
Four questions (name, what you build, tools, projects) that fill in Profile.md and Projects.md so your first /load has something to read. Everything works without it; you can also just edit those two files by hand, or let /pin fill them in as you work.
Install the CLI
Pick one path:
Linux / macOS (Apple Silicon) - curl one-liner:
curl -fsSL https://raw.githubusercontent.com/memcrate/memcrate/main/install.sh | sh
Drops the memcrate binary into /usr/local/bin (uses sudo if needed).
Windows - PowerShell one-liner:
irm https://raw.githubusercontent.com/memcrate/memcrate/main/install.ps1 | iex
Drops memcrate.exe into %LOCALAPPDATA%\Programs\memcrate\ and adds it to your user PATH.
npm (downloads the same prebuilt binary, no dependencies):
npm install -g memcrate
Any platform with Rust (also the path for Intel Macs):
cargo install memcrate
Options
memcrate --vault ~/notes # skip the location prompt
memcrate --yes # take every default, ask nothing (implied without a terminal)
memcrate --full # also create Projects/, Daily/, Tasks/, Inbox/
--yes plus --vault is the scripted form for dotfiles and container images.
Use the verbs
Start Claude Code or Codex, then type the verb. Claude Code uses a leading
slash (/load); Codex uses a leading dollar sign ($load). The three verbs:
/loadreads your vault and reconstructs context. Run it first in any new session./pinpromotes a fact intoProfile.md,Projects.md, orCurrent State.mdso it survives across sessions./savewrites a session log toCore/Sessions/so the next/loadpicks up where you left off.
Setup writes your vault’s full path into the installed skills, so they read it from there first. If that misses, they try the current directory, then ~/memcrate-vault, then a depth-1 scan of your home directory. If nothing matches, /load asks you where it is.
Skills you already own
Memcrate never replaces a skill it did not install. If you already have your own load, save, or pin, it leaves yours alone and installs its verbs in that tool as memcrate-load, memcrate-pin, and memcrate-save, then tells you what to type (/memcrate-load instead of /load). The choice is made per tool, so a conflict in Claude Code does not rename the verbs in Codex.
Advanced install options
# Specific version (Linux / macOS)
MEMCRATE_VERSION=v0.4.0 curl -fsSL https://raw.githubusercontent.com/memcrate/memcrate/main/install.sh | sh
# Specific version (Windows)
$env:MEMCRATE_VERSION="v0.4.0"; irm https://raw.githubusercontent.com/memcrate/memcrate/main/install.ps1 | iex
# Custom install dir on Linux / macOS (no sudo needed)
MEMCRATE_INSTALL_DIR=$HOME/.local/bin curl -fsSL https://raw.githubusercontent.com/memcrate/memcrate/main/install.sh | sh
Pre-built binaries on the releases page: Linux x86_64, macOS Apple Silicon, Windows x86_64. Intel Macs: install via cargo install memcrate (GitHub retired its free Intel macOS runner image in early 2026, so we no longer ship a pre-built Intel binary).
About reference-vault/
This is the template, not a vault you use. It is the canonical shape of a Memcrate vault (same as the “What your vault looks like” diagram above), compiled into the CLI binary and stamped out at whatever path you choose when you run memcrate, which defaults to ~/memcrate-vault.
The two names are deliberately different: reference-vault/ is the mold, ~/memcrate-vault is the copy on your disk. Each canonical file has section guidance inline so AI tools know what belongs where when /pin writes to it. You can also copy reference-vault/ directly into any directory if you’d rather skip the CLI.
Development
sh scripts/verify.sh is the quality gate: leak check, fmt check, clippy (warnings deny), tests, build. The same script runs as a pre-push hook (wire it once per clone with git config core.hooksPath .githooks) and in CI on every push and pull request. CI also runs the tests on Windows and macOS. tests/cli.rs runs the built binary in scratch homes, and fails if the sample output under Getting started (after the prompt) stops matching what memcrate actually prints.
scripts/smoke-install.sh and scripts/smoke-install.ps1 install Memcrate through one channel inside a scratch directory, then run setup and check the vault and skills it wrote. The default script channel runs the real installer from your checkout against the latest published release. The npm channel packs your checkout’s npm wrapper as the latest published version, installs it, and checks that the shim passes the binary’s exit code through. The Installers workflow runs both on Linux, macOS, and Windows (PowerShell 5.1 and 7) whenever an installer or the npm wrapper changes.
Pushing a v*.*.* tag runs the Release workflow. It checks that the tag, Cargo.toml, and npm/package.json agree, builds the binaries for GitHub Releases, publishes to npm, and publishes to crates.io last, since a crates.io publish cannot be undone. Both registries use trusted publishing, so the repo stores no publish tokens: npmjs.com and crates.io each list this repository’s release.yml as a trusted publisher. If a publish fails, fix the cause and rerun the failed jobs.
After every release the Installers workflow runs as a post-release check with MEMCRATE_EXPECT_VERSION set to the tag. npm and cargo install then install from their registries, and every channel (install.sh, install.ps1, npm, and cargo) must install the tagged version, which is what a plain install gets once the release is out. Pre-releases skip npm and cargo, which they are never published to. To rerun the check, start the Installers workflow from Actions with the version that should now be the latest.
The leak check exists because this repo’s reference vault and skills are generalized from a real private vault. It blocks a push when a private project name, hostname, or absolute home path reaches a tracked file. Terms are read from the maintainer’s local vault at runtime and are never committed here, so the check is a silent no-op on CI and on any other contributor’s machine.
scripts/live-test.sh answers the one question the gate above cannot: do the skills actually work in a real agent session? It installs into a scratch home, then runs headless sessions against one vault. Each step must show that the installed skill ran (Claude Code is driven with /load, /save, and /pin, because its --bare API-key mode has no automatic skill tool), and is then checked by what lands on disk, not by wording. load must answer with a fact that exists only inside the vault. save must write exactly one new session log with type: session frontmatter and a fact from the prompt. pin must put a fact from the prompt into a context file and bump its last_updated. The run also fails if anything outside the vault appears or disappears, apart from the agent’s own state. scripts/live-test.sh codex tests Codex (needs OPENAI_API_KEY); scripts/live-test.sh claude tests Claude Code (needs ANTHROPIC_API_KEY, and LIVE_TEST_CLAUDE_MODEL picks a model). Add prefixed to plant your own save skill first, check that Memcrate fell back to memcrate-load, memcrate-pin, and memcrate-save, and load by the prefixed name. Claude Desktop shares Claude Code’s skills directory but can only be driven by hand.
It is deliberately not in verify.sh, the pre-push hook, or push CI: it costs money, needs network, and an agent words its answer differently every run, so a bad day upstream should not block a push. Run it locally before tagging a release, or from the Live agent test workflow in GitHub Actions, which runs the plain test on Linux, macOS, and Windows and the prefixed test on Linux, for Claude Code, Codex, or both.
License
- Code (
skills/, future CLI source, install scripts) - MIT - Format spec (
docs/) - CC0. Build a Memcrate-compatible tool without legal friction.
Credit
The verb trio (/save, /pin, /load) generalizes EliaAlberti/cpr-compress-preserve-resume - a Claude-Code-only session-memory skill pack. Memcrate scales that pattern to multi-tool personal-context-OS, adds /pin for the bridge from session memory to permanent memory, and decouples the format from any one tool. Honest lineage.
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add memcrate/memcrate