Echo Memory is a Python package and a Postgres database. Install it once per machine and every agent you wire up — Claude Code, Cursor, anything else that speaks MCP — writes to the same graph. This is the full path, five steps, no gaps skipped.

1. The database

Echo Memory runs on Postgres with the pgvector and Apache AGE extensions. The repo ships a Docker Compose file that brings up a correctly-configured instance:

# the database — Postgres with Apache AGE and pgvector
git clone https://github.com/echo-mem/echo-mem.git && cd echo-mem
docker compose up -d

2. The package

pip install echo-mem
Not echo-memory

The distribution on PyPI is echo-mem. pip install echo-memory installs an unrelated hosted product published in March 2026 — same near-name, different maintainer, different thing. The Python import path is unaffected either way: it's echo_memory regardless of which distribution name you installed under, but only echo-mem is this project.

3. The schema

Migrations ship inside the installed package, so there's no separate migrations repo to clone or keep in sync:

export ECHO_MEMORY_DATABASE_URL="postgresql://postgres:postgres@localhost:5433/echo_memory"
echo-memory init-db

4. Wire it into Claude Code

User-scoped, so it's available across every project, not just the one you run this in:

claude mcp add --scope user echo-memory \
  -e ECHO_MEMORY_USER_ID=your-user-id \
  -e ECHO_MEMORY_AGENT_ID=claude-code \
  -e ECHO_MEMORY_DATABASE_URL="$ECHO_MEMORY_DATABASE_URL" \
  -- python -m echo_memory.server

Start a new Claude Code session and write_episode, query_memory, and get_audit_log are available immediately.

5. Add a second tool, so memory is actually shared

One agent writing to a graph nobody else reads isn't shared memory, it's a private notebook. The point is a second tool reading what the first one wrote:

echo-memory install --for both

This writes a project-scoped MCP config plus a skill (or, for Cursor, an always-applied rule) telling the agent when to record and when to recall — scoped to one repo rather than every project, if that's what you want instead of the user-scoped setup in step 4.

Check it worked

echo-memory status

This reports what each scope holds and which agents have written to it. If only one agent shows up, memory isn't shared yet, and the command will say so rather than leave you guessing.

Prefer something project-scoped from the start?

echo-memory install [path] --for claude|cursor|both does steps 4 and 5 in one call, scoped to a single repo whose memory shouldn't mingle with everything else on the machine.