Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Reason given by maintainers: no longer maintained

agent-cabinet

CI PyPI Python License

Give your agent a filing cabinet.

Ask an agent what it remembers about you and there's usually no way to check the answer. The memory lives inside a vector index or a database somewhere, opaque even when the agent gets it right.

agent-cabinet keeps everything your agent learns as ordinary text files: each memory is a Markdown file with a short YAML header. You can read, edit, or delete each memory directly, or query it later.

How is this different from Obsidian?

Obsidian is a great tool, and you can even tell agent-cabinet to write into an Obsidian vault instead of its own directory.

There are two main differences.

First, who's writing. Obsidian is built for a person writing by hand, so its frontmatter is freeform: that flexibility is the point. agent-cabinet's frontmatter is structured and schema-validated instead, following the ORC spec for shaping this kind of claim. Nothing else catches a malformed or missing field for an agent writing unsupervised.

Second, Obsidian is an application first. Extending it means writing a plugin that runs inside Obsidian itself, not linking a library into your own service, so another program can't just call into it directly. agent-cabinet is meant to be a dependency that applications build on, not an application in itself.

60 second install

From your project's git repo, run:

pip install agent-cabinet
agent-cabinet init

init creates a .cabinet directory at your project's root and tells your agent it exists, by writing to AGENTS.md/CLAUDE.md (see below). That only works if your agent actually reads one of those files — most do it automatically, but check yours does, or has actually picked up the change, before assuming it knows agent-cabinet is there.

Usage

agent-cabinet remember "The user prefers dark mode." --kind preference --basis stated
agent-cabinet recall "theme preference" --json

Either you or your agent can run these directly.

See what's in your agent's cabinet

To see what's stored, you have two options:

  • Open the .cabinet directory and read the files directly. Each entry is one .md file with YAML frontmatter. There's no export step, no hidden format, so you can just read it.
  • Query it instead: agent-cabinet has built-in ranked search. See agent-cabinet recall "<query>" above.
Where `agent-cabinet` stores things

On init, agent-cabinet finds the project root by walking up from your current directory until it finds .git (or the current directory, if you're not in a git repo yet).

This project root will then hold two new entries:

  • .cabinet is a directory built at <project root>/.cabinet.
  • AGENTS.md, created if it doesn't exist yet, with a short block telling your agent agent-cabinet is available. This is the file most agents (Cursor, Copilot, Codex, Windsurf, Cline, ...) read natively, so it's the source of truth.
  • CLAUDE.md, created if it doesn't exist yet, with a one-line @AGENTS.md import. Claude Code is the one agent that won't otherwise ever load AGENTS.md on its own, so this is what tells it to — a no-op for every other agent.

Want .cabinet somewhere else, like inside an Obsidian vault? Override with --root <path> or the AGENT_CABINET_ROOT environment variable. Note this only moves .cabinet: AGENTS.md/CLAUDE.md always go to the project root found above, regardless of --root.

How a note becomes a fact

Promoting a note to a fact is just adding evidence to the same entry: call file() on the same id with evidence/provenance filled in and overwrite=True, and it replaces the note in place. Those fields are optional on file() too, though. What actually makes something a fact is only ever whether they're filled in, not which function wrote the entry.

remember() writes down what you tell it, exactly as told. file() is for a claim something else has already checked, usually a pipeline that computed it and can show its work: a dict with an id, a type, a scope saying where it came from, and the statement itself required, plus optional evidence and provenance fields for showing that work. (This shape is called ORC, short for OpenReasoningComponents, in case you want other tools to read the same files; you don't need to know that name to use any of this.)

Here's the actual file remember("The DB is Postgres, not MySQL.") writes:

---
id: example-project/the_db_is_postgres_not_mysql
type: domain_knowledge
scope: { source: example-project }
---
The DB is Postgres, not MySQL.

And this promotes it in place, once something verifies the claim:

cabinet.file({
    "id": "example-project/the_db_is_postgres_not_mysql",
    "type": "domain_knowledge",
    "scope": {"source": "warehouse-connection-check"},
    "statement": "The DB is Postgres 16.2, confirmed by direct connection.",
    "evidence": {"confirmed_by": "SELECT version() -> PostgreSQL 16.2"},
    "provenance": {"derivation": "check_db_dialect", "derivation_version": "a1b2c3"},
}, overwrite=True)

Which overwrites the file in place to be:

---
id: example-project/the_db_is_postgres_not_mysql
type: domain_knowledge
scope: { source: warehouse-connection-check }
evidence: { confirmed_by: "SELECT version() -> PostgreSQL 16.2" }
provenance: { derivation: check_db_dialect, derivation_version: a1b2c3 }
---
The DB is Postgres 16.2, confirmed by direct connection.
Prefer MCP instead?

The server is one command: agent-cabinet mcp. As with most local MCP servers, it defaults to stdio. Your client runs the command itself and owns the process, so there's nothing you start or keep running yourself.

Here's how to point common clients at it (all three clients below can already call agent-cabinet remember/recall directly as shell commands once you run agent-cabinet init).

Claude Code

claude mcp add agent-cabinet -- agent-cabinet mcp

Cursor

Add to .cursor/mcp.json:

{ "mcpServers": { "agent-cabinet": { "command": "agent-cabinet", "args": ["mcp"] } } }

Codex CLI

codex mcp add agent-cabinet -- agent-cabinet mcp

Multiple clients

Want one server shared by more than one client, or a client on another machine? agent-cabinet mcp --transport http --port 7879 binds a port instead. You run and keep that one alive yourself; clients point at http://localhost:7879/mcp.

Python library

The same remember/recall calls, direct from Python, the way you'd embed agent-cabinet in your own service instead of shelling out:

from agent_cabinet import Cabinet

cabinet = Cabinet("./.cabinet", namespace="example-project")
cabinet.remember("User said the DB is Postgres, not MySQL.", basis="stated")
cabinet.recall("database")[0].body
# 'User said the DB is Postgres, not MySQL.'
Writing into an Obsidian vault

--root takes any directory, so pointing it at a folder inside a real vault works as-is:

agent-cabinet init --root ~/MyVault/agent-notes

Every entry is a standard frontmatter Markdown file, so Obsidian shows it as a real note: Properties panel, full-text search, all of it.

Two things worth knowing. relations/links are plain strings (acme/other), not Obsidian's [[wikilink]] syntax, so they won't wire into Obsidian's own graph view or backlinks panel on their own. And hand-editing a note through Obsidian's Properties UI is exactly the kind of edit this is built to tolerate: a required field going missing, or the id property getting retyped, produces a clean error for that one entry rather than breaking recall() for the rest of the cabinet.

Opinions behind the creation and design of agent-cabinet

agent-cabinet is meant to be a foundation other systems build on, not a finished memory system. Most memory needs (versioning, multi-agent sync, semantic search) are use-case-specific, so the substrate underneath stays simple and deterministic instead of guessing at which one any given system will need. Every opinion below follows from that.

  • Memories have upstream sources and downstream implications. In agent-cabinet, dependencies are declared explicitly, not extracted from conversation the way Zep does it, so an edge is never wrong, but it also only exists if something actually declared it: no hallucinated dependency, but no free discovery of one nobody wrote down either. Automatic discovery is a layer you can add on top, not something decided here.
  • Confidence and evidence should be filed alongside memories. In agent-cabinet, a memory just records whether a belief was stated, inferred, observed, or assumed, not a numeric confidence score the way Mem0 computes one, so you get a category you can read instead of a number you just have to trust. A computed score, if you want one, is a layer to add on top.
  • Enforcement beats convention. In agent-cabinet, dedup, schema validation, and ranked search are guarantees the code provides, not rules written into AGENTS.md and hoped for every session, so a forgotten rule can't let duplicate notes pile up or a malformed file break search unexpectedly: the common guarantee every use case would otherwise have to build for itself.
  • The search index is disposable; the file is the only source of truth. In agent-cabinet, results are ranked with BM25 over a small, rebuildable index, not a vector database the way Memsearch pairs markdown with one, so there's no embedding API key or vector store to run, and deleting the index by accident costs nothing: it just rebuilds from the files. Semantic search is a layer to add on top, not a dependency baked in for everyone.
  • Verification enriches an entry in place; it doesn't migrate it. In agent-cabinet, the same entry just gets more evidence added directly, not a new linked record the way Memora creates when it supersedes a claim, so there's never a question of which of two records is current: there's only ever one. A use case that wants lineage can build it on relations and metadata instead.

Limits

  • Single writer. One directory, used by a person or a small team sharing a git repo. Grants, SSO, and sharing across an org are a separate product's job.

License

Apache-2.0.

Release files for agent-cabinet 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-cabinet 0.1.2
File Size Uploaded
agent_cabinet-0.1.2.tar.gz 55.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-cabinet 0.1.2
File Interpreter ABI Platform
agent_cabinet-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 96.1 kB

Release files / agent_cabinet-0.1.2.tar.gz

Download URL agent_cabinet-0.1.2.tar.gz
Size 55.7 kB
Tags Source
SHA-256 checksum
How to use checksums
6e73cd49d382952b54e75d27ae20941f4536a720ef000587adf8856b1090b94b
BLAKE2b-256 checksum
How to use checksums
a3175d7f3177a14216835fa3dffe12a027a0c1e479d65df6211381cc5a0956a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / agent_cabinet-0.1.2-py3-none-any.whl

Download URL agent_cabinet-0.1.2-py3-none-any.whl
Size 40.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef4af38bd9c897d429202d9855b236e85ec65b8baff1f312a4ac5df986508232
BLAKE2b-256 checksum
How to use checksums
cd509c34f1430d3a1372bab7961dcf788668898c6084db2757b3cdde1342e59e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page