Bidirectional knowledge flow between Claude Code and Obsidian — 20 MCP tools, skills, and hooks for PKM
This is a well-engineered PKM MCP server with 15 tools. Strengths: all tools have clear, descriptive names following verb_noun convention (vault_read, vault_write, vault_search, etc.); all tools have substantive descriptions (100-300+ chars each) that explain WHAT the tool does and WHEN to use it; input schemas are complete with typed properties and descriptions for nearly all parameters; the server implements sophisticated features like pagination, semantic search, and knowledge graph traversal. Weaknesses: no tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite having tools across the risk spectrum (READ_ONLY, WRITE, REVERSIBLE, IRREVERSIBLE); output schemas are not explicitly documented in the tool definitions (LLMs must infer structure from descriptions); error handling guidance is minimal (no recovery patterns visible in tool descriptions); some parameter descriptions could be more prescriptive about constraints and formats. The server demonstrates solid engineering (proper fuzzy path resolution, markdown link formatting, frontmatter validation) but lacks some of the formal MCP patterns for error guidance and tool metadata that would elevate it to A-grade.
Query the persistent activity log to retrieve past tool invocations across sessions. Useful for building cross-session memory into Claude conversations. Filter by tool name, session ID, timestamp, or file path. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Append content to an existing file, optionally under a specific heading. When 'position' is specified, heading is required and must exist in the file. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Delete a file. Checks if any files link to it and lists those backlinks. You may want to review backlinks before deletion. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Edit a file by replacing an exact string match. The old_string must appear exactly once in the file for safety. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications. Tools marked as READ_ONLY, WRITE, REVERSIBLE, and IRREVERSIBLE should declare these formally in the MCP tool metadata to guide agent planning and safety checks.
Output schemas are not explicitly documented in tool definitions. Descriptions mention 'Returns file size, frontmatter, heading outline...' but formal output schema objects are absent, forcing LLMs to infer structure from text descriptions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 70 | 2026-07-28+ | v2 |
Explore the knowledge graph around a note: see its incoming and outgoing wikilinks, along with metadata. Useful for context-building, gap-finding, and understanding how a note fits into your PKM. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
List files and folders in the vault. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Inspect a file's metadata and structure without reading full content. Returns file size, frontmatter, heading outline with approximate section sizes, and a brief preview. Use this to plan which sections to read from large files. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Read the contents of a markdown file from the vault. Supports pagination: read a single section by heading, last N lines, last N heading-level sections, chunk number, or line range. Files exceeding ~80k characters auto-redirect to peek data (file structure/outline) unless a pagination param or force=true is specified. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Get recently modified files. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Rename a file and auto-update all wikilinks in the vault that point to it. Checks for backlinks and rewrites them to the new target. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Search for text across all markdown files in the vault. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Search for semantically similar notes using OpenAI embeddings. Returns the most contextually relevant notes even if they don't match keywords. Requires VAULT_PKM_OPENAI_KEY environment variable. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Manually trigger a full reindex of the semantic search index. Embeddings are normally updated automatically in the background as files change, but you can force a refresh if needed. Only available when semantic search is enabled (VAULT_PKM_OPENAI_KEY set). Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Update YAML frontmatter fields in an existing note. Parses existing frontmatter, updates specified fields, preserves everything else. Set a field to null to remove it. Protected fields (type, created, tags) cannot be removed. Field values are validated against the note's type (e.g. task status must be: pending, active, done, cancelled; task priority must be: low, normal, high, urgent). Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Create a new note from a template. Notes must be created from templates to ensure proper frontmatter. Available templates: ${templateDescriptions || "(Loading...)"} Built-in variables (auto-substituted): - <% tp.date.now("YYYY-MM-DD") %> - Current date - <% tp.file.title %> - Derived from output path filename Required: frontmatter.tags - provide at least one tag for the note. Optional: frontmatter.status, frontmatter.priority, frontmatter.project, frontmatter.deciders, frontmatter.due, frontmatter.source (depending on template type). Pass custom <%...%> variables via the 'variables' parameter. Paths in this tool's output are formatted as markdown links `[vault-relative-path.md](obsidian://...)` so users can Cmd/Ctrl-click to open in Obsidian. Preserve the link form when relaying paths to the user; pass only the bracket text (e.g. `01-Projects/Foo/note.md`) to other vault tools' `path` arguments, never the full markdown link.
Error handling descriptions lack recovery guidance. For example, vault_write mentions 'Notes must be created from templates' but does not explain what happens if a template is missing or invalid, or what the LLM should do next (e.g., 'Call vault_list() to see available templates').
Parameter descriptions for vault_update_frontmatter are vague about validation. Description says 'Field values are validated against the note's type' but does not specify what happens on validation failure, what valid values are for each type, or how to correct an invalid submission.
vault_semantic_search lacks required/constraint documentation for the 'threshold' parameter. Description says 'Minimum similarity score (0-1)' but does not specify if 0 and 1 are inclusive, what the default is if omitted, or what behavior occurs at boundary values.
vault_list and vault_recent descriptions are brief (65 - 70 chars) and lack guidance on when to use each vs vault_search. Both discover notes, the distinction is not clear to LLMs.