Durable, tamper-evident context for AI agents in one file. Zero dependencies.
Project description
memcask: durable context for AI agents, in one file
The SQLite of agent memory. A tiny, zero-dependency, tamper-evident store for the context an agent needs to survive across sessions, restarts, and machines.
One file on disk. Python standard library only. MIT.
from memcask import Context
ctx = Context("agent.cask") # open or create one portable file
ctx.append("user", "Book me a flight to NYC")
ctx.append("assistant", "Searching flights...")
ctx.set("pref.seat", "aisle") # durable key/value state
# ...new process, a week later...
ctx = Context("agent.cask")
ctx.messages(limit=20) # resume: recent log, ready for an LLM
ctx.get("pref.seat") # "aisle"
ctx.verify() # True: nothing was corrupted or tampered with
That's the whole idea. Your agent now remembers, across runs, in a file you can copy, commit, diff, and trust.
Why
Every agent needs to remember what happened across sessions. Today you either:
- reinvent it badly: hand-rolled JSON blobs, a pickle file, a
messageslist you forget to persist; or - adopt a heavy dependency: a hosted memory service or a framework's memory module that drags in a stack, an account, and a vendor.
There's no small, neutral, boring primitive for "durable agent context." memcask is that primitive: a single file, no dependencies, no server, no account, and because every entry is hash-chained, you can prove the record wasn't silently altered.
Features
- Zero dependencies. Pure Python standard library (
sqlite3,json,hashlib). Nothing to install but the file. - One portable file. A
.caskfile is a SQLite database. Move it, commit it, ship it, inspect it with any SQLite tool. - Append-only log + key/value state. The durable record of what happened, plus the facts your agent keeps.
- Tamper-evident. Every entry is SHA-256 hash-chained to the previous one.
verify()catches any altered, reordered, or dropped entry. - Resume is just reopening the file. No special "load" ceremony.
- LLM-ready.
messages()hands you[{"role", "content"}]straight into a model call. - Tiny. ~150 lines you can read in one sitting.
Install
It's a single file with zero dependencies, so the simplest install is to copy memcask.py into your project.
Or, once it's on PyPI:
pip install memcask
Note: the PyPI publish is pending; for now, copy the one file.
API
ctx = Context("agent.cask") # open/create
# durable append-only log
ctx.append(role, content) -> seq # content = any JSON-serializable value
ctx.history(limit=None, role=None) # [{seq, ts, role, content}], oldest-first
ctx.messages(limit=None, roles=None) # [{"role","content"}] for an LLM call
ctx.head() # hash of the latest entry
len(ctx); for e in ctx: ...
# durable key/value state
ctx.set(key, value); ctx.get(key, default=None)
ctx.delete(key); ctx.state() # full snapshot
# integrity
ctx.verify(raise_on_fail=False) # walk the hash chain
ctx.close() # or use `with Context(...) as ctx:`
It's just SQLite, no lock-in
A .cask file is a normal SQLite database. Inspect it with anything:
sqlite3 agent.cask "select seq, role, content from log order by seq;"
Your data is never trapped. That's the point.
Why not Mem0 / Zep / Letta / LangChain memory?
Those are good, bigger tools: semantic memory, vector recall, hosted services, framework integration. Reach for them when you need that.
memcask is deliberately the layer underneath: the boring, durable, portable record of an agent's context, with zero dependencies and tamper-evidence, that you can drop into anything (including those tools) without taking on a stack or a vendor. It does one thing. Most agents need that one thing first.
Integrity model
memcask is tamper-evident, not tamper-proof. Each entry's hash commits to the previous entry's hash, so any in-place edit, reordering, or deletion of a historical entry makes verify() return False. What it does not do on its own: stop someone with write access from rewriting the whole chain from scratch. Like any unanchored hash chain, catching that requires pinning a known-good head somewhere external (sign it, or store the latest head() elsewhere).
It is also not an encryption layer: a .cask file is plaintext SQLite, readable by anyone who has it. Treat it like any data file: don't put secrets in it unless the file itself is protected.
Status
v0.1, small on purpose, and it will stay that way: the cleanest possible durable-context primitive. Reference implementation of the Durable Context Spine (DCS): https://github.com/drewmattie-code/Durable-Context-Spine
License
MIT © Drew Mattie
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file memcask-0.1.0.tar.gz.
File metadata
- Download URL: memcask-0.1.0.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86a4fe2fafd4c0e260769337bca8cf8799b7c5f0144715d088b3d948ee1740f3
|
|
| MD5 |
bdc42e7578aa3eaabf8154dc75932d77
|
|
| BLAKE2b-256 |
435886242a60f45047729c70fe6fc9076c2e29fb8085ccec7e39c159ace825ba
|
File details
Details for the file memcask-0.1.0-py3-none-any.whl.
File metadata
- Download URL: memcask-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49233d2870d7ad7a1eecd349706ece922035e73f491ae7da13bf1b55fa7366e0
|
|
| MD5 |
21f0856ac0b717ded77db1e394e61fa7
|
|
| BLAKE2b-256 |
f99f2f378504f8419957b1fb2e33d2b6d09ac404283a9e4aa6d4b797d9ec86ba
|