Headless semantic MCP server for Obsidian, Logseq, Dendron and any markdown-based knowledge base
markdown-vault-mcp defines 5 tools with reasonable coverage of input schemas and descriptions. All tools have descriptions (10-50 chars median, well within 10-1024 range) that explain the action clearly. Schemas are mostly complete with proper enum constraints and type definitions. However, several tools exhibit parameter structure issues: the 'vault' and 'edit' tools accept multiple optional parameters that are interdependent but lack explicit documentation of those dependencies. Output schemas are not visible in the provided source, so composition efficiency cannot be verified. Error handling is minimal, no evidence of recovery guidance, retry classification, or actionable error messages. The 'edit' tool description is exceptionally detailed (excellent), but others are more generic. No tool exposes secrets, and destructive operations are marked with Risk labels, but no dry-run or confirmation patterns are explicitly enforced at the SDK layer.
Read multiple notes in one request. Returns full content of each file. Required when reading 2+ files. Limit: 100 files per request.
Edit notes safely. Vault scope: general markdown notes vault. Supports AST edits by heading/block ID, freeform line/string replacement, frontmatter_set metadata merges, batch operations (max 50), and dryRun=true unified diff previews. Read vault://overview for editing strategy and conventions. TIPS: Always use dryRun=true before destructive operations (delete, replace). Use bulk_read for reading 2+ files. Use view.outline before heading-specific edits when unsure of heading names. string_replace requires exact literal match including whitespace/newlines.
Search vault by semantic similarity, exact text match, or fuzzy matching. Fast vector-based retrieval from embedding index. Supports hybrid mode combining vector + fuzz. Limit: 50 results.
Manage vault notes. Vault scope: general markdown notes vault. Actions: list (browse notes), read (full note), create/update/delete (whole-file writes), stat (metadata), create_from_template (scaffold from template). For search strategy and conventions, read vault://overview.
Inspect note structure and metadata. Actions: outline (heading/block hierarchy), frontmatter (YAML metadata), backlinks (incoming links), stats (file statistics).
Output schemas not documented in source code. Tools return structured results but LLMs cannot see response field types/names, breaking downstream tool composition. No pagination metadata visible for search/list operations despite 50-item limit stated in description.
Parameter interdependencies not explicitly documented. 'vault' tool accepts 'path', 'directory', 'content', 'templatePath', 'variables' but does not state which combinations are required/invalid (e.g., 'list' action requires 'directory', not 'path'). 'edit' tool has 'heading' and 'blockId' targets but lacks mutual exclusivity rules. LLMs will guess wrong combinations.
Error handling provides no recovery guidance. No evidence of actionable error messages, retry classification, or suggestions for alternative tools/steps. A destructive operation failure (e.g., delete fails) leaves LLM with no context on whether to retry or ask the user.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 69 | 2026-07-28+ | v2 |
Destructive operations lack explicit dry-run or confirmation gates. 'edit' tool mentions dryRun=true in description but it is not visible as a schema parameter in the input definition provided. Destructive 'vault' actions (create/update/delete) have no equivalent safety mechanism.
Parameter descriptions lack format/constraint detail. 'templatePath' and 'content' in 'vault' tool, 'query' in 'search', and 'path' in 'view' lack guidance on expected format, length limits, or invalid characters. LLMs cannot validate inputs before calling.
No tool accepts natural language identifiers. All tools expect exact 'path' parameters (e.g., 'notes/project/design.md'). Users saying 'search for notes on project design' cannot directly pass that; they must call search first, extract a path, then call the tool. Forces extra lookup steps.