mddb
A minimal YAML-frontmatter + markdown-body card substrate for agentic and human knowledge work.
Cards live as .md files in a directory under git. A derived SQLite index at ~/.cache/mddb/ provides fast structured + full-text queries. Rationales live in commit messages. The substrate has no domain knowledge — flat YAML. The substrate filing vocabulary is id, title, summary, relpath, and tags (structures the substrate provides; the names are user choice). Anything heavier is layer code or an agent reasoning in a REPL.
Quickstart
import mddb
db = mddb.MDDB.init("~/my-mddb") # or mddb.MDDB(path) to open an existing one
with db.editor(rationale="bought today") as editor:
card = editor.create(
title="Shed inventory",
summary="Tools and equipment kept in the shed.",
tags=["shed"],
yaml={"location": "shed"},
body="A wheelbarrow.",
)
# read by id
card = db.read(card.id)
# mutate and write back
card.yaml["location"] = "barn"
with db.editor(rationale="moved to barn") as editor:
editor.update(card, summary="Tools and equipment, moved to the barn.")
db.editor() is the only mutation primitive. Batch many mutations into one commit + one SQLite transaction. A body exception inside the with block discards the buffer; on-disk state is unchanged.
with db.editor(rationale="bulk import") as editor:
for item in ["fridge", "shed", "loft"]:
editor.create(title=item.title(), summary=f"contents of the {item}")
# full-text via raw SQL — no DSL
ids = [r[0] for r in db.conn.execute(
"SELECT id FROM entries WHERE rowid IN "
"(SELECT rowid FROM entries_fts WHERE entries_fts MATCH ?)",
("wheelbarrow",),
)]
# history
for commit in db.history(card.id):
print(commit["sha"][:7], commit["message"])
See CLAUDE.md for the philosophy and the SQLite schema, src/mddb/schema.sql for the schema itself.
MCP server (optional)
For cross-process agents (Codex, Clawde), the mddb[mcp] extra ships a FastMCP
server. One server serves many decks — each tool call passes the deck path.
pip install mddb[mcp]
claude mcp add mddb -- mcp-mddb
Two tools: read(deck, op=list|get|history|query|blob, ...) and
editor(deck, rationale, ops) (a JSON-array of operations applied as one
commit). For example, read(deck="/home/me/finance", op="list") or
editor(deck="/home/me/home", rationale="...", ops='[{"op":"create",...}]').
A non-existent/non-deck path errors clearly rather than reading empty; bootstrap
a new deck with editor(deck, rationale, ops='[{"op":"init"}]'). The core
import mddb does not pull in the MCP dependency.
Status
Prototype. Linux only. Concurrent mddb writers (multiple processes / MCP
agents) are serialised by a short .git/mddb.lock and a base-vs-HEAD conflict
check — a stale write raises mddb.ConflictError (re-read and retry) rather
than silently clobbering; capture base = db.head() with your read and later
pass db.editor(base=base) to guard that read→write span. Raw external git commits and uncommitted editor edits are
not yet guarded.
Metadata
Release files for mddb 0.0.13
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mddb-0.0.13.tar.gz | 35.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mddb-0.0.13-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 58.3 kB
Release files / mddb-0.0.13.tar.gz
| Download URL | mddb-0.0.13.tar.gz |
|---|---|
| Size | 35.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3db363cd9bf2c1647de5ac4cc2bb03c9053ec560039d94084d458156bf1d0419
|
|
BLAKE2b-256 checksum How to use checksums |
d8fb53fcde8f6e53e738ab65de99c85d1b84fbf557edae331a5d5073111146f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|
Release files / mddb-0.0.13-py3-none-any.whl
| Download URL | mddb-0.0.13-py3-none-any.whl |
|---|---|
| Size | 22.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9544f37f4f847b8320ce9b1d49255180aa29c25dc4afcd82628efc9422d4e633
|
|
BLAKE2b-256 checksum How to use checksums |
02b5288a0823604d6408c0f110da35d445f89a2e1540dfd1fede396498f3a8dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|