"The things we see are shadows of things we cannot fully know." — Plato, The Republic
A persistent knowledge graph for AI memory. It stores what it can, in the form it can — knowing full well that no record is complete, no observation is final, and no graph ever captures the whole truth.
This is not a limitation to fix. It is the nature of memory itself.
Plato argued that the world we perceive is an imperfect reflection of ideal Forms — eternal, perfect, unreachable. Every chair is a shadow of the Form of Chair. Every memory is a shadow of the actual experience.
This server takes that seriously. What it stores:
- Is incomplete — you can only record what you noticed
- Is approximate — language compresses reality
- Is outdated the moment it is written — people change, contexts shift
- Is subjective — observations are perspectives, not facts
The graph is not the territory. Treat it as a working sketch, not a source of truth. Add to it, correct it, delete what no longer holds. A memory that goes unchallenged becomes a cage.
The nodes of the graph. Each has a name, a type, and a list of observations.
{
"name": "John_Smith",
"entityType": "person",
"observations": ["Speaks fluent Spanish", "Prefers morning meetings"]
}Observations are imperfect by design — they reflect a moment, not a person.
Directed edges between entities, always in active voice.
{
"from": "John_Smith",
"to": "Anthropic",
"relationType": "works_at"
}Relations describe what was true when they were written. Verify before trusting.
Discrete facts attached to an entity. Atomic, removable, fallible.
{
"entityName": "John_Smith",
"observations": [
"Speaks fluent Spanish",
"Graduated in 2019",
"Prefers morning meetings"
]
}By default, memory is stored as a single memory.jsonl file. But you can write memory to any directory — useful for keeping different contexts separate.
All tools accept an optional directory parameter:
directory: "/absolute/path/to/project"
If provided, the server writes memory.jsonl inside that directory (creating it if needed).
If omitted, falls back to the path set by MEMORY_FILE_PATH, or a default next to the server binary.
Use absolute paths. Relative paths resolve against the MCP server process, not your project.
| Tool | Description |
|---|---|
create_entities |
Add new nodes to the graph |
create_relations |
Connect entities with directed edges |
add_observations |
Attach facts to an existing entity |
delete_entities |
Remove nodes and their relations |
delete_observations |
Remove specific facts from an entity |
delete_relations |
Remove specific edges |
read_graph |
Read the full graph |
search_nodes |
Search by name, type, or observation content |
open_nodes |
Retrieve specific nodes by name |
All tools accept an optional directory field (see Storage above).
create_entities
entities: array of{ name, entityType, observations[] }directory?: storage directory- Silently skips entities that already exist
create_relations
relations: array of{ from, to, relationType }directory?: storage directory- Silently skips duplicate relations
add_observations
observations: array of{ entityName, contents[] }directory?: storage directory- Fails if the entity does not exist
delete_entities
entityNames: string[]directory?: storage directory- Cascades to delete associated relations
delete_observations
deletions: array of{ entityName, observations[] }directory?: storage directory
delete_relations
relations: array of{ from, to, relationType }directory?: storage directory
read_graph / search_nodes / open_nodes
- Read-only. Accept
directory?to target a specific graph.
{
"mcpServers": {
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"]
}
}
}Or run the local build:
{
"mcpServers": {
"memory": {
"command": "node",
"args": ["/path/to/memories/dist/index.js"]
}
}
}{
"mcpServers": {
"memory": {
"command": "docker",
"args": ["run", "-i", "-v", "claude-memory:/app/dist", "--rm", "mcp/memory"]
}
}
}The model needs instruction on when and how to use memory. Here is a minimal prompt that reflects the imperfect-by-design approach:
At the start of each conversation, read the knowledge graph to recall what is known.
Treat recalled information as a starting point, not ground truth — ask if things have changed.
During conversation, note:
- People, organizations, recurring events (create entities)
- Relationships between them (create relations)
- Specific facts, preferences, context (add observations)
At the end, update the graph with anything new or corrected.
Delete observations that are no longer true.
When using memory tools, pass directory as the absolute path to the current project root
so memory stays scoped to the right context.
npm install
npm run buildDocker:
docker build -t mcp/memory -f Dockerfile .MIT.