MCP server for reading and searching an Obsidian vault directly from the filesystem. No Obsidian plugin, no REST API, no running Obsidian required.
Five read-only tools with consistent, well-structured schemas and clear descriptions. All tools have proper input schemas with type definitions and parameter descriptions. Tool names follow verb_noun convention (read_notes, search_notes, search_content, search_meta, list_notes). Descriptions are substantive (100-200 chars) and explain WHEN to use each tool. Parameters include sensible defaults and constraints (limit 1-500, context_lines 0-10). Annotations correctly declare readOnlyHint=true for all tools. Key gaps: output schemas are not formally documented in the code; error handling returns text-wrapped failures without structured categorization; no guidance on retryability or recovery paths.
List the notes in the vault, or in one folder of it, newest first. Paged, so it is safe to call against a large vault. Use it to get your bearings before searching.
Read the full text of one or more notes. Each note may be given as a vault-relative path, with or without the .md extension, or as a bare note title. Notes that cannot be read are reported individually and do not stop the others from being returned.
Full-text search across the body of every note, returning the matching lines with their line numbers and surrounding context. This is the tool to reach for when you want to know what the vault says about something.
Find notes by their YAML frontmatter or their tags. Tags are collected both from the frontmatter tags key and from inline #tags in the body. Supply a tag, or a frontmatter key, or a key and a value; at least one is required.
Find notes whose title or vault-relative path matches the query. Use this to locate a note when you know roughly what it is called. To search what the notes actually say, use search_content instead.
Output schemas not formally documented. Tools return text-wrapped content without structured field definitions. LLMs cannot reliably extract or chain results.
Error handling returns plain text wrapped in isError flag without categorization. No guidance on retryability, user-fixable vs fatal, or recovery steps.
search_meta parameter constraints underdocumented. Description says 'at least one is required' but does not specify which combinations are valid (tag alone? key+value? key without value?).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
Pagination support present (limit, offset) but no total_count or next_cursor returned. LLMs cannot determine if more results exist or how to fetch them efficiently.
read_notes accepts both paths and bare titles but does not document resolution order or ambiguity handling. If a title matches a path, which wins?