MCP server for Obsidian vaults over the filesystem. CRUD, search, backlinks, and link-repairing moves.
Strong foundation with 10 well-named tools following verb_noun convention (vault_info, list_notes, read_note, search_notes, get_frontmatter, get_backlinks, create_note, edit_note, delete_note, move_note). All tools have descriptions (avg 180 chars, within 10-1024 baseline). Input schemas present with Zod validation and descriptions for all parameters. Tool annotations (readOnlyHint) correctly applied to read-only operations. Key gaps: output schemas not formally documented in code; error handling returns plain text rather than structured objects; some parameter descriptions lack format/constraint details (e.g., 'path' doesn't specify .md suffix handling); edit_note's mode enum is well-defined but conditional parameters (find/replace vs heading/content) lack explicit mutual-exclusivity documentation.
Create a new note. Fails if it already exists unless overwrite=true. Parent folders are created automatically. Pass `frontmatter` to have YAML properties generated; `content` is the markdown body.
Move a note to the vault's .trash folder. NEVER a permanent delete — the note stays in .trash until the user empties it.
Edit an existing note in place. Modes: 'append'/'prepend' content (prepend lands after frontmatter); 'find_replace' all occurrences of find→replace (fails if find is absent); 'replace_section' swaps everything under `heading` (subsections included) for `content`.
List notes that link TO a given note (wikilinks, embeds and relative markdown links). Use before editing or deleting to understand what references it, or to follow the knowledge graph backwards.
Read a note's YAML frontmatter (its properties: tags, dates, custom fields) as JSON. Cheaper than read_note when you only need metadata.
List markdown notes in the vault (or a subfolder), newest info included. Returns vault-relative paths — use those in read_note.
Output schemas not formally documented. Tools return plain text wrapped in {content: [{type: 'text', text: string}]} but LLMs cannot infer structure of text content (e.g., list_notes returns newline-delimited paths; search_notes returns 'path:line: text' format). Structured JSON responses would enable reliable parsing.
edit_note has conditional parameter dependencies not explicitly documented: find_replace mode requires 'find' and 'replace'; replace_section requires 'heading' and 'content'; append/prepend require 'content'. LLMs may pass invalid combinations. Add mutual-exclusivity note to description.
Error handling returns plain text error messages via isError flag, but does not categorize errors as retryable vs user-fixable vs fatal. E.g., 'file not found' should suggest search_notes; 'permission denied' should indicate a configuration issue. Agents cannot determine recovery strategy.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Move a note to a new path, rewriting all wikilinks and markdown links that point to it. Fails if the destination exists unless overwrite=true. Wikilinks are rewritten to preserve their style (bare links stay bare, path-form links get the new path); markdown links are rebased relative to their source file.
Read the full markdown content of one note. `path` is vault-relative (from list_notes), e.g. 'projects/alpha.md'. The .md suffix is optional.
Full-text search across all notes. Default is case-insensitive substring matching; set regex=true to treat query as a regular expression. Returns path, line number and the matching line, capped at 50 hits.
Report the vault root path and how many markdown notes it contains. Use this first to confirm the vault is mounted and readable.
Parameter descriptions lack format constraints. 'path' parameter says 'vault-relative note path' but does not clarify: Is '.md' required or optional? Are spaces allowed? Can paths contain '../'? Ambiguity invites invalid input from LLMs.
search_notes truncates results at 50 hits and mentions this in response text, but does not provide pagination parameters (offset, limit, cursor). Large vaults may require multiple searches to explore results; no way to fetch next page.