A portable memory protocol for AI agents.
Status: Live v0.1 · Site: https://universalmemoryprotocol.io · Package: @universalmemoryprotocol/core · Bindings: MCP, HTTP, file export
UMP standardizes how agents read, write, revise, forget, and exchange memory across tools, runtimes, and storage engines. It is not a database and it is not a single memory product. It is a small protocol surface, a portable signed record format, and reference SDK/server code that any agent harness or memory backend can implement.
In simple terms: you may already have useful memories in agent files, Claude or Codex project notes, Recall exports, Obsidian folders, Postgres, Redis, SQLite, or a vector database. UMP turns those into one portable memory shape and one small operation set, so new agents and new stores can extend the same memory instead of starting from scratch.
Add persistent UMP memory to any MCP host:
The server exposes:
ump.capabilitiesump.recallump.rememberump.getump.reviseump.forgetump.feedback
By default, ump-memory stores portable records in ~/.ump/memory.ump.json.
Set UMP_STORE=markdown to store human-editable *.ump.md records instead.
Use the MCP server for immediate agent integration, the TypeScript SDK for a native UMP implementation, or the HTTP binding from any language.
// MCP host config: Claude Code, Codex, Cursor, or any MCP client.
{
"mcpServers": {
"ump": {
"command": "npx",
"args": ["-y", "@universalmemoryprotocol/core", "ump-memory"]
}
}
}import {
JsonFileStore,
UmpServer,
generateKeyPair,
} from "@universalmemoryprotocol/core";
const key = generateKeyPair();
const store = await JsonFileStore.open(".ump/memory.ump.json");
const ump = new UmpServer({
name: "my-agent",
version: "1.0.0",
conformance: "L2",
store,
key,
});
await ump.remember({
kind: "procedural",
body: { text: "Use pnpm for this repository." },
scope: { owner: key.did, project: "github.com/acme/app", visibility: "private" },
provenance: { actor: key.did, actor_kind: "user", method: "user_correction" },
});
const memories = await ump.recall({
query: "package manager",
scope: { owner: key.did, project: "github.com/acme/app" },
});# Any language: expose JSON over HTTP.
UMP_HTTP=4000 npx -y @universalmemoryprotocol/core ump-memoryimport requests
base = "http://localhost:4000"
owner = requests.get(f"{base}/.well-known/ump.json").json()["owner"]
requests.post(f"{base}/ump/remember", json={
"kind": "semantic",
"body": {"text": "User prefers concise release notes."},
"scope": {"owner": owner, "project": "github.com/acme/app", "visibility": "private"},
"provenance": {"actor": owner, "actor_kind": "user", "method": "user_correction"},
}).raise_for_status()
hits = requests.post(f"{base}/ump/recall", json={
"query": "release note preference",
"scope": {"owner": owner, "project": "github.com/acme/app"},
}).json()["results"]Agent memory is fragmented. Claude Code, Codex, ChatGPT, local agents, memory engines, and framework-specific stores all use different verbs, record shapes, scope rules, export formats, and retention behavior. That creates lock-in and makes memory hard to audit, migrate, or share across agents.
UMP gives the ecosystem one interoperable contract:
portable record format + 6 core operations + MCP/HTTP/file bindings
MCP standardizes tool access. A2A standardizes agent coordination. UMP standardizes memory portability.
UMP standardizes the parts that must match for memory to travel:
- record shape: kind, body, scope, time, lifecycle, relations, provenance, consent, integrity
- operations: capability negotiation, recall, remember, get, revise, forget
- bindings: MCP tools, HTTP endpoints, JSON/Markdown file exports
- conformance: L0 through L3 so implementers can adopt incrementally
- safety: supersession instead of destructive updates, consent-aware export, scoped retrieval, signed records at the full tier
UMP deliberately does not standardize the retrieval algorithm, embedding model, database, ranking policy, summarization strategy, or consolidation engine. Those remain implementation choices.
| Operation | Purpose |
|---|---|
capabilities |
Negotiate supported kinds, bindings, conformance, limits, and signals. |
recall |
Search memory by query, scope, filters, and time. |
remember |
Write a new memory, or merge it if the store chooses. |
get |
Fetch a memory by id. |
revise |
Supersede a memory while preserving history. |
forget |
Tombstone a memory with a reason. |
Optional full-tier operations:
| Operation | Purpose |
|---|---|
feedback |
Report whether a recalled memory was followed, ignored, overridden, or contradicted. |
subscribe |
Stream memory changes where supported. |
| Level | Requirement |
|---|---|
| L0 | Portable *.ump.json or *.ump.md records. No server required. |
| L1 | capabilities, recall, remember, and get. |
| L2 | revise, forget, bi-temporal validity, provenance, scope, and consent. |
| L3 | Feedback, subscribe, signed integrity, capability-scoped tokens, and contradiction relations. |
Run the conformance probe against an HTTP endpoint:
pnpm conformance http://localhost:4000UmpServer accepts any MemoryStore. The package ships dependency-light stores
for common adoption paths:
| Store | Use case |
|---|---|
JsonFileStore |
Default. Portable, signed memory.ump.json; fast and faithful. |
InMemoryStore |
Tests, examples, and ephemeral servers. |
MarkdownDirectoryStore |
Human-editable *.ump.md records. |
PostgresStore |
Postgres-compatible clients. |
SqliteStore |
SQLite-compatible clients. |
RedisStore |
Redis hash persistence. |
VectorStore |
Generic vector-backed store (e.g. sqlite-vec) + embedding fn. |
QdrantStore / PineconeStore / WeaviateStore |
Hosted vector clients. |
RecallStore |
Opt-in adapter for a Recall-backed memory engine. |
Vendor database SDKs stay outside @universalmemoryprotocol/core, so installing the protocol package
does not force native builds or cloud clients into every project.
- Default (zero-config, local):
JsonFileStore. In benchmarks it is the fastest and most faithful baseline (all 5 kinds preserved, flat ~5ms recall at 3k records, portable signed file). This is whatump-memoryuses by default. - Semantic retrieval at scale: a vector store (
VectorStoreover sqlite-vec / Qdrant / Pinecone / Weaviate) with embeddings enabled, orRecallStore. These earn their extra latency only when embeddings are actually populated; without them you get lexical recall at higher cost than the file store. - Recall as engine (
RecallStore): opt-in semantic tier.recall umpwarms a local embedding model (no API key) and serves real vector + BM25 (RRF) search- in benchmarks, paraphrase top-1 recall jumps from 1/8 (lexical) to 5/8. The
cost is embedding compute (~100ms write, ~200ms recall), so reach for it when
retrieval quality matters more than latency; otherwise
JsonFileStorewins.
- in benchmarks, paraphrase top-1 recall jumps from 1/8 (lexical) to 5/8. The
cost is embedding compute (~100ms write, ~200ms recall), so reach for it when
retrieval quality matters more than latency; otherwise
Switching is one line: point UmpServer at a different MemoryStore. The record
format, bindings, and protocol are identical across all of them.
UMP stays separate from vendor-specific memory files, but @universalmemoryprotocol/core includes
import helpers so users can migrate existing memory into portable UMP records.
node --experimental-strip-types src/bin/import.ts \
--owner did:key:zYourOwner \
--project github.com/example/repo \
--out .ump/import.ump.json \
CLAUDE.md AGENTS.md ~/Documents/mainSupported source kinds:
| Source kind | Input |
|---|---|
claude |
CLAUDE.md style instructions. |
agents |
AGENTS.md style repo or agent instructions. |
recall |
Recall exports and context files. |
obsidian |
Obsidian-style vault folders and notes. |
generic_markdown |
Any Markdown file or directory. |
Importers emit UMP MemoryDraft records with source provenance such as
filesystem:claude. They are migration bridges, not protocol requirements.
Recall is one implementation target: a rich memory engine that can be exposed
through UMP via RecallStore. It is not the protocol, not a required dependency,
and not the only valid backend.
The reference protocol surface lives in @universalmemoryprotocol/core: schema, types, bindings,
server helpers, stores, importers, and conformance tests. Recall exists to prove
that UMP can wrap a production-grade memory engine without making the standard
vendor-specific.
pnpm install
pnpm typecheck
pnpm test
pnpm buildInstall once, then drive everything from one command:
npm install -g @universalmemoryprotocol/core # provides: ump, ump-memory, ump-serve, ump-conformance, ump-importump memory # persistent MCP memory server (~/.ump)
ump memory --http 4000 # also expose the HTTP binding
ump memory --store markdown # human-editable *.ump.md records
ump serve --http 4000 # ephemeral in-memory reference server
ump import --owner did:key:z... AGENTS.md CLAUDE.md
ump conformance http://localhost:4000
ump demo # the cross-vendor round-trip
ump --helpNo install? Use npx -y @universalmemoryprotocol/core ump <command>. MCP hosts point at the bin
directly: { "command": "npx", "args": ["-y", "@universalmemoryprotocol/core", "ump-memory"] }.
From a clone (no build needed):
node --experimental-strip-types src/bin/ump.ts demo| Path | Purpose |
|---|---|
SPEC.md |
Protocol specification. |
src/ |
Reference SDK/server, schema, bindings, stores, importers, and CLIs. |
adapters/recall/ |
Recall-backed MemoryStore adapter. |
test/ |
Binding, store, importer, conformance, and adapter tests. |
examples/ |
Round-trip portability demos. |
docs/ |
Rationale, adoption notes, and launch materials. |
Protocol GitHub repository: Apache-2.0. See LICENSE.
@universalmemoryprotocol/core, adapters, examples, and package code are MIT. See
LICENSE-PACKAGE.
Specification and documentation prose are CC-BY-4.0. See LICENSE-DOCS.
{ "mcpServers": { "ump": { "command": "npx", "args": ["-y", "@universalmemoryprotocol/core", "ump-memory"] } } }