markdown-vault-mcp
This server is an MCP interface to a markdown vault, offering hybrid search, read/write note management, relationship/graph analysis, OKF migration tooling, and git-backed history — all over a searchable, frontmatter-aware index.
Search: hybrid (keyword + semantic) search with mode override, frontmatter filters, folder scoping, snippets, and per-file section limits.
Read & enumerate: read full notes or specific sections by heading, list documents/folders/tags, get vault stats, recent notes, table of contents, and per-folder authoring conventions.
Write operations: create, overwrite (with etag/if_match optimistic concurrency), edit, append, delete, rename/move, fetch from URL, plus folder moves and attachment read/write.
Relationships & graph: backlinks, outlinks, broken links, orphan notes, most-linked notes, similar notes, connection paths, and a consolidated context dossier.
OKF support: validate OKF conformance, convert wikilinks, generate index.md, seed log.md, and OKF-aware status/stale/trust filtering.
Git integration: list commit history and show diffs for notes/folders; overwritten content is recoverable via revision reads.
Embeddings & indexing: check embedding status, build/rebuild embeddings, run incremental or forced reindexes, and retrieve background job results.
UI conveniences: open visual vault browser/context card views for the user, and get server version info.
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 "Deploy 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 (one commit per write tool call) with deferred push, plus a pull loop or a GitHub or GitLab push webhook for external changes; history and diff tools read the log back. An overwriting
writereturns the revision holding the content it replaced, andread(path, revision=sha)reads a note back at that revision, so an overwrite is recoverable from the client that made it. When the clone stops reaching its remote, every write result carries aremotewarning saying the content is committed locally only, and the log marks the transition rather than repeating each cycle. 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. Static bearer writes use tool provenance; human review through a bearer credential requires confirmation with
okf_verifyinelicitmode. 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.
Overwrite protection is enabled by default. Before replacing an existing file
with write or fetch, read that destination and pass its etag as if_match.
New files need no etag. Transfer upload links require a
new destination because they have no if_match option. Set
MARKDOWN_VAULT_MCP_WRITE_PROTECT_EXISTING=false to allow blind overwrites;
see the transfer guide.
Python integrations use VaultSettings for configuration. See the
Vault API for the migration from the
removed 4.x constructor keywords and the
configuration API for typed assembly.
The Git API covers removal of the deprecated
strategy claim keywords and the keyword-only LFS and repository options.
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 and runs as-is: copy .env.example to .env, then docker compose up -d. It publishes port 8000 on the host and assumes no reverse proxy; Docker Compose covers the configuration split, the domain sentinel blocks, and a Traefik overlay.
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.
Health
The server serves /health (liveness, a static 200) and /health/ready (readiness, 503 when a backing store or a domain check fails) outside the MCP mount and outside auth, via fastmcp_pvl_core.register_health_routes. compose.yml probes the first. Domain readiness checks go in the health_checks dict in src/markdown_vault_mcp/server.py; see Docker deployment for the routes, the mount-path rule, and MARKDOWN_VAULT_MCP_HEALTH_DETAIL.
Configuration
The most common 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. |
|
| Rich color output for a terminal; false gives one plain or JSON line per record. Off in the container image and the systemd unit, since neither is a terminal and Rich wraps a structured record at its 80-column fallback. |
This table and the one under Domain configuration
are curated subsets. The complete generated reference, with every variable
the server reads, is the configuration reference;
.env.example lists the same surface in copy-paste form.
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
The variables this project features as its entry points (domain variables use the MARKDOWN_VAULT_MCP_ prefix):
Variable | Default | Required | Description |
|
| 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 | Refuse a write that would overwrite an existing file when no if_match etag is supplied. Deliberate replacement still works: read the file first, then pass if_match. Unaffected: edit, append, delete, rename. Set to false to allow blind overwrites. |
|
| 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. |
| (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. |
| (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 | Watch the vault for external filesystem changes; auto-disabled when git pull is active or a webhook can deliver (HTTP/SSE transports only). Requires the file-watcher extra. |
| (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. |
This is a curated subset: a field appears here when its tags metadata includes readme. Every domain variable is documented in the configuration reference, grouped the same way the config wizard presents them.
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, tags, and wizard group generate the reference tables 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(). File writes return after saving, while index updates run in the background. Index-dependent mutations wait for prior writes; see index freshness.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
44 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 index refresh is queued; no reindex is needed.
| 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 already set readOnlyHint=false and destructiveHint=false; description adds non-obvious behaviors: automatic newline insertion only when missing, queued index refresh with no reindex needed, and no read required. No contradictory statements.
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 short sentences, each earns its place: purpose first, usage guidance second, newline detail third, index behavior last. No filler 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 4-param tool with full schema detail and an output schema, the description covers the behavioral decisions an agent needs: when to choose it, what happens to newlines, and post-append index state. No significant gap remains.
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 has 100% coverage, so baseline is 3; description adds practical meaning by explaining the automatic newline behavior and telling the caller to include blank lines/heading markers for separation. It does not elaborate every parameter, but the schema already does.
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 'Append text to the end of an existing .md note without reading it', giving a specific verb, resource, and scope. It explicitly contrasts with 'edit', making sibling differentiation immediate.
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?
States the exact condition for use—'purely additive at the end of the note'—and tells the agent to prefer this over 'edit'. Also notes that no prior 'read' is needed, which is the key cost/context benefit.
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 queues an index refresh. 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 destructiveHint annotation, the description reveals important side effects: .md deletions queue an index refresh, attachments do not, and deletion is irreversible unless git history exists. It also instructs the agent to confirm the path with the user, adding meaningful behavioral context not present in the structured annotation.
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, starting with a clear one-sentence summary. Every sentence earns its place: resource scope, index-refresh behavior, irreversibility, and user confirmation are all stated without 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?
For a destructive two-parameter tool with a full output schema and detailed annotations, the description supplies all essential context: what is deleted, side effects on the index, irreversibility, and the required confirmation step. The if_match concurrency behavior is already covered by the schema, so no critical guidance 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 the schema already thoroughly documents both 'path' and 'if_match', including optimistic concurrency semantics. The description reinforces the relative-path convention and the confirmation requirement but does not add significant new parameter-level meaning 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 explicitly states 'Permanently delete a document or attachment', naming both the action and the specific resource types. It clearly distinguishes this tool from siblings like edit, write, and rename by focusing on destructive deletion with a clear scope.
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 use: it is destructive, irreversible, and requires user confirmation before calling. It does not name explicit alternatives or exclusion cases, but the conditional handling of .md documents vs attachments provides practical guidance on when the tool behaves differently.
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 index refresh is queued; no reindex is needed.
| 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 are minimal (only hints about read-only, idempotency, destructiveness), so the description carries the full burden. It fully discloses behavior: three edit modes, normalization fallback with match_type='normalized', queued index refresh, and the need for a prior 'read'. This exceeds what annotations provide.
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?
Well-structured with a clear opening line, bullet-pointed modes, and a closing operational note. Every sentence earns its place; no redundancy. The most critical instruction (call read first) is placed near the end but is highlighted separately, and the overall length is justified by the tool's complexity.
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 (3 modes, normalization, concurrency), the description covers all essential context: how to invoke each mode, the normalization fallback, the index refresh behavior, and the prerequisite of reading first. An output schema exists, so not describing return values is acceptable. 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?
Schema coverage is 100%, so each parameter is individually documented. The description adds value by explaining the relationships between parameters (e.g., line-range mode requires line_start+line_end and omits old_text; scoped match combines old_text with a range). This contextual semantics goes beyond the schema's per-field 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 states a specific action ('targeted text replacement') on a specific resource ('existing .md note') and explicitly excludes attachments, clearly distinguishing it from write/append/delete/rename siblings. The three modes are detailed, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use each mode, instructs to always call 'read' first, and recommends passing if_match for safety. It doesn't explicitly contrast with sibling tools like 'write' or 'append', but the purpose is distinct enough that an agent can infer when to use it.
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 embedding provider and vector-index status.
| 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, and destructiveHint=false, so the safety profile is fully covered. The description adds the specific scope (embedding provider and vector-index status) but doesn't disclose what the status output contains, whether it performs any checks that could be slow, or what failure modes exist. With annotations covering the safety profile, a 3 is appropriate.
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 a single, efficient sentence that front-loads the verb and resource. Every word earns its place, 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?
For a zero-parameter, read-only status tool with an output schema present, the description is largely complete. The output schema presumably documents the return structure, so the description doesn't need to explain return values. The only minor gap is not naming sibling alternatives for disambiguation, but the tool's purpose is clear enough given the sibling list.
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 schema provides no parameter documentation. The description correctly indicates the tool takes no input and simply checks status. With 0 params, the baseline is 4, and the description adequately conveys that no parameters are needed.
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 ('Check') and resource ('embedding provider and vector-index status'), which clearly identifies the tool's purpose. It distinguishes itself from siblings like get_index_status and build_embeddings by focusing on status checking rather than building or indexing, though it doesn't explicitly name those alternatives.
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 usage context: it's a read-only status check for embeddings and vector-index health. However, it doesn't explicitly state when to use this tool versus alternatives like get_index_status or build_embeddings, nor does it mention any prerequisites or conditions that would make this tool the right choice.
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 index refresh is queued.
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 | Etag from 'read'; required by default to replace an existing file. A stale etag refuses the write. Omit for new files. | |
| 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?
Goes far beyond the annotations by disclosing zero context cost, server-side downloading, UTF-8 decoding for .md, binary saving for others, queued index refresh, SSRF protections, redirect-following behavior, and the need to check final_url. This is rich behavioral context that the annotations alone do not provide.
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?
Well-structured and front-loaded: the core purpose appears first, then the key context-cost insight, then path-dependent behavior. Every sentence carries useful information, including security caveats, and the formatting makes the .md vs attachment cases easy 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 5 parameters, an output schema, and nontrivial security behavior, this description is complete: it covers schemes, SSRF, redirects, etag concurrency, timeouts, optional frontmatter, and post-fetch usage. An 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?
Schema coverage is 100% and each parameter already has a detailed description, so the baseline is 3. The prose description adds context around path extension handling and frontmatter behavior, but most parameter meaning is already fully 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?
States a specific verb and resource ('Download a file from a URL and save it to the vault') and clearly distinguishes the tool's niche: MCP-to-MCP transfer of content too large for the LLM context window. It also differentiates .md note behavior from attachment behavior, so an agent can tell this apart from read/write/vault_read 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?
Explicitly gives the intended use case ('MCP-to-MCP file transfer when content is too large to pass through the LLM context window') and tells the agent what to do afterward: reference the file by path, and call read(path) only for small results. This gives clear when-to-use guidance relative to sibling read and write tools.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the inbound scope and rationale but does not disclose return behavior, edge cases, or index freshness details beyond what the parameter schema already explains. This is adequate but not rich.
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 core definition, and structured clearly. A small amount of redundancy exists: the second sentence restates the first concept ('notes reference') and the final sentence reinforces relevance, but overall it remains efficient.
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 complete input schema, output schema, and annotations covering safety and idempotency. The description supplies the missing routing context by naming get_context as the broader alternative, making the definition complete enough for an agent to select and 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%, with path, limit, and wait_for_pending_writes already documented in the input schema. The description adds no parameter-specific meaning beyond what the schema supplies, 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 a specific verb and resource: 'Find all documents that link TO the given document (backlinks).' This clearly defines inbound links and distinguishes the tool from siblings like get_outlinks and get_context by naming the alternative explicitly.
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 routing guidance: use get_context for a full picture of a note's place in the vault and call get_backlinks directly when only the inbound link list is needed. It also notes that backlinks surface relationships search alone cannot, reinforcing when the tool adds value.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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, destructiveHint=false. The description adds useful context beyond these, explaining that a broken link means the target path does not match any indexed document and why that might happen (deleted, renamed, never created). This enriches the agent's understanding of the tool's semantics.
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 mostly efficient, opening with a clear purpose and then giving concrete usage triggers. The last sentence about what 'broken link' means is slightly explanatory but adds useful background, so overall it earns its place without excessive bloat.
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 exists and annotations cover safety, the description is largely complete. It covers what the tool does, when to use it, and what a broken link means. It could mention the folder filter briefly, but the schema already does. No major 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% and both parameters ('folder', 'wait_for_pending_writes') are thoroughly documented in the input schema. The description does not add parameter-level meaning beyond the schema, 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?
States a specific verb ('find') and resource ('links that point to non-existent documents'), clearly distinguishing it from siblings like get_orphan_notes or get_backlinks. The purpose of auditing link health is explicit and actionable.
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?
Gives concrete triggers: call when 'stats' shows broken_link_count > 0, or after a 'rename' that did not use update_links=True. This tells the agent exactly when to use the tool and what scenario it addresses, without confusion.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral detail beyond annotations: links are treated as undirected, BFS is used, and max_depth is clamped to [1, 10].
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 sentences with no filler. The core purpose is front-loaded, followed by key behavioral details and a practical use case. Every sentence contributes meaningful 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?
The description fully covers what the tool does, how it behaves on the link graph, the clamping behavior, and the intended use case. An output schema exists, so return values do not need to be described. No critical information 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 four parameters. The description adds context around max_depth clamping and the undirected interpretation of links, but does not need to explain individual parameters further.
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 and resource: 'Find the shortest connection path between two notes in the link graph.' It clearly distinguishes itself from graph siblings like vault_graph_neighborhood and vault_graph_hubs by focusing on pathfinding between two specific notes rather than neighborhoods or hubs.
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?
Gives clear context for when to use the tool: discovering how seemingly unrelated notes are connected, the 'six degrees of separation' use case. It does not explicitly name alternatives or state when not to use it, but the context is strong enough to guide selection.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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, and destructiveHint=false, so the safety profile is covered. The description adds behavioral context beyond annotations: it consolidates multiple data sources into one call, includes a wait_for_pending_writes option that can return stale data with _meta.index_stale=true, and explains the similarity lookup can be skipped. This gives the agent useful operational knowledge beyond the structured 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 well-structured and front-loaded: the first sentence states the core purpose, followed by a concise list of what it returns, and ends with explicit usage guidance. Every sentence earns its place, and the length is appropriate for the tool's complexity. No fluff or 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?
The description is complete for a read-only consolidation tool. It explains what the tool returns, when to use it, and how it relates to siblings. The output schema exists, so return values don't need to be described. The parameter semantics are fully covered by the schema, and the annotations cover the safety profile. Nothing an agent needs to call 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?
Schema description coverage is 100%, so the schema already documents all four parameters thoroughly. The description adds some context by explaining the consolidation behavior and the conditional use of similar_limit, but it doesn't add significant meaning beyond what the schema provides. Baseline 3 is appropriate since the schema 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 clearly states the tool's purpose: 'Get a consolidated context dossier for a document.' It explicitly lists what it returns (metadata, backlinks, outlinks, similar notes, same-folder notes, frontmatter tags) and names the sibling tools it replaces ('get_backlinks', 'get_outlinks', 'get_similar'). This distinguishes it from siblings and gives an agent a precise understanding of its function.
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 says when to use this tool: 'Use this instead of making 4-5 separate tool calls when you need a full picture of a note's place in the vault.' It also names the alternatives it replaces, providing clear routing guidance. The parameter description for similar_limit adds conditional usage guidance ('do this when stats shows semantic_search_available=False'), which further clarifies when to adjust behavior.
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
Report FTS index readiness, progress, and last build error.
| 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, so the description's 'Report' is consistent and adds no contradiction. It supplements the annotation by specifying that the tool reports progress and last build error, which are useful behavioral details beyond the generic read-only hint. It does not discuss rate limits or side effects, but none are needed for a pure status report.
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?
A single, information-dense sentence that front-loads the action and scope. No filler or redundant wording. Every phrase contributes 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?
For a parameterless status tool, the description is complete: it states what it reports (readiness, progress, error) and the output schema covers return details. No additional guidance is necessary. The tool's role is clear within the sibling set.
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 zero parameters, the baseline is 4 per the rubric. There is nothing to document, and the description correctly mentions no inputs. The output schema (not shown) presumably defines the return structure, so the description does not need to compensate.
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 ('Report') and resource ('FTS index'), and clearly enumerates the reported aspects (readiness, progress, last build error). This distinguishes it from sibling tools like reindex, build_embeddings, or okf_generate_index, which perform actions rather than report 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 implies a read-only status check, and the readOnlyHint annotation reinforces this. However, it does not explicitly state when to use this tool versus alternatives (e.g., before reindexing, or to diagnose build failures). The intended use is inferable from the tool name and the sibling context, but not stated.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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 a behavioral detail beyond annotations by specifying that results are 'ranked by backlink count,' and it adds context about hub notes. 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?
Two sentences pack the core behavior, the value proposition, and the sibling differentiation into ~50 words with no filler. The key function 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?
This is a simple read-only tool with an output schema, fully documented optional parameters, and annotations covering safety and idempotence. The description explains what it does, why to use it, and when to switch to an alternative, so an agent can call 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?
Both 'limit' and 'wait_for_pending_writes' are fully described in the input schema (100% coverage), so the baseline applies. The description does not add any parameter-specific meaning, but the schema already handles 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?
The description states a specific verb ('Return') and resource ('documents with the most inbound links, ranked by backlink count'), and explicitly differentiates from get_backlinks: 'For the specific documents that link to a particular note, use get_backlinks instead.' An agent can distinguish this tool from its siblings clearly.
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 clearly states when to use the tool ('Useful for discovering hub notes') and when not ('For the specific documents that link to a particular note, use get_backlinks instead'), giving an explicit alternative. This is exemplary 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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only and idempotent, but the description adds important behavioral context: 'returns ALL orphans with no limit' and the warning to check orphan_count on large vaults. This goes beyond the structured annotations and helps agents avoid expensive calls.
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: main action first, then a warning, then a definition and usage trigger. Every sentence serves a purpose, and the most important operational caveat 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 simple read-only tool with one optional parameter and an output schema, the description covers what it returns, when to call it, how to identify orphans, and a performance warning. 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?
The single parameter wait_for_pending_writes is fully documented in the schema with 100% coverage, so the description does not need to repeat it. It adds no parameter-specific detail, but the schema carries the load; 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 a specific verb and resource: 'Return all notes with no inbound or outbound links.' It then defines what an orphan note is in concrete terms, making the tool's scope unambiguous and distinct from link-focused siblings like get_backlinks or get_outlinks.
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 an explicit trigger condition: 'Call this when stats shows orphan_count > 0.' It also warns to check stats before use on large vaults. It does not mention when not to use it or name alternative tools, but the usage 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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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 established. The description adds value by disclosing that 'Each result includes an exists flag — False means the link is broken (the target is missing from the vault).' This is a behavioral trait not present in the schema or annotations, informing the agent about broken-link detection. The description does not contradict any annotations, and it enriches the behavioral picture beyond the structured metadata.
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 sentences, front-loaded with the core purpose. It immediately states what the tool does, then provides usage guidance and a key output detail. Every sentence earns its place—no filler or redundancy. The structure is efficient and scannable, ideal for an agent parsing it quickly.
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 (3 parameters, all schema-documented), the presence of an output schema, and strong annotations covering safety, the description is complete. It covers the primary use case, the alternative tool for richer context, and a critical output behavior (exists flag). There is no missing information an agent would need to call this tool correctly. The description is sufficient on its own.
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%, meaning all three parameters (path, limit, wait_for_pending_writes) are already fully documented in the input schema with descriptions. The tool description adds no additional parameter-specific information, which is acceptable because the schema carries the burden. Per the rubric, a baseline of 3 is appropriate when schema coverage is high and the description does not need to compensate. It doesn't add extra meaning beyond the schema, so a 3 is warranted.
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 precise statement of function: 'Find all links FROM the given document to other documents (outlinks).' This gives a clear verb+resource combination. It also distinguishes itself from the sibling get_context by noting that get_context provides a 'full picture of a note's place in the vault,' while this tool is specifically for the outbound link list. This makes the tool's purpose unambiguous and separates it from related 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 explicit guidance: '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 clearly states both when to use this tool and when to prefer an alternative. The condition for direct use is specific, making it easy for an agent to decide.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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 description's burden is lighter. It adds ordering behavior ('ordered by file modification time, most recent first') and implies index usage without a query, which goes beyond the annotations and adds useful context.
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 primary purpose is in the first sentence, followed by the ordering detail, and then use cases. Every sentence contributes value without redundancy, making it efficient and easy 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?
With an output schema present and annotations covering safety, the description provides the essential context: what the tool does, how results are ordered, and when it's useful. It does not need to detail return values or parameter specifics because those are covered elsewhere. Nothing an agent needs to call 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?
Schema description coverage is 100% (all three parameters have detailed descriptions), so the schema already documents parameters. The tool description does not add any additional parameter semantics; it only mentions the general purpose, which is already covered by the schema. 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?
States a specific verb ('Get') and resource ('most recently modified notes in the vault'), and distinguishes itself from search by noting it works 'without a search query.' It clearly identifies what it returns (notes ordered by modification time) and separates it from siblings like search and 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?
Provides concrete use cases ('summarize recent activity or resume work on recently edited notes') and implies the alternative of a search query, but does not explicitly name siblings or state when NOT to use it. This is clear context, though not fully explicit about exclusions.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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 valuable behavioral context: it uses stored embeddings (no re-embedding), excludes the reference document from results, and returns an empty list under certain conditions. It also mentions the wait_for_pending_writes behavior via the parameter description, which is a useful behavioral disclosure.
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. The core purpose is stated in the first sentence, followed by a brief mechanism note and then actionable guidance. Every sentence adds value, and the structure front-loads the most important 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?
The description is complete for an agent to use this tool correctly. It covers prerequisites (semantic search configured), fallback behavior (empty list), and remediation (build_embeddings). The output schema exists, so return values are documented elsewhere. The parameter descriptions are exhaustive, covering edge cases and OKF semantics.
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 description adds context beyond the schema by explaining the overall mechanism (stored embeddings) and the fallback behavior (empty list if not configured). The parameter descriptions themselves are detailed, including edge cases like folder='' for root-level documents and the OKF semantics for filters.
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 function: 'Find notes most semantically similar to the given document.' It specifies the resource (notes), the operation (find similar), and the mechanism (stored embedding vectors). It also distinguishes itself from sibling tools like 'search' by emphasizing semantic similarity rather than keyword matching.
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 on when to use this tool: it requires semantic search to be configured, and it tells the agent to check 'stats' for semantic_search_available. It also explains what to do if embeddings are not configured (call 'build_embeddings') and how to handle missing vectors. This is clear, actionable usage guidance.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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 bar is lower. The description adds real behavioral value beyond that: the conditional return shape per path type, the synthetic H1 title, the ordered aggregation of notes in folder mode, and the mirroring of the toc:// resource with added controls. It does not go into truncation/staleness behavior, but the schema documents those.
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: a one-sentence summary up front, then mode-specific behavior, then the resource mirroring note. Each sentence earns its place and the most decision-relevant fact (note vs folder behavior) is front-loaded. It is slightly verbose in recounting return shapes that the output schema already captures, which keeps it from a 5.
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 — two output modes, four parameters, an existing output schema, and full schema-provided parameter descriptions — the description covers the mode-switching semantics, the synthetic H1 behavior, and the relationship to the toc:// resource. Nothing an agent needs to call it correctly is missing, and the description does not need to repeat return values because an output schema exists.
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 and the schema carries the full detail on max_level, max_notes, and wait_for_pending_writes. The description adds marginal semantics by explaining how 'path' determines mode (”.md" suffix → note vs folder prefix) and by naming the controls, but stops short of enriching the parameters' meaning beyond that.
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 opening sentence 'Heading outline for a single note or a whole folder subtree' names a specific resource and purpose, and the description immediately distinguishes two modes by path type ('If 'path' ends in '.md' it is a note... Otherwise 'path' is a folder'). This cleanly separates it from sibling read/navigation tools like read, search, and browse_vault.
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 strong operational guidance on mode selection (note vs folder based on path suffix) and connects the tool to the 'toc://vault/{path}' resource. However, it never explicitly tells the agent when to prefer this over siblings such as read, list_documents, or search, nor states any when-not conditions, so the usage context against alternatives is only implied.
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 reached), 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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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 a meaningful behavioral trait: 'Does NOT include body content — call 'read' for full text.' This goes beyond annotations by clarifying the return semantics and what the tool will not do.
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, and each subsequent sentence earns its place by addressing alternatives or exclusions. There is zero filler and every line contributes to the agent's ability to invoke the tool correctly.
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 has a rich output schema.</thinking> The description covers all decision-relevant context: enumeration vs. search, body content exclusion, attachment option, and alternative tool selection. The remaining details (folder semantics, filter behavior, pattern syntax) live in the input schema, which is thoroughly documented. Nothing an agent needs to decide when to call this tool 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 the schema fully documents all five parameters. The description adds contextual framing (e.g., 'optionally attachments', complete listing vs. search) but does not introduce parameter-level semantics beyond what the schema already provides. 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?
The description opens with a specific verb and resource: 'List documents (and optionally attachments) in the vault.' It also differentiates itself from sibling tools by explicitly contrasting with 'search' for content-based retrieval and 'read' for full text, 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 provides explicit when-to-use guidance: 'Use this to enumerate documents when you need a complete listing, not ranked search results.' It also names alternatives ('search', 'read') with the conditions that select them, leaving no ambiguity about routing.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already include readOnlyHint=true, idempotentHint=true, and destructiveHint=falseainer. The description adds useful behavioral detail by clarifying that root-level documents correspond to an empty string path. It does not contradict the annotations, though it leaves the wait_for_pending_writes behavior to the schema and parameter description.
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, and has no filler. Both sentences contribute essential information: what the tool returns and the important root-folder convention.
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 listing tool with one optional parameter, an output schema, and clear annotations, the description fully covers what an agent needs to select and invoke it correctly. The root-path clarification adds important context that is not otherwise obvious.
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% for the single optional parameter, and the schema itself explains its semantics, default, and timeout behavior. The tool description does not need to add anything further about parameters; 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 states a specific operation ('List all folder paths that contain documents') and clearly identifies the resource. It also distinguishes itself from list_documents and search by emphasizing folder paths rather than content or 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 says to call this tool to discover valid folder names before filtering 'search' or 'list_documents' by folder. This gives clear, actionable guidance on when to use it and for what purpose.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, idempotentHint=true, and destructiveHint=falsehare. The description adds non-obvious behavior: unindexed fields return an empty list rather than an error forging a timeout. This is useful behavioral context beyond 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 compact and front-loaded: the first sentence states the core purpose, the second gives direct usage guidance, and the third warns about a critical edge case. Every sentence earns its place 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 output schema existswrong documents return values, and annotations already describe safety, the description is sufficiently complete. It covers what the tool lists, how to use it, where to find valid fields ('stats'), and what happens with invalid inputs.
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 schema already documents both 'field' and 'wait_for_pending_writes' clearly. The description mostly restates the field concept at a higher level without adding new parameter-level details, so a 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 uses a specific verb and resource: 'List all distinct values for a frontmatter field across the vault.' This clearly states what the tool does and distinguishes it from sibling tools like list_documents, list_folders, and stats by focusing on frontmatter field value enumeration.
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 tells the user to reference 'stats' for indexed fields and warns that querying non-indexed fields returns an empty list, giving clear before-use context.
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. Link rewrites wait for prior index writes. The move queues an index refresh; no reindex is needed.
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?
The description discloses the atomic gate (fails if destination exists), best-effort link rewrites with failed_links reporting, and the risk of partial moves on OS errors with a recommendation to reindex. This goes well beyond the destructiveHint annotation, providing rich behavioral context.
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 lengthy but every sentence carries essential information about failure modes, link rewriting, and recovery. It is front-loaded with the core purpose and avoids fluff, though it could be tightened slightly.
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 complex recursive move with link rewriting, the description covers the atomic gate, best-effort rewrites, failure reporting, and recovery via reindex. Nothing essential for correct invocation is missing, and the output schema is referenced via failed_links.
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 already covers both parameters at 100%, but the description adds meaning by explaining old_dir/new_dir as relative prefixes, describing merge behavior into existing folders, and noting that a name clash aborts the move. This adds value beyond the schema 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?
Clearly states the tool moves an entire folder subtree in one call and rewrites all links into the moved subtree, explicitly positioning itself as the folder-level analogue of rename. This distinguishes it from sibling rename and other 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?
It identifies itself as the folder-level analogue of rename, implying use for moving folders with link rewriting. However, it does not explicitly state when not to use it or name alternatives (e.g., rename, write), leaving the selection context somewhat implicit rather than explicit.
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; attachment embeds are not links. Each changed
note is written through the write path (git commit if configured).
Re-running is safe: converted links are plain markdown and are not
touched again. Waits up to 60s for prior index writes; refresh
errors abort before conversion.
| 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?
Annotations already signal idempotent and destructive, and the description deepens this by disclosing that changed notes go through the write path with possible git commits, that it waits up to 60s for index writes, that refresh errors abort before conversion, and that re-running is safe because converted links are plain markdown. No contradiction with readOnlyHint=false, idempotentHint=true, or destructiveHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but purposeful, front-loading the core transform in the first sentence and then listing behavioral constraints. It is longer than strictly necessary because the first sentence restates the title's 'Convert Wikilinks' concept, but every remaining clause adds meaningful operational 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?
For a one-optional-parameter destructive transform with an output schema, the description covers the conversion rule, scope, skip conditions, write-path behavior, idempotency, timeout, and error handling. An agent has enough context to decide and invoke the tool without needing the return structure, which is covered by the output schema.
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 optional folder parameter is already fully documented in the schema. The description reinforces that the folder restricts subtree conversion, but it does not add semantic detail beyond the schema, 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 first sentence names a specific verb and resource: 'Rewrite wikilinks as OKF bundle-root-absolute markdown links,' and the paragraph clarifies it converts resolvable [[wikilinks]] in the vault or a folder. This distinguishes it from sibling tools like okf_validate or okf_generate_index, which serve different migration/indexing 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?
The description frames the tool as a migration transform and states explicit input constraints: only indexed/resolvable wikilinks are converted, unresolvable ones are skipped, and attachment embeds are not links. It does not name alternative tools, but the unique migration purpose and constraints give an agent clear guidance on when this tool applies.
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. Waits up to
60s for prior index writes; refresh errors abort before generation.
| 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?
Annotations already declare destructiveHint=true and idempotentHint=true, and the description adds meaningful behavioral context: it overwrites index.md, preserves frontmatter, omits reserved files, waits up to 60s for prior writes, and aborts on refresh errors. This goes beyond the annotations and gives an agent a clear model of side effects and failure modes. 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 compact and front-loaded: the first sentence states the core purpose, and the following sentences add necessary behavioral details without redundancy. Every sentence earns its place, and the structure is easy 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 tool's complexity (a migration transform with overwrite behavior, frontmatter preservation, reserved-file omission, and timeout/error handling), the description covers the key operational aspects. It does not detail the output schema's contents, but an output schema exists, so that is not required. A minor gap is not explicitly stating what happens if the folder does not exist or has no table of contents, but the description is otherwise complete enough 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 schema already documents the 'folder' parameter. The description adds value by explaining that omitting folder targets the bundle root and that the folder is vault-relative. This is useful semantic context beyond the schema's default/description.
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 ('Generate'), a specific resource ('reserved OKF index.md listing'), and the mechanism ('from the table of contents'). It clearly distinguishes this from sibling tools like okf_validate or okf_seed_log by naming the output artifact and the OKF migration-transform 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?
The description explains when to use it: to generate or regenerate a folder's index.md, with the folder parameter optional for the bundle root. It does not explicitly name alternatives or say when not to use it, but the context of OKF migration transforms and the explicit 'writes (or overwrites)' behavior gives clear usage context. A small gap is not stating which sibling tool would be used instead for other index operations.
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 Open Knowledge Format conformance.
| 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, and destructiveHint=false, so the description doesn't need to restate safety. The description adds only the notion of 'audit', implying a read-only check. It doesn't disclose what the audit returns or whether it produces a report, but the output schema likely covers that. Given the annotations carry the safety profile, the description adds minimal behavioral context, so a 3 is appropriate.
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 a single sentence with no unnecessary words. It front-loads the verb 'Audit' and the resource, making it immediately clear. There is zero waste.
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 no parameters and annotations covering safety, the description is mostly complete. It doesn't explain what 'conformance' means or what the output looks like, but the presence of an output schema and the read-only annotations cover the essentials. An agent can call it without needing extra context.
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, and the schema is empty with 100% coverage. Per guidelines, a 0-parameter tool gets a baseline of 4. The description adds no parameter information, which is fine since there are none to document.
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 'Audit' and identifies a clear resource: 'the vault's Open Knowledge Format conformance'. This distinguishes it from sibling tools like okf_convert_links and okf_generate_index, which have different purposes. It is not a tautology and directly conveys the tool's function.
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 no guidance on when to use this tool versus alternatives. It does not mention conditions like 'use when you need to verify OKF compliance before converting links' or 'use after generating an index to validate'. There is no mention of exclusions or preferred workflows, leaving the agent to infer usage from the tool name alone.
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).
Pass revision= (git-backed vaults) to read the note as it stood at that commit — the route back to content a 'write' replaced. Use a write's 'previous_revision', or a sha from 'get_history'. To restore: read again without revision= for a current etag, then 'write' with if_match set to it.
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. | |
| revision | No | Read the note as it stood at that commit instead of on disk (git-backed vaults, .md only). A sha from 'get_history' or a write result's 'previous_revision'. Pass *path* as the note is named today; renames are followed. Composes with section=. |
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, and destructiveHint=false. The description goes well beyond this by disclosing return types (raw markdown vs base64 binary), context-cost implications, byte-size limits with environment variables, ValueError behavior, and the fact that section= is ignored for non-.md paths. 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 and organized into clear paragraphs for file types, path discovery, section usage, revision usage, and context cost. It is longer than average but most sentences add value; the only minor issue is some repetition of the section= guidance near the end.
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 three parameters, annotations, and an output schema, the description covers discovery prerequisites, markdown vs attachment returns, section semantics, revision semantics, size limits, and error behavior. Nothing an agent needs to call 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?
Although the input schema already covers 100% of parameters, the description adds substantial meaning: section= should receive the heading value from a search result and is case-sensitive with collapsed whitespace; revision= accepts a sha from get_history or previous_revision and follows renames; and path should not be guessed. This meaningfully exceeds the schema 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: 'Read the full content of a document or attachment by path.' It clearly distinguishes .md behavior from attachment behavior, but it does not explicitly differentiate itself from sibling read-like tools such as get_context, vault_read, or browse_vault, so it stops short of full 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 gives explicit when-to-use guidance: use list_documents(include_attachments=True) to discover attachment paths, use stats for allowed extensions, and do not guess paths but look them up via search or list_documents. It also explains when to use section= and revision=, and how to restore a previous version with write and if_match. This is strong, actionable routing.
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 queue index updates automatically.
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?
Beyond the annotations (readOnly=false, idempotent=true, destructive=false), the description reveals async continuation: a reindex past the server deadline returns immediately with job_id, and get_index_status covers non-client-initiated builds. It also details hash-based detection, force behavior (index not queryable during rebuild), and interaction with embedding builds. This is rich disclosure out of annotation tags.
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 function and its trigger, then gives exclusions, force semantics, embedding interactions, and async result handling. Some sentences (e.g., '#1124' reference) are minor extraneous color, but each paragraph advances a decision an agent must make. It's thorough without being bloated for the tool's real complexity.
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 an output schema present and 1 param, the description references the observability tool get_index_status and attr the async job fetch tool get_job_result; it also pre-charts the build_embeddings path for force=True. The common-case and rare-case flows are both covered, leaving nothing an agent needs to call 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 schema already documents force at 100% coverage, but the description gives extra context on when to force (repair for content mismatch, version upgrade auto, manual escape hatch), contrasts it with routine reindexing, and mandates the follow-up build_embeddings. This meaningfully lifts the parameter beyond schema bare definition, justifying a step above 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?
States a specific verb-resource pair ('Run an incremental reindex on the writer thread') and immediately scopes it to files modified outside the server, distinguishing it from write/edit/delete/rename (which queue updates) and from build_embeddings (which rebuilds the vector index). The purpose is unique and not generic.
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 explains when to use: only when files were modified by an external process (text editor, sync tool, direct vault writes). It also says when NOT to use it — never after write/edit/delete/rename — and guides force=True usage, routing to build_embeddings for a full semantic rebuild. This is full when/when-not/alternatives coverage.
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.
For .md documents: link rewrites wait for prior index writes. The move queues another index refresh; no reindex is needed. For attachments: only the file is moved; update_links does not apply (attachment references are not tracked as links). Parent directories 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?
The description discloses several non-obvious behaviors beyond the annotations: link rewrites wait for prior index writes, the move queues another index refresh (no reindex needed), and attachment references are not tracked as links. It also notes that parent directories are created automatically. These details are highly valuable for an agent to understand side effects. The annotations are minimal (readOnlyHint, idempotentHint, destructiveHint) and the description does not contradict them; it adds substantial behavioral context.
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 three concise paragraphs, each with a clear purpose. The first sentence states the core function. The second gives a key rule. The third splits behavior by file type. There is no fluff or repetition; every sentence adds necessary information. The structure is logical and 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?
Given the complexity of this operation (rename/move with link rewriting, concurrency, index refresh), the description covers all non-obvious aspects: link rewrite behavior, attachment exceptions, automatic directory creation, and index refresh timing. Since an output schema exists, return format is covered elsewhere. The description is complete for an agent to correctly invoke the tool without additional hidden details.
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 all parameters are already documented in the input schema. The description adds extra semantic value by advising to always set update_links=True for .md files and clarifying that update_links is irrelevant for attachments. It also notes automatic directory creation, which relates to new_path. While it doesn't elaborate on old_path or if_match, those are self-explanatory from the schema. This goes beyond the baseline 3.
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 'Rename or move a document or attachment,' which clearly identifies the verb and resource. It distinguishes itself from sibling tools like write/edit/delete by specifying the rename/move action, and it even clarifies scope (documents and attachments). This is unambiguous and immediately tells an agent what this tool does.
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 conditional guidance: 'When renaming a .md note, always pass update_links=True' and explains that attachments don't need it. It also clarifies that parent directories are auto-created. However, it doesn't explicitly compare to alternative tools (e.g., 'use this instead of move_folder for files'), but the context is clear enough. The guidance for the key decision (update_links) is strong, so this is slightly above average.
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 reached), 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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds valuable behavioral context beyond that: result content is a snippet by default, not the full document, and read should be used for full sections. It also implies mode fallback behavior without contradicting 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 compact and front-loaded: the first sentence states the core purpose, the second paragraph gives actionable mode guidance, and the third covers the snippet caveat. No sentence is wasted, and the structure guides the agent from broad behavior to invocation 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 the rich input schema (100% coverage), the output schema, and the read-only/idempotent annotations, the description is complete enough. It covers the key decision points an agent needs—mode selection and the snippet-versus-full-document distinction—without needing to restate schema details or return values.
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 decision-oriented meaning for the mode parameter (hybrid when embeddings are configured, keyword when not, semantic for pure vector similarity) and clarifies that content fields are snippets, which helps interpret snippet_words. It does not need to repeat the well-documented schema 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: 'Find documents matching a query using full-text or semantic search.' It also clarifies the scope ('Search the vault') and differentiates the tool from read by directing the agent to use read for full document text, which separates search from a sibling retrieval tool.
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: omit mode for the best available mode, use keyword for exact terms/operators/filenames, and use semantic for pure vector similarity. It also tells the agent when to hand off to read for full section text, which is concrete alternative guidance.
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 | Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false. |
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, and destructiveHint=false, so the safety profile is clear. The description adds useful behavioral context by revealing that the output includes a semantic_search_available field that determines whether mode='semantic' or mode='hybrid' can be used in search.
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 three sentences with no filler. The purpose is front-loaded, followed by explicit usage guidance and a useful output-field hint. Every 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?
The tool has rich annotations, a well-described parameter, and an output schema, so the description does not need to repeat those. It supplies the missing context: when to call, what to use the result for, and how the result relates to search modes.
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 is only one optional parameter, and the schema description covers it 100%, including its default and timeout behavior. The tool description adds no parameter semantics, 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 an overview of the vault's size, capabilities, and configuration.' It also clarifies the practical purpose—understanding what the vault contains and which search modes are available—which distinguishes it from sibling tools 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 explicitly recommends calling this 'at the start of a session' and explains how the semantic_search_available field affects use of the search tool. It does not name alternatives or exclusions, but the context is clear enough for an agent to know when this is the right tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_contextVault ContextARead-onlyIdempotent
Return the full NoteContext for a note (app-only).
Called by the SPA context card view via app.callServerTool().
Not visible to the LLM.
| 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, so the safety profile is covered structurally. The description adds useful invocation context ('SPA context card view', 'app.callServerTool()') and notes that it returns the 'full NoteContext,' but it does not go beyond that. With strong annotations, a 3 is appropriate.
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, purposeful sentences. The core purpose is front-loaded, followed by invocation context and visibility restriction. There is no filler or repetition of annotation data.
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 one-parameter tool with a full output schema and rich annotations, the description provides sufficient context: what it returns, who calls it, and that it is not visible to the LLM. Nothing needed to select or 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?
Schema description coverage is 100%: the path parameter already has a clear description and example. The tool description adds no parameter-specific meaning, but with full schema coverage the baseline of 3 is correct.
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 and resource: 'Return the full NoteContext for a note.' It further clarifies the tool is 'app-only' and 'Not visible to the LLM,' which distinguishes it from LLM-facing context tools like get_context or show_context. This is not a tautology of the title.
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 clearly specifies when this tool is used: 'Called by the SPA context card view via app.callServerTool().' The 'Not visible to the LLM' line provides a when-not to use it, though no alternative tool is explicitly named. The invocation context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_graph_hubsGraph HubsARead-onlyIdempotent
Return the most-linked notes and their connections as a graph (app-only).
Called by the SPA graph view for the hub overview. Not visible to the LLM.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max number of hub notes to include. |
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=true, idempotentHint=true, and destructiveHint=false, indicating a safe read operation. The description adds the important behavior that it is 'app-only' and 'Not visible to the LLM,' which is critical for an agent to know before calling it, as it may not be relevant or accessible for LLM workflows.
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, with three short sentences. The core purpose is front-loaded, and every sentence adds value: what it returns, when it's used, and a crucial caveat about LLM visibility. No waste.
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 only one optional parameter and an output schema, so it's relatively simple. The description covers the purpose and usage context, and the output schema likely explains the return format. The main missing piece is an explicit mention of the 'limit' parameter's effect on performance or graph size, but this is minor.
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 provides 100% coverage for the single parameter 'limit' with a clear description of 'Max number of hub notes to include.' The description does not add further parameter semantics, but since schema coverage is high, 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 clearly states it returns the most-linked notes and their connections as a graph, specifying it is app-only and used by the SPA graph view. This distinguishes it from siblings like get_most_linked, which likely returns a simple list, and vault_graph_neighborhood, which focuses on a specific note's connections.
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 states it is called by the SPA graph view for the hub overview, giving clear usage context. However, it does not explicitly explain when to use this over siblings like get_most_linked or get_connection_path, nor does it mention any exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_graph_neighborhoodGraph NeighborhoodARead-onlyIdempotent
Return the link neighborhood of a note as a node/edge graph (app-only).
Called by the SPA graph view via app.callServerTool().
Not visible to the LLM.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Center note path. | |
| depth | No | How many hops to traverse (default 1). | |
| max_nodes | No | Soft cap on returned node count (default 200). BFS and any semantic expansion both stop once the cap is hit; the response sets ``truncated=True``. Bounds dense-vault depth=2 traversals that would otherwise bog down vis-network. | |
| include_semantic | No | When True, add dashed semantic-similarity edges for each interior node (requires embeddings to be configured; silently omitted when unavailable). |
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=false; the description adds the node/edge graph return shape and internal caller context. It does not contradict annotations, but it contributes little behavioral detail beyond what the schema and annotations already encode.
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 only three short sentences, with the core purpose front-loaded before caller context. It is efficient and scannable, with only slight redundancy between 'app-only' and 'Not visible to the LLM.'
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?
An output schema exists, the input schema is fully documented, and annotations cover safety, so the description need not repeat those details. It sufficiently conveys the tool's restricted visibility and purpose for its intended caller, though it could improve by pointing to graph-related siblings.
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 rich per-parameter details such as the default depth, soft node cap, truncated flag, and conditional semantic-edge behavior. The description itself adds no parameter-level meaning, 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 first sentence identifies a specific action and resource: 'Return the link neighborhood of a note as a node/edge graph (app-only).' The purpose is unmistakable, but it does not differentiate this from related graph siblings such as vault_graph_hubs or get_connection_path.
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 scopes the tool as 'app-only,' says it is 'Called by the SPA graph view via app.callServerTool(),' and adds 'Not visible to the LLM,' giving clear invocation context and an exclusion. It stops short of naming alternatives or selection conditions versus other graph tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_listVault ListARead-onlyIdempotent
List folders and notes in a vault directory (app-only).
Called by the SPA browser view via app.callServerTool().
Not visible to the LLM.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Folder to list (root if omitted). |
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, so the safety profile is covered. The description adds the app-only and SPA context, which is valuable behavioral context beyond the annotations, clarifying the intended invocation path and non-LLM visibility.
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 concise sentences with zero waste. The primary purpose is front-loaded, and the app-only note follows naturally. Every 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?
For a simple read-only tool with one optional parameter, annotations cover safety, an output schema exists (so return format is defined), and the description clarifies usage scope. Nothing an agent needs to correctly avoid or understand this tool 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 fully documents the single 'folder' parameter with its description ('Folder to list (root if omitted).'), giving 100% coverage. The tool description adds no extra parameter detail, so the baseline of 3 is appropriate since the schema already carries the 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 clearly states the tool lists folders and notes in a vault directory, using a specific verb and resource. It also distinguishes itself from sibling tools like list_folders and list_documents by covering both types, and notes it's app-only, which further clarifies its 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 explicitly states it is called by the SPA browser view via app.callServerTool() and is not visible to the LLM, which tells an agent this tool is not for direct LLM use. It doesn't name alternative tools, but the app-only note strongly implies the agent should look elsewhere for LLM-facing list operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_readVault ReadARead-onlyIdempotent
Read a note's full content for preview rendering (app-only).
Called by the SPA browser view via app.callServerTool().
Not visible to the LLM.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Relative note path. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, and non-destructive behavior. The description adds meaningful context beyond those: the intended caller (SPA browser view), invocation mechanism (app.callServerTool()), and visibility restriction (not visible to the LLM).
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, each carrying distinct information: purpose, invocation context, and visibility. The core purpose is front-loaded with 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?
For a simple one-parameter read tool with strong annotations and an output schema present, the description supplies the necessary invocation context and access restriction. Nothing critical is missing for an agent to decide whether and how to call 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% and the single parameter 'path' is already described as 'Relative note path.' The description adds no additional parameter-level semantics beyond confirming the resource is a note.
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 action and resource: 'Read a note's full content for preview rendering'. It also clearly scopes the tool as 'app-only', distinguishing it from LLM-facing siblings like 'read' and 'browse_vault'.
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 usage context: called by the SPA browser view via app.callServerTool(), and explicitly says it is not visible to the LLM. It stops short of naming a specific alternative ('use read instead'), but the exclusion is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_searchVault SearchARead-onlyIdempotent
Search the vault (app-only).
Called by the SPA browser search bar via app.callServerTool().
Not visible to the LLM.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Search mode (keyword, semantic, or hybrid). | hybrid |
| limit | No | Max results. | |
| query | Yes | Search query string. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive behavior. The description adds important behavioral context: the tool is app-only, invoked through a specific server call path, and hidden from the LLM. No annotation 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?
Extremely concise: three short lines front-load the core purpose, then add only the necessary caller and visibility context. Every sentence earns its place with 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?
Given the low complexity, complete input schema, and presence of an output schema, the description covers everything needed: what it does, who calls it, and why it should not be used by the LLM. 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 the schema fully documents query, mode, and limit. The description adds no parameter-level meaning beyond what the input schema already provides, matching the baseline for high 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?
States a specific verb and resource: 'Search the vault'. The qualifier '(app-only)' and the caller context distinguish it from sibling search-like tools such as 'search', 'vault_read', and 'browse_vault', making selection unambiguous.
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 names the sole caller: 'Called by the SPA browser search bar via app.callServerTool()'. It also gives a clear when-not condition with 'Not visible to the LLM', so an agent knows this tool is not intended for LLM selection.
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 index refresh is queued; no reindex is needed.
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 | Etag from 'read'; required by default to replace an existing file. A stale etag refuses the write. Omit for new files. | |
| 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?
Annotations already declare readOnlyHint=false, idempotentHint=true, destructiveHint=false. The description adds important behavioral context: it warns that the entire file is replaced, explains that the index refresh is queued (no reindex needed), and notes that 'content' and 'frontmatter' are ignored for attachments. It also discloses the base64 token cost. This goes beyond the annotations and provides meaningful behavioral transparency.
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 clear sections for .md documents and attachments. It front-loads the core purpose, then provides conditional details. Every sentence adds value: the warning about file replacement, the index refresh note, the base64 cost warning, and the parent directory behavior. 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?
The description is complete for a write tool with an output schema. It covers the two main use cases (markdown and attachments), explains the overwrite behavior, the etag requirement (via schema), the index refresh behavior, and the base64 cost. The output schema exists, so return values don't need to be described. Nothing critical is missing for an agent to call this 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 schema already documents all parameters. The description adds value by explaining the relationship between parameters (e.g., 'content' vs 'content_base64' based on file extension, 'frontmatter' ignored for attachments) and by warning about the base64 token inflation. This is more than the schema alone provides, though the schema already does 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 clearly states the tool's function: 'Create or overwrite a document or attachment.' It distinguishes between .md documents and attachments, and explicitly names the sibling 'edit' for targeted changes, which differentiates it from the write operation. The verb 'write' plus the resource types (document/attachment) makes the purpose unambiguous.
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 usage guidance: it says to use 'edit' for targeted changes, and explains when 'content' vs 'content_base64' is used. It also notes that parent directories are created automatically, which is a useful prerequisite. This is clear context for when to use this tool vs alternatives.
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.
24 tool updates
v5.0.0- Changed
fetch1 field changed- changed
Input schema / properties / if_match / descriptionPrevious value: -"Optional etag from a previous 'read' call for\noptimistic concurrency. Omit to write unconditionally."New value: +"Etag from 'read'; required by default to replace an\nexisting file. A stale etag refuses the write. Omit for new files."
- Changed
get_backlinks1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_broken_links1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_connection_path1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_context1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_most_linked1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_orphan_notes1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_outlinks1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_recent1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_similar1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
get_toc1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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)."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
list_documents2 fields changed- changed
Input schema / properties / filters / descriptionPrevious value: -"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)."New value: +"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 reached), 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\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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
list_folders1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
list_tags1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
read1 field changed- added
Input schema / properties / revisionAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Read the note as it stood at that commit instead of on\ndisk (git-backed vaults, .md only). A sha from 'get_history'\nor a write result's 'previous_revision'. Pass *path* as the\nnote is named today; renames are followed. Composes with\nsection=." +}
- 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. 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\"}."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\nreached), 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\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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Changed
stats1 field changed- changed
Input schema / properties / wait_for_pending_writes / descriptionPrevious 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."New value: +"Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false."
- Added
vault_context - Added
vault_graph_hubs - Added
vault_graph_neighborhood - Added
vault_list - Added
vault_read - Added
vault_search - Changed
write1 field changed- changed
Input schema / properties / if_match / descriptionPrevious value: -"Optional etag obtained from a previous 'read' call.\nWhen provided, the write only proceeds if the file has not\nbeen modified since that read (optimistic concurrency).\nOmit to write unconditionally."New value: +"Etag from 'read'; required by default to replace an\nexisting file. A stale etag refuses the write. Omit for new files."
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
Scored across 44 tools
Every tool has a clearly distinct purpose, reinforced by detailed descriptions and cross-references (e.g., show_context vs get_context, vault_* marked app-only). The graph-analysis tools (backlinks, outlinks, broken links, orphans, most_linked, connection_path) are each specific, and even the naming overlap between read/vault_read and search/vault_search is resolved by explicit app-only tags.
Most tools follow a verb_noun pattern with consistent prefixes like get_ and list_, but there are deviations: bare verbs (search, read, write, edit, append, delete, rename, fetch, reindex, stats) and irregular names like embeddings_status and the okf_/vault_ prefixed tools. The pattern is readable but not fully uniform.
With 44 tools (even ~38 excluding app-only), the server is well beyond the 25+ threshold for 'too many'. Many read-only query tools could be consolidated (e.g., get_context already combines backlinks/outlinks/similar but the individual get_* tools remain), adding unnecessary selection complexity for an agent.
The tool surface provides complete lifecycle coverage: CRUD (write, read, edit, append, delete, rename, move_folder), search (keyword/semantic/list), link-graph analysis, index/embedding management, git history/diff, conventions, OKF migration, and UI tools. No significant gaps for a markdown vault server are apparent.
Maintenance
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.56 npm2MIT
- AlicenseAqualityAmaintenanceLocal 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.221,202 PyPIApache 2.0