A self-hosted MCP server + dashboard that gives Claude Code, Cursor, and Hermes agents shared long-term memory over a git-backed markdown vault. An agent-native second brain.
Engram demonstrates strong definition quality across most tools with excellent descriptions that guide LLM behavior and clear parameter schemas. The vault-first design with extensive field explanations (authority, status handling, search ranking) shows sophisticated understanding of agent needs. However, there are gaps in output schema documentation and some parameter descriptions lack constraint specification. All 14 tools have descriptions and schemas, but output structures are not formally documented in the definitions. Tool naming is verb-first and clear (brain_search, brain_read, brain_write), following production conventions well.
Append markdown to the body of a note (without touching frontmatter). If the note does not exist, it is created with the appended text as its body. Useful when an agent discovers something new about a topic mid-conversation and wants to add it to an existing note without rewriting the whole thing. Append is cheap: it does not require a read-first check.
Let an LLM with `tool_choice: "required"` (Claude with 'Extended Thinking' enabled, o1, etc.) think through a complex topic and auto-file the result in the vault. Pass `text` (the full raw response from an extended-thinking model, including XML tags if present). Engram extracts reasoning and conclusions, generates a note title, and creates the note in the vault. This tool is only available in 'full' Curator mode (when Engram itself runs the extended-thinking model). Calling it from a client (MCP) is not supported — use `brain_write` instead.
Delete a note (move it to trash). Unrecoverable in this release; use with care. Pass `path` only (vault-relative). No read-first check is enforced: agents can delete notes they have never read. Use `brain_read` first if you want to check the content before deleting.
Alias for `brain_write` — same behavior. Provided for agent ergonomics: edit() feels more natural when modifying an existing note.
Output schemas not formally documented. While tool descriptions explain what fields are returned (e.g. brain_search returns 'hits' and 'excluded' with 'path', 'title', 'folder', 'status', 'snippet', 'authority'), there is no explicit outputSchema or return type definition in the tool registration. LLMs must infer output structure from descriptions alone, increasing hallucination risk.
Parameter constraints not formally specified in schema. Several parameters like 'limit' (brain_search, brain_recent) and 'folder' lack explicit min/max bounds or enum values in the inputSchema. Descriptions mention defaults (default 20, default 50) but JSON Schema should enforce numeric ranges to prevent invalid agent inputs.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
The vault's link graph: all notes (as nodes) and all wikilinks between them (as edges). Specify `folder` to limit to one folder and its backlinks — useful to find related areas of the vault without loading the whole graph.
List every note with metadata (path, title, folder, type, tags, status, authority). Use to discover what exists. `authority` tells you which notes are source-of-truth and which are history.
Move (rename) a note to a new path. Both old and new paths are vault-relative. The note's content does not change; only its location in the folder hierarchy and its filename. If the destination path already exists it will be overwritten silently. Folder ancestors are created if needed.
Read a note: full markdown (frontmatter + body), its `authority`, and its backlinks. Path is vault-relative, e.g. 'clients/mks/mks.md'. Pass `section` to read just one heading's content instead of the whole file — cheaper on long documents. If the heading isn't found you get the list of available headings back. Always check the returned `authority` before acting on the content: `archived` and `superseded` notes are history, not instructions.
Recent changes to the vault (human + agent), as a list of `{ path, who, timestamp, change }` — who changed what, and when. Useful to find out what an agent just edited, or to review a human's latest additions. Agent messages carry the agent's email (e.g. curator@engram); human changes carry 'human-via-<client>' (e.g. human-via-dashboard).
READ THIS FIRST, before searching or writing. Returns the vault's SCHEMA.md (folder taxonomy, frontmatter conventions, wikilink model, write protocol) AND a live description of this specific vault: its folders, the `status:` values actually in use, how search ranks notes by authority, and any integrity warnings. Vaults differ — never assume conventions, read them here.
Keyword search across the vault. Returns `{ hits, excluded }`. Each hit has `path`, `title`, `folder`, `status`, `snippet`, and `authority`. IMPORTANT — ranking is by keyword relevance, NOT by truth. A superseded document repeats the query words just as often as the live one, so it can outrank it. Every hit carries an `authority`: `authoritative` (source of truth — prefer it), `current`, `provisional` (draft/proposed — never quote as settled), `superseded`, `archived`. Rank order is a suggestion; `authority` is the signal. `excluded` is the explainable-rejection list: notes that matched the query but were withheld because they are archived, superseded, or **expired** (past their `valid_until`), each with a `reason` (e.g. "superseded by price-live", "expired 2026-06-01"). **When you deliberately ignore a stale note, cite its `excluded` entry** — say what you skipped and why, instead of quoting it. If you need a withheld note, re-search with `includeInvalid: true` (superseded/expired) or `includeArchive: true`. Before quoting a price, guarantee, contract term, or any other single-valued fact, open the `authoritative` note. If two live notes disagree on such a fact, that is a defect in the vault — report it rather than averaging them.
Mark a note as superseded by another. The superseding note becomes the `authoritative` source; the superseded note is demoted in search and ranked as history. Pass the path of the note being made obsolete (`path`) and the path of its replacement (`replacedBy`). Both paths are vault-relative. You do not need to have read either note first.
The vault's folder structure as a tree: folder nesting, note counts per folder, and the default sort order (convention, timestamps, file size). Use to understand the vault's layout without listing every note.
Write or create a note. Upsert: if the note exists it is replaced; if not, it is created. You must pass `path` (vault-relative) and either `body` + optional `frontmatter` object, or `content` (full raw markdown including frontmatter). Before writing a note you have not read in this session, you must have called `brain_read` on that exact path first — agents are not allowed to overwrite notes blind. Pass `overwrite: true` to force it (dangerous; use only if you have read the note's content elsewhere, e.g. via a section read, or if you are writing a new note). Frontmatter is optional; if supplied as an object it is merged with any existing frontmatter. Passing `frontmatter: {}` (empty object) is a no-op on the frontmatter. Passing `allow_conflict: true` when writing a near-duplicate note tells the vault you meant it — it will not warn you. Raises an error if the write would leave the note empty (both `body` and `content` are blank, and `frontmatter` is missing or empty).
brain_delete lacks confirmation step or dry-run. This is an irreversible destructive operation ('Unrecoverable in this release') with no confirmation mechanism. Description warns 'use with care' but there is no confirm_delete tool or dry-run parameter to prevent accidental deletion.
brain_capture restricted to 'full Curator mode'. The tool explicitly states 'only available in full Curator mode' and 'Calling it from a client (MCP) is not supported'. This means agents using the standard MCP interface cannot call this tool, creating a gap in the advertised tool set. The tool should either be unavailable in MCP (not registered) or should have a unified interface.
Error handling guidance incomplete. While brain_search documents an 'excluded' list for withheld notes, other tools do not provide recovery guidance. For example, brain_read says 'If the heading isn't found you get the list of available headings back' but does not explain what error format is returned or how the agent should respond.
brain_write and brain_edit have complex parameter logic (content vs body + frontmatter) documented only in description text, not in schema constraints. The description says 'you must pass path and either body + optional frontmatter object, or content' but the inputSchema shows all as optional with no exclusive-or constraint. This invites malformed calls.
brain_write requires 'read-first' check but brain_append does not. This inconsistency creates a footgun: agents can append to an unread note freely, but cannot write to one. The description justifies this ('Append is cheap') but this policy is not enforced in the schema and could confuse agents.