Semantic search backend for Obsidian vaults with FastMCP integration for Claude Desktop
The server implements 10 well-named tools with generally clear descriptions and reasonable parameter schemas. Tool names follow verb_noun convention (search_notes, get_note_content, create_note, etc.) and are action-oriented. Descriptions are mostly adequate (ranging 50-250 chars, within the baseline 194 char average) and include helpful context like warnings about path handling and dependencies. However, several tools lack complete input/output schema documentation, parameter descriptions are sometimes minimal, and error handling is not well-articulated in the definitions. The server uses fastmcp which provides strong framework support, but the tool definitions themselves have gaps that would require LLMs to infer behavior in ambiguous cases.
Append markdown to the end of an existing vault note and reindex it. Fails if the note does not exist — use `create_note` for a new one. Existing content is never modified; the new text is separated from it by a blank line. IMPORTANT: Call `search_notes` first to get the real path of the note you mean, rather than guessing one.
Create a new markdown note in the vault and index it. Fails if a note already exists at that path — this tool never overwrites existing writing. To add to a note that already exists, use `append_to_note` instead. Parent folders are created as needed. Write the note body as plain markdown; include YAML frontmatter at the top if the vault uses it.
Return current index statistics.
Read the full text of a vault note by its absolute path. IMPORTANT: Never construct or guess paths manually. Always call `search_notes` first and use the `file_path` value it returns. Weekly notes use Mon-Fri date ranges (e.g. 0518-0522.md), not Sun-Sat.
Index or re-index a single markdown note in the vault. The backend watches the vault and indexes saved notes automatically, so this is only needed to force a refresh — for example right after an external tool wrote the file.
Output schemas not documented for any tool. Tool definitions include input schemas but omit return type specifications. LLMs cannot plan downstream tool calls or extract fields without knowing what get_note_content, create_note, or search_notes return.
Path handling is ambiguous across tools. Some accept 'vault-relative or absolute', others expect 'absolute', others expect 'vault-relative'. This inconsistency will cause LLMs to pass paths in the wrong format, resulting in file-not-found errors. The descriptions warn against guessing paths but do not clarify when each format applies.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 70 | <=2025-11-25 | v2 |
| 2026-03-09 | D | 53 | - | v1 |
Index a PDF file at the given absolute path.
Fetch a web page, extract its content, and add it to the search index.
List all indexed documents with their chunk counts.
Remove a document and all its chunks from the search index. This only forgets the document — the file on disk is left alone.
Search across all indexed Obsidian notes, PDFs, and web pages. IMPORTANT: Always call this tool first to discover file paths before reading a note. The returned `file_path` values are absolute paths — pass them directly to `get_note_content` without any modification.
source_types and filter parameters use free-form strings instead of enums. Description states 'Filter by source type: "markdown", "pdf", or "web"' but the parameter is not formally constrained. LLMs may hallucinate values like 'document', 'web-page', 'text' or misremember the exact spelling.
No error recovery guidance in tool descriptions. If search_notes returns empty results, should the LLM broaden the query, check spelling, or verify the vault is indexed? If create_note fails because the file exists, should it try append_to_note or ask the user? Descriptions lack recovery paths.
Tool descriptions are often too brief and lack context for when to use each tool. get_index_status (42 chars), index_pdf (79 chars), and list_indexed_files (62 chars) are below the lower bound of the baseline average (194 chars). Brief descriptions force LLMs to reason about tool selection without adequate context.
Pagination not supported on list-returning tools. search_notes accepts top_k and list_indexed_files returns all documents. If a vault has 1000+ indexed files, returning all chunks at once will exceed context windows. No top/limit parameter or cursor mechanism documented.