Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
VAULT_PATHYesPath 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

CapabilityDetails
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

NameDescription
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:

  • 'full' (default) — data: {content, frontmatter, tags, aliases, wikilinks, block_refs, callouts, tasks, inline_fields}.

  • 'outline' — structure only, no body text: data: {headings, block_refs, frontmatter_keys, tags, aliases, inline_fields, word_count, line_count}. Use this on a large note when you only need its shape.

  • 'rendered' — data: {rendered}, the note with all ![[embed]] transclusions resolved inline.

depth applies to mode='rendered' only: 0=raw, 1=one level of embeds (default), 2=nested embeds.

The envelope's revision is the token to pass back as expected_revision when writing (modes 'full' and 'outline'; a rendered read spans several notes, so it pins nothing).

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 content has no frontmatter of its own and a note already exists at path, its existing frontmatter is preserved rather than dropped — check the returned frontmatter_preserved flag. The result also carries a diff (unified diff against the current file). dry_run=True previews {preview, diff, frontmatter_preserved} without writing anything — check it, then call again with dry_run=False.

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 find doesn't match anything.

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 path for one note, or paths to apply the same updates to several notes in one call — exactly one of the two.

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 path: data carries {updated_keys, diff} and the envelope a revision. With paths: one note failing doesn't abort the rest — this returns the batch envelope, with data.results holding one item per note ({success, path, revision} or {success: false, path, error}) and data.summary the {total, succeeded, failed} tally. Always check data.summary.failed. expected_revision pins a single note's bytes and so can't be combined with paths.

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. status: inbox | active | done | archived). Returns {schema, violations: [{path, field, found, expected_enum}]} — only the deviations, not a full vault dump. A field that's simply missing on a note isn't a violation, only a present value outside the declared enum is. Returns an empty schema/violations pair if no enum schema can be parsed from _AI_INSTRUCTIONS.md.

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'. path is the resolved root note; data: {nodes: [{path, title, tags}], edges: [{from, to, type}]}.

get_vault_stats_toolB

Return vault statistics: note count, link count, orphans, broken links, most-linked notes. Vault-wide, so the envelope carries no path.

list_all_tags_toolA

Return every tag in the vault.

mode:

  • 'flat' (default) — data.items: [{tag, count}], with note counts. sort_by: 'count' (descending, default) | 'name' (alphabetical).

  • 'tree' — data.tree: the same tags as a nested mapping that follows the slash hierarchy (e.g. konzept → python, ki → llm). sort_by is ignored.

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 text into their own fields. data.items: [{text, done, source, line, due, recurrence, priority, done_date}].

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. path and data.resolved are null (and path omitted) if not found.

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, url is the ready-to-use request URL — use it as-is, it already has everything this token needs (including ?vault= when relevant) baked in. Otherwise build it yourself as: curl -X PUT --data-binary @file.png
"http://host:port/attachments/{path}?exp={expires_at}&sig={sig}&vault={vault}" (omit &vault=... only if the returned vault equals the server's single/default vault — see list_vaults_tool). The token only authorizes this exact path + method + vault and stops working after expires_at. In multi-vault mode, requires an api_key identity — GitHub-OAuth identities have no static secret of their own to sign with; use a plain Authorization: Bearer request against /attachments/* instead (that path works for any identity type, but needs ?vault= added by hand if targeting a non-default vault, since nothing was pre-signed for it). data: {method, vault, expires_at, sig, url?}.

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. path is the written note; data: {template, variables}.

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

NameDescription
weekly_reviewSummarize the past week: overdue/due-soon tasks, daily note highlights.
daily_noteOpen 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

NameDescription
vault_stats_resourceCurrent vault statistics (note count, links, orphans, broken links).
vault_tags_resourceAll tags in the vault with note counts, sorted by frequency.

TDQS

A3.7/5.0

Scored across 33 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count4/5

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.

Completeness4/5

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.

Maintenance

ActivityActive
ResponsivenessNo issues