Persistent project memory for AI coding agents — semantic search, AST-aware chunking, dependency graphs, and conversation history
Mimirs is a well-structured RAG/memory server with 22 tools covering semantic search, git history, dependency analysis, and conversation memory. Naming is verb-first and clear (search_*, get_*, create_*, list_*, delete_*). Descriptions are generally strong (100-300 chars, above baseline 194 avg), explaining WHAT, WHEN, and purpose. Schemas are comprehensive with proper types and validation ranges. However, output schemas are not explicitly documented in the visible code, return types are inferred from implementation rather than declared in the tool registration. Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are marked in the assessment but NOT visible in the schema definitions, which is a spec alignment gap. Error handling is present but lacks explicit recovery guidance (actionable next steps). Overall, this is a high-quality tool suite, above median for community MCP servers, with minor gaps in output documentation and error messaging.
Attach a persistent note to a file or symbol that surfaces inline in future read_relevant results. Call this immediately when you encounter: a known bug or race condition, fragile code that shouldn't be changed yet, a non-obvious architectural constraint, or a workaround that needs context. Calling again with the same path+symbol updates the existing note.
Files that historically change in the same commit as a given file — logical coupling the import graph can't see (doc↔code, test↔impl, synced mirrors, sibling files with no import edge). Use before editing a file to find what else usually changes with it, or to widen a change's blast radius beyond static dependents. Ranked by Jaccard so ubiquitous files (lockfiles, manifests) sink. Requires git history to be indexed.
Save a checkpoint so future sessions know what was done and why. REQUIRED: call this as your final step after completing any user-requested task, before responding to the user. Also call when hitting a blocker or changing direction mid-task.
Remove an annotation that is no longer relevant — e.g. a bug that was fixed, a constraint that no longer applies, or a note on a deleted file/symbol. Use get_annotations first to find the annotation ID.
List all files that import a given file (reverse dependencies). Shows the blast radius before modifying a file — every file that would be affected by a change. This is FILE-level, inward direction. Routing — reverse (what this file imports) is depends_on; for finer SYMBOL-level blast radius use impact (transitive callers + tests) or usages (flat refs).
Output schemas not explicitly documented in tool registration. Return types are inferred from implementation (text content arrays) but not declared via output schema in the tool definition. LLMs must guess the response structure rather than reading a schema.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are not visible in the schema definitions. The Risk field in the assessment (READ_ONLY, WRITE, DESTRUCTIVE) suggests these should be declared in the MCP tool registration, but cannot be verified in the provided source code.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 73 | 2026-07-28+ | v2 |
List all files that a given file imports (its dependencies). Shows the resolved import graph — what this file actually depends on. This is FILE-level, outward direction. Routing — reverse (files that import this one) is dependents; for a single symbol's references use usages.
Get the commit history for a specific file. Returns commits that touched the file, sorted by date (newest first). Faster than git log for indexed repositories.
Retrieve persistent notes attached to files or symbols. Pass path to get all notes for a file. Pass query to search semantically across all annotations. Pass both to filter by file and rank by relevance.
Show git context for the working tree: uncommitted changes annotated with index status, recent commits, and changed files. Use this at the start of a session to understand what has already been modified before searching or editing.
Find the transitive closure of callers to a symbol — everyone who calls it directly or indirectly, ranked by depth (deepest/outermost callers first). Highlights which test files exercise this symbol. Useful before refactoring or changing a function's signature. On ambiguous symbols (multiple definitions), pass a file to pick one. This is SYMBOL-level, transitive, 2+ hops. Routing — for flat/1-hop call sites use usages; for the path between two specific symbols use trace; for FILE-level dependents use dependents.
Index files in a directory for semantic search. Without patterns, indexes the project from config and prunes deleted or now-excluded files. With patterns, refreshes or expands only matching files and leaves the rest of the index untouched.
Show the current state of the RAG index for a project directory.
List conversation checkpoints, most recent first. Cross-session by default.
Visualize how files relate to each other — imports, exports, and fan-in/fan-out. Faster than reading import statements across many files. Use 'focus' to zoom into a specific file's neighborhood. Use format 'json' for structured data with fan-in/fan-out metrics. Use search or read_relevant next to explore specific areas of the map. Routing — for ONE file's direct connections use depends_on/dependents; for a SYMBOL's callers use usages/impact.
Read the full verbatim text of past conversation turns by session + turn index. The read counterpart to search_conversation, which only returns short snippets — use it to hydrate a turn you located, or to pull a range of recent turns. Set includeToolOutput to also get tool results (re-parses the raw transcript).
Remove a specific file from the RAG index.
Show search usage analytics: query counts, zero-result queries, low-relevance queries, top searched terms.
Semantic search over checkpoint titles and summaries.
Semantically search git commit history. Use this to find why code was changed, when decisions were made, or what an author worked on. Returns commits ranked by relevance to the query.
Search through conversation history. Finds past decisions, discussions, and tool outputs from current or previous sessions.
Trace a path from one symbol to another through the call graph (if a path exists). Answers 'how can A reach B?' — useful for understanding complex call chains, data flow, or permission/state propagation. If no path exists, returns that fact. On ambiguous symbols (multiple definitions), pass a file to pick one. This is SYMBOL-level, point-to-point, path tracing. Routing — for all callers use impact; for direct call sites use usages; for FILE-level chains use dependents.
Find call sites and references to a symbol across indexed files — with file paths, line numbers, and matching lines. Resolves aliased imports: searching the original name finds call sites that import it under an alias (`import { getDB as g }; g()`). Primary matches come from an AST-derived reference index (real call/reference sites); for file types without reference extraction (e.g. HTML/CSS/YAML) or names not in that index it falls back to a text search, which can also surface matches inside comments or strings. Use before renaming or changing a function signature. This is the SYMBOL-level, flat, 1-hop view. Routing — for the transitive caller TREE plus tests to run use impact; for FILE-level importers use dependents; for the path between two symbols use trace.
Error handling lacks explicit recovery guidance. Tools return success/failure but do not provide actionable next steps when failures occur (e.g., 'try search_users() first' or 'call index_files to rebuild the index'). This forces LLMs to reason about recovery paths.
Some tool descriptions could be more specific about prerequisites and dependencies. For example, git_context and search_commits depend on a git repository being initialized; co_change requires git history to be indexed. These dependencies should be explicitly stated in the description.
Directory parameter is optional with fallback to env var or cwd, but this behavior is not clearly explained in all parameter descriptions. Agents may not understand when the default is used, leading to confusion about which project is being queried.