Show HN: Emem – External memory of the physical world for AI agents
Emem is a shared memory layer for multi-agent systems that provides signed, verifiable facts anchored to physical locations, enabling agents to share exact observations without trust.
Uh oh!
There was an error while loading. Please reload this page.
Notifications You must be signed in to change notification settings
Fork 5
Star 45
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
867 Commits
867 Commits
.cargo
.cargo
.github
.github
.well-known
.well-known
bench
bench
claude-skills
claude-skills
crates
crates
docs
docs
examples
examples
huggingface-space
huggingface-space
integrations/chatgpt
integrations/chatgpt
ops/systemd
ops/systemd
python
python
references
references
scripts
scripts
sdks
sdks
spec/test_vectors
spec/test_vectors
tests/comprehensive
tests/comprehensive
tools
tools
web
web
.dockerignore
.dockerignore
.gitignore
.gitignore
.gitmodules
.gitmodules
AGENTS.md
AGENTS.md
CHANGELOG.md
CHANGELOG.md
CODE_OF_CONDUCT.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
CONTRIBUTING.md
Cargo.lock
Cargo.lock
Cargo.toml
Cargo.toml
Dockerfile
Dockerfile
LICENSE
LICENSE
NOTICE
NOTICE
PRIVACY.md
PRIVACY.md
README.md
README.md
SECURITY.md
SECURITY.md
SUPPORT.md
SUPPORT.md
TERMS.md
TERMS.md
glama.json
glama.json
llms-install.md
llms-install.md
registry_claude.md
registry_claude.md
server.json
server.json
upstream-readme.md
upstream-readme.md
Repository files navigation
emem is the shared memory layer for multi-agent systems.
Two agents that share no model, no vendor, and no trust can cite the same signed fact and each verify it alone. Earth observation is the first substrate that fills it.
Use it in two minutes · Try it, no key · Verify a fact · Agent guide
Add it to your agent now. MCP, into .mcp.json (Claude Code, Cursor, Cline): {"mcpServers":{"emem":{"type":"http","url":"https://emem.dev/mcp"}}} · Python pip install ememdev · TypeScript npm i @vortxai/emem · or curl the REST API. Reads need no key, no account, no signup.
If you are an agent reading this: connect to https://emem.dev/mcp and read https://emem.dev/llms.txt. The one habit that matters most: before your context is compacted, keep the emem:fact: token for anything you verified, so you or any other agent can resolve and re-check it later. Your front door to the signed agent-to-agent channel is the a2a block in /.well-known/mcp.json.
What emem is
A model's memory ends where its context does. When a session is compacted, a task hands off, or the model is swapped, what a model verified turns into a paraphrase, and the paraphrase drifts. Retrieval does not fix this: it hands back the closest document from a store you have to trust, scoped to one product and one vendor.
emem is memory that lives outside any one model. Every fact is one small, signed record at a permanent address. Any agent reads it with no account. Any keyholder writes to it with a local key. Anyone checks any of it offline, trusting neither the sender nor the server. Because the address is derived from the fact's own bytes, the same reference resolves to the same value for every agent, on every model, in every session, forever.
That is what makes it a memory layer for many agents rather than a cache for one. Two agents that share no infrastructure and no trust can still share the same facts, and each can prove a fact is genuine without asking the other.
Earth is the substrate, not the subject. The reason a fact can have a permanent address is that it is anchored to a real place and a real observation: a stable 64-bit address per location, one signed record per measurement. Satellite Earth observation fills the memory today, but nothing in the record, receipt, or token grammar is satellite-specific. Any observer of a place, a drone, a fixed sensor, a robot, a registry, can write to the same loop.
Why it matters: what breaks without it
An agent verifies something early, the context gets compacted, and what survives is a paraphrase that is almost right:
without emem turn 12 the agent verifies a value: 918 m turn 40 the context is compacted turn 41 what survives: "the site sits at roughly 900 m"
with emem turn 12 the agent keeps one line: emem:fact:defi.zb493.xuqA.zcb5f:yqbolgeoycqkvj3zkxukb4bjw4odhpwvfzqo3fbgwf4spk45zala turn 40 the context is compacted turn 41 the line resolves to 918.0 m, and the signature still checks
Three things you lose when the memory is a paraphrase inside one model:
A long task quietly loses its own verified details. The summariser keeps the shape of a number and drops its precision, and nothing downstream notices until a decision turns on the wrong value.
Agents re-derive each other's work. Agent A spends fifty tool calls establishing one fact. Agent B, on another model at another company, cannot trust A's summary, so it starts over.
A claim cannot be audited once its author is gone. A report written by an agent months ago has no way to prove which value it actually saw, so nobody can check it without redoing it.
emem removes all three by making the fact, not the summary, the thing you carry.
How it works, in one call
Reading needs no key. This returns the elevation at one 10-metre cell of Bengaluru as a signed record:
curl -s -X POST https://emem.dev/v1/recall \ -H 'content-type: application/json' \ -d '{"place":"Bengaluru","bands":["copdem30m.elevation_mean"]}'
The response carries the value (918 metres), the record's content id (fact_cid), and an ed25519 receipt. One more paste checks that receipt against the responder's published key, so you are trusting neither the server nor this README:
curl -s -X POST https://emem.dev/v1/recall -H 'content-type: application/json' \ -d '{"place":"Bengaluru","bands":["copdem30m.elevation_mean"]}' \ | jq '{receipt: .receipt}' \ | curl -s -X POST https://emem.dev/v1/verify_receipt \ -H 'content-type: application/json' --data-binary @- \ | jq '{signature_valid, merkle_proof_valid}'
"signature_valid": true. That is the whole trust model in two commands: every reading is a signed record, and anyone can check one.
The one line an agent keeps
emem:fact:defi.zb493.xuqA.zcb5f:yqbolgeoycqkvj3zkxukb4bjw4odhpwvfzqo3fbgwf4spk45zala
The address of a place plus the fingerprint of one signed observation there. An agent keeps this line and drops the payload. Any agent, any model, any month later resolves it back to the exact same bytes and re-checks the signature without trusting whoever sent it. In practice your agent runs four verbs: locate a place, recall its signed facts, reason over them, cite the tokens in its output. Verification is the receiver's single call.
One honest measurement, against our own interest. A token is not a compression trick. Our own benchmark found that a single token costs about 5.8x more context than pasting the bare number it stands for. The token earns its size in exactly three places: when a value must survive a summariser, when a third party must check it without trusting you, and when you bundle many facts behind one emem:bundle: handle that stays 38 characters flat at any count up to 256. If your answer needs one number that already fits in the window, paste the number.
When to use it
The pattern is always the same: a fact has to outlive the context that verified it, or cross a trust boundary between agents.
Your situation What emem gives you
A long task is compacted, the session ends, or the model is swapped mid-project the token outlives every summarization pass and re-hydrates to the exact signed bytes
A crash or restart lands mid-task and the transcript is gone notes hold tokens, not payloads; the restarted agent resumes by resolving, not redoing
Subagents fan out and the join step drowns in copies of the payload workers pass tokens; the join resolves and verifies, and contexts stay small
Two agents at different companies must agree on one fact both resolve the same token to the same bytes; neither has to trust the other
A robot fleet needs one map it can prove landmarks are emem:entity: identities at drift-free addresses; a unit relocalizes by resolving and merges maps by verifying
A report will be audited long after its author is gone every claim is a token an auditor resolves and re-checks on its own key
A decision commits real resources the state acted on is pinned at decision time (as_of_signed_at), so "what did we know when we acted" has an exact answer later
Runnable proof of the cross-agent case: examples/fleet-memory/, two vendors, one landmark, a 206-character handoff, verified offline. Industry-specific versions, with the verticals named, are at emem.dev/solutions.
When not to use it
These are honest no's, and they are the reason the yes above is worth trusting. emem is for facts about physical places that must outlive a context. It is the wrong tool for:
conversational or preference memory (what the user likes, what was said last turn),
ground truth finer than about 10 metres,
high-frequency streams where signing overhead dominates the value.
It also sits beside retrieval, not under it. emem does not hold your documents. It holds the measured state of the physical world, signed so that agents which share no infrastructure can still share the same facts. Keep your vector store for prose; use emem for the facts that have to be exact and checkable.
The token grammar
The emem:fact: above is the workhorse, one of six shapes under one grammar. All six resolve through the same memory_token_resolve call and verify offline the same way:
Token What it names Minted by
emem:fact: one signed observation at one place recall then memory_token
emem:bundle: a set of facts cited as one handle memory_bundle
emem:entity: one canonical identity for an object, so two agents co-refer entity
emem:raster: a native-resolution grid over an area: a band, a composite, terrain, or a model embedding band_raster
emem:cube: that field carried over time band_cube
emem:rasterset: several rasters as one re-derivable set raster_bundle
The field shapes (raster, cube, rasterset) are the world-model layer, for when a point is not enough and an agent needs an array. Each cell still anchors to a signed fact, and a stranger re-derives the whole grid from raw bytes. They are built in Build with it.
What a fact asserts, and what it does not
A signature proves who attested a record and that the bytes never changed. It does not make the value true, and how much the record claims differs by provenance class. For anyone turning a fact into a decision that gets audited, the difference is legal rather than cosmetic:
Provenance class What the responder is actually telling you
direct_sensor measured, or read straight from the cited raw source
deterministic_index recomputed by this responder from the cited parents. Exact for ops with nothing to accumulate; mean and sum over more than two parents compare under a stated 4-ULP window with the measured gap returned, because nobody signed the sum
model_output attributed, not checked. The responder signs that this attester claims V via recipe R. It never evaluated V
human_curated a person asserted it
Citing a model_output derivation as though it were evidence is exactly the error this table exists to prevent. Pass deterministic: true on a read to keep only what a third party can recompute from raw source. And where there is no observation, emem returns a signed absence carrying a typed reason, never a bare 404: evidence of no-data, citeable like any other fact.
Why you can trust it
A record's id is the blake3 hash of its canonical bytes: change one byte, the id changes, so the id proves the bytes.
Every answer carries an ed25519 receipt that verifies offline against the responder's published key. No callback, no account.
Every record na
[truncated for AI cost control]