emem
The emem server is a verifiable memory protocol for the physical world, enabling AI agents to locate, recall, cite, verify, and share signed facts about real-world places.
Discover tools (
emem_tools): Find the right tool by topic, shape (scalar, raster, timeseries), or bundle (robotics, agriculture, climate_risk), or retrieve a specific tool's schema and runnable example.Locate places (
emem_locate): Resolve free-text place names or lat/lng coordinates into a canonical 64-bit cell address (cell64) and view available data bands at that location.Ask free-text questions (
emem_ask): Submit a natural-language question about a real-world place and receive a signed, citation-bearing answer backed by satellite, elevation, weather, and other Earth observation data.Recall signed facts (
emem_recall): Read signed, immutable facts (elevation, NDVI, temperature, etc.) at a specific cell; auto-materializes missing data on first call, with support for bitemporal queries (as_of_tslot,as_of_signed_at) and provenance filtering by trust class.Mint memory tokens (
emem_memory_token): Create compact 84-character citation handles (emem:fact:<cell64>:<fact_cid>) that any agent can resolve to the exact original signed bytes, preventing referential drift.Resolve memory tokens (
emem_memory_token_resolve): Dereference a citation handle back to its full signed fact body in a single call.Bundle multiple facts (
emem_memory_bundle): Group multiple (place, band, time) facts into one signed envelope with a singleemem:bundle:citation token.Manage object identities (
emem_entity,emem_entity_resolve,emem_entity_link): Mint, resolve, and link canonical identities for real-world objects (bridges, farms, landmarks) so multiple agents co-refer to the same thing regardless of phrasing.Find similar places (
emem_find_similar): Run k-nearest-neighbor search over the corpus using embeddings (cosine or Hamming) to find geographically or spectrally similar locations.Detect contradictions (
emem_memory_contradictions): Surface disagreements between multiple attesters on the same place, band, and time, with severity scores and citations to all conflicting facts.Verify receipts (
emem_verify_receipt): Server-side ed25519 signature verification of any signed receipt, confirming bytes are untampered and the signer's identity is valid.Intent-based planning (
emem_intent): Submit a high-level intent (e.g.,where_is,did_change,find_like,confirm) and let the planner route it to the correct tool automatically.Attest new facts: Keyholders can write and sign their own observations, adding to the shared memory.
Self-hostable: Run a local node whose receipts are fully compatible with and verifiable against the global memory.
Provides LangChain agents with tools to access emem's Earth memory protocol for recalling, comparing, and verifying spatial facts about locations worldwide.
Enables OpenAI GPT agents to query content-addressed Earth memory facts via MCP or OpenAPI actions, including recall, comparison, and similarity search.
emem
The verifiable memory protocol for the physical world, built for AI agents to cite.
Agents inherit a measured, signed account of the physical world instead of re-observing it; every observation becomes a shared, verifiable Memory Token that persists across long-horizon AI tasks.
Walk the memory in 3-D · Try it, no key · Verify a fact · Agent guide
What is emem
A shared memory of the physical world, and a systems primitive for agents: memory that lives outside any one model, so an agent cites a fact instead of carrying a paraphrase of it. Location is the first key: every place on Earth has a stable 64-bit address, and every observation recorded there, an elevation, a temperature, a forest-loss year, is one signed, immutable record at that address. Any agent can read it, any keyholder can add to it, and anyone can check any of it offline. No account to read.
Satellite Earth observation fills it today; nothing in the record, receipt, or token grammar is satellite-specific, so the same loop carries any observer of a place (substrates). If you build agents, robot fleets, or anything else that must hold a fact longer than one context window, this is for you.
Related MCP server: giskard-memory
The failure it removes
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 checksOne line, about 50 BPE tokens, standing in for a signed record of about 1,600. A paraphrase drifts; the token re-hydrates to the exact bytes for any agent, on any model, any month later. And that token is real: it names the fact the next section verifies.
One call, one verified fact
Reading needs no key and no account. 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"]}'A band names one measurement; this one is mean elevation from the Copernicus DEM. The response carries the value (918 metres), the record's content id (fact_cid), and an ed25519 receipt.
{
"facts": [{
"band": "copdem30m.elevation_mean",
"cell": "defi.zb493.xuqA.zcb5f",
"value": 918.0,
"unit": "m",
"kind": "primary",
"confidence": 0.95,
"derivation": { "fn_key": "open_meteo_copdem90m@1", "args": [12.9719, 77.5937] },
"sources": [{ "scheme": "open_meteo", "captured_at": "2021-04-30T00:00:00Z", "id": "https://api.open-meteo.com/v1/elevation?…" }],
"signed_at": "2026-05-28T19:54:32Z",
"signer_pubkey_b32": "777er3yihgifqmv5hmc2wwmyszgddzderzhsx6rex4yoakwomvka",
"fact_cid": "yqbolgeoycqkvj3zkxukb4bjw4odhpwvfzqo3fbgwf4spk45zala",
"memory_token": "emem:fact:defi.zb493.xuqA.zcb5f:yqbolgeo…zala"
}],
"receipt": { "primitive": "emem.recall", "fact_cids": ["yqbolgeo…"], "merkle_proof": {…}, "signature": "…", "responder_pubkey_b32": "…" }
}No documents and no blobs: a fact is one small signed value carrying its own provenance, the function and source it is recomputable from. Even embeddings arrive this way, as bands whose record names the model checkpoint.
One more paste checks that receipt against the responder's published key, so you are not trusting the server or 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. If that worked, the star button helps other builders find this. The line an agent keeps instead of the payload is next.
The ladder
Six steps, each adding one idea, and every step works before the next exists:
Read. Recall signed facts for any place, no key, no account: two minutes.
Cite. Keep the 84-character token, drop the payload: the Memory Token.
Verify. Re-check a token's bytes and signature offline, trusting nobody: why you can trust it.
Write. Attest your own facts with a local ed25519 key, no registration: if you are an agent.
Self-host. Run the exact hosted binary; a receipt minted on one node verifies on the other: run your own node.
Federate. Several independent responders, one address space. Next, not now: docs/roadmap.md.
The Memory Token
emem:fact:defi.zb493.xuqA.zcb5f:yqbolgeoycqkvj3zkxukb4bjw4odhpwvfzqo3fbgwf4spk45zalaOne line: the address of a place plus the fingerprint of one signed observation there. It is 84 characters, about 50 BPE tokens; the full signed record it stands in for is about 1,600. An agent keeps the line and drops the payload. Any agent, any model, any month later resolves the line 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, and cite the tokens in its output. Verification is the receiver's single call.
Where it sits in your stack
The retrieval memory you run | emem |
documents chunked, embedded, ranked by similarity | one signed record per observation, at a content address |
the top hit is close enough | the address returns exactly one record, or a signed absence |
you trust the retriever, the store, and whoever filled them | the receipt verifies offline; no trust in the sender or the server |
memory scoped to one session, one product, one vendor | one shared memory: any agent reads, any keyholder writes |
It 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 and no trust can still share the same facts.
When the token earns its keep
A long task survives its own context window. The harness compacts, the session ends, the model gets swapped. A paraphrase drifts; the token does not. After compaction it re-hydrates to the exact signed value, signature still checking. Record it once, cite it forever.
Two agents stop re-deriving each other's work. Agent A spends fifty tool calls establishing one fact and leaves the token in its report. Agent B, at another company, on another model, resolves it to the same bytes and proves it is genuine in one call. No shared database, no shared credentials, no "trust me".
A fleet shares one map it can prove. Robots and autonomous systems keep landmarks as emem:entity: identities and terrain or hazard readings as signed facts at addresses that never drift, shareable across vendors over the same MCP and REST surface agents use, verifiable without trusting the peer that wrote them. Runnable proof: examples/fleet-memory/, two vendors, one landmark, a 206-character handoff, verified offline.
Technical long-horizon tasks, the failure modes every agent and robot developer already knows:
Your problem | What survives |
Context compaction quietly turns your agent's verified details into paraphrase | the 84-char 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 |
The model gets swapped or upgraded halfway through the project | the address derives from the bytes, not from who asked; the successor resolves the same tokens identically |
Subagents fan out and the join step drowns in payload copies | workers receive and return tokens; the join resolves and verifies, contexts stay small |
"Did I, or anyone, already compute this?" asked on every loop | recall is ensure, not get: what exists is reused ( |
"Is what I knew last week still valid?" with no cheap way to answer |
|
A robot reboots, or a unit from another vendor joins the fleet | landmarks are |
Long-horizon work, the same survival stretched from minutes to months:
Task | What the memory does |
A watch that runs for months, across hundreds of sessions | change evidence accrues as signed facts; every alert cites the fact ids it fired on, and the relieving agent resumes from tokens, not from a predecessor's summary |
A report that will be audited long after the agent that wrote it is gone | every claim in it is a token; an auditor, human or agent, resolves each one to the signed record and re-checks the signature without contacting the author |
A project handed from one contractor's agents to another's | every prior finding stays citable across the handover; the successor resolves the same tokens to the same bytes instead of trusting the summary it was given |
A decision that commits real resources | the state acted on is pinned at decision time ( |
A number that must hold across years of reports | records are immutable and supersession is explicit, so the baseline stays re-checkable by anyone, without trusting the author's laptop |
Industry-specific versions of these, with the verticals named, live at emem.dev/solutions.
If you are an agent reading this, the runnable version is below, and
https://emem.dev/llms.txtis the machine-readable entry point. The habit that matters most: before your context gets compacted or your turn ends, put theemem:fact:token for anything you verified into your notes or your final answer. You, your successor, or a different agent entirely can resolve and re-check it later.
See the memory
The memory is not an abstraction; you can walk through it. Each 3-D world at emem.dev/worlds draws one gaussian per cell of signed facts: height, tilt, thickness, and colour are each a measurement. Click any splat to read its values, copy its Memory Token, or re-check its signature at /verify. The dense worlds at emem.dev/splats push the same signed substrate to photoreal, with every splat labelled measured, interpolated, or synthesized, so the invented detail peels off and the signed trust root stays.
Prefer a console? emem.dev has a live recall on the homepage, and emem.dev/humans is the whole corpus as an explorable constellation.
Use it in two minutes
Reading needs no key, no account, no signup.
MCP (Claude Code, Claude Desktop, Cursor, Cline; drop into .mcp.json):
{ "mcpServers": { "emem": { "type": "http", "url": "https://emem.dev/mcp" } } }REST (any language):
CELL=$(curl -s -X POST https://emem.dev/v1/locate \
-H 'content-type: application/json' -d '{"q":"Bengaluru"}' | jq -r .cell64)
curl -s -X POST https://emem.dev/v1/recall \
-H 'content-type: application/json' \
-d "{\"cell\":\"$CELL\",\"bands\":[\"weather.temperature_2m\"]}" | jq '.facts[0].value'Python: pip install ememdev, then from ememdev import Client. Real as of 1.1.0, verified by installing into a clean environment and calling the live node; the wheel also ships the signing extra (pip install "ememdev[signing]") and an ememdev CLI for attested memory writes. Do not guess a shorter name: emem on PyPI is an unrelated project by another company. TypeScript: sdks/emem-ts/ publishes to npm as ememdev too; first publish pending, status in docs/roadmap.md.
Client | Setup |
Claude Desktop |
|
Claude Code |
|
Cursor |
|
Cline (VS Code) |
|
Gemini CLI |
|
ChatGPT (Custom GPT) |
|
LangChain / LlamaIndex / Agno / AutoGen / CrewAI / Mastra |
|
Any MCP client over the standard bridge |
|
Packaged Claude skills live under claude-skills/; llms-install.md is a plain-text install guide an agent can follow by itself. TypeScript SDK: sdks/emem-ts/ (npm name ememdev; first publish pending).
If you are an agent
Reads need no key, and four moves cover most sessions.
Connect to https://emem.dev/mcp. It advertises the 14 tools of the loop, not the whole catalog. A host loads every descriptor it is handed, and all 94 cost about 210 KB of context whether or not the session ever touches Earth observation. Narrowing discovery removes nothing: tools/call dispatches all 94 by name at either endpoint, so a tool missing from your list is still callable. Use /mcp/full to have every tool registered up front.
Do not know which tool? Call emem_tools. With no arguments it returns the loop, a bundle menu, and a shape menu in about 6 KB. Ask by the shape of the answer you need, which is usually the real question, rather than by topic:
curl -s -X POST https://emem.dev/mcp -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"emem_tools","arguments":{"shape":"raster"}}}'Every tool carries exactly one shape (scalar, timeseries, raster, geometry, vector, identity, token, proof, plan, file, catalog) and any number of overlapping bundles (tokenisation, verification, agent_to_agent, long_horizon, robotics, satellites, agriculture, forestry, climate_risk). {"bundle":"robotics"} returns just that bundle; {"name":"emem_ndvi"} returns one tool's input schema and a runnable example in about 2 KB; {"q":"ndvi"} searches the text.
Ground a place, then cite it. emem_locate maps a place to its cell64. emem_recall returns the signed facts there, and its receipt carries the fact_cid. emem_memory_token composes the two into one handle:
emem:fact:defi.zb5b3.mAmi.leco:nzyep244xoxx6uvw4ope5dghy3eniawczovvzrrp7almuydzdbtaHand the token to another agent. They call emem_memory_token_resolve on that line, get the byte-identical signed fact back, and emem_verify_receipt checks the ed25519 signature without trusting you or the server. That is the whole claim, and it is the only one worth making: the same token resolves to the same bytes for anyone, and the receipt verifies on its own.
Writes are the one place a key appears, and it is still not an API key. Memory writes need an attester block signed by an ed25519 keypair you generate locally, with no registration step. A refused write answers with the exact digest to sign, the base32 encoding rules, and a worked example, so an agent gets from refusal to signed write in one turn without going to look for docs.
Build with it
Operation | What it means for your agent | Tools |
Recall | read memory for a place; a miss fetches, signs, and stores for everyone |
|
Cite | one token per fact, or one |
|
Verify | trust a fact without trusting the sender, offline |
|
Weigh | every fact says how it was produced; model and human classes carry an in-band | inside every recall |
Time travel |
| flags on every read |
Self-check | disagreement between writers is kept and scored, never averaged away |
|
Or skip the menu: emem_ask takes a plain-language question and returns a signed answer. Each agent also gets a private signed memory with the six standard file verbs, and any keyholder writes shared facts through POST /v1/attest. The full handbook is emem.dev/agents.md.
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 names its source, its versioned algorithm, and its provenance class, so you know whether a value is recomputable from raw data or trusted through a model or a person.
A missing value is a signed absence with a typed reason, never a bare 404.
Nothing is overwritten. Later records supersede; disagreement between writers is kept and scored as evidence.
An append-only transparency log (RFC 6962 construction, BLAKE3) with witness co-signing records every attestation batch. Pin a signed tree head from
/v1/log/sth, then prove the log only grew since your pin. The receipt does not yet chain to the log; the whitepaper's honest limits say exactly what that does and does not prove.
The signature proves who attested a record and that the bytes never changed, not that the value is objectively true; confidence, uncertainty, and provenance travel with it. Deeper: how it works with live consoles, the formal model, the wire spec.
The world drifts too
Generating a plausible answer is cheap. The scarce thing is a shared account of the physical world that is measured, signed, and checkable by someone who was not there. Drift threatens that account from two directions. In language, the reference drifts: a paraphrase mutates while the world stands still, and the token pins it; that is everything above. In the world, the readout drifts: the reference stands still, the signal at it moves, and not every move is the world. Between two visits to one address, the observed change is a sum:
Δz = Δ_env + Δ_sensor + Δ_geo + Δ_encoder + εThe world changed; the instrument changed; the pixels moved; the model changed; noise. Only the first term is about the world, and the substrate already pins the rest of the ledger. An embedding record carries its model checkpoint, so a model swap can never pose as change on the ground. Bitemporal recall keeps "the world changed" and "what the memory knew changed" as separate questions. Every change points at a specific immutable record by its id, and the receipt lets someone who was not there check the split. A first attribution ledger ships at /v1/change_attribution: per-term evidence with the fact ids it read, and no numeric split. The split itself is still roadmap work; the design and its honest gaps live in docs/roadmap.md.
Substrates: today and next
Today: satellite Earth observation. Open data from ESA, NASA, USGS, and the EU JRC fills the memory on demand: 124 wired measurements, drawn from a catalog of 46 declared source schemes of which several are declared but not yet fetchable (live lists at /v1/sources and /v1/bands), from elevation and NDVI to weather, forest change, and four open foundation-model embeddings.
Next: everything else that observes a location. Nothing in the record, receipt, or token grammar is satellite-specific; any observer with a location and a signing key can join the same attest, recall, cite, verify path. The multi-writer endpoint (POST /v1/attest) ships today; written substrate profiles for CCTV and fixed sensors, drones, robot fleets, industrial machines, government registries, and open data programs are roadmap work, tracked with the rest in docs/roadmap.md. Location stays the first key for all of them.
Run your own node
The hosted node runs the exact binary in this repo, and both name the planet the same way, so a receipt minted on one verifies on the other:
docker run -p 5051:5051 ghcr.io/vortx-ai/emem:latest # or: cargo run --release --bin emem-serverOne note worth reading twice: the signing key is your node's identity. Mount a volume for EMEM_DATA (or set EMEM_SECRET_B32) before you hand out receipts you care about. Full guide: docs/self-host.md.
Measured on the production node (methods in docs/benchmarks.md): warm recall p50 2.5 ms, offline verification p50 0.13 ms, 632 requests/s on one node, cold materialize 0.5 to 1.6 s depending on the upstream.
Honest limits
Version 1.1.0, under the stability promise 1.0.0 made: the wire format, receipt preimage, and address space are settled and will not break under a 1.x. Today it is a single-host deployment (no federation yet), the memory holds thousands of places rather than billions, and it grounds facts about physical places, not arbitrary text. Verification is per-responder: a receipt proves what this responder signed, never a network consensus. The change attribution described above ships as an evidence ledger; the numeric split of a delta among its terms is still roadmap. The complete edge list, the staged path to federation, and the open research live in docs/roadmap.md.
Learn more
What | Where |
How it works, with live consoles | |
The whitepaper, canonical | |
The formal memory model and algebra | |
Agent integration handbook | |
Ten minutes to a verified, shareable fact | |
Limits, roadmap, open research | |
Benchmarks, with methods | |
Industry use cases | |
Wire spec · OpenAPI (118 paths) · MCP (94 tools) | |
Live proof in a regulated workflow | |
Companion open model |
Research and citation
emem: A research on Content-Addressed, Verifiable Earth-Memory Protocol for AI Agents over Foundation-Model Embeddings. Jaya Kumari, Avijeet Singh. Vortx AI, 2026. Open preprint (Zenodo, CC-BY-4.0; not yet peer-reviewed). doi.org/10.5281/zenodo.20706893
@misc{emem2026,
title = {emem: A research on Content-Addressed, Verifiable Earth-Memory
Protocol for AI Agents over Foundation-Model Embeddings},
author = {Kumari, Jaya and Singh, Avijeet},
year = {2026},
doi = {10.5281/zenodo.20706893},
publisher = {Zenodo}
}Contributing and license
Issues and pull requests welcome: CONTRIBUTING.md, SECURITY.md. Pure Rust, Apache-2.0 (LICENSE, NOTICE); default-build data sources are open, with no API keys and no lock-in. Built by vortx.ai. A shared memory is worth more the more agents read and write it; if yours use emem, a star helps other builders find it.
Maintenance
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vortx-AI/emem'
If you have feedback or need assistance with the MCP directory API, please join our Discord server