Model Context Protocol (MCP) server for managing structured project accomplishments in Obsidian
The Obsidian MCP server provides structured tool definitions with reasonable parameter schemas and descriptions, but falls short of production-grade quality due to inconsistent schema completeness, undocumented output structures, and missing error handling guidance. Tool naming follows verb-first conventions (batch_update, cleanup_completed, manage_documents, search_docs, msrl_status), which is appropriate. However, descriptions vary in completeness, some tools like search_docs have rich parameter documentation (excerpt_budget with nested properties, filter objects), while others like msrl_status lack input parameter descriptions entirely. The batch_update tool demonstrates dependency injection for composition and includes dry_run/atomic options for safety, but output schemas are not visible in the source provided. Error handling and recovery guidance are absent from all tool descriptions.
Unified batch operation with client_id support for idempotency and cross-referencing. Supports create, update, and archive operations in a single call.
Archive completed stories/tasks under completed milestones. Finds completed milestones and their stories/tasks, marks non-completed items as completed (unless blocked), re-links decisions/documents, archives items, and removes from default canvas.
Consolidated tool for document and decision management. Dispatches to appropriate handler based on action (get_decision_history, supersede_document, get_document_history, check_freshness).
Get the status of the MSRL semantic search index. Returns state (ready/building/error), snapshot information, index statistics (document, node, leaf, and shard counts), and file watcher status.
Semantic search across all documents in the vault using hybrid vector + keyword search. Finds relevant documents by meaning, combines semantic (vector) and keyword (BM25) matching, supports relevance-weighted excerpt budgets and score threshold filtering.
Output schemas are not documented. Tool descriptions do not specify what fields are returned, forcing LLMs to infer response structures. This violates pattern:tool-description and pattern:response-shaper, LLMs need to know what data is available for downstream tool calls.
Error handling and recovery guidance are absent from all tool descriptions. When batch_update fails, manage_documents encounters a missing document_id, or search_docs hits a threshold, the LLM has no guidance on what to do next. This violates pattern:recovery-guide, errors must state 'what to do next' in human-readable form.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 54 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 42 | - | v1 |
manage_documents combines four distinct actions (get_decision_history, supersede_document, get_document_history, check_freshness) under one tool, requiring the LLM to choose an enum value. This violates pattern:tool (one tool, one job). The action parameter necessitates context-switching for the LLM and makes each action harder to discover and invoke independently.
cleanup_completed and batch_update lack confirmation/dry-run guidance in descriptions. While dry_run parameter exists, the tool description does not explain when to use it, what happens when atomic=true fails, or what compensatory steps are available. This violates pattern:confirmation-request and pattern:command-tool.
msrl_status has no input parameter descriptions (empty input object {}). The tool description states it returns 'state (ready/building/error), snapshot information, index statistics, and file watcher status', but the response structure is not documented. This violates pattern:tool-description, every parameter and every output field needs description.
search_docs includes a deprecated parameter max_excerpt_chars with notation '[DEPRECATED] Use excerpt_budget.max_per_result instead'. Deprecation pathways should be documented in migration guides or removal timelines. Currently no guidance on when max_excerpt_chars will be removed or how to transition.
cleanup_completed accepts confirmed_blockers (array of IDs) but the description does not explain what 'blocked' means, how to identify blocked items, or how the tool determines if an item is still blocked. This leaves the LLM guessing at prerequisite tool calls.