markdown-vault-mcp
The markdown-vault-mcp server turns a directory of Markdown files into a searchable, editable knowledge base accessible to LLMs via the Model Context Protocol. It provides 33 tools, 9 resources, and 7 prompt templates covering:
Search & Discovery
Full-text search (SQLite FTS5/BM25), semantic vector search (FastEmbed, Ollama, or OpenAI), and hybrid search via Reciprocal Rank Fusion
Filter by frontmatter fields, restrict to folder subtrees, find semantically similar notes, and retrieve recently modified notes
Reading & Navigation
Read full documents or specific sections by heading, list documents/folders/tags, get a table of contents for a note or folder subtree, and read attachments (PDFs, images, etc.) as base64
Link Graph Analysis
Find backlinks, outlinks, broken links, orphan notes, hub notes (most-linked), and shortest connection paths between notes
Get a full context dossier for a note (backlinks, outlinks, similar notes, folder peers, tags)
Write Operations (when not read-only)
Create, edit (by text replacement or line range), delete, rename/move documents and attachments with optional backlink rewriting
Move entire folder subtrees with automatic link updates; download a URL and save as a note
Indexing & Embeddings
Incremental reindexing, build/rebuild vector embeddings, check index and embedding status, filesystem watcher for external changes
Git Integration
View commit history and diffs, force git pull/push, optional auto-commit/push on write
Deployment & Auth
Deploy as a Python library, CLI, Docker, Linux package, Claude Desktop, or Claude Code plugin
Secure with OIDC or static bearer token auth; mint one-time download/upload URLs
Visual UI (MCP Apps clients)
Interactive vault browser with file tree, link graph, note preview, and context card
Integrate with Authelia for OIDC authentication to secure HTTP deployments of the MCP server.
Automatically commit and push changes to a Git repository on every write operation, with manual sync tools available.
Integrate with Keycloak for OIDC authentication to secure HTTP deployments of the MCP server.
Interact with an Obsidian vault: search, read, write, edit, and organize Markdown notes with full-text and semantic search, frontmatter-aware indexing, and attachment support.
Use Ollama for local embedding generation to enable semantic vector search across the vault.
Use OpenAI's API for embedding generation to enable semantic vector search across the vault.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@markdown-vault-mcpsearch for meeting notes about project planning"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Markdown Vault MCP
Generic markdown vault MCP with hybrid search
Documentation | Config wizard | PyPI | Docker
Features
Hybrid search: SQLite FTS5 keyword search (BM25, porter stemming) and semantic search (FastEmbed, Ollama, OpenAI, or Voyage AI embeddings, plus any OpenAI-compatible endpoint via
OPENAI_BASE_URL), fused with Reciprocal Rank Fusion; diversity-aware ranking returns sentence-scale snippets with full-section recovery viaread(path, section=heading). See the Embeddings guide, including the recipe for OpenAI-compatible endpoints.Frontmatter-aware indexing: YAML frontmatter fields become filterable and searchable, with optional required-field enforcement and adaptive heading-level chunking for long documents.
Write operations: the write tools (
write,edit,append,delete,rename,move_folder,fetch,git_sync, theokf_*tools,create_upload_link) are registered by default and hidden whenMARKDOWN_VAULT_MCP_READ_ONLY=true; writes update the index automatically, per-folder_conventions.mdauthoring rules are surfaced to LLM clients at write time, and attachments (PDFs, images, and other non-markdown files) are read/write too.Incremental reindexing: hash-based change detection with boot-time reconciliation; the vector index converges to the reconciled chunk set, and parse-pipeline upgrades rebuild the index once automatically.
Git integration: optional auto-commit on every write with deferred push, a pull loop or GitHub webhook for external changes, and git history/diff tools. See the Git integration guide.
OKF-aware: recognizes Open Knowledge Format bundles and annotates results with each note's type, lifecycle status, staleness, and trust tier, plus conformance audit and migration tooling. See the OKF guide.
MCP surface: 34 LLM-visible tools, 9 resources, and 8 prompt templates, plus browser-based MCP Apps views and one-time transfer links. Full references: Tools, Resources, Prompts, MCP Apps, Transfer links, CLI.
Related MCP server: kmd
What you can do with it
With this server mounted in Claude, you can:
Capture a URL as a note. "Fetch , summarize as a Resource note under
3-Resources/, and link any existing notes on the topic." Claude composesfetch+search+write.Research a topic into your vault. "Research product security regulations, compare them, and create a set of interlinked notes: one per regulation, plus a map-of-content." Claude composes web-search tools (client-side) +
writewith wikilinks. See the Research workflows guide for the full loop.Distill today's thinking. "Summarize today's conversations into Inbox notes." Claude.ai only; uses
conversation_search+recent_chats+write. Thepara-capture-chatsprompt is the one-click version.Find missing links. Fire the
propose-linksprompt from the+menu: it scans recently modified notes and proposes links between notes that aren't yet connected, writing them on confirmation.Split or merge captures. "Split this Inbox note into two." / "Merge this into
<existing note>instead of duplicating." Claude composesread+write+delete.
The vault needs no external scheduler or separate capture app: it sits behind your conversations and absorbs their output.
Installation
From PyPI
pip install markdown-vault-mcpIf you add optional extras via the PROJECT-EXTRAS-START / PROJECT-EXTRAS-END sentinels in pyproject.toml, document them below:
pip install markdown-vault-mcp[mcp] # FastMCP server
pip install markdown-vault-mcp[embeddings-api] # Ollama/OpenAI embeddings via API
pip install markdown-vault-mcp[embeddings] # FastEmbed local embeddings
pip install markdown-vault-mcp[file-watcher] # watchdog-based external-change watcher
pip install markdown-vault-mcp[all] # MCP + FastEmbed + API embeddingsFor the Claude Code plugin channel (/plugin install markdown-vault-mcp@pvliesdonk) and all other install routes, see the Installation guide and the Claude Code plugin guide.
From source
git clone https://github.com/pvliesdonk/markdown-vault-mcp.git
cd markdown-vault-mcp
uv sync --all-extras --all-groupsDocker
docker pull ghcr.io/pvliesdonk/markdown-vault-mcp:latestTo run the newest merged code instead of the newest release, use the rolling edge tag. It is rebuilt on every merge to main and carries no version identity. See Image tags for the full tag list.
docker pull ghcr.io/pvliesdonk/markdown-vault-mcp:edgeA compose.yml ships at the repo root as a starting point. Copy .env.example to .env, edit, and docker compose up -d.
To attach a remote Python debugger (development only; the protocol is unauthenticated), see Remote debugging.
Linux packages (.deb / .rpm)
Download .deb or .rpm packages from the GitHub Releases page. Both install a hardened systemd unit; env configuration is sourced from /etc/markdown-vault-mcp/env (copy from the shipped /etc/markdown-vault-mcp/env.example).
Claude Desktop (.mcpb bundle)
Download the .mcpb bundle from the GitHub Releases page and double-click to install, or run:
mcpb install markdown-vault-mcp-<version>.mcpbClaude Desktop prompts for required env vars via a GUI wizard, with no manual JSON editing needed.
For manual Claude Desktop configuration and setup options, see Claude Desktop deployment.
Release channels
Artifacts ship on three channels. Each row lists exactly what that channel publishes.
Channel | Version identity | Artifacts |
| None; the commit is the identity | Docker image |
Pre-release |
| PyPI (as the pre-release |
Stable |
| Everything: PyPI, Docker (version tag plus ordering-aware |
Pre-releases reach PyPI so that a candidate's .mcpb bundle installs: the bundle points at PyPI rather than carrying the code. Ordinary installers never see them, because a PEP 440 resolver skips pre-releases unless the requirement pins one or you pass --pre. Ask for a candidate by name with pip install markdown-vault-mcp==X.Y.ZrcN. PyPI spells it in the PEP 440 canonical form, while tags use SemVer. Rolling pointers are ordering-aware, so a patch release cut from an old release/X.Y branch never moves latest-style tags back to older content, and a candidate for an already-released version never moves rc. See Release process for the full model.
Quick start
markdown-vault-mcp serve # stdio transport
markdown-vault-mcp serve --transport http --port 8000 # streamable HTTPFor library usage (embedding the domain logic without the MCP transport), import from the markdown_vault_mcp package directly. See the project's domain modules under src/markdown_vault_mcp/ for entry points.
Server info
The server registers a built-in get_server_info tool (via fastmcp_pvl_core.register_server_info_tool) so operators can confirm the deployed version with a single MCP call. The default response carries server_name, server_version, and core_version. Servers that talk to a remote upstream wire upstream version reporting inside the DOMAIN-UPSTREAM-START / DOMAIN-UPSTREAM-END sentinel in src/markdown_vault_mcp/server.py; see tool-registration for the wiring pattern.
Configuration
Core environment variables shared across all fastmcp-pvl-core-based services:
Variable | Default | Description |
|
| Persistent-state backend URL shared by every pvl-core subsystem that needs state. |
|
| Log level for FastMCP internals and app loggers (DEBUG / INFO / WARNING / ERROR / CRITICAL). The -v CLI flag overrides to DEBUG. |
|
| Set false for plain or structured JSON log output. |
Domain-specific variables go below under Domain configuration.
Authentication
Callers authenticate via a bearer token or OIDC (mutually exclusive). See the Authentication guide for setup, mapped multi-subject tokens, OIDC, and troubleshooting.
Post-scaffold checklist
After copier copy and gh repo create --push:
Fill in the DOMAIN blocks (every section marked with a
DOMAINsentinel comment) in this README and inAGENTS.md. TheGENERATED-ENV-TABLE-*regions are not DOMAIN blocks; the config generator owns them and rewrites them on every run.Configure GitHub secrets (see below).
Install dev + docs tooling:
uv sync --all-extras --all-groups.Install pre-commit hooks:
uv run pre-commit install.Run the gate locally:
uv run pytest -x -q && uv run ruff check --fix . && uv run ruff format . && uv run mypy src/ tests/.Push the first commit. CI should be green.
GitHub secrets
CI workflows reference two required repository secrets and one optional Claude token. Configure them via Settings → Secrets and variables → Actions or with gh secret set:
Secret | Used by | How to generate |
|
| Fine-grained PAT at https://github.com/settings/personal-access-tokens/new with |
|
| https://codecov.io: sign in with GitHub and add the repo. The upload token is on its settings page. |
|
| Optional. Run |
gh secret set RELEASE_TOKEN
gh secret set CODECOV_TOKEN
# Optional: enables @claude and opted-in automatic review.
gh secret set CLAUDE_CODE_OAUTH_TOKENDependency updates are handled by Renovate (
renovate.yml), which reusesRELEASE_TOKEN. It maintainsuv.lockand auto-merges patch/minor bumps once theCI Successcheck is green;bootstrap.ymlenables auto-merge and applies the repository rulesets (.github/rulesets/) on first push. See Repository Protection for the per-branch posture and bypass model. GitHub Actions are updated in the copier template and arrive viacopier update, not per-repo.
GITHUB_TOKEN is auto-provided; no action needed.
Local development
The PR gate (matches CI):
uv run pytest -x -q # tests
uv run ruff check --fix . && uv run ruff format . # lint + format
uv run mypy src/ tests/ # type-checkPre-commit runs a subset of the gate on each commit; see .pre-commit-config.yaml for details, or AGENTS.md for the full Hard PR Acceptance Gates.
Troubleshooting
Moving a scaffolded project
uv sync creates .venv/bin/* scripts with absolute shebangs pointing at the venv Python. If you move the repo after scaffolding (mv /old/path /new/path), uv run pytest fails with ModuleNotFoundError: No module named 'fastmcp' because the stale shebang resolves to a different interpreter than the venv's site-packages.
Fix:
rm -rf .venv
uv sync --all-extras --all-groupsuv run python -m pytest also works as a one-shot workaround (bypasses the stale entry-script shim).
uv.lock refresh after copier update
When copier update introduces new dependencies (such as a new extra added to pyproject.toml.jinja), the CI install step runs uv sync --locked, which fails against a stale lockfile. Run uv lock locally and commit the refreshed uv.lock alongside accepting the copier-update PR.
CI installs with --locked (and the review workflow with --frozen) so no job ever rewrites uv.lock in its own workspace: a job that re-locks hides the drift it just repaired, and a dirty workspace breaks any later git checkout in the same job. Lockfile drift then shows up as a red install step with a clear message, not as a silent mutation.
Contributing
CONTRIBUTING.md holds the rules for issues and pull requests, and where a
fix belongs: fastmcp-pvl-core for library code, the template for
template-owned files, this repository for anything inside its DOMAIN-* /
CONFIG-* / PROJECT-* blocks. AGENTS.md carries the conventions and
gates; the skills under .agents/skills/ carry the task procedures, among
them code-review (local self-review before a pull request),
writing-release-notes (release notes),
applying-template-updates (the weekly template update pull request) and
authoring-issues-prs (filing). The release procedure is in
docs/deployment/release-process.md;
the template update procedure in
docs/deployment/template-updates.md.
Links
Domain configuration
Domain environment variables use the MARKDOWN_VAULT_MCP_ prefix:
Variable | Default | Required | Description |
|
| No | Ollama server URL for the ollama embedding provider. Bare (not MARKDOWN_VAULT_MCP_-prefixed), matching the Ollama ecosystem convention. |
| (none) | No | OpenAI API key for the openai embedding provider, and the fallback key for the summarize tool when MARKDOWN_VAULT_MCP_SUMMARIZE_OPENAI_API_KEY is unset. Bare (not MARKDOWN_VAULT_MCP_-prefixed), matching the OpenAI ecosystem convention. |
| (none) | No | Voyage AI API key for the voyage embedding provider. Bare (not MARKDOWN_VAULT_MCP_-prefixed), matching the OPENAI_API_KEY / OLLAMA_HOST convention. Setting it never auto-selects the provider; choose it explicitly with MARKDOWN_VAULT_MCP_EMBEDDING_PROVIDER=voyage. |
| (none) | No | Bare fallback for MARKDOWN_VAULT_MCP_OPENAI_BASE_URL (embeddings). For the summarize tool it only routes traffic when an API key already enables the feature; it never enables summarize by itself. |
| (none) | No | Bare fallback for MARKDOWN_VAULT_MCP_OPENAI_EMBEDDING_MODEL. |
|
| No | Maximum seconds an index-backed tool or resource waits for the FTS index to become queryable during a cold-start background build before raising IndexUnavailableError(reason="timeout"). Increase for large vaults. |
|
| No | Maximum seconds an index-querying read tool waits for the IndexWriter to drain when called with wait_for_pending_writes=true. On timeout the tool answers from the current index and reports index_stale=true in the response _meta. |
|
| No | Path to the markdown vault directory. Required; the server refuses to start without it. Symbolic links inside the vault are followed on Python 3.13+. |
|
| No | Set to true to hide the write tools (write, edit, append, delete, rename, move_folder, fetch, git_sync, the okf_* tools, create_upload_link) and serve a search-only vault. git_sync also needs managed git mode; create_upload_link needs an HTTP transport. |
|
| No | Set to true to refuse a write that would overwrite an existing file when no if_match etag is supplied. Deliberate replacement (read first, pass if_match) still works, and edit / append / delete / rename are unaffected. |
|
| No | Hide the MCP Apps UI tools (browse_vault, show_context) from the tool listing for clients that do not render MCP Apps panels. |
| (none) | No | Path to the SQLite FTS5 index file; unset keeps the index in memory. Set it for persistence across restarts. |
| (none) | No | Path to the change-tracking state file. Defaults to {SOURCE_DIR}/.markdown_vault_mcp/state.json. |
| (none) | No | Path to the numpy embeddings file; required to enable semantic search. |
| (none) | No | Comma-separated frontmatter fields promoted to the tag index for structured filtering. Changing it cold-rebuilds the index once on next startup; SEARCHABLE_FIELDS inherits this value when unset. |
| (none) | No | Comma-separated frontmatter fields required on every document; documents missing any are excluded from the index. |
| (none) | No | Comma-separated glob patterns excluded from scanning (.obsidian/,.trash/). |
|
| No | Frontmatter field used as the document title (falls back to title, the first H1, then the filename). Changing it cold-rebuilds the index once on next startup. |
| (none) | No | Comma-separated frontmatter fields whose text values become keyword-searchable and enrich first-chunk embeddings. Inherits INDEXED_FIELDS when unset; the sentinel none means filterable but not searchable. Changing it cold-rebuilds the index and re-embeds once on next startup. |
|
| No | Relative folder where note templates live (used by the create_from_template prompt). |
| (none) | No | Directory of .md prompt files that extend or override built-in prompts; a relative path is resolved against SOURCE_DIR. |
|
| No | Filename of the per-folder conventions files surfaced to clients at write time (bare .md filename without glob characters). Set to none to disable folder conventions. |
|
| No | OKF (Open Knowledge Format) read semantics. With auto (the default), read annotations switch on when the vault declares an OKF version in its root index.md. Use off to disable OKF semantics entirely, or on to force them for an undeclared vault. Annotations are read-only; write behavior is never affected. |
|
| No | OKF (Open Knowledge Format) enforced write layer. When true on an OKF-active vault, the server stamps generated provenance on each write and clears any verified attestation when a note's content changes. It also keeps each written folder's log.md and index.md current, and exposes the okf_verify tool. Requires OKF_MODE to be auto or on (a true value with OKF_MODE=off is a config error). Off by default. |
|
| No | How the okf_verify tool attributes a human review. This applies only when OKF_WRITE is on, which gates the tool. With elicit (the default), okf_verify asks the human to confirm the review through an MCP elicitation and records the attestation only on an affirmative reply. It fails closed when the client cannot elicit or the human declines, so a model that holds the human's token cannot self-attest. Use trust-auth to attribute to the authenticated caller with no confirmation (safe only when the sole caller is a human-driven UI), or off to hide the tool so attestation happens through external tooling. A non-default value with OKF_WRITE off is a config error. |
| (none) | No | Comma-separated allowed attachment extensions without the dot (such as pdf,png,jpg); use * to allow every non-markdown file. Unset selects the built-in allowlist. |
|
| No | Maximum attachment size in MB returned by read / accepted by write; 0 disables the limit. |
|
| No | Maximum bytes returned by a full-document read of a note; use |
|
| No | Mode used when a search call omits 'mode': auto, keyword, semantic, or hybrid. The default 'auto' picks hybrid when embeddings are configured and keyword when they are not. Pin 'keyword' to keep unqualified searches off the embedding provider (each hybrid or semantic search embeds the query, which costs an API call on a metered provider). A configured semantic/hybrid default also degrades to keyword without embeddings, so no setting can make a vault unsearchable; an explicit mode= argument is never downgraded. |
|
| No | Maximum chunks returned per document in search results. |
|
| No | Width of the snippet window (words) in search results; 0 returns full chunk content. |
|
| No | Down-weights longer chunks in ranking: score / (1 + alpha * log(chunk_count)). |
|
| No | Word cap per chunk; the adaptive chunker splits at deeper heading levels, then paragraph/word boundaries, to respect it. Match it to the embedding model's context. A reindex applies a new value. |
| (none) | No | Character cap enforced alongside MAX_CHUNK_WORDS to bound token-dense chunks. Unset derives min(1500, model context * 2.8). Set a positive value for an exact cap, or -1 to scale with the model's full context (can exhaust memory on long-context models). A reindex applies a new value. |
|
| No | Words of overlap between adjacent budget-split fragments of the same heading section (0 disables). A reindex applies a new value. |
| (none) | No | Folder-prefix score multipliers ( |
| (none) | No | Per-column BM25 weights ( |
| (none) | No | Embedding provider: openai, voyage, ollama, or fastembed. Unset auto-detects from the environment (never voyage). Any OpenAI-compatible endpoint works with openai plus OPENAI_BASE_URL; see the embeddings guide. |
|
| No | Ollama embedding model name. |
|
| No | Force Ollama to embed on CPU only. |
|
| No | Voyage AI embedding model name. |
|
| No | OpenAI-compatible API base URL for embeddings; the bare OPENAI_BASE_URL is honoured as a fallback. |
|
| No | OpenAI-compatible embedding model name; the bare OPENAI_EMBEDDING_MODEL is honoured as a fallback. |
|
| No | FastEmbed model name. |
| (none) | No | FastEmbed model cache directory (in Docker, stored under /data/state/fastembed). |
|
| No | Enrich embedding input with the note title, chunk heading, and (first chunk) searchable-field values. Flipping it re-embeds the whole vault once on next startup. |
|
| No | Per-request wall-clock budget in seconds for a single embedding HTTP call (OpenAI/Ollama). The local FastEmbed backend runs in-process with no network call and ignores this. CPU-only or large-model workloads may need 60-120 s; raise this if batches time out. |
|
| No | Number of chunks sent per embedding request. Smaller batches shorten each request (useful under a tight timeout on slow models) at the cost of more round-trips. |
| (none) | No | Token/password for HTTPS git auth; remotes must be HTTPS when set. |
| (none) | No | HTTPS remote URL for managed git mode: the server clones into an empty SOURCE_DIR on startup (or validates an existing origin) and enables the pull loop, auto-commit, and deferred push. |
|
| No | Username for HTTPS git auth prompts (x-access-token for GitHub, oauth2 for GitLab, the account name for Bitbucket). |
|
| No | Seconds between git fetch + fast-forward update attempts; 0 disables periodic pull. |
|
| No | Seconds of write-idle time before pushing; 0 pushes only on shutdown. |
|
| No | Git committer name for auto-commits; set this in Docker where git config user.name is empty. |
|
| No | Git committer email for auto-commits. |
| (none) | No | OIDC claim key used as the commit author name (such as name); overrides GIT_COMMIT_NAME per request when an OIDC token is present. The claim is resolved when the tool call arrives and carried to the background commit, so it applies on every write. |
| (none) | No | OIDC claim key used as the commit author email (such as email); overrides GIT_COMMIT_EMAIL per request when an OIDC token is present. Resolved and carried the same way as the name claim. |
|
| No | Run git lfs pull on startup to fetch LFS-tracked attachments; set to false for repos without LFS. |
|
| No | Watch the vault for external filesystem changes; auto-disabled when git pull or the webhook is active. Requires the file-watcher extra. |
|
| No | Seconds of quiet after the last filesystem event before reindexing. |
|
| No | Keep the non-recursive watch on the vault root; set false to register zero source-dir-rooted FSEvents streams (avoids repeated macOS access prompts on a home-rooted vault) at the cost of root-level files relying on scans. |
| (none) | No | Shared secret for the GitHub push-event webhook; when set, mounts POST /github-webhook on HTTP/SSE transports to trigger an immediate pull + reindex on push events. |
| (none) | No | Summarization backend (only openai is recognised). Unset auto-detects: the backend activates when credentials or an explicit endpoint are present. |
| (none) | No | API key for the OpenAI-compatible summarize endpoint; the bare OPENAI_API_KEY is honoured as a fallback. Unset works for keyless local endpoints (Ollama). |
| (none) | No | OpenAI-compatible endpoint base URL for the summarize tool; setting it enables the tool even without an API key. The bare OPENAI_BASE_URL routes traffic only when a key already enables the feature. |
|
| No | Chat model id used for summaries. |
|
| No | Upper bound on generated tokens per summarize call; on reasoning models this budget also covers internal reasoning tokens. |
|
| No | Cap on the number of notes summarised in one call (subtree expansion truncates to this many). |
|
| No | Aggregate cap on note characters sent to the model in one call; excess is truncated with a flag on the result. |
|
| No | Per-request wall-clock budget in seconds for a single summarize backend call; keep it below the MCP client's request timeout so the server-side error wins the race. |
|
| No | Link lifetime in seconds when the caller requests no explicit TTL. |
|
| No | Ceiling in seconds a caller-requested link TTL is clamped to. |
|
| No | Post-success grace window in seconds: a served token's TTL shrinks to this so a stalled transfer can retry within it. |
|
| No | Crashed-handler reclaim window in seconds for an in-flight reservation. |
|
| No | Maximum size in bytes of a single upload. |
|
| No | Seconds a long-running tool call may run in the foreground before it is promoted to a background job and a job handle is returned instead. |
|
| No | Seconds a background-job record (working or finished) is retained for polling before it expires from the store. |
|
| No | Maximum live background jobs per calling subject; further promotions are rejected until older records expire. |
Domain-config fields are composed inside src/markdown_vault_mcp/config.py between the CONFIG-FIELDS-START / CONFIG-FIELDS-END sentinels; env reads go through fastmcp_pvl_core.env(_ENV_PREFIX, "SUFFIX", default) so naming stays consistent, and field invariants go in __post_init__ between the CONFIG-VALIDATE-START / CONFIG-VALIDATE-END sentinels. Each field's metadata help and tags generate the table above directly, so keep them accurate and complete.
Key design decisions
Document identity is the relative path with
.mdextension; frontmatter is optional by default (REQUIRED_FIELDSopts into enforcement).Hybrid search uses Reciprocal Rank Fusion over the FTS5 and vector result lists, with diversity-aware ranking capping chunks per document.
Tool semantics mirror Claude Code's Read/Write/Edit patterns, so LLM clients drive the vault with habits they already have.
The library is synchronous; the MCP layer wraps calls in
asyncio.to_thread().Indexing is hash-based: unchanged files are never re-parsed, and any change to how stored rows derive from a note's bytes bumps
INDEX_SEMANTICS_VERSIONso deployed vaults rebuild themselves once on upgrade.
The full decision log lives in the design document.
Available Tools
38 toolsappendAppend to NoteA
Append text to the end of an existing .md note without reading it.
The cheapest way to add content at the end of a note (log entries, journal additions, checklist items): unlike 'edit', no prior 'read' is needed, so the existing note content never enters the context. Prefer this over 'edit' whenever the change is purely additive at the end of the note.
A newline is inserted between the existing content and the appended text when the file does not already end with one, so the appended text starts on its own line. Include leading blank lines or heading markers in 'content' yourself if you want a separating paragraph or section. The search index is updated immediately; do not call 'reindex' afterward.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path to the document (e.g. "Journal/2026.md"). | |
| content | Yes | Text to append (must be non-empty). Added at the end of the file, after frontmatter and all existing content. | |
| if_match | No | Optional etag obtained from a previous 'read' call. When provided, the append only proceeds if the file has not been modified since that read (optimistic concurrency). Omit to append unconditionally. | |
| create_if_missing | No | When true, a missing note is created with 'content' as its body instead of failing. Default false — a typo in 'path' fails loudly rather than silently creating a new note. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only convey basic hints, so the description carries the burden and succeeds. It discloses the automatic newline insertion behavior, the immediate index update, the unconditional behavior when if_match is omitted, and the failing-loudly behavior for missing files by default.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and the deciding factor (no read needed). Every sentence adds practical value—newline behavior, index updates, and avoid-reindex guidance—without redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich output schema and fully covered input schema, the description is complete. It answers the key operational questions an agent needs: when to use it, what happens to formatting, concurrency behavior, missing-file behavior, and post-call indexing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaningful behavior beyond the schema: how newlines are handled, that leading blank lines/heading markers are the caller's responsibility, and that a typo in path fails loudly rather than creating a note. This elevates it above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action (append text) on a specific resource (an existing .md note) with a precise location (end of the note). It also explicitly distinguishes itself from 'edit' by noting that no prior read is needed, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use guidance: use for purely additive at-end changes, prefer over 'edit' because it avoids loading the note into context. It also explicitly says not to call 'reindex' afterward, and explains the tradeoff of create_if_missing behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
browse_vaultBrowse VaultARead-onlyIdempotent
Open a visual vault explorer UI for the user — not for reading vault content.
Displays an interactive visual panel (MCP Apps) to the user so they can
browse the file tree, explore the link graph, or view a note's relationships.
Do NOT call this to retrieve or inspect vault content programmatically — use
search to find notes, read for note content, list_documents to
enumerate files, and get_context for a note's relationships instead.
Only call this when the user explicitly asks to open the visual vault browser or explorer (e.g. "show me the vault browser", "open the graph view").
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Optional note path to focus on (e.g. ``"Journal/2024-01-15.md"``). | |
| view | No | Which view to open: ``"context"`` (note relationships), ``"graph"`` (link visualization), ``"browse"`` (file tree), or ``"note"`` (full note preview). Defaults to ``"context"`` if a path is given, ``"browse"`` otherwise. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds context that the tool displays an interactive visual panel (MCP Apps) to the user, which is useful beyond annotations. However, it does not describe any additional behavioral aspects like permissions or side effects beyond what annotations imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: front-loaded with the purpose, followed by exclusions (what not to use for), and then when to call. Every sentence adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (opens a UI), the description covers purpose, usage guidelines, parameter hints, and has output schema present. No need to explain return values. It is fully complete for agent decision-making.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% description coverage, so the schema already documents both parameters. The description mentions optional note path and view types but does not add additional semantics beyond what is in the schema. Baseline of 3 is appropriate given high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool opens a visual vault explorer UI for the user, using specific verbs and resource. It explicitly distinguishes itself from sibling tools by stating it is not for reading content programmatically and lists alternative tools for different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage guidelines are explicit: only call when the user asks for the visual vault browser or explorer, and do NOT use for programmatic retrieval. Alternative tools (search, read, list_documents, get_context) are listed, providing clear when-to and when-not-to guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
build_embeddingsBuild EmbeddingsAIdempotent
Rebuild vector embeddings for semantic and hybrid search.
Embeddings are built automatically on startup, so this is normally not needed. Use force=True to rebuild from scratch after changing the embedding model. Without force, the vector index converges to the FTS chunk set: missing or changed documents are embedded, orphaned vectors are removed, unchanged chunks are untouched.
A fast convergence (small drift) returns its result inline. A build
still running at the server's soft deadline — typical for a
force=True rebuild of a large vault — continues in the background
and returns {"status": "working", "job_id": ...} immediately;
fetch the outcome with get_job_result. embeddings_status
remains the observability view of the vector index.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | When True, discards existing embeddings and rebuilds from scratch. Use only if the embedding model has changed. When False (default), converges the vector index to the FTS chunk set — work scales with the size of the drift, not the size of the vault (#665). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by detailing convergence behavior (missing/changed docs embedded, orphans removed, unchanged chunks untouched), inline vs. background execution, soft-deadline semantics, and the immediate return shape with status and job_id. The destructive nature of force=True is disclosed clearly, and nothing contradicts the idempotentHint or destructiveHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than typical, but every sentence carries distinct information: purpose, normal unnecessity, force semantics, convergence behavior, and background execution. It is front-loaded with the core action and progresses logically, though it could arguably be tightened by merging the convergence and background sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema, annotations, and sibling context, the description covers all essential operational aspects: when to call, what force does, return behavior, background continuation, and how to obtain the final result. An agent has enough information to invoke the tool correctly and handle both fast and slow builds.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the force parameter already has a detailed schema description. The tool description adds contextual meaning—explaining when force is appropriate and what happens without it—which reinforces the parameter semantics without repeating schema text verbatim.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states an explicit action and resource: 'Rebuild vector embeddings for semantic and hybrid search.' It clearly distinguishes the tool from siblings like embeddings_status (observability) and get_job_result (outcome fetching) by describing the rebuild action and background-job semantics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains that embeddings are built automatically on startup, so this tool is 'normally not needed,' and gives explicit guidance for when to use force=True (after changing the embedding model). It also references get_job_result and embeddings_status as alternatives for fetching outcomes and observing index state, though it does not provide an explicit when-not-to-use list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteDelete NoteADestructiveIdempotent
Permanently delete a document or attachment.
For .md documents: removes the file and immediately updates all search indices — do not call 'reindex' afterward. For attachments: only the file is deleted (no index to update). IRREVERSIBLE unless git history exists. Confirm the path with the user before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path to the document or attachment to delete. | |
| if_match | No | Optional etag obtained from a previous 'read' call. When provided, the deletion only proceeds if the file has not been modified since that read (optimistic concurrency). Omit to delete unconditionally. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (destructiveHint=true, readOnlyHint=false, idempotentHint=true), the description discloses critical behavior: irreversibility unless git history exists, immediate search-index updates for .md files, and no index update for attachments. This adds substantial context about side effects and recovery options. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four compact sentences: first states the action and object, then differentiates .md behavior from attachments, then gives irreversibility and confirmation warnings. No filler or repetition; the most important warning is placed last for emphasis.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive two-parameter tool with an output schema, the description covers what is deleted, index implications, what not to do afterward, irreversibility, and a user-confirmation requirement. Nothing essential is missing for an agent to invoke this tool safely and correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so path and if_match are already fully documented in the input schema. The description adds only user-confirmation guidance about the path, which is more of a usage rule than parameter semantics. Baseline 3 is appropriate when structured schema handles parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Permanently delete a document or attachment.' This clearly distinguishes it from sibling tools like read, write, edit, append, and rename by naming the destructive action and the object types. The title 'Delete Note' further reinforces the tool's role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: after deleting .md files, 'do not call reindex afterward' — an instruction that prevents an unnecessary follow-up action. It also states a precondition that the path must be confirmed with the user before calling. It does not explicitly name alternative tools, but the destructive-purpose distinction is clear among the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
editEdit NoteA
Make a targeted text replacement in an existing .md note (not supported for attachments).
Three edit modes:
Exact match (old_text only): pass a portion of the file as old_text — must appear exactly once. Frontmatter can be edited.
Line-range (line_start + line_end, no old_text): replace the specified lines with new_text. Lines are 1-based (matching 'read' output). Recommended: pass if_match for safety.
Scoped match (old_text + line_start/line_end): search for old_text within the line range only — useful when old_text appears multiple times in the file.
When exact match fails, a normalized comparison is attempted (Unicode NFC, dash/quote normalization, whitespace collapsing). If a unique normalized match is found, it is used and match_type='normalized' is returned.
Always call 'read' first to get the current text and line numbers. The search index is updated immediately; do not call 'reindex'.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path to the document. | |
| if_match | No | Optional etag obtained from a previous 'read' call. When provided, the edit only proceeds if the file has not been modified since that read (optimistic concurrency). | |
| line_end | No | Last line to replace (1-based, inclusive). Must be provided together with line_start. | |
| new_text | No | Replacement text. May be longer or shorter. | |
| old_text | No | Text to replace. Must appear exactly once in the document or line range. Get this via 'read'. Optional when using line-range mode. | |
| line_start | No | First line to replace (1-based, inclusive). Must be provided together with line_end. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state readOnly=false, idempotent=false, destructive=false. The description adds substantial behavioral context beyond this: frontmatter is editable, line numbers are 1-based, normalized Unicode/comparison fallback may apply, match_type='normalized' can be returned, if_match provides optimistic concurrency, and the search index updates immediately. This is exactly the kind of operational detail an agent needs to avoid surprising edits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but efficiently structured: a one-sentence summary, a compact bulleted mode list, a normalization note, and workflow guidance. Every section earns its place, and the most important scoping information is front-loaded. Nothing is redundant with the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given six parameters, three modes, normalization behavior, and concurrency control, the description is remarkably complete. It tells the agent how to select modes, how to prepare with 'read', how to stay safe with if_match, and what to expect regarding index updates. An output schema exists, so it is acceptable that return details are not spelled out in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds real value by organizing old_text, line_start, line_end, and new_text into three named modes and explaining valid combinations, uniqueness constraints, and safety recommendations. It does not merely restate the schema; it clarifies how the parameters interact, which is meaningful beyond the property-level descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Make a targeted text replacement in an existing .md note.' It clearly distinguishes this from sibling tools by noting it applies to existing notes, not attachments, and by defining three concrete replacement modes. An agent can immediately tell this is the in-place modification tool rather than write, append, or delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit mode-selection guidance: exact match when text appears once, line-range for replacing by line numbers, and scoped match when old_text appears multiple times. It also says to call 'read' first and not to call 'reindex.' However, it does not explicitly contrast this tool with write/append/delete for creation or additive changes, so the broader sibling-tool selection guidance is slightly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
embeddings_statusEmbeddings StatusARead-onlyIdempotent
Check the embedding provider configuration and vector index status.
Use this to diagnose why semantic search is unavailable. Embeddings are built automatically on startup when configured, so chunk_count should normally match the FTS chunk count from 'stats'. If it is lower, call 'build_embeddings' (without force) to embed the missing chunks. Use 'build_embeddings' with force=True only to rebuild from scratch after changing the embedding model.
Returns: Dict with the following fields:
- available (bool): True if semantic search can be used in 'search'.
- provider (str | None): Provider class name when configured
(e.g. "OllamaProvider"), or null if not configured.
- chunk_count (int): Number of chunks currently in the vector index.
- path (str | None): Vector index file path when persisted, or null.| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the agent knows it's a safe read. The description adds behavioral context: it checks configuration and status, and details the return fields (available, provider, chunk_count, path). It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two paragraphs: first paragraph focuses on usage guidance, second lists return fields. It is front-loaded with the main purpose, and every sentence provides necessary information. No redundant or vague statements.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema, the description fully explains the return fields and their semantic meaning. It covers the diagnostic use case and provides actionable guidance. It is complete for the tool's purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so the baseline is 4. The description adds value by explaining the output fields and their interpretation, which goes beyond the input schema (empty).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a clear verb and resource: 'Check the embedding provider configuration and vector index status.' It also specifies the use case: 'diagnose why semantic search is unavailable.' This distinguishes it from sibling tools like build_embeddings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('to diagnose why semantic search is unavailable') and provides guidance on interpreting the chunk_count field relative to the FTS chunk count from 'stats'. It also directs to call 'build_embeddings' (without force) if chunk_count is lower, and specifies when to use force=True. This provides clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetchFetch to VaultAIdempotent
Download a file from a URL and save it to the vault.
Fetches content from an HTTP/HTTPS URL and writes it as a note or attachment. Designed for MCP-to-MCP file transfer when content is too large to pass through the LLM context window.
Context cost: zero for the bytes themselves — the file is
downloaded server-side and saved to the vault. After a successful
fetch, reference the file by its path (call read(path) only
for small results, otherwise pass the path to other tools).
For .md paths: the response is decoded as UTF-8 text and saved as a markdown note with optional frontmatter. The search index is updated immediately.
For other paths: the response is saved as a binary attachment. The existing attachment size limit applies.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Source URL to download from. Only http:// and https:// schemes are allowed. SSRF protection (via pvl-core's hardened ``fetch_url``, #862): the host is resolved and rejected unless every address is publicly routable (private, loopback, link-local, CGNAT/shared, and reserved ranges are all blocked), the validated IP is pinned for the connection (closing DNS rebinding), and ambient HTTP(S)_PROXY / .netrc settings are ignored. Redirects ARE followed (changed in #1116; through v3.1.0 a redirect was refused), and every hop repeats the whole chain above — a ``Location`` pointing at an internal target is refused exactly as a directly supplied one is. Because of that, the bytes need not come from the host in *url*: check the returned ``final_url`` when the source host matters. | |
| path | Yes | Destination path in the vault (e.g. "notes/report.md" or "assets/diagram.png"). Extension determines handling: .md for notes, anything else for attachments. | |
| if_match | No | Optional etag from a previous 'read' call for optimistic concurrency. Omit to write unconditionally. | |
| timeout_s | No | Download timeout in seconds (default 30). Increase for large files on slow connections. | |
| frontmatter | No | Optional YAML frontmatter dict for .md files, e.g. {"title": "Report", "source": "http://..."}. Ignored for attachments. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses key behavioral traits: the download happens server-side so the bytes cost zero context, the search index is updated immediately for .md files, and non-.md files are saved as binary attachments subject to the existing size limit. It also clarifies that after a successful fetch the agent should use the returned path rather than expecting content in the response, which is genuinely useful behavior not covered by 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose, then moves to context cost, then to path-specific behavior, with each sentence earning its place. It is detailed but not redundant, and the use of short labeled paragraphs makes it easy for an agent to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 5-parameter schema with 100% coverage, the annotations, and the presence of an output schema, the description is complete: it covers the intended use case, when not to use read, how path determines handling, the zero-context-cost property, and the attached security-relevant redirect behavior in the URL parameter. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all parameters at 100% with detailed descriptions, so the baseline is 3. The tool description adds extra semantic value by explaining how the path extension changes the behavior (.md becomes UTF-8 markdown with frontmatter, other paths become binary attachments) and by clarifying the practical meaning of the path parameter in the post-fetch workflow.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair, 'Download a file from a URL and save it to the vault,' and immediately clarifies scope: HTTP/HTTPS URLs, saved as a note or attachment. This clearly differentiates it from sibling file-writing tools like write and edit, whose input would be literal content rather than a remote URL.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: for MCP-to-MCP file transfer when content is too large to pass through the LLM context window. It also gives post-fetch guidance, telling the agent to reference the file by path and to only call read(path) for small results, which is actionable and distinguishes the intended workflow from plain read/write usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_backlinksBacklinksARead-onlyIdempotent
Find all documents that link TO the given document (backlinks).
Use this to discover which notes reference a particular document. For a full picture of a note's place in the vault (backlinks, outlinks, similar notes, folder peers), use 'get_context' instead of calling this separately. Call 'get_backlinks' directly when you only need the inbound link list. Backlinks reveal implicit relationships that search alone cannot surface — they show what other authors considered relevant to this document.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path of the target document (e.g. "notes/topic.md"). Case-sensitive. | |
| limit | No | Maximum number of backlinks to return. Omitted (the default) returns all. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds meaningful behavioral context by explaining that the tool returns the set of documents linking to the target and frames backlinks as implicit relationships. It does not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and uses short, purposeful sentences. The final conceptual sentence about implicit relationships is slightly extra but helps the agent understand when the tool is valuable; overall it is efficient and well organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with rich annotations, a fully documented 3-parameter schema, and an output schema, the description is complete. It covers purpose, usage context, alternatives, and direct-call conditions without leaving operational gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents path, limit, and wait_for_pending_writes. The description does not add parameter-level detail beyond naming the 'given document' and 'inbound link list,' so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Find all documents that link TO the given document (backlinks).' It clearly distinguishes the tool from siblings by naming get_context and contrasting backlinks with the broader context set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to call this tool directly versus using get_context: 'For a full picture... use get_context instead... Call get_backlinks directly when you only need the inbound link list.' It also contrasts with search, explaining why backlinks add value search cannot.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_broken_linksBroken LinksARead-onlyIdempotent
Find all links that point to non-existent documents (broken links).
Use this to audit link health across the vault. Call this when 'stats' shows broken_link_count > 0, or after a 'rename' that did not use update_links=True, to see what links were left pointing to the old path. A broken link means the target path does not match any indexed document — the referenced note may have been deleted, renamed, or never created.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Optional folder filter. When provided, only checks links from documents in this folder (e.g. "Journal"). Use folder="" for root-level (top-level) documents only. Without this, checks all documents. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful domain context by explaining what a broken link means ('target path does not match any indexed document'), but it does not disclose additional behavioral details such as indexing freshness, rate limits, or output structure. This is adequate but not exceptional given 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, followed by clear usage guidance and a concise definition of a broken link. Every sentence contributes useful information, and there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With detailed parameter schemas, a present output schema, and annotations covering safety, the description adds the remaining important context: when to call it and what a broken link semantically means. There is no critical missing information for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters have detailed descriptions, including the wait_for_pending_writes behavior and index staleness handling. The tool description itself adds no new parameter semantics, so it relies on the schema, which already does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Find all links that point to non-existent documents (broken links).' This clearly identifies what the tool returns and is distinct from related link tools like get_backlinks, get_outlinks, and get_orphan_notes, even without naming them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit trigger conditions: 'Call this when stats shows broken_link_count > 0, or after a rename that did not use update_links=True.' It provides clear context for when the tool is appropriate, though it does not explicitly state when not to use it or name alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_connection_pathConnection PathARead-onlyIdempotent
Find the shortest connection path between two notes in the link graph.
Treats links as undirected — a link from A to B or B to A both count as a connection. Uses BFS; max_depth is clamped to [1, 10].
Useful for discovering how two seemingly unrelated notes are connected through the vault's link structure (the "six degrees of separation" for your notes).
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | Vault-relative path of the starting note (e.g. 'Ideas/spark.md'). | |
| target | Yes | Vault-relative path of the destination note. | |
| max_depth | No | Maximum number of hops to search. Default 10, max 10. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the mutation safety profile. The description adds meaningful behavioral detail beyond that: links are treated as undirected, the search uses BFS, and max_depth is clamped to [1, 10]. This gives the agent a solid model of how the search behaves.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the core purpose, the second adds algorithmic behavior, and the third provides a helpful use-case metaphor. Every sentence earns its place without redundancy or padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the annotations, fully documented parameters, and the presence of an output schema, the description covers the essential aspects: purpose, algorithm, edge-case clamping, and illustrative use case. It could be slightly stronger with explicit guidance on when to prefer it over direct-link tools, but nothing critical is missing 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.
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 adds extra semantic value by explaining the BFS algorithm and that max_depth is clamped to [1, 10], which is more specific than the schema's 'max 10' note. Source and target are already well documented in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Find the shortest connection path between two notes in the link graph.' This clearly distinguishes the tool from graph-related siblings like get_similar, get_backlinks, and get_outlinks by emphasizing shortest path between two notes rather than listing links or similar notes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: 'Useful for discovering how two seemingly unrelated notes are connected through the vault's link structure.' This tells the agent when to reach for this tool, though it does not explicitly mention alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_contextNote ContextARead-onlyIdempotent
Get a consolidated context dossier for a document.
Replaces separate calls to 'get_backlinks', 'get_outlinks', and 'get_similar' when you need more than one.
Returns everything useful about a note in one call: its metadata, backlinks (documents that link to it), outlinks (documents it links to), semantically similar notes, other notes in the same folder, and indexed frontmatter tags. Use this instead of making 4-5 separate tool calls when you need a full picture of a note's place in the vault.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path of the document (e.g. "notes/topic.md"). Case-sensitive. | |
| link_limit | No | Maximum number of backlinks and outlinks to include each (default 10). | |
| similar_limit | No | Maximum number of similar notes to include (default 5). Pass 0 to skip the similarity lookup — do this when 'stats' shows semantic_search_available=False (embeddings are not configured). | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds behavioral context by clarifying that this tool aggregates multiple lookups into one response and explicitly lists the categories of information returned, which goes beyond the annotations and helps the agent predict the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured, leading with the core purpose, then the relationship to siblings, then the concrete return contents. There is minor redundancy between "Replaces separate calls..." and "Use this instead of making 4-5 separate tool calls...," but the information density is high and each sentence adds relevant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for an agent's decision-making: it states what the tool returns, when to use it instead of alternatives, and the exact scope of the 'context' it provides. The input schema and output schema cover parameter details and return structure, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already well-documented in the input schema. The description itself adds no parameter-level detail beyond the schema, which matches the baseline expectation of 3 when the schema carries the explanatory burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: it "gets a consolidated context dossier for a document" and then enumerates exactly what that dossier contains (metadata, backlinks, outlinks, similar notes, same-folder notes, frontmatter tags). It also names the sibling tools it replaces, so an agent can distinguish it from get_backlinks, get_outlinks, and get_similar without opening their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: use get_context instead of making 4-5 separate calls when you need a full picture, and use it instead of get_backlinks, get_outlinks, and get_similar when more than one is needed. This directly tells the agent when to choose this tool over its siblings and when the consolidated call is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_conventionsFolder ConventionsARead-onlyIdempotent
Get the user's authoring conventions that apply to a note or folder.
Vaults may carry per-folder convention files (by default '_conventions.md') describing how notes in that folder should be authored — for example "reference material: keep notes self-contained; do not link out to project or journal notes". Conventions accumulate down the tree: a vault-root file applies everywhere and nested files add to it, so entries are returned root-first with the most specific guidance last.
Call this before creating, restructuring, or linking notes so the result follows the vault owner's rules. The write/edit tools also echo applicable conventions in their responses for a post-write compliance check. Reads directly from disk — works even while the search index is still building.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Relative note path (e.g. "3-Resources/topic.md") or folder path (e.g. "3-Resources"). A note path resolves to its parent folder. Pass "" (default) for discovery mode: vault-root conventions plus the full list of folders carrying convention files. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive. The description goes well beyond this by disclosing that conventions accumulate down the tree, are returned root-first with most specific last, load from a default '_conventions.md', and read directly from disk even while the search index is building. This is substantial behavioral context an agent could not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a one-sentence purpose and then layers in behavior, usage, and disk-read rationale. Each paragraph earns its place, though the example convention text is slightly verbose and could be trimmed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and rich annotations, the description covers what the tool does, when to call it, how results are ordered, and why it works during index building. It is nearly complete, but it does not explicitly address what happens when no convention file exists for a given path, leaving a minor edge case to the output schema or agent inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% parameter coverage, including path resolution to parent folder and the empty-string discovery mode. The description adds no parameter-level semantics beyond what the schema documents, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: "Get the user's authoring conventions that apply to a note or folder." It also gives a concrete example of what conventions contain, making the tool's purpose unmistakable and distinct from generic read or list operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear usage guidance is provided: "Call this before creating, restructuring, or linking notes so the result follows the vault owner's rules." It also mentions that write/edit tools echo conventions for post-write checks, giving useful contextual boundaries. It does not explicitly name alternative tools or conditions when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_diffNote DiffARead-onlyIdempotent
Return the diff of a note between a reference point and HEAD.
Only available for git-backed vaults. Exactly one of 'since_sha' or 'since_timestamp' must be provided. Use 'get_history' first to find commit SHAs.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-relative path of the note or attachment to diff (e.g. "notes/alpha.md" or "assets/diagram.png"). May be a `.md` note or a configured attachment extension (png, pdf, svg, …). A binary attachment returns a `--stat` size/rename summary instead of a full unified patch; a text attachment (e.g. `.svg`, `.csv`) returns a full unified diff. `.md` notes are unchanged. An unsupported extension is rejected. | |
| limit | No | When per_commit=True, cap the number of intervening commits returned to the `limit` most recent ones. Clamped to [1, 100]. Defaults to null (unbounded — still bounded by the underlying since..HEAD range). Ignored when per_commit=False. Useful for keeping per-commit responses within context budgets when auditing long histories. | |
| since_sha | No | A commit SHA (full or abbreviated, at least 4 hex digits) to diff from. Mutually exclusive with since_timestamp. | |
| per_commit | No | When False (default), return a single unified diff from the reference point to HEAD. When True, return one diff per intervening commit. | |
| since_timestamp | No | ISO 8601 datetime string, resolved via `git rev-list --before=<ts> -1 HEAD` to the most recent commit at or before that instant. Boundary is **inclusive**: a commit whose committer date equals since_timestamp IS the resolved ref. Mutually exclusive with since_sha. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint as true, so safety is clear. Description adds behavioral details: supported vault types, binary vs text handling, and the mutual exclusivity constraint. Could be slightly more detailed on return value shape, but helpful beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with core purpose, then conditions and advice. No redundant words or repetition. Efficient and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (indicated), rich input schema descriptions, and annotations, the description is complete. It covers prerequisites, parameter requirements, behavioral notes, and references related tools. No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for all 5 parameters. The description adds value by restating the mutual exclusivity of since_sha and since_timestamp and noting binary attachment behavior. While schema already covers details, the description reinforces key constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool returns the diff of a note between a reference point and HEAD. Distinguishes from siblings like 'get_history' (which returns commit history) and 'read' (which returns content). The resource and action are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states prerequisite ('only available for git-backed vaults'), parameter requirement ('exactly one of since_sha or since_timestamp'), and references sibling tool ('Use get_history first to find commit SHAs'). Provides clear when-to-use and when-not-to-use context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_historyNote HistoryARead-onlyIdempotent
List commits that touched a note, folder, or the whole vault.
Only available for git-backed vaults. Use 'stats' to check whether git is configured, or call this and handle the error.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Vault-relative path to filter on. A `.md` note or a configured attachment extension (png, pdf, svg, …) scopes to that single file (e.g. "notes/alpha.md", "assets/diagram.png"); an existing folder scopes to its subtree (e.g. "guides" returns commits touching guides/**). Omit (or pass null) for vault-wide commit history. | |
| limit | No | Maximum number of commits to return. Default 20, max 100. | |
| since | No | ISO 8601 datetime string ("2026-04-01T00:00:00") or a git date expression ("1 week ago"). Passed as --since to git log. Omit for full history. | |
| until | No | ISO 8601 datetime string or git date expression, passed as --until to git log. Both 'since' and 'until' boundaries are inclusive: a commit whose committer date equals either endpoint is included in the result. Omit to disable the upper bound. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already classify this as readOnly, idempotent, and non-destructive. The description adds a meaningful behavioral constraint: the tool only works on git-backed vaults and can raise an error otherwise, which is not inferable from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences deliver the purpose and the key precondition without redundancy. The core action is front-loaded, and the git prerequisite and stats fallback are presented immediately after.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema, detailed parameter docs, and annotations, the description covers the essential contextual gap—git dependency and error handling. An agent can decide whether to call it and what to do if the vault isn't git-backed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for path (vault-relative, file/folder subtree semantics), limit (default/max), and since/until (ISO 8601 or git expressions, inclusive boundaries). The description contributes no additional parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List commits that touched a note, folder, or the whole vault,' giving a specific verb and resource while scoping the operation to git-backed vaults. This clearly distinguishes it from content-reading siblings like read and search, and from diff/recent variants like get_diff and get_recent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the precondition (git-backed vault) and gives an actionable fallback: use 'stats' to check whether git is configured, or call this and handle the error. It does not enumerate alternatives, but the precondition provides a clear selection rule versus non-git history tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_index_statusIndex StatusARead-only
Return background-build state of the FTS index.
Use this when initialize returned but bucket-3/4 calls
block longer than expected or surface
IndexUnavailableError — the status field
distinguishes "still building" from "build failed," and the
error field carries the exception message from the last
background-build attempt that captured one. error may be
populated when status is "queryable" (a successful
build followed by a later failed rebuild leaves the captured
diagnostic in place until the next successful build clears
it) and is always None when status is "building".
Returns: Dict with the following fields:
- status (str): ``"queryable"``, ``"building"``, or
``"failed"``.
- documents_indexed (int): Count of documents committed to
the FTS index right now (rises during ``"building"``).
``0`` both for an empty index and when the count could not
be read — see ``documents_indexed_error`` to tell them apart.
- documents_indexed_error (str | None): ``None`` on a normal
read; the SQLite error message when the document count
could not be read (e.g. a locked or closed database), in
which case ``documents_indexed`` is ``0``.
- error (str | None): ``None`` unless the background build
raised.
- skipped_files (list[dict]): Files dropped from the index for a
surfaced deterministic reason. Each entry is
``{"path", "category", "detail"}`` where ``category`` is one of
``"parse_error"``, ``"encoding_error"``,
``"missing_frontmatter"``, or ``"internal_error"`` (an
unexpected indexer error, vs a content problem). Empty when
nothing was skipped.
Distinguishes a parse-dropped note from an unsynced one without
reading container logs. Exclude-pattern and transient-I/O skips
are intentionally not listed.| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond annotations (readOnlyHint=true) to disclose critical behavioral details: the error field may be populated even when status is 'queryable' and is always None during 'building'. This helps the agent correctly interpret responses, especially 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat lengthy but well-structured with a bullet list for return fields. Every sentence adds value, but it could be slightly more concise without losing clarity. Nonetheless, it effectively communicates the necessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and the presence of an output schema (described thoroughly), the description is complete. It covers all return fields, their types, possible values, and edge cases (e.g., documents_indexed vs documents_indexed_error). No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the parameter semantics dimension gets a baseline score of 4. The description adds no parameter information because none is needed, and the schema coverage is vacuously 100%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Return background-build state of the FTS index.' This is a specific verb-resource combination, and it distinguishes itself from sibling tools like embeddings_status or build_embeddings which deal with different indexes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 when initialize returned but bucket-3/4 calls block longer than expected or surface IndexUnavailableError.' It also explains what the status and error fields indicate, aiding correct invocation. It lacks explicit when-not-to-use or alternatives, but the context is sufficiently clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_job_resultGet Job ResultARead-only
Retrieve the outcome of a background job started by a long-running tool on this server. When such a tool answers with status "working" and a job_id, call this tool with that job_id every few seconds until the status is terminal. Job records expire after a while — fetch results soon after completion. On this server, background jobs come from slow summarize, reindex, and build_embeddings calls.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds valuable behavior beyond that: job records expire after a while, so results should be fetched promptly. It also explains the polling loop and the terminal state concept, which are not captured in annotations. It doesn't cover error handling for expired or invalid job_ids, but the key operational behavior is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences cover purpose, when to call, polling cadence, expiration warning, and source tools. Information is front-loaded with the core purpose first, then operational details. No repetitive or extraneous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter polling tool, the description covers all necessary operational aspects: what the tool does, how to obtain the parameter, polling behavior, expiration risk, and which tools produce jobs. An output schema exists to document return values, so that requirement is met externally. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the sole parameter job_id is just a generic string type. The description fully compensates by explaining that job_id is the identifier returned by a long-running tool in its 'working' status response, and instructs the agent to use that same job_id when calling this tool. With one parameter, this is sufficient and precise.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Retrieve') and clearly states the resource ('outcome of a background job'). It explicitly distinguishes itself from the long-running tools by explaining that it is the polling mechanism for jobs started by summarize, reindex, and build_embeddings calls. The purpose is unambiguous and easily differentiated from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a direct trigger condition: call when a tool responds with status 'working' and a job_id. It also provides polling cadence ('every few seconds until the status is terminal') and a timing caution ('fetch results soon after completion'). This is explicit, actionable guidance with no need for inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_most_linkedMost-Linked NotesARead-onlyIdempotent
Return the documents with the most inbound links, ranked by backlink count.
Useful for discovering hub notes — frequently-referenced notes that are likely key concepts in the vault. For the specific documents that link to a particular note, use 'get_backlinks' instead.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return. Default 10. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds the ranking-by-backlink-count behavior but does not add further behavioral context such as tie-breaking, self-link handling, or index freshness; the latter is addressed in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loads the primary behavior, includes a concrete use case, and ends with a clear pointer to an alternative. No sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a simple read-only query, annotations cover safety, the schema covers all parameters, an output schema exists, and the description adds use-case and sibling context. Nothing important is missing for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents both limit and wait_for_pending_writes. The description does not need to add parameter details, and the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation: return the documents with the most inbound links ranked by backlink count. It also explicitly distinguishes itself from the sibling tool get_backlinks, making the tool's unique role easy to identify.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool ('discovering hub notes') and explicitly points to get_backlinks for the alternative case of finding documents that link to a particular note. This gives an agent actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_orphan_notesOrphan NotesARead-onlyIdempotent
Return all notes with no inbound or outbound links.
WARNING: returns ALL orphans with no limit — check 'stats' for orphan_count before calling on large vaults.
An orphan note has no backlinks (no other note links to it) and no outlinks (it links to nothing). Call this when 'stats' shows orphan_count > 0. Useful for finding isolated notes that may need to be connected to the rest of the vault or removed.
| Name | Required | Description | Default |
|---|---|---|---|
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds important behavioral context beyond this: it warns that the tool 'returns ALL orphans with no limit' and advises checking orphan_count first. This is exactly the kind of unbounded-result warning that annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core behavior is stated immediately, followed by the high-value warning, then the precise definition and usage trigger. Every sentence serves a purpose, and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety, a fully documented optional parameter, an output schema present, and a description that includes the semantics of orphan notes plus a scalability warning, all information an agent needs to select and invoke this tool correctly is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single parameter wait_for_pending_writes is already thoroughly documented in the schema. The tool description adds no additional parameter-level guidance, but it does not need to because the schema carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Return all notes with no inbound or outbound links.' This clearly distinguishes it from sibling tools like get_backlinks or get_outlinks, which return link data for specific notes rather than orphan detection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a concrete trigger condition: 'Call this when stats shows orphan_count > 0.' It also warns to check stats before calling on large vaults, which is useful usage guidance. It does not explicitly name alternative tools or when not to use it, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_outlinksOutlinksARead-onlyIdempotent
Find all links FROM the given document to other documents (outlinks).
Use this to see what a document references. For a full picture of a note's place in the vault, use 'get_context' instead of calling this separately. Call 'get_outlinks' directly when you only need the outbound link list. Each result includes an 'exists' flag — False means the link is broken (the target is missing from the vault).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path of the source document (e.g. "notes/topic.md"). Case-sensitive. | |
| limit | No | Maximum number of outlinks to return. Omitted (the default) returns all. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds extra behavioral context beyond annotations by explaining the 'exists' flag and that False means a broken link to a missing target, which is useful and non-obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded. It opens with the core action, then adds usage routing, then gives one crucial output-behavior note. Every sentence earns its place and there is no repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's read-only nature, the rich input schema, and the presence of an output schema, the description is complete enough. It covers purpose, when to use it, the main alternative, and a key semantic detail about broken links, so an agent can confidently select and invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the input schema already provides detailed meaning for all three parameters: path, limit, and wait_for_pending_writes. The description does not add parameter-level detail, but with full schema coverage the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Find all links FROM the given document to other documents (outlinks).' It clearly distinguishes the tool from siblings like get_context by defining outlinks as the outbound link list, and it states the directionality of the links.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when to use this tool vs. an alternative: 'For a full picture of a note's place in the vault, use get_context instead of calling this separately. Call get_outlinks directly when you only need the outbound link list.' This is clear routing guidance with a named alternative and a condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recentRecent NotesARead-onlyIdempotent
Get the most recently modified notes in the vault.
Returns notes ordered by file modification time (most recent first). Useful for surfacing recently changed content without a search query — for example to summarize recent activity or resume work on recently edited notes.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of notes to return (default 20). | |
| folder | No | Optional folder filter. When provided, only returns notes from this folder (e.g. "Journal"). Use folder="" for root-level (top-level) documents only. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the read-only, idempotent, non-destructive profile. The description adds the useful behavioral detail that results are sorted by file modification time, most recent first, and clarifies it surfaces recently changed content. It does not discuss index lag or error conditions, but the wait_for_pending_writes parameter schema addresses consistency, so the additional context is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly written sentences, with the core operation in the first sentence, ordering semantics in the second, and concrete use cases in the third. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a comprehensive schema and an output schema, the description provides the remaining orienting context: scope is notes, ordering is by modification time, and no search query is needed. That is complete for selecting and invoking the tool. Minor absence of explicit alternative-routing is already accounted for under usage guidelines.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is fully self-descriptive (100% coverage), including defaults for limit, folder semantics including empty-string root behavior, and an extensive explanation of wait_for_pending_writes. The tool description itself adds no parameter-level guidance, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description leads with a clear verb+object: 'Get the most recently modified notes in the vault' and specifies ordering by file modification time. It distinguishes itself from search via 'without a search query' but does not name sibling tools such as list_documents, so it doesn't fully capitalize on sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when it is useful ('summarize recent activity', 'resume work on recently edited notes') and contrasts with a search query. However, it does not explicitly say when not to use it or point to an alternative tool by name, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_server_infoServer InfoARead-only
Report wrapper and upstream version info for markdown-vault-mcp. Returns server_name, server_version, core_version (fastmcp-pvl-core), and (when configured) an upstream version block. Useful for verifying a deployment matches the expected build.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. Description adds value by specifying the returned fields (server_name, version, core_version, upstream block) and that it is a read operation, consistent 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the key purpose. No unnecessary words; each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and no parameters, the description fully explains what the tool returns and why it's useful. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters; schema coverage is 100% with an empty schema. Description compensates by explaining the output, meeting baseline for zero-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it reports server and upstream version info for markdown-vault-mcp, listing specific fields. This distinguishes it from sibling tools that operate on vault content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides a use case: 'verifying a deployment matches the expected build.' No explicit when-not-to-use or alternatives, but for a simple info tool this is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_similarSimilar NotesARead-onlyIdempotent
Find notes most semantically similar to the given document.
Uses stored embedding vectors — no re-embedding needed. The reference document is excluded from results. Requires semantic search to be configured (check 'stats' for semantic_search_available). Returns an empty list if embeddings are not configured (check 'embeddings_status') or the document has no stored vectors (call 'build_embeddings' to embed missing chunks).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path of the reference document (e.g. "notes/topic.md"). Case-sensitive. | |
| limit | No | Maximum number of similar notes to return (default 10). | |
| folder | No | Restrict results to this folder (exact match or sub-folder prefix), e.g. "3-Resources". Useful to scope link candidates to one part of the vault. Use folder="" for root-level (top-level) documents only. | |
| filters | No | Frontmatter equality filters, ANDed — e.g. {"type": "resource"}. Matched post-hoc against each candidate's full frontmatter, so any frontmatter key works (unlike keyword 'search' filters, which are limited to indexed_frontmatter_fields). List-valued fields match if the value is among them. On an OKF bundle three keys carry OKF semantics, exactly as in 'search': status ("stable" also matches notes without a status field), stale ("true"/"false"), and trust_tier. | |
| chunks_per_file | No | Maximum sections returned per file (default 2). Set to 1 for one best section per file. Must be >= 1. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses meaningful behavior: no re-embedding is performed, the reference document is excluded, and an empty list is returned in specific unconfigured or missing-vector cases. It also points to a remediation path via build_embeddings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and every subsequent sentence adds actionable detail: no re-embedding, exclusion behavior, configuration prerequisites, and failure-mode handling. There is no repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the detailed input schema, output schema, and readOnly/idempotent annotations, the description covers the key operational context an agent needs: when the tool works, when it returns empty, and how to make it work via build_embeddings. Nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The tool description adds some context around the path parameter (reference excluded, missing vectors) but does not need to compensate for any parameter documentation gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Find notes most semantically similar to the given document,' which names a specific action, resource, and comparison basis. It clearly distinguishes this from sibling tools like 'search' by emphasizing semantic similarity via stored embeddings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete usage context: semantic search must be configured, embeddings_status should be checked, and build_embeddings should be called when vectors are missing. It does not explicitly route to an alternative tool such as 'search' for keyword or non-semantic use, but the conditions are clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tocTable of ContentsARead-onlyIdempotent
Heading outline for a single note or a whole folder subtree.
If 'path' ends in '.md' it is a note: returns a flat ordered list of {heading, level} (the title as a synthetic H1). Otherwise 'path' is a folder: returns {path, notes, truncated} where 'notes' is an ordered list of {path, title, headings} aggregating every note under the subtree. Mirrors the 'toc://vault/{path}' resource, adding the max_level / max_notes controls below.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Note path ("a/b.md") or folder prefix ("a/b"). | |
| max_level | No | Drop headings deeper than this level (e.g. 2 keeps H1-H2); must be >= 1. The synthetic H1 title always survives. Default None returns all levels. | |
| max_notes | No | Folder mode only — cap on distinct notes (default 200, must be >= 1). When more notes match, the first max_notes (by path) are returned and 'truncated' is True. | |
| wait_for_pending_writes | No | When True, wait until recent document mutations are applied to the index before answering. Default False answers from the current index; inspect '_meta.index_stale' to tell whether a write was still in flight. Bounded by a server timeout (default 60s). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the bar for added context is lower. The description adds valuable behavioral detail: synthetic H1 in note mode, aggregation and truncation in folder mode, and the parallel to the 'toc://vault/{path}' resource. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then branches into clear note vs. folder behavior. Every sentence contributes meaning, and the resource cross-reference is useful without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a rich input schema, annotations, and an output schema present, the description covers the remaining conceptual context: the two path modes, aggregation semantics, and truncation behavior. There are no significant gaps an agent would need to resolve elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains all four parameters in detail. The description adds only a high-level pointer to the max_level/max_notes controls and the path-mode distinction, which does not materially exceed what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact resource ('heading outline') and clearly distinguishes the two operating modes: single note ('.md' path) vs. folder subtree. It also states the return shape for both cases, which makes the tool's purpose unambiguous even among many sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: you supply a note path or folder prefix and get a heading outline. It does not explicitly name alternatives or exclusion criteria, but the behavior is specific enough that an agent can infer when it is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_documentsList DocumentsARead-onlyIdempotent
List documents (and optionally attachments) in the vault.
Use this to enumerate documents when you need a complete listing, not ranked search results. For finding documents by content, use 'search'. Does NOT include body content — call 'read' for full text.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Return only documents in this folder (e.g. "Journal"). Use folder="" for root-level (top-level) documents only. | |
| filters | No | Frontmatter equality filters, ANDed (e.g. {"tags": "craft"}); any frontmatter key works and list fields match by membership. On an OKF bundle three keys carry OKF semantics: status ("draft"/"stable"/"deprecated"; "stable" also matches notes without a status field), stale ("true"/"false" — stale_after passed), and trust_tier ("unverified"/"machine-confirmed"/"human-reviewed"). Use {"status": "deprecated"} or {"stale": "true"} to build triage listings. Any filter excludes attachments (they carry no frontmatter). | |
| pattern | No | Unix glob matched against relative paths (e.g. "Journal/*.md", "**/*meeting*.md"). | |
| include_attachments | No | When True, also returns non-.md files (PDFs, images, etc.) that match the configured allowlist. Each attachment entry includes kind="attachment" and mime_type. Default False (notes only). | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only/idempotent behavior, and the description adds the key behavioral constraint 'Does NOT include body content' and the optional-attachments behavior. This is useful beyond the annotations and prevents the agent from expecting full note text.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences: the first states the action/scope, the second gives usage context, and the third states an important exclusion with a pointer to the alternative. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich input schema, output schema, and annotations, the description fully covers what the tool does, when to use it instead of search/read, and what it deliberately omits. Nothing needed for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with detailed parameter descriptions in the schema itself. The tool description adds little beyond the phrase 'optionally attachments,' so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb and resource: 'List documents (and optionally attachments) in the vault.' It also distinguishes from siblings by explicitly contrasting with 'search' (ranked content search) and 'read' (body content), so an agent can select it without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: use for a 'complete listing, not ranked search results,' and names the alternatives 'search' for content and 'read' for full text. This directly routes the agent to the correct sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_foldersList FoldersARead-onlyIdempotent
List all folder paths that contain documents.
Call this to discover valid folder names before filtering 'search' or 'list_documents' by folder. The root folder (top-level documents) is represented as an empty string "".
| Name | Required | Description | Default |
|---|---|---|---|
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful non-obvious detail beyond annotations, especially that the root folder is represented as an empty string. It does not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short, front-loaded with the action, and every sentence adds value: it states what is listed, why/when to call it, and the non-obvious root-folder convention. There is no redundant restatement of the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one fully documented optional parameter and an output schema, the description supplies the key missing semantics: folder names are discoverable pre-filter values and the root folder is an empty string. No additional context is needed for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the wait_for_pending_writes parameter is already thoroughly documented in the schema. The description does not need to repeat parameter details, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 all folder paths that contain documents.' It also distinguishes this tool from sibling list operations by clarifying that these are folder names meant for filtering search/list_documents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs when to use the tool: before filtering search or list_documents by folder. It does not enumerate when not to use it or fully compare against list_tags, but the intended call context is clear and unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tagsList TagsARead-onlyIdempotent
List all distinct values for a frontmatter field across the vault.
Use this to discover valid filter values before calling 'search' with the 'filters' argument. Only fields listed in indexed_frontmatter_fields (see 'stats') are indexed — querying other fields returns an empty list.
| Name | Required | Description | Default |
|---|---|---|---|
| field | No | Frontmatter field name to enumerate (default "tags"). Must be one of the values in indexed_frontmatter_fields (from 'stats') — passing any other field silently returns an empty list, not an error. | tags |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, covering the safety profile. The description adds meaningful behavioral context beyond that: unsupported fields silently return an empty list rather than an error, which the agent must know to interpret results correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tight and front-loaded: purpose in the first sentence, usage guidance in the second, and the key indexed-field caveat in the third. Every sentence earns its place and there is no redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple optional-parameter read tool with an output schema and safety annotations, the description covers the decision-relevant information: what it does, when to use it, and the non-obvious failure mode for invalid fields. It also points to stats for the authoritative list of valid fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with detailed parameter descriptions for both field and wait_for_pending_writes. The description reinforces the purpose of field as a filter-discovery mechanism but does not add semantic detail beyond what the schema already provides, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List all distinct values for a frontmatter field across the vault,' naming a concrete operation, resource, and scope. It clearly distinguishes this tool from sibling list tools by focusing on frontmatter field enumeration rather than documents or folders.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use this to discover valid filter values before calling 'search' with the 'filters' argument.' It also gives a critical constraint by directing the agent to stats for indexed_frontmatter_fields and warning that non-indexed fields return an empty list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_folderMove FolderADestructive
Move an entire folder subtree to a new location in one call, rewriting every link across the vault that points into the moved subtree — the folder-level analogue of 'rename'.
Moves all files under old_dir (.md notes, attachments, and any other files) to the matching path under new_dir, preserving structure. Links between documents inside the subtree and backlinks from outside are all rewritten. The search index is updated immediately — do not call 'reindex' afterward.
The move is atomic at the gate: if any destination file already exists, the call fails before moving anything. Link rewrites are best-effort — a source that cannot be rewritten is reported in failed_links rather than aborting the move. Note: an OS error during the move phase itself (permission error, full disk, concurrent file removal) can leave the subtree partially moved with the index unchanged; call 'reindex' to reconcile the index with the on-disk state.
| Name | Required | Description | Default |
|---|---|---|---|
| new_dir | Yes | Relative target folder prefix (e.g. "archive/2026"). May be an existing folder — files merge in; a per-file name clash aborts the whole move. | |
| old_dir | Yes | Relative source folder prefix (e.g. "drafts"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses atomicity at the gate, best-effort link rewrites with failed_links reporting, and the real possibility of a partially moved subtree with an unchanged index on OS errors. This is rich, honest behavioral disclosure that materially 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core definition and then adds progressively deeper detail in a logical order. Every sentence carries necessary information about behavior, failure modes, or index handling; there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent folder operation, the description covers the critical operational concerns: atomicity, link rewriting success/failure, index update timing, and partial-move recovery. The presence of an output schema covers return-value details, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaningful semantics beyond the schema: new_dir may be an existing folder with merging, and a per-file name clash aborts the whole move. This extra context justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: moving an entire folder subtree to a new location in one call, and explicitly frames it as the 'folder-level analogue of rename,' distinguishing it from the sibling rename tool. The scope (all files under old_dir, links rewritten, structure preserved) is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage context: it is the folder-level equivalent of rename, and it warns not to call reindex afterward because the index is updated immediately. It also instructs to call reindex after a partial OS failure, which is concrete when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
okf_convert_linksOKF: Convert WikilinksADestructiveIdempotent
Rewrite wikilinks as OKF bundle-root-absolute markdown links.
A migration transform (Open Knowledge Format): converts every
resolvable [[wikilink]] in the vault (or one folder) into
[text](/path/note.md), OKF's recommended link style. Only links
whose target is indexed are converted, so the link graph is
preserved exactly — a converted link points at the same note the
wikilink resolved to. Unresolvable wikilinks are left untouched and
counted as skipped. Each changed note is written through the normal
write path (git commit if configured). Re-running is safe: already-
converted links are plain markdown and are not touched again.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Restrict to this folder subtree (e.g. "guides"). Omit to convert the whole vault. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: writes go through the normal write path, git commit occurs if configured, re-running is safe, resolvability determines conversion, and the link graph is preserved exactly. This gives an agent a clear model of side effects and safety considerations, complementing the destructiveHint and idempotentHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the primary action, and every subsequent sentence adds meaningful information about behavior, edge cases, or safety. There is no filler or repetition that detracts from its usefulness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a rich description, an output schema, and annotations covering mutability and idempotency. The description covers the main action, scope, exceptions, side effects, re-run behavior, and link-graph preservation, leaving no material gap for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'folder' is fully described in the schema with default and behavior (restrict to folder subtree, omit for whole vault). The description reiterates the 'vault or folder' scope but does not add new parameter-level semantics beyond what the schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Rewrite wikilinks as OKF bundle-root-absolute markdown links') and identifies the exact resource (resolvable wikilinks in the vault or a folder). It clearly differentiates this migration tool from siblings like okf_validate and okf_generate_index by describing its unique transformation purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes when to use the tool: during an OKF migration to convert wikilinks to markdown links. It also specifies constraints on usage, such as only converting indexed targets and leaving unresolvable links untouched. It does not explicitly name alternative tools, but the context is strong enough to make the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
okf_generate_indexOKF: Generate index.mdADestructiveIdempotent
Generate a reserved OKF index.md listing from the table of contents.
A migration transform (Open Knowledge Format): writes (or overwrites)
the folder's index.md as a progressive-disclosure listing —
- [title](/path.md) - description per note, description drawn from
frontmatter. Existing frontmatter is preserved, so regenerating the
bundle-root index.md keeps its okf_version declaration. Reserved
files (index.md, log.md) are omitted from the listing.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Vault-relative folder to index (e.g. "guides"). Omit for the bundle root. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations by disclosing that it 'writes (or overwrites) the folder's index.md', preserves existing frontmatter, and omits reserved files like index.md and log.md. It also specifies the listing format and that descriptions come from frontmatter, giving a complete picture of the tool's side effects consistent with destructiveHint and idempotentHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then adds precisely targeted details: output format, data source, overwrite behavior, frontmatter preservation, and omitted files. Every sentence earns its place; there is no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only one optional parameter, full schema coverage, an output schema, and annotations covering idempotence and destructiveness, the description supplies the remaining essential context: what gets overwritten, what is preserved, and what is excluded. The agent has everything needed to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes the only parameter (`folder`) completely, including its meaning and default behavior. The tool description adds context about 'bundle-root' but does not materially expand parameter semantics. Baseline 3 is appropriate given 100% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Generate a reserved OKF index.md listing from the table of contents.' It then details the exact output format and source, making the tool's purpose unmistakable and distinguishing it from sibling tools like get_index_status or okf_validate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool—when you need to generate or regenerate an OKF index.md—but it does not explicitly state when to prefer it over alternatives such as write, reindex, or get_index_status. No exclusions or alternate routing are provided, so the usage context is clear but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
okf_seed_logOKF: Seed log.mdA
Seed a reserved OKF log.md change history from git history.
A migration transform (Open Knowledge Format): writes a log.md with
newest-first ## YYYY-MM-DD sections built from the vault's git
commit history (one bullet per commit). folder both chooses where
log.md is written and scopes its content: a folder seeds only the
commits that touched that subtree, while the bundle root seeds the
whole vault's history. Refuses to overwrite an
existing log.md — a change history is hand-maintained after seeding,
so it is never clobbered. Requires the vault to be git-backed; with no
git history the log is written empty.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Vault-relative folder to write log.md into and scope history to (e.g. "guides"). Omit for the bundle root (whole-vault history). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It goes well beyond the annotations by disclosing exactly what is written, that an existing log.md is never overwritten, and that a log is written empty when there is no git history. These behaviors are consistent with readOnlyHint=false, idempotentHint=false, and destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The lead sentence states the purpose, and every subsequent sentence adds necessary behavioral, scoping, or prerequisite detail. There is no filler, ambiguity, or repeated schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter tool with an output schema, the description covers creation behavior, overwrite protection, folder scoping, the git-backing prerequisite, and the empty-history edge case. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents folder's role and default at 100% coverage, so the baseline of 3 applies. The description adds nuance about subtree-scoped commits versus whole-vault history, but it does not introduce significant new parameter-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Seed a reserved OKF log.md change history from git history', naming a specific action and artifact. It then explains the newest-first format and folder scoping, which distinguishes it from generic write/edit tools and sibling OKF transforms like okf_generate_index.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete invocation context: folder selects write location and content scope, the bundle root seeds whole-vault history, and a git-backed vault is required. It does not explicitly name sibling alternatives or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
okf_validateValidate OKF BundleARead-onlyIdempotent
Audit the vault's OKF (Open Knowledge Format) conformance.
Reports conformance as degrees, not a verdict — during a migration this is the progress meter. Reads the vault from disk (works before the index is built and before the vault declares 'okf_version'), and skips paths matching the vault's effective exclude patterns.
Findings come in three severities. Conformance (spec violations): notes missing a non-empty 'type', notes with unparseable frontmatter, and 'okf_version' declared outside the root index.md. Advisory (tolerated but worth fixing): 'status' values outside draft/stable/deprecated, log.md files whose '##' headings are not YYYY-MM-DD dates, and a missing root index.md. Informational (not deviations): notes containing wikilinks (relevant only when exporting; internal links resolve fine either way) and notes lacking the recommended 'title'/'description'. Reserved files (index.md, log.md) are exempt from the 'type' rule.
Returns: Report dict: 'mode', 'declared_version', 'active' (detection state); 'total_notes' and 'conformant_notes' (the progress ratio); per-rule findings each carrying 'count' and up to 20 'examples' paths ('missing_type', 'unparseable_frontmatter', 'misplaced_okf_version', 'unknown_status', 'log_heading_shape', 'wikilink_files', 'missing_recommended'); and 'root_index_missing' (bool).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantial context: reads from disk, respects exclude patterns, reports degrees rather than verdicts, and exempts reserved files. This goes well beyond the structured annotation fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: purpose, usage timing, severity taxonomy, and exact return keys. It front-loads core behavior and organizes the detailed enumeration clearly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter audit tool with rich output, the description fully covers detection semantics, severity rules, exclusions, and the exact report structure. The presence of an output schema plus this description leaves no ambiguity about what the agent will receive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing to document and the empty schema is fully covered. The detailed return-format description is valuable but belongs to contextual completeness rather than parameter semantics, so the baseline of 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Audit') and resource ('vault's OKF conformance'), and distinguishes itself from sibling okf_* tools by focusing on conformance reporting rather than conversion, index generation, or log seeding. The description clearly defines what validation means in this context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames the tool as a migration progress meter and notes it works before the index is built or okf_version is declared, giving clear conditions for use. It does not name sibling alternatives or exclusions, but the context is unambiguous and sufficient for a zero-parameter tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
readRead NoteARead-onlyIdempotent
Read the full content of a document or attachment by path.
For .md documents: returns content (the full raw file including frontmatter), plus the parsed frontmatter, title, and folder. For attachments (pdf, png, etc.): returns base64-encoded binary content and MIME type. Use 'list_documents(include_attachments=True)' to discover attachment paths. Use 'stats' to see allowed extensions.
Do not guess paths — look them up first via 'search' or 'list_documents'.
To recover the full text of a specific section returned by 'search', pass section=heading (the value from the result's 'heading' field).
Context cost: every byte returned counts against the LLM's
context budget. Reads above MARKDOWN_VAULT_MCP_MAX_NOTE_READ_BYTES
(default 256 KB for .md) or
MARKDOWN_VAULT_MCP_MAX_ATTACHMENT_SIZE_MB (default 1 MB for
binaries) raise ValueError. For partial markdown reads, pass
section=heading (use the heading field from a search()
result).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path to the document or attachment (e.g. "Journal/note.md" or "assets/diagram.pdf"). Case-sensitive. | |
| section | No | When provided, return the whole section whose heading matches *section* — every paragraph, list, and sub-section from the heading up to the next heading at the same or higher level (case-sensitive; internal whitespace is collapsed before comparison). Pass the ``heading`` value from a ``search`` result unchanged for guaranteed match. ``None`` (the default) returns the whole document. Ignored for non-.md paths. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, indicating safe read-only operation. The description adds valuable behavioral context: context cost limits and ValueError for large reads, which is not covered by 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bullet points and clear sections, front-loading the main purpose. However, it is somewhat lengthy; the context cost paragraph could be more concise. Still, it effectively communicates key information without excessive redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (different handling for .md vs attachments, section parameter, size limits, path discovery), the description covers all essential aspects: behavior, error conditions, context cost, and prerequisite steps. The presence of an output schema does not reduce the need for this clarity; the description enhances it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaning beyond schema, especially for the 'section' parameter, explaining its matching behavior and how to use search results. It also reinforces case-sensitivity for path.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads full content of documents or attachments by path, and distinguishes between .md documents (returning content, frontmatter, title, folder) and attachments (returning base64 and MIME type). This specificity and resource differentiation make it highly clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs not to guess paths but to use 'search' or 'list_documents' first, and explains when to use the 'section' parameter. While it does not exhaustively list alternatives, it provides sufficient context for when to use this tool versus siblings like 'search'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reindexReindex VaultAIdempotent
Run an incremental reindex on the writer thread.
Only needed when files are modified outside this server — for example, by a text editor, a sync tool, or another process writing directly to the vault directory. Do NOT call this after using 'write', 'edit', 'delete', or 'rename' — those tools update the index immediately as part of the operation.
Change detection is hash-based, so an unchanged file is never re-parsed. Use force=True to drop the index and re-parse every file regardless of hashes — the repair for index content that no longer matches what the current server would extract. A version upgrade that changes extraction does this by itself on the next start (#1124), so force=True is a manual escape hatch, not routine maintenance. When semantic search is configured, follow a force=True run with 'build_embeddings' (without force) so the vector index converges to the rebuilt chunk set; an ordinary reindex re-embeds as it goes.
To rebuild all embeddings from scratch (e.g. after changing the embedding model), use 'build_embeddings' with force=True.
A fast reindex (the common case — work scales with the drift, not
the vault) returns its result inline. A reindex still running at the
server's soft deadline continues in the background and returns
{"status": "working", "job_id": ...} immediately — fetch the
outcome with get_job_result. get_index_status remains the
observability view of the index (it also covers boot-time builds and
file-watcher reindexes no client call initiated).
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | When True, drop every indexed document and re-parse the whole vault instead of applying the hash-detected delta. The index is not queryable while the rebuild runs, and the cost scales with the vault rather than the drift, so prefer the default. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: hash-based change detection, background execution with job_id, index unavailability during force rebuilds, and the relationship with embedding convergence. It also clarifies that force=True is a 'manual escape hatch, not routine maintenance,' which is exactly the kind of judgment context an agent needs. No contradiction with the idempotentHint or destructiveHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries operational weight. It front-loads the core purpose immediately and organizes the rest by when-to-use, when-not-to-use, force semantics, follow-up actions, and response behavior. Nothing feels redundant or promotional.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter, the description fully covers the common path, the force edge case, background job behavior, and how to retrieve results. It also explains the relationship to get_index_status and build_embeddings, so an agent can handle the complete workflow without guessing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already documents the force parameter at 100% coverage, the description goes further by explaining the trade-offs of force=True: it drops every indexed document, re-parses the whole vault, makes the index unqueryable during the rebuild, and scales cost with vault size. It also tells the agent to follow force=True with build_embeddings in semantic-search setups. This adds real decision-making value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Run an incremental reindex on the writer thread.' It clearly distinguishes reindex from sibling tools like build_embeddings and get_index_status by explaining what reindex does versus what those tools handle. Even without knowing the siblings, an agent understands this is an index-refresh operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when reindex is needed ('files modified outside this server') and when it is not ('Do NOT call this after using write, edit, delete, or rename'). It also routes the agent to alternatives: build_embeddings for embedding rebuilds, get_job_result for background outcomes, and get_index_status for observability. This is exceptional usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
renameRename NoteA
Rename or move a document or attachment. When renaming a .md note, always pass update_links=True to rewrite links in other documents that point to the old path — omitting this leaves those links broken.
For .md documents: the file and its search index entries are updated immediately — do not call 'reindex' afterward. For attachments: only the file is moved (no index update needed). Parent directories for new_path are created automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| if_match | No | Optional etag obtained from a previous 'read' call for old_path. When provided, the rename only proceeds if the file has not been modified since that read (optimistic concurrency). Omit to rename unconditionally. | |
| new_path | Yes | Target relative path (e.g. "projects/idea.md" or "assets/new.png"). Fails if new_path already exists. | |
| old_path | Yes | Current relative path (e.g. "drafts/idea.md" or "assets/old.png"). | |
| update_links | No | When True, all .md documents that link to old_path are also updated so their links point to new_path. Replacement is best-effort — failures are logged but do not prevent the rename. Default False; set True whenever renaming a .md note (omitting this leaves backlinks pointing to the old path). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations only saying readOnlyHint=false, idempotentHint=false, and destructiveHint=false, the description carries the behavioral burden and does so thoroughly. It discloses immediate index updates for .md files, no index update for attachments, automatic parent directory creation, best-effort link rewriting, and the broken-link risk when update_links is omitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a clear opening, a prominent warning about update_links, then labeled .md and attachment behavior. Every sentence carries actionable information, and the most important usage rule is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has four parameters and non-trivial side effects (link rewriting, index updates, directory creation), and the description covers all of these without needing to explain return values since an output schema exists. It is complete enough for an agent to call this tool correctly and avoid common mistakes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful parameter context beyond the schema: parent directories are created automatically for new_path, .md files get index updates immediately, and attachments do not. This helps the agent reason about the consequences of the parameters, not just their types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Rename or move a document or attachment.' It clearly distinguishes the tool from siblings like write/edit (content changes) and move_folder (folders) by restricting scope to documents and attachments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: always set update_links=True for .md notes, and it explicitly says not to call reindex afterward. It does not explicitly compare against move_folder or write, but the .md vs. attachment distinction and the reindex exclusion provide clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchSearch VaultARead-onlyIdempotent
Find documents matching a query using full-text or semantic search.
Search the vault. Omit 'mode' for the best mode this vault can serve — hybrid when embeddings are configured, keyword when they are not. Pass mode="keyword" for exact terms, operators, or filenames, where FTS5/BM25 beats fusion. Use mode="semantic" for pure vector similarity.
The 'content' field in each result is a snippet by default, not the full document. Use read(path, section=heading) to retrieve the full text of a specific section.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | "keyword" uses FTS5/BM25 for exact terms. "semantic" uses vector similarity (requires embeddings). "hybrid" fuses both via reciprocal rank fusion — best quality when available. Omit it (the default) to follow the vault's configured DEFAULT_SEARCH_MODE, which ships as "auto": hybrid where embeddings exist, keyword otherwise. Any configured default degrades to "keyword" when it needs embeddings the vault lacks; an explicit "semantic"/"hybrid" still errors when unconfigured. | |
| limit | No | Maximum results to return (default 10). | |
| query | Yes | Natural language or keyword query string. | |
| folder | No | Restrict to documents under this folder path (e.g. "Journal"). Must match a value from 'list_folders'. Use folder="" for root-level (top-level) documents only. | |
| filters | No | Filter by indexed frontmatter field values, e.g. {"cluster": "craft", "tags": "pacing"}. Only fields listed in indexed_frontmatter_fields (see 'stats') can be filtered. Multiple filters are ANDed. For list fields (e.g. tags), this checks membership — {"tags": "pacing"} matches any document where "pacing" appears in the tags list. On an OKF bundle three keys carry OKF semantics: status ("draft"/ "stable"/"deprecated"; "stable" also matches notes without a status field), stale ("true"/"false" — stale_after passed), and trust_tier ("unverified"/"machine-confirmed"/ "human-reviewed"); "type" filters normally, e.g. {"type": "Playbook", "stale": "false"}. | |
| snippet_words | No | Width of the snippet window in words. Omit to use the server default. Set to 0 to return full chunk content. Use read(path, section=heading) for full section recovery. | |
| chunks_per_file | No | Maximum number of sections to return per file (default 2). Set to 1 to get only the top-ranked section per file. Must be >= 1. | |
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the readOnly/idempotent/destructive annotations by revealing important runtime behavior: the default mode automatically adapts based on whether embeddings are configured, and the 'content' field returns snippets rather than full documents. This is genuinely useful behavioral context that an agent could not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: purpose first, then mode-selection guidance, then a critical output caveat. Every sentence earns its place, and the most actionable decision logic is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with 8 parameters, a dedicated output schema, and rich schema-level parameter documentation, the description covers the essential non-obvious context: mode fallback behavior, snippet semantics, and when to delegate to 'read'. Nothing an agent needs to select or invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already has a rich description, so the baseline is 3. The description adds value by condensing the mode decision logic into clear heuristics ('hybrid when embeddings are configured, keyword when they are not') and by explaining why keyword can beat fusion for exact-term queries. That goes slightly beyond the schema without duplicating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Find documents matching a query using full-text or semantic search.' This clearly identifies the tool's function and immediately distinguishes it from read-focused siblings. It also names the vault as the scope and the query as the primary input.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit mode-selection guidance: omit 'mode' for the best automatic option, pass keyword for exact terms/operators/filenames, and pass semantic for pure vector similarity. It also tells the agent when to use the sibling tool 'read' instead — when full section content is needed rather than snippets.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_contextContext CardARead-onlyIdempotent
Open a visual context card UI for the user — not for reading note relationships.
Displays an interactive context panel (MCP Apps) to the user showing a
note's backlinks, outlinks, similar notes, tags, and frontmatter visually.
Do NOT call this to retrieve note relationship data programmatically — use
get_context instead, which returns the full structured data.
Only call this when the user explicitly asks to open the visual context card or explorer (e.g. "show me the context card for this note").
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative note path (e.g. ``"Journal/2024-01-15.md"``). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds behavioral context that the tool displays an interactive panel to the user, not for reading relationships, which complements the annotations 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: three sentences total, with the main purpose front-loaded, followed by clear usage guidelines. Every sentence serves a purpose without any redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one parameter, full schema coverage, clear annotations, and an output schema), the description provides all necessary context for an AI agent to correctly select and invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage for the single parameter 'path', the description does not need to add additional parameter semantics. The schema already provides sufficient description, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it opens a visual context card UI for the user, using specific verbs like 'open' and 'display'. It explicitly distinguishes from sibling tool 'get_context' which returns structured data, ensuring no ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: only call when the user asks to open the visual context card (e.g., 'show me the context card for this note'), and warns against using it for programmatic data retrieval, directing to 'get_context' instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statsVault StatsARead-onlyIdempotent
Get an overview of the vault's size, capabilities, and configuration.
Call this at the start of a session to understand what the vault contains and what search modes are available. The 'semantic_search_available' field tells you whether mode="semantic" or mode="hybrid" can be used in 'search'.
| Name | Required | Description | Default |
|---|---|---|---|
| wait_for_pending_writes | No | When True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context by pointing to the semantic_search_available field and how it affects search mode choices, which helps the agent interpret the response. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the purpose, the second gives a concrete usage recommendation, and the third highlights a key response field. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only stats tool, the description is complete: it explains when to call it, what it returns at a high level, and which field drives search-mode decisions. The detailed parameter schema and presence of an output schema cover the remaining invocation needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100% and the wait_for_pending_writes parameter is fully explained in the schema. The tool description does not add parameter-level meaning beyond the schema, which matches the baseline for full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get an overview of the vault's size, capabilities, and configuration.' This clearly distinguishes the tool as a vault-level stats endpoint, but it does not explicitly contrast it with related siblings like get_server_info or get_index_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance to call this tool 'at the start of a session' to understand vault contents and available search modes. It does not provide exclusions or when-not-to-use guidance, but the recommended usage context is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
writeWrite NoteAIdempotent
Create or overwrite a document or attachment.
For .md documents: uses 'content' (markdown body) and optional 'frontmatter'. WARNING: replaces the entire file — use 'edit' for targeted changes. The search index is updated immediately; do not call 'reindex' afterward.
For attachments (pdf, png, etc.): uses 'content_base64' (base64- encoded binary). 'content' and 'frontmatter' are ignored. Parent directories are created automatically for both.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative path (e.g. "Journal/note.md" or "assets/photo.png"). Extension determines handling. | |
| content | No | Full markdown body for .md files (excluding frontmatter). Ignored for attachments. | |
| if_match | No | Optional etag obtained from a previous 'read' call. When provided, the write only proceeds if the file has not been modified since that read (optimistic concurrency). Omit to write unconditionally. | |
| frontmatter | No | Optional YAML frontmatter dict for .md files, e.g. {"title": "My Note", "tags": ["draft"]}. Ignored for attachments. | |
| content_base64 | No | Base64-encoded binary content for attachment files. Required when path is not ``.md``. **Context cost:** base64 encoding inflates by ~33%; even a 1 MB attachment becomes ~1.3 MB of tokens. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description warns 'replaces the entire file', which is a destructive overwrite behavior, while the annotations declare destructiveHint=false. This is a direct contradiction: an agent relying on annotations could wrongly assume the operation is non-destructive. Despite useful disclosures like immediate index updates, the contradiction forces a score of 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: the core purpose appears first, followed by clearly separated markdown and attachment branches. The warning and index-update note are valuable rather than filler. It is slightly long but every section earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the two main usage modes, the overwrite warning, index behavior, automatic parent directory creation, and the concurrency option via if_match. Since an output schema exists, return-value details are not required. A small gap is that it does not describe failure behavior when if_match conflicts, but overall the description is complete enough for successful invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds meaningful semantics beyond the schema by grouping parameters by file type: content/frontmatter for .md files, content_base64 for attachments, and explicitly noting that content and frontmatter are ignored for attachments. It also adds the base64 token-cost warning, which is helpful context not present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: 'Create or overwrite a document or attachment.' It clearly separates markdown documents from binary attachments and explicitly names the sibling alternative 'edit' for targeted changes, so an agent can distinguish write from edit/append/delete without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: use 'edit' for targeted changes instead of write, and do not call 'reindex' afterward because the search index updates immediately. It also states that parent directories are created automatically, removing any need for a separate mkdir step.
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. Dates show when Glama detected each change.
1 tool update
v4.1.0- Changed
search5 fields changed- added
Input schema / properties / mode / anyOfAdded value: +[ + { + "enum": [ + "keyword", + "semantic", + "hybrid" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / mode / defaultPrevious value: -"keyword"New value: +null - changed
Input schema / properties / mode / descriptionPrevious value: -"\"keyword\" uses FTS5/BM25 for exact terms. \"semantic\" uses\nvector similarity (requires embeddings). \"hybrid\" fuses both\nvia reciprocal rank fusion — best quality when available."New value: +"\"keyword\" uses FTS5/BM25 for exact terms. \"semantic\" uses\nvector similarity (requires embeddings). \"hybrid\" fuses both\nvia reciprocal rank fusion — best quality when available.\nOmit it (the default) to follow the vault's configured\nDEFAULT_SEARCH_MODE, which ships as \"auto\": hybrid where\nembeddings exist, keyword otherwise. Any configured default\ndegrades to \"keyword\" when it needs embeddings the vault\nlacks; an explicit \"semantic\"/\"hybrid\" still errors when\nunconfigured." - removed
Input schema / properties / mode / enumRemoved value: -[ - "keyword", - "semantic", - "hybrid" -] - removed
Input schema / properties / mode / typeRemoved value: -"string"
30 tool updates
v4.0.0- Added
append - Added
delete - Added
edit - Added
fetch - Changed
get_backlinks1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_broken_links2 fields changed- changed
Input schema / properties / folder / descriptionPrevious value: -"Optional folder filter. When provided, only checks\nlinks from documents in this folder (e.g. \"Journal\").\nWithout this, checks all documents."New value: +"Optional folder filter. When provided, only checks\nlinks from documents in this folder (e.g. \"Journal\").\nUse folder=\"\" for root-level (top-level) documents only.\nWithout this, checks all documents." - changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_connection_path1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_context1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Added
get_conventions - Changed
get_history1 field changed- changed
Input schema / properties / path / descriptionPrevious value: -"Vault-relative path of the note or attachment to filter on\n(e.g. \"notes/alpha.md\" or \"assets/diagram.png\"). May be a\n`.md` note or a configured attachment extension (png, pdf,\nsvg, …). Omit (or pass null) for vault-wide commit history."New value: +"Vault-relative path to filter on. A `.md` note or a\nconfigured attachment extension (png, pdf, svg, …) scopes to\nthat single file (e.g. \"notes/alpha.md\",\n\"assets/diagram.png\"); an existing folder scopes to its\nsubtree (e.g. \"guides\" returns commits touching guides/**).\nOmit (or pass null) for vault-wide commit history."
- Added
get_job_result - Changed
get_most_linked1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_orphan_notes1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_outlinks1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_recent2 fields changed- changed
Input schema / properties / folder / descriptionPrevious value: -"Optional folder filter. When provided, only returns\nnotes from this folder (e.g. \"Journal\")."New value: +"Optional folder filter. When provided, only returns\nnotes from this folder (e.g. \"Journal\").\nUse folder=\"\" for root-level (top-level) documents only." - changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_similar3 fields changed- added
Input schema / properties / filtersAdded value: +{ + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Frontmatter equality filters, ANDed — e.g.\n{\"type\": \"resource\"}. Matched post-hoc against each\ncandidate's full frontmatter, so any frontmatter key works\n(unlike keyword 'search' filters, which are limited to\nindexed_frontmatter_fields). List-valued fields match if\nthe value is among them. On an OKF bundle three keys carry\nOKF semantics, exactly as in 'search': status (\"stable\"\nalso matches notes without a status field), stale\n(\"true\"/\"false\"), and trust_tier." +} - added
Input schema / properties / folderAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Restrict results to this folder (exact match or\nsub-folder prefix), e.g. \"3-Resources\". Useful to scope\nlink candidates to one part of the vault.\nUse folder=\"\" for root-level (top-level) documents only." +} - changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
get_toc1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until recent\nwrite/edit/delete/rename operations are applied to the index\nbefore answering. Default False answers from the current\nindex; inspect '_meta.index_stale' to tell whether a write was\nstill in flight. Bounded by a server timeout (default 60s)."New value: +"When True, wait until recent\ndocument mutations are applied to the index\nbefore answering. Default False answers from the current\nindex; inspect '_meta.index_stale' to tell whether a write was\nstill in flight. Bounded by a server timeout (default 60s)."
- Changed
list_documents2 fields changed- added
Input schema / properties / filtersAdded value: +{ + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Frontmatter equality filters, ANDed (e.g.\n{\"tags\": \"craft\"}); any frontmatter key works and list\nfields match by membership. On an OKF bundle three keys\ncarry OKF semantics: status (\"draft\"/\"stable\"/\"deprecated\";\n\"stable\" also matches notes without a status field), stale\n(\"true\"/\"false\" — stale_after passed), and trust_tier\n(\"unverified\"/\"machine-confirmed\"/\"human-reviewed\"). Use\n{\"status\": \"deprecated\"} or {\"stale\": \"true\"} to build\ntriage listings. Any filter excludes attachments (they\ncarry no frontmatter)." +} - changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
list_folders1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
list_tags1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Added
move_folder - Added
okf_convert_links - Added
okf_generate_index - Added
okf_seed_log - Added
okf_validate - Changed
reindex1 field changed- added
Input schema / properties / forceAdded value: +{ + "default": false, + "description": "When True, drop every indexed document and re-parse the\nwhole vault instead of applying the hash-detected delta.\nThe index is not queryable while the rebuild runs, and the\ncost scales with the vault rather than the drift, so prefer\nthe default.", + "type": "boolean" +}
- Added
rename - Changed
search2 fields changed- changed
Input schema / properties / filters / descriptionPrevious value: -"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list."New value: +"Filter by indexed frontmatter field values, e.g.\n{\"cluster\": \"craft\", \"tags\": \"pacing\"}. Only fields listed\nin indexed_frontmatter_fields (see 'stats') can be filtered.\nMultiple filters are ANDed. For list fields (e.g. tags),\nthis checks membership — {\"tags\": \"pacing\"} matches any\ndocument where \"pacing\" appears in the tags list. On an OKF\nbundle three keys carry OKF semantics: status (\"draft\"/\n\"stable\"/\"deprecated\"; \"stable\" also matches notes without\na status field), stale (\"true\"/\"false\" — stale_after\npassed), and trust_tier (\"unverified\"/\"machine-confirmed\"/\n\"human-reviewed\"); \"type\" filters normally, e.g.\n{\"type\": \"Playbook\", \"stale\": \"false\"}." - changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Changed
stats1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious value: -"When True, wait until your recent\nwrite/edit/delete/rename operations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a write/edit/delete/rename whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."New value: +"When True, wait until your recent\ndocument mutations have been applied to the\nindex before answering, so the results reflect those changes.\nUse it right after modifying notes when this read must see\nthem (e.g. right after a document mutation whose\neffect this read should reflect). Default\nFalse answers immediately from the current index — almost\nalways already up to date; inspect the response's\n``_meta.index_stale`` field to tell whether a write was still\nin flight. Bounded by a server timeout (default 60s); on\ntimeout it answers from the current index rather than waiting\nlonger."
- Added
write
25 tool updates
v3.1.0- First observed
browse_vault - First observed
build_embeddings - First observed
embeddings_status - First observed
get_backlinks - First observed
get_broken_links - First observed
get_connection_path - First observed
get_context - First observed
get_diff - First observed
get_history - First observed
get_index_status - First observed
get_most_linked - First observed
get_orphan_notes - First observed
get_outlinks - First observed
get_recent - First observed
get_server_info - First observed
get_similar - First observed
get_toc - First observed
list_documents - First observed
list_folders - First observed
list_tags - First observed
read - First observed
reindex - First observed
search - First observed
show_context - First observed
stats
TDQS
Each tool has a clearly distinct purpose, with detailed descriptions explaining when to use which. For example, 'get_backlinks' and 'get_outlinks' are separate for inbound vs outbound links, and 'get_context' consolidates multiple calls. No two tools appear to do the same thing.
Most tools follow a verb_noun pattern (e.g., 'get_', 'list_', 'read', 'search'). However, 'embeddings_status' and 'stats' use a noun-only format, breaking the pattern slightly. Overall consistent but with minor deviations.
With 25 tools, the server covers a broad range of vault operations. The count is slightly high but each tool addresses a specific need. It earns its place given the complexity of vault management (search, links, git, embeddings, UI).
The tool set lacks mutation tools (create, write, edit, delete, rename) which are essential for a vault server. The 'reindex' tool description references these operations, implying they exist but are not in the provided list. This is a significant gap for a complete CRUD surface.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Personal knowledge base MCP server with semantic search, auto-categorization, metadata extraction
Read-only MCP server for the OrchestKit docs: full-text search + Markdown fetch. No auth.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceMCP server that enables full-text search and link navigation over Markdown files as a knowledge graph.-
- AlicenseNot gradedqualityBmaintenanceMCP server for structured markdown knowledge vaults that provides validation, FTS5 search, and wikilink cross-references. Enables AI agents to prime context and search across vaults using two MCP tools and template resources.7MIT
- AlicenseAqualityCmaintenanceMCP server for local knowledge management with Markdown and PDF indexing using SQLite FTS5.5122MIT
- AlicenseAqualityBmaintenanceLocal MCP server for querying and maintaining a Markdown vault. Provides full-text search, backlinks, note retrieval, and optional confined write tools, without sending the whole vault to the client context.20Apache 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/pvliesdonk/markdown-vault-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server