Compartment

Encrypted, offline long-term memory vault shared by every MCP client on one computer

By Max Freedom Pollard (individual) Python Local · stdio Knowledge and memory

54 popularity score ★ 570 ↓ 1.6k/mo

Connect your client

Local (PyPI)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

FirstTerminal
pipx install compartment
compartment init
Claude CodeTerminal
claude mcp add compartment -- compartment serve
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "compartment": {
      "command": "compartment",
      "args": [
        "serve"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "compartment": {
      "command": "compartment",
      "args": [
        "serve"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "compartment": {
      "type": "stdio",
      "command": "compartment",
      "args": [
        "serve"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.compartment]
command = "compartment"
args = ["serve"]
Gemini CLITerminal
gemini mcp add --scope user compartment compartment -- serve

Settings 3

COMPARTMENT_VAULT Optional: Path of the vault to use. Default ~/.compartment/memory.vault.
COMPARTMENT_PASSPHRASE secret Optional: Vault passphrase for scripts and CI; otherwise unlock with `compartment unlock`.
COMPARTMENT_SESSION_DIR Optional: Directory holding the unlock credential. Default ~/.compartment/session.

What it does

Compartment keeps an assistant's memories in a single encrypted vault file on your own machine and serves it over stdio to any MCP client, so Claude Code, Cursor, Codex and others read and write the same store. Everything in the vault is encrypted with XChaCha20-Poly1305, embedding vectors included, under a key derived from a passphrase you choose; nothing is sent over the network and there is no account or API key. Search combines a bundled local embedding model with keyword matching, and memories can be tagged, linked into an entity graph, given an expiry date, or replaced when an opinion changes.

The store is opinionated about what a memory is: each record must be a single claim of at most 200 characters (the max_memory_chars setting) and must name its source, and lists or headings are rejected with an error explaining how to split them. memory_store_many writes a batch in one call. Forgetting with shred destroys the record's own key, so the content cannot be recovered from the current vault.

The server exposes 14 tools in version 4.13.0, but memory_unlock refuses to run unless unlock_tool_enabled is set in the vault's config file, so a default install offers 13. If no unlock credential is found at start, the server still starts but every memory tool returns a locked error until you run `compartment unlock` on the machine (src/compartment/server.py). A desktop panel (menu bar on macOS, tray on Windows, a window on Linux) and a read-only browser dashboard on 127.0.0.1 come with the package.

What it needs

RuntimePython 3.11+
Runs onmacOS, Windows, Linux
Also
  • Microsoft Visual C++ runtime on Windows
  • Tk (python3-tk) for the Linux panel window

Python 3.11 to 3.14 for the pipx (recommended), uv or pip install. Intel Macs stop at Python 3.13 and Windows on ARM needs 3.12 or newer. A system-wide pip install is refused on Debian 12+, Ubuntu 23.04+, Fedora, Arch and Homebrew Python, so use pipx, uv or a virtual environment. A macOS .pkg bundles Python instead. Run `compartment init` once before connecting a client: it asks for a passphrase and creates the vault at ~/.compartment/memory.vault. The vault must be unlocked (`compartment unlock`, the app, or COMPARTMENT_PASSPHRASE) for tools to work. A client started from the Dock or Start menu may not see your PATH, so give it the full path that `which compartment` prints.

Limits

  • Size cap Each stored memory is capped at 200 characters and one claim unless max_memory_chars is changed (0 turns the check off)
  • Size cap memory_search returns 8 results by default (top_k), memory_recent 20 by default, memory_relations at most 500 by default (limit)
  • Limit The vault locks after 30 idle minutes by default (auto_lock_minutes, 0 turns it off) and at each reboot unless the macOS Keychain option is chosen
  • Limit No recovery: losing the passphrase (and the 2FA keyfile, if enrolled) leaves the vault permanently unreadable
  • Not covered The --caller name that scopes namespace grants is self-declared, so a client can claim another client's name
  • Platform Pip wheels cover macOS 13.4+, Windows 10/11 and glibc 2.28+ Linux; Alpine, FreeBSD and Termux need the system's onnxruntime
  • Limit No Docker image is published; the image is built from a checkout

Each authored memory is capped at 200 characters and one claim unless max_memory_chars is changed (0 turns the check off). memory_search returns 8 results by default (top_k); memory_recent 20 by default; memory_relations at most 500 relations by default. The vault locks after 30 idle minutes by default and always on reboot, unless macOS Keychain unlock is opted into. There is no recovery: losing the passphrase (and the 2FA keyfile, if enrolled) makes the vault permanently unreadable. The --caller identity that scopes namespace grants is self-declared, so a client can claim another's name. The Docker image is built from a checkout; none is published.

Who it suits

Suits a developer who wants one private memory shared across several local coding assistants, and who is willing to manage a passphrase and unlock the vault after each reboot. Because everything runs and stays on one machine, it fits offline or privacy-sensitive setups. It is a poor fit for a team that needs a shared memory across machines through a hosted service, or for anyone who wants long free-form notes or documents stored as single entries, since records are limited to short single claims.

Tools 14

7 only read, 5 change things, 2 can delete or overwrite. A ? marks an optional parameter.

memory_search
Hybrid semantic and keyword search of the vault, with namespace, tag and date filtersquery: stringnamespace?: stringtags?: arraytop_k?: integersince?: numberuntil?: numberdiscovered_since?: stringdiscovered_until?: string
memory_store changes
Save one short claim with its source, optional tags, kind, expiry and supersedes listtext: stringsource: stringnamespace?: stringtags?: arrayimportance?: numberquarantined?: booleandiscovered?: stringexpires?: stringkind?: enumsupersedes?: array
memory_store_many changes
Save a batch of claims in one callfacts: arraysource: stringnamespace?: stringdiscovered?: string
memory_get
Fetch one memory by its id, including superseded onesrecord_id: string
memory_recent
List the most recently saved memorieslimit?: integernamespace?: stringinclude_seeded?: boolean
memory_forget deletes
Delete a memory, optionally shredding its key so it cannot be recoveredrecord_id: stringshred?: boolean
memory_link changes
Record a subject-predicate-object relation between two entitiessubject: stringpredicate: stringobject: stringsrc_id?: stringvalid_from?: numbervalid_to?: numbernamespace?: string
memory_relations
Query the entity relation graph with filtersentity?: stringsubject?: stringpredicate?: stringobject?: stringas_of?: numbernamespace?: stringlimit?: integer
memory_unlink deletes
Remove a stored relation by idrelation_id: string
memory_list_namespaces
List the namespaces the caller may use
memory_status
Report vault path, lock state and counts
memory_selftest
Run a quick check that storage and search work
memory_lock changes
Drop the key from memory and lock the vault
memory_unlock changes
Unlock the vault with its passphrase; disabled unless unlock_tool_enabled is setpassphrase: string

Similar servers