emem
Cite-able, content-addressed, signed memory of every place on Earth
README
emem — Earth memory protocol for AI agents
Cite-able, content-addressed, signed memory of every place on Earth. 1 protocol. 8 read primitives. ed25519 receipts. No keys for L0/L1. Apache-2.0. Pure Rust + open data only.
GET /health POST /v1/recall POST /v1/find_similar
GET /v1/agent_card POST /v1/compare POST /v1/diff
GET /openapi.json POST /v1/query_region POST /v1/trajectory
GET /.well-known/emem.json POST /v1/verify POST /v1/intent
GET /v1/demos POST /v1/attest POST /mcp
POST /v1/verify_receipt GET /v1/facts/:cid
What it is
emem is a protocol — not a service — for content-addressed Earth memory.
Every fact about every place gets a stable CID derived from the canonical CBOR
of its (cell × band × tslot) payload. Every read is a signed receipt that
any client can verify offline with the responder's ed25519 public key.
emem is built for AI agents: when a user mentions a place, the agent
should call emem and cite receipt.fact_cids[0]. The protocol works equally
well over plain REST, MCP JSON-RPC 2.0, and OpenAPI 3.1 custom actions.
Why agents need it
LLMs confabulate spatial facts. Without a verifiable, content-addressed memory layer, every "what is at place X?" answer is unauditable. emem fixes this by:
- giving every spatial fact a cid that two parties recompute byte-for-byte,
- signing every read with ed25519, including the responder's pubkey, so the receipt is offline-verifiable,
- covering the whole Earth with a square cell64 address (~10 m × ~10 m at the equator, lat 21 bits × lng 22 bits — matches Sentinel-1/-2 native pitch). The codec's bigram alphabet is Hilbert-ordered so neighbouring cells get visually similar strings, but the geometry is a square grid.
Quickstart
Option A — Docker (no Rust toolchain needed)
docker run --rm -p 5051:5051 -v emem-data:/var/emem \
ghcr.io/vortx-ai/emem:latest
curl -s http://localhost:5051/health
Option B — HuggingFace Space
A hosted instance lives at
huggingface.co/spaces/vortx-ai/emem.
Hit ${SPACE_URL}/mcp from any MCP client to talk to it.
Option C — Build from source
# 1) Build the workspace.
cargo build --release --workspace
# 2) Run the server (defaults: 0.0.0.0:5051, persistent storage at ./var/emem).
EMEM_BIND=0.0.0.0:5051 EMEM_DATA=./var/emem ./target/release/emem-server
# 3) Hit it.
curl -s http://localhost:5051/health
curl -s -X POST http://localhost:5051/v1/recall \
-H 'content-type: application/json' \
-d '{"cell":"damO.zb000.xUti.zde78"}' # Mt Fuji
MCP / Claude Desktop / Cursor / Cline
Paste-ready configs live under examples/:
| platform | file |
|---|---|
| Claude Desktop | examples/claude-desktop.json |
| Claude Code | examples/claude-code.mcp.json |
| Cursor | examples/cursor.mcp.json |
| Cline (VS Code) | examples/cline.mcp.json |
| OpenAI GPT | examples/openai-gpt-action.json |
| LangChain | examples/langchain.py |
| LlamaIndex | examples/llamaindex.py |
The full agent integration walkthrough is at docs/AGENTS.md.
Live end-to-end demos
Two CLI binaries exercise the full protocol against a running server and
write per-step request + response + receipt files to var/demos/<UTC>/:
./target/release/emem-livedemo # synthetic data, every primitive
./target/release/emem-realdemo # real Copernicus DEM 30m S3 tiles
The server exposes the trace artifacts at GET /v1/demos.
How it works
┌──────────────┐ ┌────────────────────┐
user ──────► │ AI agent │ ──────► /v1/ │ emem responder │
│ (Claude / │ /mcp │ ┌──────────────┐ │
│ Cursor / │ /openapi.json │ │ ed25519 key │ │
│ GPT / etc) │ │ └──────────────┘ │
└──────┬───────┘ │ ┌──────────────┐ │
│ │ │ sled cache │ │
│ signed receipt │ └──────────────┘ │
▼ │ ┌──────────────┐ │
┌──────────────┐ │ │ merkle log │ │
│ user reply │ │ └──────────────┘ │
│ + cid │ │ ┌──────────────┐ │
└──────────────┘ │ │ vsicurl COG │ ──► open data
│ └──────────────┘ │ (Cop-DEM, JRC,
└────────────────────┘ Hansen, ESA…)
Address algebra (token cost)
| field | bits | wire form | tokens |
|---|---|---|---|
cell |
64 | 4 BPE bigrams | ≤ 4 |
tslot |
64 | base32 short | ≤ 2 |
vec |
1792 D fp16 | 12-byte prefix | ≤ 3 |
cid |
32 B | 8-byte prefix | ≤ 3 |
Crypto: blake3 hashing, ed25519 signatures, base32-nopad-lowercase CIDs.
Receipts are signed over blake3(request_id || served_at || primitive || cells || fact_cids) so any client offline-verifies with the responder pubkey
in /.well-known/emem.json.
Full math + architecture in docs/WHITEPAPER.md. Wire-format spec in docs/SPEC.md.
Open source, open data
emem ships with only open-source dependencies and reads only from open-data providers in its default build. No API keys, no operator credentials, no SaaS lock-in.
| concern | how it's handled |
|---|---|
| code license | Apache-2.0 (this repo) |
| crate licenses | All deps are MIT / Apache-2.0 / BSD / ISC — see NOTICE |
| data licenses | Copernicus DEM (open), JRC GSW (CC-BY 4.0), Hansen GFC (open), ESA WorldCover (CC-BY 4.0), GHSL / WorldPop (CC-BY 4.0), OSM (ODbL) — see NOTICE |
| auth | none for L0/L1 reads; ed25519 attester key for L2 writes |
| transport | HTTPS via in-process rustls + Let's Encrypt ACME (no Cloudflare, no proxies) |
Workspace layout
emem/
├── Cargo.toml # workspace root
├── crates/
│ ├── emem-core/ # types, manifests, errors
│ ├── emem-codec/ # cell64, cid64, vec64, hilbert
│ ├── emem-fact/ # canonical CBOR + facts + receipts
│ ├── emem-claim/ # structured claims, verify outcomes
│ ├── emem-cache/ # sled hot cache (cell64 → cid64 → fact)
│ ├── emem-fetch/ # vsicurl Range reads, source connectors
│ ├── emem-storage/ # Storage trait, append-only merkle log
│ ├── emem-cubes/ # 1792-D voxel cube loader (legacy AgriSynth bootstrap)
│ ├── emem-primitives/ # recall, compare, find_similar, …
│ ├── emem-attest/ # merkle root, batch verify
│ ├── emem-intent/ # intent → plan
│ ├── emem-mcp/ # MCP tool surface
│ ├── emem-api-rest/ # axum router + OpenAPI + content nego
│ └── emem-cli/ # emem-server, emem-livedemo, emem-realdemo
├── docs/ # SPEC, WHITEPAPER, AGENTS, DEPLOY
├── examples/ # paste-ready MCP configs
└── web/ # landing surface (HTML, JSON, llms.txt)
Deploying
For a full multi-channel rollout (GitHub public, GHCR, Docker Hub mirror, HuggingFace Space, MCP Server Registry, awesome-mcp-servers PR), follow docs/GO_LIVE.md.
See docs/DEPLOY.md for the full deploy story for a
self-hosted bare-metal emem.dev-style instance.
TL;DR for emem.dev:
EMEM_TLS_DOMAINS=emem.dev,www.emem.dev EMEM_TLS_CONTACT=mailto:avijeet@vortx.ai ./target/release/emem-server- open
:443in your cloud security list, setcap 'cap_net_bind_service=+ep' ./target/release/emem-server,- point
emem.dev's A record at the host's public IP — done.
The server does its own TLS + Let's Encrypt ACME via rustls-acme /
TLS-ALPN-01 (only :443 is needed; no :80, no Cloudflare, no Caddy).
Contributing
Issues and PRs welcome — see CONTRIBUTING.md for the dev loop, CODE_OF_CONDUCT.md, and SECURITY.md for vulnerability disclosure.
License
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.