Persistent memory for AI agents: Markdown entries, hybrid search, typed graph links
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Inkwell.
rememberCreate or update an entry (upsert with duplicate detection, or version it via `supersede`). `entry_type` is required, and `part_of` (hub UUIDs) is required/optional/rejected per type per the schema's `membership` rule. Returns `size`, non-blocking atomicity `warnings` (Markdown headers, >3 paragrapβ¦
recallRead an entry with its graph relations (outgoing + backlinks). Returns `size` and `last_modified`. High-degree types (hubs) return `in_digest` β back-links grouped by linking type, plus members grouped by `part_of` β instead of an arbitrarily truncated list.
searchHybrid keyword + semantic search, filterable by tags, exact `entry_type`, and/or `part_of
listBrowse entries sorted by title, filterable by tags, exact `entry_type`, and/or `part_of
tagsList all tags with entry counts
forgetDelete an entry (file and index). Warns when other entries still link to it.
Inkwell is a self-hosted Model Context Protocol server that gives AI agents persistent memory across sessions and projects. Three things set it apart from the other memory servers: plain Markdown files are the source of truth (the index is a throwaway cache you can delete and rebuild), entries are connected by a typed kb:// graph rather than dumped into a flat pile, and updates are bi-temporal β superseding a fact keeps the old version readable instead of overwriting it.
Docker Hub: foreigndmitryi/inkwell-memory Β· Website: veronchenko.github.io/inkwell-memory
Formerly Engram. Renamed in 0.14.0 β there are a dozen unrelated projects called "Engram" and the name had stopped being findable. Not affiliated with any of them, nor with the Engram keyboard layout. See the changelog for what the rename breaks.
Agent conversations end and take their context with them. Inkwell is the piece that survives: a knowledge base an agent searches before acting and writes to after resolving something non-obvious, so the next session β same project or a different one β starts with what was already learned instead of re-deriving it.
It deliberately stores zero discoverable information. If a fact can be pulled from code, git history, config files, or existing docs, it does not belong in Inkwell β that's what greps and re-reads are for. What belongs is the kind of knowledge a conversation would otherwise lose: a decision and the alternatives it ruled out, a bug's root cause and fix, a procedure learned the hard way, a preference stated once that should hold from then on.
Two things keep the base usable as it grows:
remember warns (non-blocking) on Markdown headers, more than 3 paragraphs, or content past 512 B/1 KB, pushing multi-fact dumps back into separate linked entries instead of a wall of text no search will rank well.kb://uuid#type references, so related facts (a hub project, its features, a diagnostic tied to one of them) stay navigable both ways instead of living as isolated rows.kb://uuid#type links between entries, resolved both directions (outgoing + backlinks) on every recall, with an optional second hop (hops=2) to see how two entries connect through an intermediate onehub, decision, diagnostic, feature, procedure, integration, pattern, snippet, preference, idea β declared in schema.json and exposed to the client as an enum, so an invalid type can't be written; filterable on search/listdoctor integrity pass β one schema-driven check over the Markdown files for dangling and superseded links, undeclared types, missing template fields, supernodes, and tag/type collisionspart_of structural membership β links a detail entry (decision, diagnostic, feature, procedure, integration, ...) to its hub, enforced per type by the schema; filterable on search/list, grouped alongside kb:// back-links in a hub's recall digestremember(..., supersede=True) creates a new version instead of overwriting; old versions stay in history (include_superseded=True) instead of being lostremember matches near-identical titles to avoid duplicate entries, and returns suggested_links (embedding-similarity matches) so related facts get cross-referenced instead of orphanedrebuild, no data is ever lost| Inkwell | Mem0 | Zep / Graphiti | LangMem | |
|---|---|---|---|---|
| Source of truth | Markdown files on disk | Vector DB / managed API | Temporal knowledge graph | Vector store (LangChain-backed) |
| Search | BM25 + local Model2Vec embeddings (RRF fusion) | Vector similarity | Graph traversal + embeddings | Vector similarity |
| Relations | Explicit kb://uuid#type links, agent-authored | Implicit (LLM-extracted facts) | Auto-extracted temporal graph edges | None built-in |
| Temporal model | Bi-temporal valid_at/supersede on write | Fact overwrite | Native temporal graph (bi-temporal edges) | None built-in |
| Deployment | Self-hosted, single Docker image, no cloud dependency | Hosted API or self-hosted + vector DB | Self-hosted, needs Neo4j | Library, no server |
| Design center | Deliberately minimal β zero discoverable info, agent decides what's worth keeping | Automatic fact extraction from conversations | Automatic entity/relationship extraction | Composable memory primitives for LangGraph agents |
Inkwell trades automatic extraction (Mem0, Zep) for an agent-curated, atomic, explicitly-linked knowledge base β no LLM-driven ingestion pipeline, no graph database dependency, and the on-disk Markdown stays human-readable and diffable.
Inkwell was benchmarked against the same knowledge base packaged as an ordinary Markdown wiki β one file per topic, organized in folders by project and category (decision, diagnostic, feature, procedure, ...), each project with an index page and cross-links between related pages, browsed with Read/Grep/Glob/Bash. Same content, two ways of finding it β for equivalent fact coverage, Inkwell's search/recall used:
| Inkwell | Wiki | Improvement | |
|---|---|---|---|
| Tool calls | 104 | 186 | -44% |
| Total tokens | 3.87M | 5.91M | -35% |
| Cost | $1.31 | $1.62 | -19% |
| Wall time (sum) | 577s | 760s | -24% |
| Fact rate | 1.000 | 0.964 | +3.7% |
32 questions (single-hop, multi-hop, negative, cross-lingual, supersede) over 5,070 entries β 70 curated facts across 4 fictional projects plus 5,000 real-text distractor entries, so retrieval has to work at a scale that doesn't fit in an agent's context:
Every category folder is a flat list of one-file-per-entry, and every project folder (real or distractor) has its own README.md index page linking to all of them β structurally identical, so the wiki arm can't tell curated fact from distractor by shape alone.
An agent that already knows where to look doesn't need to grep, re-read, and re-grep its way there β the efficiency edge holds for equivalent fact coverage. Retrieval ranking has also been improving: adding an IDF-weighted exact-match channel (below) moved MRR from 0.851 to 0.857 and recall@5 from 0.851 to 0.869, with no regression across any language.
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/inkwell)<a href="https://allmcps.com/mcp/inkwell"><img src="https://allmcps.com/api/badge/inkwell?style=directory" alt="Inkwell on AllMCPs" /></a>