emem-langmem
LangChain BaseStore backed by emem.dev — drop-in
agent memory for LangGraph with ed25519 receipts and content-addressed
recall.
Install
pip install emem-langmem
Use
from emem_langmem import EmemStore
from langgraph.graph import StateGraph
store = EmemStore(base_url="https://emem.dev", signing_key=SEED)
graph = StateGraph(...).compile(store=store)
SEED is a raw 32-byte ed25519 seed that you own and persist, for
example os.urandom(32) once, then kept wherever the agent's other
secrets live. It signs every write, and the responder requires that:
an unattested write is refused unless the operator opened the responder
with EMEM_MEMORY_OPEN=1. The key also decides where the store writes.
EmemStore implements the four BaseStore verbs by issuing MCP
tools/call requests to the emem responder against the six Anthropic
memory-tool verbs:
| BaseStore verb | emem MCP tool | Signed |
|---|---|---|
mget(keys) |
emem_memory_view |
read, no signature |
mset(pairs) |
emem_memory_create |
yes |
mdelete(ks) |
emem_memory_delete |
yes |
yield_keys |
emem_memory_view (directory walk) |
read, no signature |
Namespaces
With a signing key, the store roots itself at
/memories/by_attester/<pubkey8>/, where <pubkey8> is the first 8
characters of your base32 pubkey. Only that key can write there, so
agents sharing one responder cannot overwrite each other. LangChain
calls mget(("ns","key")) and the store reads
/memories/by_attester/<pubkey8>/ns/key.
store.root # '/memories/by_attester/aoqqpp7t'
store.signer.pubkey_b32 # the full base32 pubkey
A key that starts with / is taken as a literal absolute path and is
left alone, which is how you reach outside your own root. Writing into
another key's namespace is refused with a 403. Without a signing key the
root stays /memories and writes go out unattested. See
docs/memory.html for the wire format.
EmemSigner is public if you drive the memory tools yourself and need
the same attester block:
from emem_langmem import EmemSigner
signer = EmemSigner(SEED)
signer.attester_block("create", f"{signer.namespace_root}/n.md", b"hi")
# {'pubkey_b32': '...', 'sig_b32': '...'}
Async variants amget / amset / amdelete / ayield_keys are
implemented over httpx.AsyncClient.
Self-host
EmemStore(base_url="http://127.0.0.1:5051")
or set EMEM_BASE_URL in the environment.
Receipts
Every read and write returns an ed25519 receipt from the emem responder.
The receipt is currently dropped at the BaseStore interface boundary
(LangChain's contract has no receipt slot). To inspect receipts, call
the underlying MCP tool directly:
import json, httpx, uuid
r = httpx.post(
"https://emem.dev/mcp",
json={
"jsonrpc": "2.0",
"id": str(uuid.uuid4()),
"method": "tools/call",
"params": {
"name": "emem_memory_view",
"arguments": {"path": "/memories/my/note.txt"},
},
},
).json()
print(r["result"]["structuredContent"]["receipt"])
License
Apache-2.0.
Metadata
Release files for emem-langmem 2.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| emem_langmem-2.3.0.tar.gz | 17.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| emem_langmem-2.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.9 kB
Release files / emem_langmem-2.3.0.tar.gz
| Download URL | emem_langmem-2.3.0.tar.gz |
|---|---|
| Size | 17.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f78a2ef5ff3f5cd5142fd710eef1a8114851664ba8557941c39aa95a41d3007b
|
|
BLAKE2b-256 checksum How to use checksums |
0197a1460df1eb7b5c511028cbf168a5826dfc5fdeb2f44d5d09cf6e106c4aa5
|
| 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 Aug 27, 2026.
Transparency logRelease files / emem_langmem-2.3.0-py3-none-any.whl
| Download URL | emem_langmem-2.3.0-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
17a395442d8650d31c1de2da8137fde1af2e6058383389e75ac36c368bb1dfd4
|
|
BLAKE2b-256 checksum How to use checksums |
6cd452fddb1233fd42d7a71b601886b58852ab42e690d77c0ec853f12650b340
|
| 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 Aug 27, 2026.
Transparency log