Skip to main content
Glama

Seekstone

obsidian-mcp-server (#1 by downloads)

REST-proxy servers

Local REST API plugin

Not needed

Required

Required

Obsidian app running

Not needed — works with Obsidian closed

Required

Required

Search payload @ 10k notes

2.0 KB

47 KB

up to 95 MB

Warm search latency @ 10k notes

5.2 ms

732 ms (~141× slower)

up to 1,550 ms

Structured frontmatter queries

Built-in (query_notes) — property/date/size predicates, answers in a few hundred bytes

JSONLogic via REST

Varies

Same queries, same committed vaults, 20 runs each, one machine. In-process adapters were re-run on the fixture-v2 vault in September 2026; the REST-proxy rows (rest, obsidian-mcp-server, mcp-obsidian) plus obsidian-mcp and obsidian-mcp-pro are June 2026 captures on fixture v1 — per-row provenance in benchmarks.json, the generated source of truth every number here is checked against in CI — full results across eight servers and three vault sizes below, fully reproducible from the harness.



What is Seekstone?

Seekstone is an Obsidian MCP server — it gives Claude (and any Model Context Protocol client) direct read and write access to your Obsidian vault. No Obsidian app needs to be open, no plugins are required, and nothing leaves your machine.

It reads your vault directly from disk rather than routing through the Obsidian Local REST API plugin, and holds a warm full-text index in-process. The practical difference is twofold:

  • Speed. Keyword searches return in single-digit milliseconds warm and semantic searches in ~26 ms — up to ~514× faster than every other Obsidian MCP server we benchmarked, because there's no subprocess to spawn and no HTTP round-trip per query.

  • Context. A broad search that returns tens of megabytes and millions of tokens via a REST-proxy server returns ~2 KB via Seekstone — up to a ~47,000× reduction that only widens as your vault grows.

Search comes in three modes: ranked full-text search (fuzzy and prefix matching), optional local semantic search (meaning-based, via a small on-device embedding model — opt-in, offline at runtime after a one-time ~30 MB model download), and structured metadata queriesquery_notes filters by frontmatter properties (status, due, type, …), tags, folder, modified time, and size, answering questions like "which draft notes changed this week?" in a few hundred bytes instead of a search-and-read loop.

Claude can search and read your entire note library, in milliseconds, without burning most of its context window on a single tool call.

Published on npm as seekstone — install with npx -y seekstone. (Previously also published as obsidian-mcp-seekstone; that alias is deprecated but existing installs keep working.)


Related MCP server: mcp-obsidian-ek

Why Seekstone? The numbers.

Most Obsidian MCP servers return full note content for every search hit. On a broad query that's megabytes of text your LLM has to process — most of it irrelevant, all of it burning context window.

Seekstone returns short ranked excerpts instead (~120 characters by default, tunable per query). We benchmarked Seekstone against 7 other Obsidian MCP servers — 8 servers total — across three vault sizes — 1,000 / 5,000 / 10,000 notes (20 runs each). Every number below is fully reproducible: the vaults are committed to this repo (generated from the public-domain 1911 Encyclopædia Britannica), so you can clone it and run the exact same benchmark yourself.

The point of testing three sizes is that this is where the architectures diverge — a real vault only grows.

Search payload — bytes returned per query (context tax; lower is better)

Server

Architecture

1k notes

5k notes

10k notes

🥇 Seekstone

in-process index

1.6 KB

1.8 KB

2.0 KB

mcpvault

fs-direct subprocess

1.7 KB

1.9 KB

2.2 KB

obsidian-mcp-rs

fs-direct, per-query scan

5.4 KB

5.8 KB

6.2 KB

obsidian-tc

SQLite platform

4.6 KB

6.8 KB

7.2 KB

obsidian-mcp-server

REST API

55 KB

47 KB

47 KB

obsidian-mcp-pro

fs-direct subprocess

25 KB

84 KB

114 KB

obsidian-mcp

fs-direct subprocess

18 KB

105 KB

201 KB

mcp-obsidian

REST API

9.8 MB

45 MB

95 MB

Seekstone stays flat (~2 KB) no matter how big your vault gets, because it always returns ranked excerpts — and it's now the smallest payload of every server tested, edging out mcpvault at all three sizes. The REST-proxy servers return full note content for every match, so they grow with the vault — mcp-obsidian hits 95 MB at 10k notes, and a single broad query (the capital of) averaged 370.9 MB / 97.8 million tokens per call across 20 runs. At 10k notes that's a ~47,000× context-tax difference.

Search latency — warm mean, ms (lower is better)

Server

1k notes

5k notes

10k notes

vs Seekstone @10k

🥇 Seekstone

1.0

2.7

5.2

obsidian-mcp-rs

5.8

18

35

~7× slower

obsidian-mcp-pro

46

213

430

~83× slower

obsidian-mcp-server

82

356

732

~141× slower

obsidian-mcp

82

405

811

~156× slower

mcpvault

89

436

897

~173× slower

mcp-obsidian

164

740

1,550

~299× slower

obsidian-tc

263

1,253

2,667

~514× slower

Every competitor spawns a subprocess or makes HTTP round-trips per query, and most do work that scales with vault size. Seekstone holds a warm in-process index — no IPC, no network — so keyword search stays in single-digit milliseconds even at 10,000 notes (the shipped semantic pipeline — embed, scan, MaxSim rerank — lands at ~26 ms). And the gap widens with scale: from 1k → 10k notes the competitors slow down 5–10×, while Seekstone barely moves. Even the fastest alternative — obsidian-mcp-rs, which re-scans the vault on every query — is ~7× slower warm at 10k notes with 3× the payload, and the REST-proxy generation runs ~110–300× slower.

Seekstone is the only server in our benchmark set that delivers both ~2 KB payloads and single-digit-ms keyword latency at every vault size — and, as far as we know, the only Obsidian MCP server with published, reproducible benchmarks. The harness, the synthetic vaults, and the full results are open source: see benchmark-scaling.md and the harness. Clone, run, verify.


Install

Choose the method that suits you best.

Using an AI agent? Paste this prompt

If you use Claude Code, Cursor, or another coding agent, you don't need to follow any instructions yourself — paste this prompt and the agent does the install:

Install the seekstone MCP server for this editor. Run npx -y seekstone init --client code --write (use desktop, cursor, or vscode for other clients). It auto-detects my Obsidian vault; if it lists several, ask me which one and re-run with --vault "<path>". Relay any errors to me, then tell me to restart this session so the seekstone tools load.

seekstone init is fully non-interactive — with --write it validates the vault and patches the client config in one shot (Claude Code via claude mcp add, other clients via an additive JSON patch with a timestamped backup).

Option 1 — One-click (Claude Desktop, no terminal needed)

  1. Download seekstone.mcpb (direct link, always the latest release)

  2. Open it with Claude Desktop — double-click in Finder, or right-click → Open With → Claude Desktop

  3. Pick your Obsidian vault folder when prompted

You'll know it worked when seekstone appears in Claude's toolbar. No JSON editing, no terminal, no Node.js required.

Want semantic search? Grab seekstone-semantic.mcpb instead — same server with the local embedding model shipped inside the bundle (~28 MB bigger), so meaning-based search works out of the box: still no terminal, and nothing is downloaded at runtime.

Open Terminal (macOS: Cmd+Space, type "Terminal", press Enter) and run:

npx -y seekstone init

You'll know it worked when Seekstone appears in Claude's toolbar under the plug icon.

Seekstone reads Obsidian's own vault registry to detect your vault, validates it, and either prints the config block to paste or patches Claude Desktop directly:

# Auto-detect vault, print config to paste
npx -y seekstone init

# Auto-detect vault, patch Claude Desktop in place (with backup)
npx -y seekstone init --write

# Specify vault explicitly if you have multiple
npx -y seekstone init --vault "/path/to/vault"

# Auto-configure Claude Code in one step (auto-detects vault, runs claude mcp add)
npx -y seekstone init --client code --write

# Or just print the Claude Code command without running it
npx -y seekstone init --client code

Option 3 — Manual config (Claude Desktop)

Add to claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "seekstone": {
      "command": "npx",
      "args": ["-y", "seekstone"],
      "env": { "SEEKSTONE_VAULT": "/absolute/path/to/your/vault" }
    }
  }
}

Option 4 — Claude Code

Auto-detects your vault and configures Claude Code in one command:

npx -y seekstone init --client code --write

Or manually, if you prefer to specify the vault path explicitly:

claude mcp add seekstone --env SEEKSTONE_VAULT=/absolute/path/to/your/vault -- npx -y seekstone

Option 5 — Cursor

One-click: — then set SEEKSTONE_VAULT to your vault's absolute path in Cursor's MCP settings (the link installs a placeholder).

Or let the CLI auto-detect your vault and patch ~/.cursor/mcp.json (with a backup):

npx -y seekstone init --client cursor --write

Or add the block manually to ~/.cursor/mcp.json (global) or <project>/.cursor/mcp.json (per-project):

{
  "mcpServers": {
    "seekstone": {
      "command": "npx",
      "args": ["-y", "seekstone"],
      "env": { "SEEKSTONE_VAULT": "/absolute/path/to/your/vault" }
    }
  }
}

Option 6 — VS Code

One-click: — then set SEEKSTONE_VAULT to your vault's absolute path when VS Code opens the server config (the link installs a placeholder).

Or let the CLI auto-detect your vault and write the workspace config (.vscode/mcp.json in the current directory):

npx -y seekstone init --client vscode --write

Or add it from the terminal:

code --add-mcp '{"name":"seekstone","command":"npx","args":["-y","seekstone"],"env":{"SEEKSTONE_VAULT":"/absolute/path/to/your/vault"}}'

Or add the block manually to .vscode/mcp.json (workspace) or via Command Palette → MCP: Open User Configuration (user-global). Note VS Code's two quirks: the top-level key is servers (not mcpServers), and "type": "stdio" is required:

{
  "servers": {
    "seekstone": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "seekstone"],
      "env": { "SEEKSTONE_VAULT": "/absolute/path/to/your/vault" }
    }
  }
}

Requires VS Code 1.102+; seekstone appears in Copilot Chat's Agent mode tools picker.

Other MCP clients (Windsurf, Cline, …)

Seekstone is a standard MCP stdio server — any MCP client can run it. Use the same JSON block as above in your client's MCP config (command: npx, args: ["-y", "seekstone"], env SEEKSTONE_VAULT).


After installing, restart the client. On startup Seekstone walks the vault, builds an in-memory full-text index (a few seconds for thousands of notes), and keeps it live as you edit. The 21 tools below are then available to Claude.

Requires Node.js ≥ 22 for the CLI options. The one-click .mcpb bundle has no external requirements.

If Seekstone saves you context, consider ⭐ starring the repo — it helps others find it.


What can Claude do with your vault?

Once Seekstone is connected, you can ask Claude things like:

  • "Search my notes for everything about [topic] and give me a summary" — uses search, returns ranked excerpts, not full files

  • "Find all notes tagged #project and list their titles" — uses list_notes with a tag filter

  • "Read just the 'Decisions' section of my [project] note" — uses read_note with a section selector, so only that slice enters context

  • "What links to my [topic] note, and what does it link out to?" — uses get_backlinks and get_links to walk your graph

  • "Append today's standup notes to my daily note" — uses append_periodic_note, resolving the daily-note path from your vault config (Obsidian doesn't need to be open)

  • "Fix every occurrence of the old project name in this note" — uses replace_in_note, with a dry-run preview before it writes

  • "Add a summary section to the bottom of [note]" — uses append_note, never touches frontmatter

  • "Move all notes in /inbox to /archive/[year]" — uses move_note

  • "Update the status field in this note's frontmatter to 'done'" — uses patch_frontmatter, preserves key order and quote style

  • "Create a new meeting note for today with a standard template" — uses create_note

Claude never sees your full vault at once — it searches and reads selectively, so even large vaults (10k+ notes) stay within context budget.


Tools

Read

Tool

Description

search

Full-text search. Returns ranked excerpts (default ~120 chars, tunable via excerptLength), not full notes. Fuzzy and prefix matching; with SEEKSTONE_SEMANTIC=1, mode: "semantic"/"hybrid" searches by meaning via a local embedding model (nothing leaves your machine).

query_notes

Structured metadata query. Filter by frontmatter key/value predicates (eq, ne, contains, exists, missing, gt/gte/lt/lte), tag, folder, modified time, and size; sort and select the fields you need. Returns compact rows (path + title by default), not note content.

context_pack

Answer-ready context for a natural-language question in one call, hard-capped at a byte budget (default 2 KB): ranked excerpts, linked neighbor notes with one-line summaries, and follow-up source paths — replaces a search → read → get_backlinks round-trip loop.

read_note

Read the full content of a note by vault-relative path. Supports returning a single section, block, or line range.

list_notes

List notes, optionally filtered by folder prefix or tag.

list_tags

List all tags in the vault sorted by usage count (or alphabetically).

outline_note

Return a note's heading and block structure without its full content — cheap navigation before a targeted read.

get_backlinks

Find all notes that link to a given note.

get_links

List all outgoing wikilinks and markdown links from a note.

get_periodic_note

Read today's (or any date's) daily, weekly, monthly, quarterly, or yearly note — path resolved from your vault config, no Obsidian required.

list_writes

Recent writes from the journal — seq, timestamp, tool, touched paths, and whether each is still undoable. Metadata only, never note content.

Write

Tool

Description

create_note

Create a note (optional frontmatter + body); parent directories are created automatically.

delete_note

Move a note to the vault's .trash/ folder (Obsidian-compatible, restorable). Pass permanent: true to skip the trash — the write journal still lets undo_write restore it.

move_note

Move or rename a note — wikilinks and markdown links in other notes that point at it are rewritten so nothing breaks (rewriteLinks: false to opt out); destination directories are created automatically.

rename_heading

Rename a heading in a note — every [[note#heading]] wikilink and embed across the vault is rewritten so references keep working (aliases preserved, fenced code blocks left alone).

append_note

Append text to a note body without touching frontmatter.

patch_frontmatter

Set, update, or delete frontmatter keys without reordering existing keys or changing quote style.

patch_note

Append, prepend, or replace text at a heading or block reference (createIfMissing to add the section) — frontmatter untouched.

replace_in_note

Find and replace text in the note body — literal or regex, case sensitivity, whole-word matching, optional limit (replaces all occurrences by default), and a dry-run preview.

append_periodic_note

Append to today's periodic note, creating it from a template if it doesn't yet exist.

undo_write

Revert a journaled write: every file it touched goes back to its byte-identical pre-write state (a multi-file move or heading rename is restored whole; a delete is restored even if it was permanent). Defaults to the most recent write; refuses with undo_conflict if a file changed since, unless force: true. The undo is itself journaled — undo_write({ seq }) on the undo entry redoes it.

Every write tool (append_note, patch_note, patch_frontmatter, replace_in_note, rename_heading, move_note, delete_note, append_periodic_note, and create_note with overwrite: true) supports optional compare-and-swap: pass the contentHash you got from read_note as prevHash and the call fails cleanly if the note changed underneath you — no silently discarded concurrent edit, no moving or deleting content you haven't seen. Every mutating result returns the new contentHash, so chained edits need no re-reads.

Every write is reversible. Before any write tool changes a byte, it journals the pre-image of every file it is about to touch under <vault>/.seekstone/history/ — content-addressed (identical states are stored once) and fsync'd before the vault write commits. list_writes shows the journal; undo_write restores byte-identically: a multi-file move_note or rename_heading is restored whole (the note and every link rewrite), and a delete_note comes back even if it was permanent. An undo after an external edit is refused with a structured undo_conflict unless you pass force: true — and even then the clobbered state is journaled first, so nothing is ever lost. Undo is itself journaled: repeated default undos walk backwards through the history, and undo_write({ seq }) on an undo entry redoes it. .seekstone/ is excluded from indexing and search like .trash/; add it to your vault's .gitignore. This complements git and Obsidian's File Recovery rather than replacing them — it is the recovery path the agent can drive.

Every write leaves a receipt. Set SEEKSTONE_AUDIT_FILE and every write-tool call — successful or refused — appends one JSON line: tool, vault-relative paths, sha-256 before/after, outcome (ok, hash_conflict, undo_conflict, policy_denied, error), and op metadata such as replacement counts or the .trash/ destination — never note content, frontmatter values, or search queries, so the file is safe to attach to a bug report.

{"v":1,"ts":"2026-08-29T21:02:11.042Z","tool":"replace_in_note","outcome":"ok","durationMs":1.8,"seq":42,"files":[{"path":"notes/a.md","hashBefore":"3f9c…","hashAfter":"b71e…"}],"path":"notes/a.md","replacements":3}

The hashes are the same contentHash values read_note returns, so any record can be checked against the vault; seq is the journal entry the call committed, so a row indexes straight into list_writes / undo_write. Records are appended and fsync'd after the vault write commits, the file rotates to <file>.1 past SEEKSTONE_AUDIT_MAX_SIZE, an unwritable audit path fails boot, and a failed append reports the call as a structured audit_failed error rather than a clean success. A few jq recipes:

jq -r '[.tool, .outcome] | @tsv' audit.jsonl | sort | uniq -c            # session summary by tool + outcome
jq -c 'select(.files[]?.path == "notes/a.md")' audit.jsonl              # history of one note
jq -c 'select(.ts > "2026-08-29T21:00:00Z" and .outcome == "ok")' audit.jsonl   # what changed since a timestamp

Fast and complete. Seekstone is the only Obsidian MCP server in our benchmark set to expose list_tags, outline_note, get_backlinks, and get_links as first-class tools. Four more capabilities set it apart:

  • Local semantic search, fully in-process. With SEEKSTONE_SEMANTIC=1, search gains mode: "semantic" and "hybrid" — meaning-based retrieval through a small on-device embedding model (one-time npx -y seekstone fetch-model download, or the seekstone-semantic.mcpb bundle which ships the model inside; the running server never touches the network), with a MaxSim late-interaction rerank on top since 0.17.0. On our committed 10k-note benchmark vault (150-query golden set, fixture v2), the default model — measured end-to-end through the real search tool — scores 83.3% overall hit@5, 86.7% on the held-out split (vs 34.7% for keyword search alone) at ~26 ms warm p50, and the opt-in potion-retrieval-32M model (SEEKSTONE_SEMANTIC_MODEL; ~129 MB) reaches 86.7% overall hit@5, 86.7% held-out at ~55 ms. No other server we benchmarked ships offline, zero-native-dependency embeddings — and we measured the alternatives head-to-head on the same golden set, same run, committed dev/holdout split (committed comparison, read-out in COMPETITORS-SHA-322): obsidian-tc's plain Ollama-backed semantic search edges us on the held-out split (90.0% vs our 86.7%) at 169 ms/query and a 30-minute index vs our ~28 s, and its GraphRAG mode scores highest of anything we benchmarked (95.0% held-out), paying for it with seconds-per-query latency (2.9 s p50, 4.2 s p95 — against our 26–55 ms), ~8× the payload (16 KB vs ~2 KB per query), and a second server (Ollama + a 137M-parameter model) you must install and run. We pre-registered a gate to claim the #1 spot (GATE-V2-SHA-316, run on fixture v1) and missed it — that verdict is published with the same prominence a win would have been; no new gate ran on v2, and the same clauses recompute to the same miss. obsidian-mcp-pro could not index the 10k-note vault at all (its JSON vector store exceeds JavaScript's string limit after ~17 minutes of embedding). Pick your trade — the numbers are all committed.

  • Periodic notes, filesystem-direct. get_periodic_note and append_periodic_note resolve daily, weekly, monthly, quarterly, and yearly note paths by reading your vault's own config (.obsidian/daily-notes.json and the Periodic Notes plugin) — with Obsidian closed. Every REST-based server can only do this while the app is running.

  • Byte-identical frontmatter, guaranteed. patch_frontmatter edits YAML in place — preserving key order, quote style, and comments — and write-safety is proven byte-for-byte by the test harness. No other server we surveyed makes this guarantee.

  • Zero coupling. No Obsidian app, no Local REST API plugin, no plugin-version drift. Just your files on disk.


Configuration

Variable

Required

Description

SEEKSTONE_VAULT

Yes

Absolute path to your Obsidian vault.

SEEKSTONE_LOG_LEVEL

No

error | warn | info (default) | debug.

SEEKSTONE_LOG_FILE

No

Absolute path; when set, JSON-line logs are appended here (size-rotated).

SEEKSTONE_LOG_MAX_SIZE

No

Log-rotation threshold for SEEKSTONE_LOG_FILE (e.g. 10mb; default 5 MB).

SEEKSTONE_WATCH_POLL

No

Set to 1 to stat-poll for changes instead of native OS events — slower but reliable on network drives, WSL, and some containers.

SEEKSTONE_WATCH_POLL_INTERVAL

No

Stat-poll interval in ms (default 10000). Only used with SEEKSTONE_WATCH_POLL=1. Lower = faster pickup of external edits, higher CPU; raise it on slow network/9p mounts.

SEEKSTONE_READ_ONLY

No

Set to 1 to run read-only: the 10 write tools are unregistered from the tool list entirely (and rejected if called anyway), so the session provably cannot modify your vault.

SEEKSTONE_WRITE_PATHS

No

Comma-separated vault-relative globs (e.g. journal/**,inbox/*.md). Writes are permitted only under matching paths; the rest of the vault stays read-only.

SEEKSTONE_HISTORY

No

Set to 0 to disable the write journal (default on). With it on, every write tool stores the pre-image of each file it touches under <vault>/.seekstone/history/ so undo_write can restore it byte-for-byte.

SEEKSTONE_HISTORY_MAX_SIZE

No

Cap on stored pre-images (e.g. 100mb; default 50 MB). Oldest entries are evicted first and then show undoable: false in list_writes — never silently.

SEEKSTONE_HISTORY_MAX_ENTRIES

No

Cap on journal entries (default 1000); the oldest are dropped past it.

SEEKSTONE_AUDIT_FILE

No

Absolute path; off unless set. Appends one JSON-line audit record per write-tool call — ok or refused — with the tool, paths, sha-256 before/after, outcome, and op metadata. Never note content.

SEEKSTONE_AUDIT_MAX_SIZE

No

Rotate the audit file to <file>.1 past this size (e.g. 10mb; default 10 MB).

SEEKSTONE_SEMANTIC

No

Set to 1 to enable semantic search (search gains mode: "semantic" and "hybrid"). Requires the local embedding model — download it once with npx -y seekstone fetch-model; the running server never touches the network. The seekstone-semantic.mcpb bundle sets this automatically and ships the model inside.

SEEKSTONE_SEMANTIC_MODEL

No

Which local model to load: potion-base-8M (default, ~30 MB, 256-dim) or potion-retrieval-32M (~129 MB, 512-dim — more accurate on description-style queries at roughly 2× the query latency). Fetch it first with npx -y seekstone fetch-model --model potion-retrieval-32M.

SEEKSTONE_MODEL_PATH

No

Directory holding the Model2Vec embedding model (default: where fetch-model puts the selected model, under the cache dir).

SEEKSTONE_CACHE_DIR

No

Cache root for the downloaded model and per-vault embedding caches (default ~/.cache/seekstone).

SEEKSTONE_BUNDLED_MODEL_DIR

No

Set by the seekstone-semantic.mcpb bundle's manifest — points at the sharded model files shipped inside the extension, which the server reassembles into the model directory at boot (disk-only, verified against the pinned SHA-256 hashes). Not usually set by hand.


How it works

Seekstone walks the vault with fast-glob, parses each note's frontmatter (byte-aware, so writes can prove the frontmatter region is byte-identical pre- and post-write), and builds a MiniSearch full-text index in memory. Search returns short ranked excerpts rather than whole notes — that excerpt-not-document design is where the context-tax win comes from. A cross-platform file watcher (chokidar) keeps the index current as you edit in Obsidian.

Writes are conservative by design: append_note never touches frontmatter, and patch_frontmatter edits the YAML document in place rather than re-serializing it, preserving key order, quote style, and comments.

It's built to stay up. Seekstone is tested on macOS, Linux, and Windows in CI on every commit, its write tools are hardened against pathological (ReDoS) inputs, and a stray unhandled rejection is logged rather than crashed on — so your long-lived MCP session keeps its warm index instead of dropping out mid-conversation.

For a layer-by-layer tour of the codebase — packages, the server's internals, the end-to-end request flow, and the measurement harness — see docs/ARCHITECTURE.md.


Security & privacy

Seekstone reads — and, via the write tools, modifies — files under SEEKSTONE_VAULT on your local disk. The running server makes no network calls and sends no telemetry (the one network path in the package is the explicit npx -y seekstone fetch-model subcommand — a SHA-256-verified, one-time download of the optional semantic-search model that exits before serving starts; the seekstone-semantic.mcpb bundle skips even that by shipping the model inside and reassembling it from disk at boot, verified against the same pinned hashes). Logs are metadata-only by default (note contents only appear at debug level). Nothing is written outside the vault except an optional log file you configure and, with SEEKSTONE_SEMANTIC=1, the per-vault embedding cache under ~/.cache/seekstone (derived vectors of your notes — never sent anywhere).

The Write-Safety Contract

Giving an AI write access to your notes deserves more than "trust us." Seekstone ships a named, tested contract — docs/WRITE-SAFETY.md — of ten guarantees, each linked to the code that enforces it and the test that proves it, verified byte-by-byte by the harness safety suite in CI on every commit and release: zero network, vault sandbox, byte-identical frontmatter on body edits, atomic writes (no torn files), creates never clobber, recoverable deletes (.trash/), optional compare-and-swap on every write tool, configurable write scoping / read-only mode, a write journal that makes every write reversible (undo_write), and a hash-verifiable audit log — every write call leaves a receipt. The same suite runs headlessly against other FS-direct servers — the comparison table is in the contract.


Frequently asked questions

Does the Obsidian app need to be running? No. Seekstone reads the vault folder directly from disk. Obsidian can be open or closed.

Do I need the Local REST API plugin? No. Seekstone bypasses it entirely — that's the source of the up-to-47,000× payload reduction. No plugins are required.

Which AI clients does it support? Any client that supports the Model Context Protocol (MCP) over stdio — Claude Desktop, Claude Code, Cursor, Windsurf, Continue, and others.

Is it safe to use on my vault? Seekstone never modifies files except when you explicitly invoke one of its write tools (the ten in the table above — create_note, append_note, patch_note, patch_frontmatter, replace_in_note, move_note, rename_heading, delete_note, append_periodic_note, undo_write). Every one of them journals the pre-image of each file it touches first, so undo_write can put it back byte-for-byte — see the write-journal note above — and with SEEKSTONE_AUDIT_FILE set, every write call leaves a hash-verifiable audit record (refused attempts included). The running server makes no network requests (semantic search's model is fetched once, out-of-band, by the explicit fetch-model subcommand). The vault path is sandboxed — no tool can read or write outside it. And you can tighten it further: SEEKSTONE_READ_ONLY=1 removes the write tools from the session entirely, and SEEKSTONE_WRITE_PATHS restricts writes to the folders you allow (say, only journal/**). Both are enforced at the dispatch layer, not per-tool, so no tool can forget the check.

Does it work on Windows? Yes. Seekstone is tested on macOS, Linux, and Windows in CI on every commit.

What Obsidian vault sizes does it handle? Seekstone has been profiled against vaults with thousands of notes. On the committed 10,000-note benchmark vault, the cold index build takes tens of seconds and process RSS lands under ~100 MB; typical personal vaults index in a few seconds. Semantic mode embeds in the background after boot (~30 s at 10k notes, then cached per-vault so restarts reload in well under a second).

How does seekstone init find my vault automatically? It reads Obsidian's own vault registry (obsidian.json) — the same file Obsidian uses to track your known vaults. If you have one vault, it's selected automatically. If you have multiple, it lists them and asks you to pick with --vault.

What is the .mcpb file? An MCP Bundle — a self-contained zip with the server and its manifest. To install: double-click in Finder (or right-click → Open With → Claude Desktop), pick your vault, and you're done. No terminal or Node.js required. Two variants ship with every release: seekstone.mcpb (standard) and seekstone-semantic.mcpb (same server with the local embedding model inside, semantic search on out of the box).


Contributing & development

Contributions welcome. See CONTRIBUTING.md for guidelines, or jump straight in:

npm install                                          # install all workspace deps
npm test                                             # run all tests
npm run lint                                         # biome check
npm run build -w seekstone                           # tsup → dist/
npm run build:mcpb                                   # build seekstone.mcpb bundle

npx vitest run packages/server/src/tools/search.test.ts  # single test file
npx vitest run -t 'parses a typical frontmatter'         # single test by name
npx tsc -p packages/server/tsconfig.json --noEmit        # typecheck

Repository layout

Package

Purpose

packages/server

The published seekstone MCP server (21 tools, stdio, MiniSearch index, chokidar watcher).

packages/core

Shared vault primitives — walk, frontmatter parser, link/tag extractor, outline, percentiles, pmap, and the Model2Vec embedder. Bundled into the server build.

packages/harness

Profiler + benchmark + write-safety harness (REST vs filesystem) that produced the payload numbers above. Dev-only; not published.

The server has a real build (tsup → dist/) and is published to npm. The harness is run from source via tsx. Releases are automated — see docs/RELEASING.md.

The measurement harness

The harness exists to reproduce the benchmark numbers that motivated the filesystem-direct design. The default reproduction path (fs/seekstone backends against the committed synthetic vault) needs nothing extra; only the REST-backed backends (rest, mcp-obsidian, obsidian-mcp-server) need Obsidian running with the Local REST API plugin.

export SEEKSTONE_VAULT="/absolute/path/to/your/vault"

npx tsx packages/harness/src/cli.ts profile --vault "$SEEKSTONE_VAULT"
npx tsx packages/harness/src/cli.ts bench \
  --queries packages/harness/queries/default.json \
  --stats reports/vault-stats.json
npx tsx packages/harness/src/cli.ts safety --vault "$SEEKSTONE_VAULT"

Harness env vars: SEEKSTONE_REST_API_KEY (from the Local REST API plugin) and SEEKSTONE_REST_URL (defaults to https://127.0.0.1:27124).


Support

Seekstone is free and open source. If it saves you context (and money), you can buy me a coffee.


License

MIT © Shaq Mughal

Available Tools

21 tools
append_noteA

Append text to a note body without touching the frontmatter. Safe for meeting notes, daily logs, and append-only workflows.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path to the note.
contentYesText to append.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate it's a write operation (readOnlyHint=false) and non-destructive (destructiveHint=false). The description adds valuable behavioral detail: it preserves frontmatter and is safe for 'append-only workflows,' which provides context beyond the annotations. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no filler. The core purpose is stated first, and the additional safety/use-case context is provided in a second sentence. Every phrase adds value, making it appropriately sized and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple append operation with three parameters, the description covers the key points: it appends, preserves frontmatter, and indicates safe workflows. However, it does not mention error behaviors (e.g., what happens if the path doesn't exist) or whether it creates a note if missing. Given the low complexity and existing annotations, this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter (path, content, prevHash) already documented in the schema. The description does not add any additional parameter-specific semantics, so it remains at the baseline score of 3 given the complete schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Append text to a note body without touching the frontmatter.' This is a specific verb (append) and resource (note body), and it explicitly distinguishes itself from other mutation tools by mentioning the frontmatter preservation, which differentiates it from patch_note or replace_in_note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context on when the tool is appropriate ('Safe for meeting notes, daily logs, and append-only workflows'), but does not explicitly mention when NOT to use it or point to alternative tools. It implies usage scenarios but lacks explicit exclusions or sibling comparisons, leaving the agent to infer the boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

append_periodic_noteA

Append text to a periodic note (daily, weekly, monthly, quarterly, or yearly). Preserves existing frontmatter exactly. Creates the note first (from template if configured) when createIfMissing is true (default).

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoISO date string (YYYY-MM-DD). Defaults to today when omitted.
periodNoPeriod type. Default: daily.
contentYesText to append to the note body.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.
createIfMissingNoCreate the note if it does not exist before appending. Default true.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With all annotations false, the description carries the full behavioral burden. It adds genuinely useful guarantees ('Preserves existing frontmatter exactly') and creation-flow detail ('from template if configured'), which go beyond the raw annotations. However, it omits the most salient risk of an append operation — non-idempotency (duplicate calls duplicate content) — even though the prevHash parameter hints at concurrency concerns.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, zero filler. The primary action leads, the scoping list follows, and the creation behavior closes. Every clause serves a distinct purpose with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a moderate-complexity tool with 5 simple params and no output schema, the description covers the essentials well. Gaps remain: no mention of timezone handling for date-boundary behavior (critical for 'today' defaults), no duplicate-append warning, and no interaction with prevHash conflict recovery. These are real but not fatal omissions for an append operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, establishing a baseline of 3. The description adds value by clarifying the createIfMissing parameter's effect ('Creates the note first (from template if configured)') and confirming its default, which is not fully obvious from the schema text alone. This is a small but genuine increment over baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description leads with a specific verb+resource: 'Append text to a periodic note' and immediately scopes it to '(daily, weekly, monthly, quarterly, or yearly)'. This clearly differentiates it from sibling 'append_note' (regular notes) and 'get_periodic_note' (read path) without needing to inspect either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'periodic note' qualifier implies the tool's niche, and the description notes the conditional creation behavior when createIfMissing is true. However, it never explicitly points to an alternative (e.g., 'use append_note for regular notes') or states when not to use this tool, despite siblings like append_note and patch_note existing. Usage context is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

context_packA
Read-only

Assemble everything needed to ANSWER a natural-language question in one call, under a strict byte budget (default 2048): ranked excerpts, linked neighbor notes (backlinks/outlinks) with one-line summaries, and follow-up source paths. Use search to locate notes and query_notes for metadata filters; use context_pack when you want answer-ready context without multiple round-trips. Empty excerpts with confidence "none" or "low" means the vault lacks coverage — do not infer content.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesNatural-language question or topic.
budgetBytesNoHard cap on response JSON bytes (256–16384, default 2048).

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint=true annotation, the description adds critical behavioral disclosure: the byte-budget mechanism, the three output components, and especially the empty-result semantics ("Empty excerpts with confidence 'none' or 'low' means the vault lacks coverage — do not infer content"), which prevents an agent from hallucinating answers. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, each with a distinct job: what it returns, when to use it, and how to interpret empty results. Purpose is front-loaded and there's no fluff, though the middle sentence could arguably be split for skimmability. Minor polish would push this to 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries full responsibility for explaining return values and edge cases, which it does thoroughly: outputs (ranked excerpts, summaries, source paths), budget behavior, and the empty-coverage case are all disclosed. An agent has everything needed to call this tool correctly, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the description's parameter-related details (byte budget default, natural-language query) are already present in the input schema's field descriptions. The description reinforces but does not extend the schema, so it sits at the baseline of 3 for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with a specific verb and resource: "Assemble everything needed to ANSWER a natural-language question in one call," then enumerates exact outputs (ranked excerpts, linked neighbor notes with one-line summaries, follow-up source paths). This differentiates it from siblings by promising answer-ready context "without multiple round-trips," which no sibling claims.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes to alternatives: "Use search to locate notes and query_notes for metadata filters; use context_pack when you want answer-ready context without multiple round-trips." Names two siblings and the precise condition that selects this tool, making the when-versus-when-not distinction unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_noteA
Destructive

Create a new note at a vault-relative path. Optionally sets frontmatter and body content. Parent directories are created automatically. Fails if the note already exists unless overwrite is true (prevHash may guard the overwrite).

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path, e.g. "Daily Notes/2026-06-01.md".
contentNoBody content for the note.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.
overwriteNoOverwrite an existing note. Defaults to false.
frontmatterNoFrontmatter key-value pairs.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint:true annotation, the description discloses three concrete behaviors: automatic parent-directory creation, the fail-on-existing-note rule, and the prevHash compare-and-swap guard that can gate the overwrite. These are non-obvious side effects and failure modes the annotations alone do not convey. The description is consistent with readOnlyHint:false and destructiveHint:true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: the core action first, then the optional parameters, then the critical existence-failure and CAS-guard behavior. No filler and no repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter destructive write with no output schema, the description covers creation, optional fields, directory auto-creation, the existence failure mode, and the overwrite/CAS guard. The one notable gap is the return contract on success — the CAS workflow implied by prevHash would benefit from knowing whether the note's contentHash is returned — but the invocation semantics are fully specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter (path, content, prevHash, overwrite, frontmatter) is already documented in the input schema. The description's only added semantic is the coupling between prevHash and overwrite ('prevHash may guard the overwrite'), a small increment over the schema's per-parameter text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence 'Create a new note at a vault-relative path' names a specific verb, resource, and scope qualifier. This cleanly distinguishes it from sibling mutators like append_note, patch_note, replace_in_note, and move_note, which all act on existing notes, and from delete_note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The fail-if-exists clause ('Fails if the note already exists unless overwrite is true') gives the agent a clear condition for choosing the overwrite path. However, it does not explicitly route to alternatives — e.g., checking existence with list_notes first or selecting patch_note/append_note for modifying an existing note — so cross-tool selection is left implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_noteA
Destructive

Delete a note. By default it is moved to the vault .trash/ folder (recoverable by moving it back); pass permanent: true to remove it outright.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path of the note to delete.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since — so you never delete content you have not seen.
permanentNoPermanently remove instead of moving to .trash/. Defaults to false.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description reveals critical behavior: the default action is non-permanent (trash) and reversible, and only permanent deletion requires an explicit flag. It also discloses recoverability. This transparency is essential for an agent deciding whether to call this tool and mitigates risk, going well beyond what the annotation already provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact at two sentences, with the action verb first and the most important behavioral nuance immediately following. Every word contributes value, and the sentence structure flows from the core action to the key conditional. No fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three parameters and one required field, the description covers the essential behavior (delete, default trash, permanent override) and confirms reversibility. It does not mention error handling for missing paths or concurrency, but given the schema and annotations, the definition is complete for an agent to call it correctly. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents all three parameters with 100% coverage, so the description needn't add parameter details. The description's mention of 'pass permanent: true' restates the schema without adding new meaning. This meets the baseline of 3 but does not elevate it further.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Delete a note', which is a specific verb and resource, and immediately clarifies the default trash behavior and the permanent deletion option. This distinguishes it from siblings like move_note or patch_note, which are about modifying instead of removing. The tool's purpose is unambiguous and immediately scoped.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on how deletion works by default (to trash) and how to override it, which implicitly tells the agent when this tool is appropriate. However, it does not explicitly mention alternatives like move_note or state when NOT to use it (e.g., for reorganization). This is a slight gap in otherwise clear guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_periodic_noteA

Get the path and existence status of a periodic note (daily, weekly, monthly, quarterly, or yearly) for a given date. Reads folder/format config from .obsidian/daily-notes.json (daily) or the periodic-notes plugin data.json. Optionally creates the note from the configured template if it is missing.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoISO date string (YYYY-MM-DD). Defaults to today when omitted.
periodNoPeriod type. Default: daily.
createIfMissingNoCreate the note from the configured template if it does not exist. Default false.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and destructiveHint=false, so the description correctly adds that the tool may create a note when createIfMissing is true – a behavioral detail beyond the annotations. It also discloses the config file locations (.obsidian/daily-notes.json and plugin data.json). No contradictions. However, it does not describe the exact return shape or failure modes, which are minor gaps given the side‑effect disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The primary purpose ('Get the path and existence status') is front‑loaded, followed by config sources and the optional creation behavior. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Since there is no output schema, the description conveys that the return includes 'path and existence status', and it explains the config‑reading logic and optional creation. This is sufficient for an agent to call correctly. It lacks explicit error cases or what happens after creation (e.g., returns path or just status), but the core information is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Parameter schema coverage is 100% – all three parameters (date, period, createIfMissing) already have descriptions in the schema, including defaults. The description adds no new semantic meaning beyond restating the defaults ('Defaults to today', 'Default: daily', 'Default false') which are already present. Baseline 3 applies because the schema carries the weight.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Get the path and existence status of a periodic note' and enumerates the period types (daily, weekly, monthly, quarterly, yearly). This clearly distinguishes it from sibling tools like create_note or append_periodic_note, even though it never names them. The purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what the tool does and mentions the optional creation side‑effect, but never explicitly states when to use this tool versus a sibling like create_note or append_periodic_note. It gives context (reads config from specific files) but no when‑to‑use or when‑not‑to‑use guidance, leaving the agent to infer suitability.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_notesB
Read-only

List notes, optionally filtered by folder prefix or tag.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNoFilter by tag (# prefix optional).
limitNoMax results (1–500, default 100).
folderNoVault-relative folder prefix.

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds the filtering behavior but does not disclose result shape, ordering, pagination behavior, or whether note content is returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, compact, front-loaded sentence. It communicates the essential verb, resource, and optional filters with no unnecessary filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with fully documented optional parameters, this is mostly adequate. However, it lacks guidance on sibling alternatives and does not clarify what the returned note list contains, which matters in the absence of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already fully documented. The description adds minimal semantic value beyond restating that folder and tag filtering exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List notes', with an optional filter by folder prefix or tag. It is distinguishable from single-note operations like read_note, but it does not explicitly differentiate itself from search or query_notes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use list_notes versus search, query_notes, or list_tags. The description only states what the tool does, not when it should be preferred over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tagsA
Read-only

List all tags in the vault with usage counts. Supports substring filtering, minimum count threshold, and sort order. Nested tags (e.g. area/work) include a parent field.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNoSort by usage count descending (default) or alphabetically.
patternNoSubstring filter on tag name. Example: "work" matches "work" and "area/work".
minCountNoOnly return tags used in at least this many notes.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already signals a safe read operation. The description adds useful behavioral details—that all tags are returned, filtering behaviors, and that nested tags include a parent field—which goes beyond the annotation's minimal information.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences deliver the purpose, options, and a notable output feature with zero redundancy. Front-loaded with the primary action and immediately informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no output schema, the description covers the return contents (usage counts, parent field for nested tags) and behavioral parameters fully. No gaps are apparent for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers all parameters with descriptions (100% coverage), so the description adds no significant new meaning about inputs. It merely reiterates what the schema already specifies, meeting the baseline but not exceeding it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Describes a specific action ('List all tags in the vault') with clear scope and distinguishes itself from siblings by focusing solely on tags. The mention of usage counts and nested tags further specifies the tool's unique function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

While it doesn't explicitly contrast with alternatives, there is no other tag-listing tool among siblings, making the purpose self-evident. It provides clear context but omits explicit exclusions or when-to-use guidance beyond its self-description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_writesA
Read-only

List recent writes from the journal — every write tool records the pre-image of each file it touches, so any of them can be reverted with undo_write. Returns compact metadata rows (seq, timestamp, tool, paths, undoable), never note content.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoOnly entries that touched this vault-relative path.
limitNoMax entries to return, newest first (1–200, default 20).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as read-only, and the description reinforces that by promising metadata rows and explicitly stating 'never note content.' It adds value beyond the annotation by disclosing the exact fields returned (seq, timestamp, tool, paths, undoable) and explaining the pre-image journaling mechanism that makes undo_write possible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences front-load the main purpose, then add the key behavioral constraint and output shape. Every sentence earns its place, and there is no redundant repetition of the tool name or schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description explicitly lists the returned fields and their nature, so an agent knows what response to expect. Combined with full schema coverage for optional parameters, this is complete enough for a low-complexity list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with both path and limit already described in the input schema. The tool description does not need to repeat parameter details; it adds context about the journal concept but no additional parameter-level semantics. Baseline 3 is appropriate because the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('List recent writes') and the resource ('the journal'), making the tool's purpose immediately obvious. It also distinguishes this from content-focused tools by explicitly noting it returns metadata and never note content, which separates it from siblings like list_notes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: this tool is for reviewing write operations and identifying entries that can be reverted with undo_write. It does not explicitly say 'use this instead of list_notes' or list exclusions, but the connection to undo_write and the metadata-rows framing gives enough context for an agent to choose it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_noteA
Destructive

Move or rename a note to a new vault-relative path, rewriting wikilinks and markdown links in other notes that point at it so nothing breaks (links inside fenced code blocks are left alone). Parent directories at the destination are created automatically. Fails if the destination already exists unless overwrite is true.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesVault-relative destination path.
fromYesVault-relative source path.
prevHashNoOptional compare-and-swap guard on the source note: the contentHash from a prior read. Fails with hash_conflict if the note changed since.
overwriteNoOverwrite destination if it exists. Defaults to false.
rewriteLinksNoRewrite references in other notes to follow the move. Defaults to true; pass false to move the file only.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description discloses concrete behavioral traits: it rewrites wikilinks and markdown links in other notes while leaving fenced code blocks untouched, auto-creates parent directories, and fails if the destination exists unless overwrite is true. This is rich, actionable context that goes well beyond the annotation and helps an agent anticipate side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences, front-loaded with the primary purpose, followed by critical behaviors (link rewriting, directory creation, overwrite failure). No filler — every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 5 parameters and no output schema, the description covers the main side effects (link rewriting, directory creation, failure conditions) and explains the overwrite and rewriteLinks parameters behaviorally. The prevHash guard is documented in the schema but not in the description; however, the agent can infer it from the parameter description. Given the complexity, this is complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter already has a clear meaning. The description adds context around rewriteLinks (rewriting links in other notes) and overwrite (failure behavior) but does not add new information for from, to, or prevHash beyond the schema. It sits at the baseline of 3 because the schema carries the parameter explanation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Move or rename a note to a new vault-relative path' — a clear verb, resource, and target location. It explicitly describes the link-rewriting side effect, distinguishing it from destructive delete_note and heading-renaming rename_heading.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly conveys when to use the tool (moving/renaming notes) and details the overwrite and link-rewriting behavior. It does not explicitly name alternative tools, but the purpose is unambiguous given the sibling list; this falls short of a perfect 5 that requires explicit when-not/alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outline_noteA
Read-only

Return a note's structure — heading tree with offsets, block-reference anchors, and frontmatter key list — without returning any prose. Use this before section reads or patches to discover what sections exist at a fraction of the cost of reading the full note.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path to the note.
includeSizesNoInclude per-section character length in each heading entry. Default false.
includeBlocksNoInclude block-reference anchors (^id). Default true.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds meaningful behavioral context: it returns only structural data (headings, offsets, anchors, frontmatter keys) and explicitly excludes prose. It also signals a performance advantage ('fraction of the cost'), which is not in the annotations. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero wasted words. The most critical information (what it returns and what it excludes) is front-loaded, and the usage guidance is packed efficiently into the second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully covers the return value (heading tree, offsets, anchors, frontmatter keys), the exclusions (no prose), and the usage context (before reads/patches). With only 3 well-documented parameters and read-only annotations, nothing essential is missing for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description doesn't add extra semantics to the parameters beyond what the schema already states, but it does clarify the overall output context (e.g., 'frontmatter key list' implies what includeFrontmatter might do). No compensation needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Return') with a precise resource ('a note's structure') and enumerates the components (heading tree, offsets, block-reference anchors, frontmatter key list). It clearly distinguishes from siblings like read_note by explicitly saying 'without returning any prose,' so an agent knows exactly what it gets.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: 'Use this before section reads or patches to discover what sections exist at a fraction of the cost of reading the full note.' This tells the agent the ideal scenario and why it's preferable to full reads, effectively excluding alternatives like read_note.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

patch_frontmatterA
DestructiveIdempotent

Set, update, or delete frontmatter keys without reordering existing keys or changing quote style. Pass null as a value to delete a key.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path to the note.
patchYesKey-value pairs to set. Null value removes the key.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses important behavioral traits: it preserves key ordering and quote style, and explicitly explains that null values delete keys. These details go beyond the annotations (readOnlyHint=false, destructiveHint=true), which only indicate mutation and destructiveness. It adds useful context without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the core action, key guarantees, and deletion semantics. No filler or repetition; every clause adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential behavior, deletion semantics, and safety guarantees. It does not mention error cases like hash_conflict, but those are captured in the schema. It also omits prerequisites (e.g., note must exist), but given the simple tool and existing schema, the description is near-complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all three parameters. The description repeats the null-deletion behavior for the patch parameter, which is also stated in the schema, and adds no new semantic information beyond what is structured. Thus baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: setting, updating, and deleting frontmatter keys. It specifies the resource (frontmatter keys) and includes a concrete behavioral guarantee (preserving key order and quote style), which distinguishes it from sibling tools like patch_note that modify note content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives such as patch_note or replace_in_note. The description gives no context on selection criteria, exclusions, or comparative advantages beyond the formatting guarantee.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

patch_noteA
Destructive

Surgically edit a section of a note — targeted by heading or block reference — without rewriting the whole file. Operations: append (add after section), prepend (add after heading line), replace (swap section content). Frontmatter is never touched.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path to the note.
targetYesExactly one of: { heading: "Section Title" } or { block: "block-id" } (without the ^ prefix).
contentYesContent to insert or replace with.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.
operationYesappend: insert after section content. prepend: insert after heading line. replace: swap section content.
createIfMissingNoIf the heading target is not found, append a new heading (level 2) + content. Only valid for heading targets. Default false.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false. The description adds operational semantics — exact behavior of append, prepend, replace — and the frontmatter constraint, which is useful. It does not mention the prevHash concurrency guard or hash_conflict failure, but those are fully documented in the schema, and there is no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three compact segments: the main purpose, the operations list, and the frontmatter constraint. It is front-loaded with the core purpose, contains zero fluff, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 6 parameters, the description covers the operational model and key constraints (frontmatter untouched). It omits details like prevHash and createIfMissing, but these are fully specified in the schema, so the description plus schema together provide a complete picture. A small addition like mentioning the concurrency guard would push it higher.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds significant meaning beyond the schema by defining what each operation does (append after section, prepend after heading line, replace section content) and clarifying the targeting mechanism (heading or block without ^ prefix). This goes well beyond the schema's individual descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool surgically edits a specific section of a note, targeted by heading or block reference, without rewriting the whole file. It identifies three operations (append, prepend, replace) and explicitly notes frontmatter is untouched, distinguishing it from siblings like append_note and patch_frontmatter.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Conveys that it is for targeted, non-rewriting edits and excludes frontmatter, which gives helpful context for choosing this tool. However, it does not name specific alternatives or provide explicit when-to-use/when-not-to-use guidance beyond these implications.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_notesA
Read-only

Structured metadata query — filter notes by frontmatter key/value predicates, tag, folder, modified time, and size. Returns compact rows (path + title by default; opt into more via select), not note content. Use this instead of search when filtering by properties rather than text.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagNoRestrict to notes with this tag (# optional).
sortNoSort field (default path).
limitNoMax results (1–500, default 100).
orderNoSort order (default asc).
whereNoFrontmatter predicates — all must match (AND).
folderNoRestrict to a vault-relative folder prefix.
selectNoExtra fields per hit: frontmatter keys, or "mtime", "size", "tags". Default returns only path + title.
maxSizeBytesNoOnly notes at most this many bytes.
minSizeBytesNoOnly notes at least this many bytes.
modifiedAfterNoOnly notes modified at or after this ISO 8601 date/time.
modifiedBeforeNoOnly notes modified before this ISO 8601 date/time.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnlyHint=true, so the description correctly adds no mutation warnings and instead discloses a non-obvious behavioral contract: results are compact rows (path + title by default, extensible via select) and never the note content itself. This materially changes what an agent expects to receive and is not stated in the annotations. The only missing behavioral context would be pagination/size caps beyond the schema limit parameter, but the schema already covers that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each earning its place: scope definition, return-format contract, and sibling routing. The most distinguishing trait (metadata vs content) is front-loaded, and nothing is wasted restating annotations or schema defaults. It is unusually economical for a tool with 11 parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter read-only tool with a 100%-covered schema, the description covers purpose, filter dimensions, result shape, and the main sibling alternative; the output-schema absence is compensated for by the explicit 'returns compact rows, not note content' statement. The only marginal gap is that it doesn't mention distinguishing siblings like list_notes or get_tags, and the sort/select defaults are left to the schema. An example 'where' predicate would be nice but is not a genuine completeness gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema documentation covers 100% of the 11 parameters, each with a meaningful description, including defaults for select and sort and the AND semantics of where. The description only echoes the filter axes (tag, folder, modified time, size) and the select default, with no syntax or format details that the schema lacks. Per the high-coverage baseline, the description adds no real param-value meaning, so a 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Structured metadata query') and enumerates the exact filter dimensions: frontmatter key/value predicates, tag, folder, modified time, and size. It also distinguishes itself by declaring that it returns compact rows rather than note content, which clearly separates it from content-returning siblings like read_note and search. An agent can tell what this does and is not without reading any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The final sentence explicitly routes usage: 'Use this instead of search when filtering by properties rather than text.' It names the alternative sibling and gives the classification condition, effectively covering both the when (property-based filtering) and the when-not (text-based filtering). This is explicit routing guidance, not just implied context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_noteA
Read-only

Read a note or a span of it — by heading section, block reference, or line range. Returns structured JSON with the content, bytes returned, total note size, and a contentHash to pass as prevHash to edit tools for compare-and-swap. Use search or outline_note first to find the right path and section names.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path, e.g. "Daily Notes/2026-05-29.md".
blockNoReturn only the line anchored by this block id (^ prefix optional).
linesNoReturn only this line range (1-indexed, inclusive).
sectionNoReturn only this heading section (heading text, # prefix optional). First match wins.
includeFrontmatterNoPrepend frontmatter to section/block span results. Default false for spans.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description discloses the exact JSON return shape (content, bytes returned, total note size, contentHash) and the hash's purpose for compare-and-swap with edit tools. This behavioral context is not captured in annotations and is valuable for the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences: first states the operation and modes, second the return value, third the usage context. It is front-loaded with the core purpose and contains zero wasted words, making it efficiently structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 5 parameters, a nested object, and no output schema, the description covers the return structure, the purpose of contentHash, and the prerequisite discovery steps. An agent has everything needed to call the tool correctly and understand its output without ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully describes all five parameters (100% coverage), so the description adds no extra parameter meaning. The mention of block reference and line range merely echoes schema descriptions; no new semantics are introduced, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (read) and resource (note or span), enumerates three selection modes (heading section, block reference, line range), and distinguishes it from siblings like outline_note and search by its read-only content-return focus. The purpose is unambiguous and the description clearly differentiates the tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent to use search or outline_note first to find the path and section names, and explains the contentHash is to pass as prevHash to edit tools for compare-and-swap. This provides clear when-to-use guidance and ordering, effectively routing the agent to the correct prerequisite tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rename_headingA
Destructive

Rename a heading in a note and rewrite every [[note#heading]] wikilink and embed across the vault so references keep working — aliases preserved, fenced code blocks left alone. Served from the warm backlink index, no vault scan. Heading matching is case-insensitive; with duplicate headings the first match wins, mirroring Obsidian link resolution.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path of the note containing the heading.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.
newHeadingYesNew heading text, without # markers. Must not contain newlines, "[", "]", "|", or "#".
oldHeadingYesCurrent heading text, without # markers. Case-insensitive; first match wins.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite having annotations, it adds valuable context about case-insensitivity, first-match-wins on duplicates, and skipping code blocks. It doesn't contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences pack a lot of precise information: what it does, how it works (warm backlink index), and key edge-case behaviors. No fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a rename operation, it covers the mutation, the link rewriting, the index source, and important resolution semantics. It could elaborate on return values, but the description is comprehensive for typical usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage, the schema already documents each parameter. The description adds value by explaining the exact behavior of heading matching and what happens with the prevHash guard.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it renames a heading and rewrites links and embeds across the vault, which distinguishes it from simple rename or edit tools. It mentions specific behavioral nuances like alias preservation and ignoring fenced code blocks.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies this tool is for renaming headings specifically, not for other edits, and mentions how it handles duplicate headings. It doesn't explicitly mention alternative tools, but the context is clear for when to use this over a generic edit tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

replace_in_noteA
Destructive

Find and replace text within a note body. Supports literal and regex search, case sensitivity, whole-word matching, and a replacement limit. Frontmatter is never touched. Use dryRun to preview matches before writing.

ParametersJSON Schema
NameRequiredDescriptionDefault
findYesText or pattern to find.
pathYesVault-relative path to the note.
limitNoMaximum number of replacements. Omit to replace all.
regexNoTreat find as a regular expression. Default false.
dryRunNoIf true, report matches without writing. Default false.
replaceYesReplacement text. Supports $1, $2, … backreferences in regex mode.
prevHashNoOptional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.
wholeWordNoMatch whole words only (\b boundary). Default false.
caseSensitiveNoCase-sensitive matching. Default false.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and readOnlyHint=false, so the write nature is known. The description adds valuable behavioral context beyond that: it clarifies that frontmatter is never affected (scope of mutation) and recommends dryRun for previewing. It does not discuss failure modes like hash_conflict, but the schema documents that, and the bar is lower given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. The core purpose is front-loaded, and the supporting details (feature list, frontmatter exclusion, dryRun tip) follow in a logical order. Every sentence earns its place, and nothing is redundant with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 9 parameters and no output schema, the description could do more to explain return values or error conditions. It does not mention what the tool returns on success (e.g., count of replacements, updated content) or how it reports failures like hash_conflict or note-not-found. The schema and annotations cover some aspects, but the lack of output guidance leaves a gap for a mutation tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 9 parameters are individually documented. The description adds only a high-level summary of capabilities ('Supports literal and regex search, case sensitivity, whole-word matching, and a replacement limit') and a tip about dryRun, but this does not meaningfully augment the schema, which already explains each parameter's semantics. Thus, baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource and action: 'Find and replace text within a note body.' It goes beyond a simple verb by listing supported features (literal/regex, case sensitivity, whole-word, limit) and explicitly excludes frontmatter, which distinguishes it from sibling tools like patch_frontmatter or append_note. An agent can immediately understand what it does without needing to inspect the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: it is for body text replacement, and explicitly states 'Frontmatter is never touched,' which serves as a when-not-to-use boundary. It also advises using dryRun to preview before writing, which is a concrete usage tip. However, it does not name any alternative sibling tools, so it stops short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

undo_writeA
Destructive

Revert a journaled write: restores every file it touched to its byte-identical pre-write state (a multi-file move or heading rename is restored whole; a delete is restored even if it was permanent). Defaults to the most recent undoable write. Refuses with undo_conflict if a file changed since that write, unless force: true. The undo is itself journaled — undo it to redo.

ParametersJSON Schema
NameRequiredDescriptionDefault
seqNoJournal entry to revert (from list_writes). Defaults to the most recent undoable write.
forceNoRestore even if a file changed after the journaled write; the clobbered state is journaled first so nothing is lost. Defaults to false.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, and the description adds substantial behavioral detail beyond that: byte-identical restoration, whole-operation restoration for multi-file changes, handling of permanent deletes, the undo_conflict guard, the effect of force, and the fact that the undo is itself journaled and can be undone to redo. This is exemplary disclosure of side effects and edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence carries necessary information, and key facts are front-loaded: what the tool does, how it handles tricky cases, then defaults and conflict behavior. Despite covering complex semantics, the description remains compact and well-ordered with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that there is no output schema, the description still tells the agent everything needed to invoke the tool correctly: default target, failure mode, force escape hatch, permanent-delete restoration, and redo possibility. The reference to list_writes in the schema completes the workflow context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description reinforces the schema's default behavior for seq and explains the force semantics, but it does not add significantly new parameter-level information beyond what the input schema already provides. The description's added value is mostly behavioral, not parameter-specific.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Revert a journaled write' and precisely defines the effect ('restores every file it touched to its byte-identical pre-write state'). It also distinguishes the tool's scope by giving concrete examples like multi-file moves, heading renames, and permanent deletes, leaving no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational guidance: it defaults to the most recent undoable write, explains the undo_conflict refusal condition, and clarifies how force:true changes the behavior. While it does not explicitly state 'use list_writes to find a seq,' the schema parameter references list_writes, and there is no competing sibling tool for undo operations, so the context is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.3.22
    • Addedlist_writes
    • Addedundo_write
  2. 1 tool updatev0.3.19
    • Changedsearch1 field changed
      • addedInput schema / properties / excerptLength
        Added value: +{
        +  "description": "Max characters of match context per hit (20–2000, default 120).",
        +  "type": "number"
        +}
  3. 3 tool updatesv0.3.18
    • Changeddelete_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since — so you never delete content you have not seen.",
        +  "type": "string"
        +}
    • Changedmove_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard on the source note: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
    • Changedsearch1 field changed
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "lexical = keyword search (default). semantic = meaning-based search (requires SEEKSTONE_SEMANTIC=1). hybrid = exact-title lookups go lexical, everything else semantic.",
        +  "enum": [
        +    "lexical",
        +    "semantic",
        +    "hybrid"
        +  ],
        +  "type": "string"
        +}
  4. 2 tool updatesv0.3.17
    • Addedcontext_pack
    • Addedrename_heading
  5. 7 tool updatesv0.3.16
    • Changedappend_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
    • Changedappend_periodic_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
    • Changedcreate_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
    • Changeddelete_note1 field changed
      • addedInput schema / properties / permanent
        Added value: +{
        +  "description": "Permanently remove instead of moving to .trash/. Defaults to false.",
        +  "type": "boolean"
        +}
    • Changedpatch_frontmatter1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
    • Changedpatch_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
    • Changedreplace_in_note1 field changed
      • addedInput schema / properties / prevHash
        Added value: +{
        +  "description": "Optional compare-and-swap guard: the contentHash from a prior read. Fails with hash_conflict if the note changed since.",
        +  "type": "string"
        +}
  6. 1 tool updatev0.3.15
    • Changedmove_note1 field changed
      • addedInput schema / properties / rewriteLinks
        Added value: +{
        +  "description": "Rewrite references in other notes to follow the move. Defaults to true; pass false to move the file only.",
        +  "type": "boolean"
        +}
  7. 1 tool updatev0.3.13
    • Addedquery_notes
  8. 2 tool updatesv0.3.8
    • Addedappend_periodic_note
    • Addedget_periodic_note
  9. 1 tool updatev0.3.7
    • Addedreplace_in_note

TDQS

A3.9/5.0

Scored across 21 tools

Disambiguation4/5

Most tools have clearly distinct purposes — search vs. query_notes vs. list_notes are separated by text, metadata, and folder/tag listing, and the edit tools are differentiated by scope. A few pairs like list_notes/query_notes and append_note/patch_note/replace_in_note could require careful reading, but the descriptions mostly resolve the ambiguity.

Naming Consistency4/5

The set largely follows a verb_noun snake_case convention: get_*, list_*, append_*, patch_*, and create/delete/move/rename are all predictable. Exceptions like search, context_pack, and replace_in_note introduce minor inconsistency but do not undermine readability.

Tool Count4/5

21 tools is on the heavier side, but the count is justified by the broad scope of vault operations: searching, reading, linking, editing, periodic notes, and undo/journaling. Each tool has a real job, so the set feels comprehensive rather than padded.

Completeness5/5

The surface covers the full note lifecycle — create, read, update via multiple surgical edit tools, delete, move, rename, search, metadata querying, link management, periodic notes, and journaled undo. No critical dead ends or obvious missing operations are apparent for an Obsidian-style note vault.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

Appeared in Searches