Python client for emem.dev, the agent-native Earth memory protocol
Project description
ememdev: Python client for emem.dev
Thin, typed Python client for the emem.dev Earth memory
protocol. Wraps the public REST surface in a single Client class that
returns parsed JSON verbatim. Every ed25519-signed receipt and
content-addressed CID is preserved for citation and offline verification.
The current surface is whatever /openapi.json
lists; this README does not restate a count that would go stale.
Install
pip install ememdev
The distribution and the import package are both named ememdev (so
pip install ememdev, then from ememdev import Client); the shorter name
emem on PyPI belongs to an unrelated project. To work from a checkout
instead:
pip install -e sdks/emem-py
Requires Python 3.9+. The only runtime dependency is
httpx. To sign memory writes (below),
add the signing extra, which pulls blake3 and cryptography:
pip install "ememdev[signing]"
Quick start
from ememdev import Client
with Client() as em:
cell = em.locate("Mount Fuji")["cell64"]
facts = em.recall(cell, bands=["copdem30m.elevation_mean"])
print(facts["facts"][0]["value"])
Async
import asyncio
from ememdev import AsyncClient
async def main() -> None:
async with AsyncClient() as em:
out = await em.ask("How tall is Mount Everest?")
print(out["answer"])
asyncio.run(main())
Configuration
| Env var | Default | Effect |
|---|---|---|
EMEM_BASE_URL |
https://emem.dev |
Responder root; point at a self-hosted node |
EMEM_TIMEOUT_SECS |
180 |
HTTP timeout (matches gateway timeout) |
You can also pass base_url= and timeout= directly to the constructor.
Surface coverage
Geocoder + read primitives, physics solvers, boring lat/lng shortcuts, and
introspection — see the inline docstring on emem.client for the full
endpoint → method mapping.
Writing a signed note
Reads are anonymous. Writes into the agent memory namespace are gated by an
ed25519 attester block, and that signature is the one thing the MCP client
cannot produce for you. ememdev[signing] produces it, from a persistent
identity, so leaving a signed note is one command rather than a hand-rolled
crypto script.
The identity is resolved once and reused every session, because the key is
what owns your namespace at /memories/by_attester/<pubkey8>/.... Resolution
order: EMEM_AGENT_KEY (a 64-char hex seed or a key-file path), then
~/.emem/agent_ed25519.pem (override the directory with EMEM_HOME), minted
0600 on first use if absent.
From the command line, for an agent that already speaks to emem over MCP:
ememdev whoami # your pubkey and namespace_root
# emit just the attester block, sign nothing else (no network):
ememdev sign --verb create --path /memories/by_attester/<you>/note.md --stdin < note.md
# or sign a create and POST it to /mcp in one step:
ememdev write --path /memories/by_attester/<you>/note.md --body-file note.md
Or in Python:
from ememdev import load_or_create_signer
signer = load_or_create_signer() # persistent identity
path = f"{signer.namespace_root}/note.md"
body = b"a durable, signed, citeable note"
attester = signer.attester_block("create", path, body)
# POST {path, file_text, kind, attester} to /mcp memory_create.
str_replace and insert sign the whole file after the edit, and rename
binds both ends of the move (signer.rename_attester_block(old, new)); see the
ememdev.signing docstring for the per-verb body rule. A write into another
key's namespace is refused with a 403, and sign/write refuse it locally
first.
Receipts
Every non-introspection response carries a receipt block with:
responder_pubkey(ed25519 base32-nopad-lowercase)signature_b32(ed25519 over the canonical CBOR preimage)merkle_root(BLAKE3 over the fact CIDs)fact_cids[](the BLAKE3 CIDs of every fact returned)
To cite an answer: quote receipt.fact_cids[0] and the responder pubkey.
The signature can be verified offline against the public key at
https://emem.dev/.well-known/emem.json; no callback to the responder is
required.
License
Apache-2.0. Same as the upstream protocol.
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 ememdev-1.2.1.tar.gz.
File metadata
- Download URL: ememdev-1.2.1.tar.gz
- Upload date:
- Size: 24.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd9a8ebd5507d9fda741dbc79cb41c487b28a32ede566c3098c8f76923678679
|
|
| MD5 |
ed56f28e7224e76b58c122be35ab7b39
|
|
| BLAKE2b-256 |
6ceeab87ea195dbd036ea5a5f6f87607abe0f5209c74bc90aa9c4714de2fce9c
|
Provenance
The following attestation bundles were made for ememdev-1.2.1.tar.gz:
Publisher:
publish-pypi.yml on Vortx-AI/emem
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ememdev-1.2.1.tar.gz -
Subject digest:
fd9a8ebd5507d9fda741dbc79cb41c487b28a32ede566c3098c8f76923678679 - Sigstore transparency entry: 2216006445
- Sigstore integration time:
-
Permalink:
Vortx-AI/emem@2564e2dad828d2c7b1dff41fe581e2bcf8a21404 -
Branch / Tag:
refs/tags/v1.2.1 - Owner: https://github.com/Vortx-AI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@2564e2dad828d2c7b1dff41fe581e2bcf8a21404 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ememdev-1.2.1-py3-none-any.whl.
File metadata
- Download URL: ememdev-1.2.1-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74024c5df1688dbcdb8a5301a7203f6aac73e1cbcabf97bfb1b78e6acd66004e
|
|
| MD5 |
997ab7fe1ac97dee7e173a8cab938605
|
|
| BLAKE2b-256 |
d73116a55e34fec61f98de1ea02ed4d0029498a1c954345bb914f5d74a9c2b65
|
Provenance
The following attestation bundles were made for ememdev-1.2.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on Vortx-AI/emem
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ememdev-1.2.1-py3-none-any.whl -
Subject digest:
74024c5df1688dbcdb8a5301a7203f6aac73e1cbcabf97bfb1b78e6acd66004e - Sigstore transparency entry: 2216006482
- Sigstore integration time:
-
Permalink:
Vortx-AI/emem@2564e2dad828d2c7b1dff41fe581e2bcf8a21404 -
Branch / Tag:
refs/tags/v1.2.1 - Owner: https://github.com/Vortx-AI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@2564e2dad828d2c7b1dff41fe581e2bcf8a21404 -
Trigger Event:
release
-
Statement type: