Project-scoped GraphRAG memory for agents.
Project description
Memorable
Memorable gives your AI coding agent a long-term memory for a project — what was decided, what changed, and what's true now — so it doesn't lose context between sessions and you don't have to repeat yourself.
Instead of scattering this across Markdown files, Memorable stores it as structured, searchable memory that your agent can write to and read back. You use it two ways:
- With your agent — the MCP server (
memorable-mcp) plugs Memorable into Claude, Cursor, and other MCP clients so the agent remembers and recalls on its own. This is the main way to use it. - By hand — the
memorableCLI lets you write, search, and inspect memory directly from the terminal.
Under the hood it's a GraphRAG memory system backed by Neo4j.
Install
Run it as a one-shot tool with uvx:
uvx --from memorable-kg memorable --help
Or install it once for regular use:
uv tool install memorable-kg
The published distribution is memorable-kg; the installed commands are
memorable and memorable-mcp. The examples below assume the persistent
install — if you prefer uvx, prefix each command with uvx --from memorable-kg.
Requirements: Python 3.14+, and Docker (only if you use the bundled local Neo4j; not needed when you point Memorable at a remote/cloud Neo4j).
Quickstart
Start in the project directory whose memory you want to manage:
mkdir memorable-quickstart
cd memorable-quickstart
Start the local Neo4j runtime (requires Docker):
memorable db start
Set up memory for this project. This creates a starter config file you can grow into later:
memorable init --space memorable-quickstart --description "Quickstart memory"
The scaffold lives at .memorable/memory.yaml:
version: 1
space:
name: "memorable-quickstart"
description: "Quickstart memory"
entities: []
relations: []
records: []
This file describes your project's memory. You can leave the three lists empty to start — they're there for when you want to teach Memorable about your specific domain:
entities— the things in your project worth remembering, like a service, an API, or a person.relations— how those things connect, like "service A depends on service B."records— your own kinds of memory, when the built-in ones aren't specific enough.
You don't need any of that to get going. Memorable already understands a few universal kinds of memory — Decisions, Observations, and Tasks — so you can start saving and searching memory right away, then add project-specific types later as you need them.
Check the runtime before writing memory:
memorable doctor
Remember your first Decision:
memorable remember decision \
--id decision-first-memory \
--statement "Use Memorable to keep project decisions searchable." \
--source quickstart \
--at 2026-05-30T00:00:00Z \
--reason "Verify a fresh install can persist a kernel Decision."
Search for it — by meaning, not just keywords:
memorable search --query "project decisions searchable"
The JSON result should include a hit like:
{
"source_id": "decision-first-memory",
"source_kind": "Decision"
}
Configuration
Memorable resolves its runtime configuration from four layered sources, each overriding the one before it:
- Built-in defaults (shown below).
.memorable/runtime.yaml— committed, shared project defaults..memorable/runtime.local.yaml— gitignored, per-developer overrides..memorable/.env(or environment variables) — secrets only.
Inspect the resolved values and where each one came from:
memorable db status
What you can configure
All non-secret settings live in runtime.yaml / runtime.local.yaml. Secrets
(Neo4j password, embedding API key) come from .env or the environment.
| Setting | Env var | Default | Notes |
|---|---|---|---|
neo4j.uri |
MEMORABLE_NEO4J_URI |
bolt://localhost:7687 |
Bolt URI. Use neo4j+s://… for cloud. |
neo4j.user |
MEMORABLE_NEO4J_USER |
neo4j |
Database user. |
neo4j.password |
MEMORABLE_NEO4J_PASSWORD |
memorable |
Secret — set via .env/env. |
docker.neo4j_version |
— | 5.26 |
Image tag for the local container. |
docker.http_port |
— | 7474 |
Local Neo4j HTTP port. |
docker.bolt_port |
— | 7687 |
Local Neo4j Bolt port. |
embeddings.provider |
— | fastembed |
fastembed, openrouter, or fake. |
embeddings.model |
— | BAAI/bge-small-en-v1.5 |
Model name for the provider. |
embeddings.dimensions |
— | 384 |
Vector size; must match the model. |
embeddings.api_key |
MEMORABLE_OPENROUTER_API_KEY |
— | Secret — required for openrouter. |
Embeddings
To search by meaning, Memorable turns your memory into vectors (number lists that capture meaning) using an embedding provider. Three are built in:
fastembed(default) — runs locally via ONNX, no API key, no network. Default modelBAAI/bge-small-en-v1.5at 384 dimensions.openrouter— remote, OpenAI-compatible API. Default modelgoogle/gemini-embedding-2-preview, whose native size is 3072 dimensions (it supports Matryoshka truncation to 128–3072; recommended 768, 1536, or 3072). Memorable's built-in default for this provider is 768.fake— deterministic hash-based vectors for tests; do not use for real memory.
Using OpenRouter for embeddings
.memorable/runtime.yaml (committed):
embeddings:
provider: openrouter
model: google/gemini-embedding-2-preview
dimensions: 3072 # native size; or truncate to 1536 / 768
.memorable/.env (gitignored — keep the key out of version control):
MEMORABLE_OPENROUTER_API_KEY=sk-or-...
provider, model, and dimensions are not read from environment variables —
they must live in runtime.yaml / runtime.local.yaml. Only the API key comes
from .env/env.
Important:
dimensionsmust match the model you choose. The vector index is created from this value, so if you switch providers/models after writing memory, re-create the space against a clean database.
Verify the provider builds correctly:
memorable doctor
The embedding_provider_builds check fails fast if, for example, you selected
openrouter without setting MEMORABLE_OPENROUTER_API_KEY.
Neo4j
Local (Docker)
memorable db start runs a packaged docker-compose.yml (Neo4j with the APOC
plugin, a persistent memorable-neo4j-data volume). Manage it with:
memorable db start # docker compose up -d
memorable db stop # docker compose down
memorable db status # show resolved config + value sources
To customize the container (extra plugins, memory limits, etc.), eject the template and edit your local copy — it then takes precedence over the packaged one:
memorable db eject # writes .memorable/docker-compose.yml
Remote / cloud Neo4j
Point Memorable at an existing instance instead of running Docker. In
.memorable/runtime.yaml:
neo4j:
uri: neo4j+s://<your-instance>.databases.neo4j.io
user: neo4j
And the password in .memorable/.env:
MEMORABLE_NEO4J_PASSWORD=<your-password>
When the URI is remote (neo4j+s://, neo4j+ssc://, or a non-localhost host),
memorable db start/stop become no-ops — there is no local container to
manage. Run memorable doctor to confirm connectivity.
CLI reference
Setup & diagnostics:
| Command | Purpose |
|---|---|
memorable init |
Create .memorable/memory.yaml scaffold and initialize the MemorySpace. |
memorable doctor [--json] |
Run health checks (connectivity, constraints, vector index, embeddings, profile). |
memorable status |
Print the diagnostic status payload. |
memorable db start|stop|status|eject |
Manage / inspect the local Neo4j runtime. |
memorable profile show |
Show the loaded MemoryProfile. |
Writing memory (remember):
| Command | Writes |
|---|---|
memorable remember entity |
An Entity (--id --type --name --source --at). |
memorable remember decision |
A Decision (--id --statement --source --at, optional --supersedes). |
memorable remember observation |
An Observation (same shape as decision). |
memorable remember task |
A Task (--id --title --source --at). |
memorable remember relation |
A Relation between two entities (--id --source-entity-id --target-entity-id --relation-type --statement --source --at). |
Most write commands also accept --space, --writer (default
agent:memorable), and --reason.
Lifecycle, truth & history:
| Command | Purpose |
|---|---|
memorable complete task --id --at |
Mark a Task complete. |
memorable task inspect --id [--as-of] |
Snapshot a Task's lifecycle. |
memorable truth current --id |
Current truth following the supersession chain. |
memorable truth as-of --id --at |
Point-in-time truth. |
memorable inspect history --id |
Full supersession chain with lifecycle states. |
memorable inspect provenance --id |
Source, writer, reason, validity times. |
memorable invalidate --id --record-type --at |
Mark a record invalidated (no successor). |
memorable correct --id --record-type --new-statement --source --at |
Append a corrected statement. |
Search:
| Command | Purpose |
|---|---|
memorable search --query [--mode current|as-of] [--as-of] |
Hybrid GraphRAG retrieval. |
Run any command with --help for its full option list.
MCP server
This is the main way to use Memorable: the MCP server connects it to your AI agent (Claude, Cursor, and other MCP clients), so the agent can save and recall memory on its own — no manual CLI commands.
Start it manually to test:
memorable-mcp
Wire it into an MCP client. For Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"memorable": {
"command": "memorable-mcp"
}
}
}
If you installed with uvx instead of uv tool install, use:
{
"mcpServers": {
"memorable": {
"command": "uvx",
"args": ["--from", "memorable-kg", "memorable-mcp"]
}
}
}
The server operates on the .memorable/ of its working directory, so launch it
from (or configure your client to run it in) the project whose memory you want.
It picks up that project's .memorable/.env, so you do not need to repeat
secrets in the client config.
If the client can't run the server inside the project (no
.memorable/.envon disk), pass secrets via anenvblock instead. Note that when a.memorable/.envdoes exist it takes precedence and anyenvvalues are ignored:{ "command": "memorable-mcp", "env": { "MEMORABLE_OPENROUTER_API_KEY": "sk-or-..." } }
More information
Start with the product charter in docs/product.md.
Maintainers cutting 0.0.x releases should follow the release version ladder.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file memorable_kg-0.0.2.tar.gz.
File metadata
- Download URL: memorable_kg-0.0.2.tar.gz
- Upload date:
- Size: 304.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af93f24d35c3a036984ff9a32afb18e5b791fe130d28d0fcc343e8bb44c489b4
|
|
| MD5 |
7ba78383b1fa281da8c1bdf1667409c4
|
|
| BLAKE2b-256 |
c1e2987934c5a02b86b86d5f8a980264b3ef71c2079e31826a853ded4f13533a
|
Provenance
The following attestation bundles were made for memorable_kg-0.0.2.tar.gz:
Publisher:
release.yml on taecontrol/memorable
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memorable_kg-0.0.2.tar.gz -
Subject digest:
af93f24d35c3a036984ff9a32afb18e5b791fe130d28d0fcc343e8bb44c489b4 - Sigstore transparency entry: 1676780626
- Sigstore integration time:
-
Permalink:
taecontrol/memorable@0063dc24e3c4de16271dd66c2dfb3faf9fbe0ca0 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/taecontrol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0063dc24e3c4de16271dd66c2dfb3faf9fbe0ca0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file memorable_kg-0.0.2-py3-none-any.whl.
File metadata
- Download URL: memorable_kg-0.0.2-py3-none-any.whl
- Upload date:
- Size: 66.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1686a867989bc3bc1fd1bcfe44ef962148c8a5000b58b77ea80d2885742c45e5
|
|
| MD5 |
a96fe2dda9407f201ea0f456522cca2e
|
|
| BLAKE2b-256 |
cc153ec385496a2a105ad9993ddb4c15f34c3b8b4f4fdeccde0cab297deb90b3
|
Provenance
The following attestation bundles were made for memorable_kg-0.0.2-py3-none-any.whl:
Publisher:
release.yml on taecontrol/memorable
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memorable_kg-0.0.2-py3-none-any.whl -
Subject digest:
1686a867989bc3bc1fd1bcfe44ef962148c8a5000b58b77ea80d2885742c45e5 - Sigstore transparency entry: 1676780631
- Sigstore integration time:
-
Permalink:
taecontrol/memorable@0063dc24e3c4de16271dd66c2dfb3faf9fbe0ca0 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/taecontrol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0063dc24e3c4de16271dd66c2dfb3faf9fbe0ca0 -
Trigger Event:
push
-
Statement type: