obsidian-local-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| OBSIDIAN_MCP_VAULT | No | Optional vault name to use from the configuration. If omitted, the server uses the default_vault defined in the YAML config (e.g. "main"). | |
| OBSIDIAN_MCP_CONFIG | Yes | Path to the vaults.yaml configuration file, kept outside the repository. Required so the server can locate vault and repo definitions. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| upsert_nodeB | Create or update one graph node. Prefer this for curated nodes (feature:, ext:, note: ids, or a manual correction to a code node) -- code nodes (file:/fn:) are normally written by index_repo instead, so a later reindex does not immediately overwrite what you just wrote. |
| upsert_nodesB | Create or update several nodes at once, in the (id, kind, label) shape (each entry may also set repo/path/status/confidence/etc). |
| upsert_edgeB | Create or update one edge. weight/origin default from the edge type (see graph.weights) when omitted -- pass origin='manual' explicitly when in doubt; that is the one origin a reindex never overwrites. |
| upsert_edgesC | Create or update several edges at once, in the (src, dst, type) shape from starter_edges (each entry may also set weight/origin/etc). |
| delete_nodeA | Remove a node. Soft delete (default) hides it from reads but keeps the row; hard=True also deletes every edge touching it, irreversibly. |
| delete_edgeB | Remove one edge by its (src, dst, type) key. |
| rename_nodeB | Move a node to a new id, carrying every edge with it (e.g. after a file move index_repo would otherwise treat as delete-then-create, losing manual/git edges attached to the old id). |
| set_node_statusB | Update a node's status (verified/probable/assumed/outdated/refuted) and optionally its confidence, without touching anything else. |
| get_nodeC | Fetch one node by its exact id. |
| neighborsC | One-hop neighbors of a node. direction is 'out', 'in', or 'both'. |
| search_nodesC | Full-text search over node id/label/path/curated-note body. If
|
| retrieve_contextB | The main entry point: FTS5-seeded, PageRank-expanded context for a natural-language description of a task. Read MUST_READ first, note DANGER, expect MAY_CHANGE/MUST_TEST before you consider a change done. |
| impact_ofB | Impact analysis for one specific node: what it needs (MUST_READ), what depends on it (MAY_CHANGE), what exercises it (MUST_TEST), the knowledge that documents it, and anything flagged DANGER. |
| path_betweenB | Shortest connection between two nodes through the graph (either direction), for "how are these two things related" questions. |
| graph_statsC | Node/edge counts by kind and type. |
| index_repoA | Full (re)index of one configured repo: wipes and rewrites every scanner-origin node/edge for it, leaving manual/git-origin rows alone. |
| reindex_pathsB | Incremental reindex of just these relpaths within a repo -- call this after editing files so the graph does not drift from the code. |
| index_git_coeditsB | Derive co_edit edges from this repo's git history: files that keep changing together, even without an import connecting them. |
| detect_divergenceA | Find nodes/notes pointing at paths that no longer exist, and manual/git edges whose endpoint node vanished -- read-only, reports only; nothing here is deleted automatically. |
| clear_graphA | Wipe every node and edge for a vault. Irreversible; requires confirm=True. |
| read_noteC | Read one note's frontmatter and body. |
| write_noteB | Create or update a note. Enforces the vault's note contract (id, type, area, status, confidence, source, ...) when the vault's profile requires it, and refuses content that looks like a live secret unless allow_secrets=True. |
| update_note_frontmatterB | Merge |
| promote_node_to_noteA | Materialize a graph node (file/symbol/feature) as a curated note under 20-Knowledge/codebase/{files,symbols,features}, pre-filled with its neighbors from the graph. Written as status:"assumed" (it is a skeleton, not verified prose) -- promote sparingly, per Instructions.md Sec.12: not every file earns a note. |
| list_notesC | List note paths under the vault (or under |
| search_vaultC | Substring search over every note's id/body, with a short snippet per hit. |
| archive_noteB | Move a note to 99-Archive/ with a dated filename and a header recording why -- nothing in the vault is ever hard-deleted. |
| consolidation_reportA | The Instructions.md Sec.7 consolidation ritual, as a read-only report: decayed notes, isolated graph nodes, and divergence issues. Run this every ~10 sessions, or when asked to 'consolida'. |
| sync_note_linksB | Add wikilinks to curated notes for graph neighbors that also have a note (documents/decided_by/depends_on/dangerous/test edges). Additive only -- never removes a link you added by hand. |
| get_statusA | Report which vaults are configured and whether the requested (or default) vault's graph store is reachable. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 30 tools
The set is mostly well-differentiated, with clear splits between node/edge CRUD, note operations, indexing, and context queries. Minor overlaps remain, especially between search_vault and search_nodes, and between consolidation_report and detect_divergence, but descriptions usually clarify the intended choice.
All tool names use snake_case consistently, and most follow recognizable verb_noun or verb_object patterns. A few tools are noun-only or prepositional phrases (neighbors, graph_stats, path_between, impact_of), which is a minor deviation from a strict verb_noun convention.
With 30 tools, the surface is above the 25+ threshold that typically indicates an overloaded set. The domain is complex, but the many granular single/batch and lifecycle operations could likely be consolidated or grouped more tightly.
The set covers node/edge lifecycle, note lifecycle, indexing, retrieval, impact analysis, pathfinding, stats, divergence detection, and consolidation. Gaps are minor: no batch delete, no explicit edge listing/search, no note rename, and no wikilink removal beyond additive sync.