Reproduce the OMI/Obsidian memory integration for AI agents, plus a local web app to view, edit, and add memory entries.
omind demonstrates solid tool design with 13 well-named, verb-prefixed tools (read-, list-, create-, update-, write-, delete-, restore-, search, backlinks, graph, lint, recall, help). All tools have descriptions (avg ~120 chars, within 10-1024 baseline). Input schemas are present and typed for all tools. However, output schemas are not documented in the source code, LLMs cannot see what fields to expect from responses. Parameter descriptions are present but sometimes terse (e.g., 'Page size (1-100, default 25)' lacks context on when to use pagination). Error handling is minimal, no recovery guidance, no categorization of retryable vs fatal errors. The 'graph' tool is overloaded with 6 operations (nodes, edges, orphans, dangling, connected, distance) in a single tool, violating single-responsibility; this should be split into separate tools. Optimistic locking via version tokens is well-designed for conflict detection.
List all notes that link to a given note via [[wikilinks]].
Create a new note. Fails if the filename already exists.
Delete (archive) a note. In mesh mode, archives (soft-delete, restorable); otherwise removes the file.
Analyze the [[wikilink]] graph. Operations: 'nodes' (all notes), 'edges' (all links), 'orphans' (unreferenced notes), 'dangling' (broken links), 'connected' (reachable from a note), 'distance' (shortest path between two notes).
Get help on vault structure, note format, wikilinks, tags, action items, and best practices.
Lint the vault for common issues: missing titles, empty notes, broken wikilinks, duplicate content, conflicting notes, low-confidence assertions, and stale notes.
Output schemas not documented. LLMs cannot see what fields read-note, list-notes, search, graph, lint, and recall return. This forces LLMs to guess field names and types, increasing errors and wasting tokens on trial-and-error extraction.
graph tool violates single-responsibility principle. It bundles 6 distinct operations (nodes, edges, orphans, dangling, connected, distance) behind a single 'op' parameter. This forces LLMs to reason about which operation to select and makes the tool harder to discover and use correctly.
No error handling guidance. Tools lack descriptions of what errors can occur, whether they are retryable, and what the LLM should do next. E.g., create-note fails if filename exists, but the error message and recovery path are not documented.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | 2026-07-28+ | v2 |
List all notes in the vault with pagination. Returns summaries (title, created, tags, etc.) but not full content.
Read one note by filename. Returns the raw Markdown, parsed fields, and a version token for optimistic locking.
Retrieve recent memory entries from the journal (compact form, ~180 chars per entry). Useful for context-building and deduplication.
Restore an archived (soft-deleted) note. Only works in mesh mode.
Hybrid search over notes using BM25 keyword matching, dense vector embeddings (when available), and recency ranking. Returns ranked chunks with excerpts.
Update a note's structured fields (title, summary, details, tags, connections, action items, references). Supports optimistic locking via expected_version.
Overwrite a note's raw Markdown content verbatim. Supports optimistic locking via expected_version.
Parameter descriptions lack actionable constraints. E.g., 'Page size (1-100, default 25)' does not explain when to use pagination or what happens if limit exceeds 100. Descriptions should state format, range, and consequences.
delete-note and restore-note descriptions do not clearly state the difference between soft-delete (mesh mode) and hard-delete (non-mesh). LLMs cannot determine which behavior applies without reading implementation details.