obsidian-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| VAULT_PATH | Yes | Path to the Obsidian vault |
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
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_notes_toolA | List all Markdown notes in the vault (or a subfolder). Set include_meta=True to get title, tags, status, created per note. data.items is a list of paths, or of {path, title, tags, status, created, mtime} when include_meta=True. |
| read_note_toolA | Read one note at the level of detail you actually need. mode:
depth applies to mode='rendered' only: 0=raw, 1=one level of embeds (default), 2=nested embeds. The envelope's |
| search_notes_toolA | Full-text search with snippets and relevance ranking. mode: 'exact' (default) | 'regex' | 'fuzzy'. data.items: [{path, score, snippets, tags}]. frontmatter_filter: combine with the text search in one call — same shape as query_notes_tool's (plain value = exact match, or {"$ne": v} / {"$nin": [...]} / {"$exists": bool}). field: None/'body' (default, search note content) | 'filename' (match only the file name). threshold: fuzzy-match similarity cutoff 0-1 (only used when mode='fuzzy'; lower = looser matches, higher = less noise). |
| find_similar_notes_toolA | Find conceptually related notes even when the wording differs — for duplicate prevention before creating a new note ("does this topic already exist under different vocabulary?"). Ranks by TF-IDF cosine similarity over the vault's own vocabulary (a lightweight heuristic, not a transformer embedding model — it catches shared distinctive words across differently-phrased notes, not pure synonym rewrites). exclude_path: skip a note (e.g. the one you're editing) from results. min_score: filters out noise-level matches (0-1, higher = stricter). data.items: [{path, score}], most similar first. |
| write_note_toolA | Write (create or overwrite) a note. Respects READ_ONLY and WRITE_PATHS.
If |
| patch_note_toolA | Edit a section or block reference inside a note. mode: 'replace' (default) | 'insert_before' | 'insert_after' | 'append'. target_type: 'heading' (default) | 'block_ref' (use section='^block-id'). dry_run=True previews data {preview, diff} without writing — check it, then call again with dry_run=False. |
| patch_note_text_toolA | Find and replace text anywhere in one note's body — no heading/block-ref
anchor required, unlike patch_note_tool. Cheaper than write_note_tool for
a scattered single-note edit (e.g. bumping one enum value inside a long note).
mode: 'exact' (default, literal substring) | 'regex'.
count: max replacements (default 1, first match only); 0 = replace all.
dry_run=True previews {replacements, preview, diff} without writing.
Raises ValueError if |
| append_to_note_toolA | Append content to a note without reading and rewriting the whole file. section: optional heading to append under. create=True creates the note if missing. |
| patch_frontmatter_toolA | Update specific YAML frontmatter keys without touching the note body. Pass merge_arrays=True merges list values (e.g. tags); False replaces them. dry_run=True previews data {preview, diff, updated_keys} without writing — check it, then call again with dry_run=False. With |
| manage_tags_toolA | Add or remove tags on a note. Updates frontmatter tags array and strips inline #tag occurrences from the body. Returns {added, removed}. |
| get_backlinks_toolB | Return all notes that link to the given note (alias-aware). data.items is a list of note paths. |
| get_vault_conventions_toolA | Return the vault's AI instructions / conventions from _AI_INSTRUCTIONS.md. data.conventions is the raw Markdown. |
| get_audit_log_toolA | Query the append-only log of write-tool activity (who/what changed, not just the .trash/ state after the fact). Most recent first. path/tool/since are optional filters (since: ISO timestamp, inclusive). Entries: {timestamp, tool, path, summary}. Covers the core note/folder write tools; canvas/kanban/excalidraw/bases writes aren't logged yet. |
| list_vaults_toolA | List the vault(s) the current identity (API key or GitHub login) may access. Returns [{name, description, is_default}]. Call this at the start of a session whenever more than one vault comes back — pass vault= on any other tool to operate on a non-default one for that single call; omit it to use whichever entry has is_default=true. In single-vault mode (no VAULTS_CONFIG) this always returns exactly one entry with is_default=true — there's nothing to choose between. data.items: [{name, description, is_default}]. |
| lint_schema_toolA | Validate every note's frontmatter against the enum fields declared in
the vault's _AI_INSTRUCTIONS.md (under a "Frontmatter Schema" heading,
e.g. |
| get_broken_links_toolB | Find all wikilinks in the vault that point to non-existent notes. data.items: [{source, link}]. |
| get_orphans_toolA | Find notes that no other note links to. Excludes Journal and Templates by default. data.items is a list of paths. |
| get_link_graph_toolC | Return a traversable link graph starting from a note.
direction: 'outgoing' | 'incoming' | 'both'.
|
| get_vault_stats_toolB | Return vault statistics: note count, link count, orphans, broken links,
most-linked notes. Vault-wide, so the envelope carries no |
| list_all_tags_toolA | Return every tag in the vault. mode:
|
| get_tasks_toolA | Return tasks from across the vault.
status: 'open' | 'done' | 'all'. Optionally filter by folder or tag.
due_before/due_after: 'YYYY-MM-DD', inclusive; matches the Tasks-plugin
📅 due date (tasks without one never match either filter).
Parses Tasks-plugin emoji markers: 📅 due, ✅ done date, 🔁 recurrence,
⏫/🔼/🔽 priority (high/medium/low) — stripped from |
| get_periodic_note_toolA | Read or preview a periodic note. period: 'daily' | 'weekly' | 'monthly' | 'quarterly' | 'yearly'. date: 'today' | 'yesterday' | 'YYYY-MM-DD'. data: {period, date, exists, content, frontmatter, tasks}. |
| resolve_alias_toolA | Resolve a note alias or stem to its real vault path.
|
| query_notes_toolA | Dataview-like query: filter notes by tags, status, frontmatter, or inline fields. tags: all must match (AND). sort_by: 'path'|'title'|'created'|'mtime'. inline_field_filter: match Dataview inline fields (key:: value syntax). data.items: [{path, title, tags, status, created, mtime, frontmatter, inline_fields}]. |
| list_attachments_toolB | List all non-Markdown files in the vault: images, PDFs, audio, etc. data.items: [{path, size_bytes, mime_type, mtime}]. |
| read_attachment_toolC | Read an attachment file. data.content is a UTF-8 string for text files, or base64-encoded bytes for binary ones (images, PDFs) — data.mime_type and data.encoding say which. |
| add_attachment_toolC | Write a binary attachment (image, PDF, etc.) to the vault from base64-encoded content. data: {size_bytes, mime_type}. |
| create_attachment_token_toolA | Create a short-lived, single-file upload/download token for the GET/PUT /attachments/{path} HTTP route, instead of handing out the server's master API_KEY. method: 'PUT' (upload) or 'GET' (download). expires_in: seconds until the token expires (default 300, max 3600). If the server has
PUBLIC_BASE_URL configured, |
| list_templates_toolC | List all template files in the Templates/ folder. data.items is a list of template paths. |
| create_from_template_toolB | Render a template and write it as a new note.
Built-in variables: {{date}}, {{time}}, {{title}}, {{week}}, {{month}}, {{year}}, {{weekday}}.
Supports format specs: {{date:YYYY-MM}} → '2026-07'.
Custom variables passed in 'variables' dict override built-ins.
Unknown {{vars}} are preserved as-is.
|
| list_folder_toolA | List the contents of a vault folder (non-hidden items only). path='': root of the vault. recursive=False (default): immediate contents only — data: {folders, files}. recursive=True: full tree dump in one call — data: {tree: {folders: {name: tree}, files: [...]}}. max_depth limits how many levels deep to descend (None = unlimited). |
| list_files_toolA | List every file in the vault (or a subfolder), any type — not just notes/attachments/bases/canvases (e.g. .lock files, stray non-Markdown files). extension filters by suffix without the dot (e.g. "lock", "canvas"); omit for everything. Hidden files/folders are skipped. data.items is a list of vault-relative paths. |
| create_folder_toolB | Create a folder (and any missing parents) in the vault. Returns {path, status}. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| weekly_review | Summarize the past week: overdue/due-soon tasks, daily note highlights. |
| daily_note | Open or create a daily note, carrying over yesterday's open tasks. date: 'today' | 'yesterday' | 'YYYY-MM-DD'. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| vault_stats_resource | Current vault statistics (note count, links, orphans, broken links). |
| vault_tags_resource | All tags in the vault with note counts, sorted by frequency. |
TDQS
Scored across 33 tools
Each tool targets a distinct operation: reading, writing, searching, patching (section/text/frontmatter), managing attachments, templates, folders, tags, tasks, periodic notes, link graph, and vault stats. Overlapping tools like write_note vs patch_note vs append are clearly differentiated by descriptions.
All 33 tools follow a consistent verb_noun_tool pattern in snake_case (e.g., list_notes_tool, read_note_tool, create_folder_tool). Verb choices (list/get/read/query/patch/manage) align with their actions, making naming predictable and unambiguous.
33 tools is high but appropriate for the broad scope of full Obsidian vault management—covering notes, attachments, templates, tasks, periodic notes, frontmatter, and vault health. Some tools like create_attachment_token are niche, but they fill real gaps. Slightly heavy, yet each earns its place.
The surface is largely complete: full note lifecycle (create/read/update via write/patch/append), search, query, linking, tags, attachments, templates, folders, and vault stats. Missing delete_note and move/rename operations are notable gaps, and exotic formats (canvas/kanban) aren't supported, but core workflows are covered.