Skip to main content

Echo Memory

Shared memory for AI coding agents. What Claude Code learns, Codex and Cursor can recall — in one graph, on your own machine, with every write auditable.

Apache 2.0. No LLM call on the write path, so recording a memory costs nothing to run.

Install

Run it yourself — nothing leaves your machine:

pipx install echo-mem
echo-memory quickstart

That starts the database, applies the schema, and prints the claude mcp add command that registers it with your tools, filled in with the port it actually used. Docker is the only prerequisite; the Postgres image is published, so nothing is compiled.

Or use the hosted service and run no database at all:

pipx install echo-mem
echo-memory connect <key>          # a key from https://api.echo-mem.com

Either way, restart your client afterwards. An MCP server holds the code and config it started with.

Then, once per machine, so the agent knows when to record and recall rather than only that the tools exist:

echo-memory install --global

Why

Every AI agent starts from zero unless something remembers what happened last time, and remembers it well enough and fast enough to still be useful after months or years of accumulated history. Most memory tools solve short-term recall with plain vector search over stored facts. That degrades as history grows: more candidates, more noise, slower retrieval. Echo Memory is built around the read/write algorithm and the data structure that keeps working at long horizons, not just at day one:

  • A temporal, self-consolidating memory graph. Facts are edges between entities, not flat vector rows. Old, rarely-accessed memory doesn't just accumulate: it gets consolidated into higher-level summaries over time (never deleted, always traceable back to the original), so retrieval cost stays bounded by what's currently relevant, not by everything that's ever been written. See docs/designs/echo-memory-design.md for the actual mechanism.
  • Real graph structure, not just similarity. Multi-hop queries like "how did we end up here?", answerable because facts are connected, not just individually embedded.
  • Causal typing, not just similarity. Edges can be tagged caused_by, led_to, blocked_by, contradicts, set by the agent's own read of the conversation, not inferred statistically. Honest about what's tractable today and what isn't.
  • Auditable by design. Every change to memory is logged, with a plain-language reason you can read back (echo-memory why <fact_id>). Memory that consolidates and edits itself is only trustworthy if you can see why.
  • A write path that costs nothing to run. Extraction happens in the calling agent, never on the server, so recording a memory makes zero LLM calls. Measured locally with echo-memory benchmark: write 15ms median, query 8ms, digest 1ms, $0.00 inference cost per episode. The tradeoff is explicit and worth stating: the agent must arrive with entities and facts already extracted, which is more work for the caller and the reason the MCP tool contract spells the shape out. The comparison that makes this matter is Zep/Graphiti, the closest architectural match (bi-temporal edges, fact invalidation, episode provenance): its own published description of ingestion is that "every episode triggers multiple LLM calls for extraction, entity resolution, and invalidation" and that "write cost scales with volume". Here it doesn't.
  • One storage engine, every scale. Postgres + pgvector + Apache AGE, from a single local agent up to an organization-wide shared graph spanning every agent a business runs. No forced migration later. (The novel work is the memory structure and algorithm running on top of Postgres, not a new database engine; see the design doc for why.)
  • Any agent, not one vendor's. The interface is MCP: any MCP-compatible agent can read and write the same memory graph, whether that's a coding assistant, a chatbot, an ops agent, or something built in-house.

Who this is for

  • A developer running local agents who wants Claude Code, Cursor, or anything else to stop losing context between sessions and tools.
  • A team or organization running agentic systems in production (support bots, DevOps agents, internal tooling) that needs a shared memory layer instead of N disconnected ones, with the tenancy model (below) to keep it scoped correctly per agent, per team, or org-wide.

Status

Early and staged. See docs/designs/ for the full architecture and the v1a → v1b build plan. The validated wedge driving v1a is specifically cross-tool coding agent memory (the founder's own daily pain, real and tested). The broader vision above is the target this architecture is built toward, not yet something v1a itself proves. v1a proves basic recall works before v1b adds causal typing and multi-hop graph retrieval, and before v1.1 adds the org-wide tenancy the broader vision depends on.

Setting it up by hand

quickstart is the short way. If you would rather see every step, or you are working on Echo Memory itself, docs/DEVELOPMENT.md has the long version: clone, docker compose up -d, pip install -e ".[dev]", alembic upgrade head, and the claude mcp add line with its environment.

Wiring a second tool? Give it its own ECHO_MEMORY_AGENT_ID. Cursor should say cursor, Claude Desktop claude-desktop. Memory is shared either way, but a fact records which tool learned it, and two tools claiming the same id makes cross-tool recall impossible to see afterwards. echo-memory adopt wires every MCP client on the machine at once, each with its own id, and shows the diff before writing anything.

Scoped to one project instead — a single Claude project, a Cursor workspace, a repo whose memory should not mingle with the rest? echo-memory install [path] writes a project-scoped MCP config plus a skill (or, for Cursor, an always-applied rule), committed alongside the code.

See docs/INTEGRATIONS.md for using Echo Memory from an agent that does not speak MCP — a chatbot, a DevOps agent, or any custom tool-calling loop.

The graph

Memory is a graph, not a list of notes. Entities are nodes; a fact is an edge between two of them. That is the whole data model, and everything below follows from it.

The memory graph

Three projects here. checkout-api, mobile-app and data-pipeline were recorded in separate sessions and never told about each other, yet the picture already separates them — because separation is a property of the edges, not a label anyone applied.

Clusters come from structure. Densely connected facts are grouped by label propagation over the edges, and each cluster is named after its most-connected node. That is why data-pipeline sits apart on the left: nothing it knows touches payments. It is also why checkout-api and mobile-app share a cluster despite being different codebases — they genuinely do share an idea, and the graph found it rather than being told.

Components are the stronger claim. Two nodes in different components have no path between them at all, which is the strongest statement this graph can make that two memories are unrelated.

Projects are a facet, not the structure. Every fact records the project it was written from, and you can colour by it, but project says where a fact was written, not what it belongs with.

Click a node: everything it takes part in

A node selected

idempotency keys is the concept that joined those two codebases. The panel shows it referenced from checkout-api twice and mobile-app once, the three facts it appears in, and how the node itself resolved — each mention matched an existing node by exact name rather than creating a duplicate.

Nobody wrote "these projects are related." Two sessions independently recorded a fact about idempotency keys, entity resolution matched them to one node, and the relationship exists as a consequence.

Click a link: why memory believes it

A fact selected

This is what a knowledge graph gives you that a code map cannot. Selecting the edge answers, for that single fact:

what the sentence, its relation_type, and how confidently it was stated
when when it became valid, and when it was superseded if it has been
who which agent wrote it, in which session
where which project it came from
why the audit trail — created, superseded from what to what, and the entity-resolution rationale for the nodes at either end

A superseded fact is never deleted. It stops being drawn, because the graph no longer asserts that relationship, but it stays reachable from its node and keeps its full history. echo-memory why <fact_id> prints the same trail in a terminal.

Seeing your own

echo-memory dashboard --serve --open

The images above come from a synthetic dataset (scripts/demo-seed.py) rather than a real store, for the obvious reason: a real memory graph is full of hostnames, account numbers and client names.

Architecture

  • Storage: PostgreSQL with the pgvector and Apache AGE extensions
  • Retrieval: hybrid vector + full-text search (v1a), with Personalized PageRank via networkx added in v1b for multi-hop associative retrieval
  • Interface: Model Context Protocol server: write_episode, query_memory, record_recall_save, get_audit_log

Is the graph in good shape?

echo-memory health

A score, what is strong, what needs attention, and what to do about each, including what recall has cost: how often memory was read, how often a read returned anything, roughly how many tokens were injected, and how many saves those reads produced. Writes were counted from the start; reads were not counted at all, so nothing could answer whether recall earns what it costs. It exists to be run when you have no question - a store can look healthy by every number this CLI reports while most of its facts came from a bulk import, the last real write was a week ago, and only one of several wired agents has ever written anything. --json for machine-readable output.

Nothing in it is gated. The paid tiers sell hosting and the things that only exist when several people share a graph; diagnostics about your own data are not a thing to withhold from the person whose data it is.

Contributing

See CONTRIBUTING.md. Issues and PRs welcome; please read the design docs first so proposals fit the staged build plan. A first pull request is asked to sign the Contributor License Agreement — once, in the PR thread.

License

Apache License 2.0. See LICENSE.

mcp-name: io.github.ayushcodes10/echo-mem

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

echo_mem-0.3.0.tar.gz (179.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

echo_mem-0.3.0-py3-none-any.whl (219.9 kB view details)

Uploaded Python 3

File details

Details for the file echo_mem-0.3.0.tar.gz.

File metadata

  • Download URL: echo_mem-0.3.0.tar.gz
  • Upload date:
  • Size: 179.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for echo_mem-0.3.0.tar.gz
Algorithm Hash digest
SHA256 2ab3a5f58f8f0587c86272da9aca81c106dd180be712419bae6e665e4b6a158d
MD5 066de821822b8b9305a90092635eb8b0
BLAKE2b-256 606a9ff5ae8d5f8e59e82c91bfb5ac16585e213da7798f53ad44c28462ad91dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for echo_mem-0.3.0.tar.gz:

Publisher: release.yml on ayushcodes10/echo-mem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file echo_mem-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: echo_mem-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 219.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for echo_mem-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7f8c3603ce48b666b3864c824f61dfdd9b965744d3712ab97c1d8325eb1fa466
MD5 3492f8dc51e59c82538a3122b5f20675
BLAKE2b-256 dfc5eecd16c342f34e76309cb85e37bf8be806e8d405022d6e17cc99b9dd142f

See more details on using hashes here.

Provenance

The following attestation bundles were made for echo_mem-0.3.0-py3-none-any.whl:

Publisher: release.yml on ayushcodes10/echo-mem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page