Skip to main content
Glama
pvliesdonk

markdown-vault-mcp

by pvliesdonk

Markdown Vault MCP

CI codecov PyPI Python License Docker Docs llms.txt Template

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 via read(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, the okf_* tools, create_upload_link) are registered by default and hidden when MARKDOWN_VAULT_MCP_READ_ONLY=true; writes update the index automatically, per-folder _conventions.md authoring rules are surfaced to LLM clients at write time, and attachments (PDFs, images, and other non-markdown files) are read/write too.

  • Incremental reindexing: hash-based change detection with boot-time reconciliation; the vector index converges to the reconciled chunk set, and parse-pipeline upgrades rebuild the index once automatically.

  • Git integration: optional auto-commit on every write with deferred push, a pull loop or GitHub webhook for external changes, and git history/diff tools. See the Git integration guide.

  • OKF-aware: recognizes Open Knowledge Format bundles and annotates results with each note's type, lifecycle status, staleness, and trust tier, plus conformance audit and migration tooling. See the OKF guide.

  • MCP surface: 34 LLM-visible tools, 9 resources, and 8 prompt templates, plus browser-based MCP Apps views and one-time transfer links. Full references: Tools, Resources, Prompts, MCP Apps, Transfer links, CLI.

Related MCP server: kmd

What you can do with it

With this server mounted in Claude, you can:

  • Capture a URL as a note. "Fetch , summarize as a Resource note under 3-Resources/, and link any existing notes on the topic." Claude composes fetch + 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) + write with 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. The para-capture-chats prompt is the one-click version.

  • Find missing links. Fire the propose-links prompt 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 composes read + 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-mcp

If 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 embeddings

For 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-groups

Docker

docker pull ghcr.io/pvliesdonk/markdown-vault-mcp:latest

To 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:edge

A compose.yml ships at the repo root as a starting point. Copy .env.example to .env, edit, and docker compose up -d.

To attach a remote Python debugger (development only; the protocol is unauthenticated), see Remote debugging.

Linux packages (.deb / .rpm)

Download .deb or .rpm packages from the GitHub Releases page. Both install a hardened systemd unit; env configuration is sourced from /etc/markdown-vault-mcp/env (copy from the shipped /etc/markdown-vault-mcp/env.example).

Claude Desktop (.mcpb bundle)

Download the .mcpb bundle from the GitHub Releases page and double-click to install, or run:

mcpb install markdown-vault-mcp-<version>.mcpb

Claude 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

edge (rolling)

None; the commit is the identity

Docker image :edge rebuilt on every merge to main; .mcpb bundle as the mcpb-bundle-edge workflow artifact; Claude Code plugin .zip as the plugin-zip-edge artifact; rolling unstable docs version. It leaves no git tag, GitHub release, or PyPI entry behind.

Pre-release

vX.Y.Z-rc.N, computed and reviewed in its release pull request

PyPI (as the pre-release X.Y.ZrcN); GitHub release with wheels, sdist, .deb/.rpm packages, .mcpb bundle, plugin .zip, and SBOM attached; Docker image under its immutable vX.Y.Z-rc.N tag plus the ordering-aware rolling rc tag. Skips the plugin marketplace, the MCP registry, and the docs deploy.

Stable

vX.Y.Z

Everything: PyPI, Docker (version tag plus ordering-aware latest / vX / vX.Y), .deb/.rpm, GitHub release assets (wheels, sdist, .mcpb bundle, plugin .zip, SBOM), plugin marketplace and MCP registry entries (when the release is the newest stable), versioned docs with an ordering-aware latest alias.

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 HTTP

For library usage (embedding the domain logic without the MCP transport), import from the markdown_vault_mcp package directly. See the project's domain modules under src/markdown_vault_mcp/ for entry points.

Server info

The server registers a built-in get_server_info tool (via fastmcp_pvl_core.register_server_info_tool) so operators can confirm the deployed version with a single MCP call. The default response carries server_name, server_version, and core_version. Servers that talk to a remote upstream wire upstream version reporting inside the DOMAIN-UPSTREAM-START / DOMAIN-UPSTREAM-END sentinel in src/markdown_vault_mcp/server.py; see tool-registration for the wiring pattern.

Configuration

Core environment variables shared across all fastmcp-pvl-core-based services:

Variable

Default

Description

MARKDOWN_VAULT_MCP_KV_STORE_URL

file:///data/state

Persistent-state backend URL shared by every pvl-core subsystem that needs state. memory:// is in-process and lost on restart; file:///path persists on one server; redis://, dynamodb:// and mongodb:// each need their matching extra. When unset, defaults to file:///data/state (the volume family Docker images mount), or to memory:// (with a warning) on a host where that directory is not usable.

FASTMCP_LOG_LEVEL

INFO

Log level for FastMCP internals and app loggers (DEBUG / INFO / WARNING / ERROR / CRITICAL). The -v CLI flag overrides to DEBUG.

FASTMCP_ENABLE_RICH_LOGGING

true

Set false for plain or structured JSON log output.

Domain-specific variables go below under Domain configuration.

Authentication

Callers authenticate via a bearer token or OIDC (mutually exclusive). See the Authentication guide for setup, mapped multi-subject tokens, OIDC, and troubleshooting.

Post-scaffold checklist

After copier copy and gh repo create --push:

  1. Fill in the DOMAIN blocks (every section marked with a DOMAIN sentinel comment) in this README and in AGENTS.md. The GENERATED-ENV-TABLE-* regions are not DOMAIN blocks; the config generator owns them and rewrites them on every run.

  2. Configure GitHub secrets (see below).

  3. Install dev + docs tooling: uv sync --all-extras --all-groups.

  4. Install pre-commit hooks: uv run pre-commit install.

  5. Run the gate locally: uv run pytest -x -q && uv run ruff check --fix . && uv run ruff format . && uv run mypy src/ tests/.

  6. 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

RELEASE_TOKEN

release-prepare.yml, release.yml, copier-update.yml, renovate.yml, bootstrap.yml

Fine-grained PAT at https://github.com/settings/personal-access-tokens/new with contents: write, pull_requests: write, and administration: write (bootstrap applies the repository rulesets + auto-merge). Must belong to a repository admin: the shipped rulesets grant bypass to the admin role, and the release tag + GitHub release that knope creates after a release pull request merges rely on it (pull requests the token opens also need it so their CI runs). Scoped to this repo.

CODECOV_TOKEN

ci.yml

https://codecov.io: sign in with GitHub and add the repo. The upload token is on its settings page.

CLAUDE_CODE_OAUTH_TOKEN

claude.yml

Optional. Run claude setup-token locally and configure this only for @claude or opted-in automatic review.

gh secret set RELEASE_TOKEN
gh secret set CODECOV_TOKEN
# Optional: enables @claude and opted-in automatic review.
gh secret set CLAUDE_CODE_OAUTH_TOKEN

Dependency updates are handled by Renovate (renovate.yml), which reuses RELEASE_TOKEN. It maintains uv.lock and auto-merges patch/minor bumps once the CI Success check is green; bootstrap.yml enables 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 via copier 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-check

Pre-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-groups

uv 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.

Domain configuration

Domain environment variables use the MARKDOWN_VAULT_MCP_ prefix:

Variable

Default

Required

Description

OLLAMA_HOST

http://localhost:11434

No

Ollama server URL for the ollama embedding provider. Bare (not MARKDOWN_VAULT_MCP_-prefixed), matching the Ollama ecosystem convention.

OPENAI_API_KEY

(none)

No

OpenAI API key for the openai embedding provider, and the fallback key for the summarize tool when MARKDOWN_VAULT_MCP_SUMMARIZE_OPENAI_API_KEY is unset. Bare (not MARKDOWN_VAULT_MCP_-prefixed), matching the OpenAI ecosystem convention.

VOYAGE_API_KEY

(none)

No

Voyage AI API key for the voyage embedding provider. Bare (not MARKDOWN_VAULT_MCP_-prefixed), matching the OPENAI_API_KEY / OLLAMA_HOST convention. Setting it never auto-selects the provider; choose it explicitly with MARKDOWN_VAULT_MCP_EMBEDDING_PROVIDER=voyage.

OPENAI_BASE_URL

(none)

No

Bare fallback for MARKDOWN_VAULT_MCP_OPENAI_BASE_URL (embeddings). For the summarize tool it only routes traffic when an API key already enables the feature; it never enables summarize by itself.

OPENAI_EMBEDDING_MODEL

(none)

No

Bare fallback for MARKDOWN_VAULT_MCP_OPENAI_EMBEDDING_MODEL.

MARKDOWN_VAULT_MCP_BUILD_TIMEOUT_S

60

No

Maximum seconds an index-backed tool or resource waits for the FTS index to become queryable during a cold-start background build before raising IndexUnavailableError(reason="timeout"). Increase for large vaults.

MARKDOWN_VAULT_MCP_DRAIN_TIMEOUT_S

60

No

Maximum seconds an index-querying read tool waits for the IndexWriter to drain when called with wait_for_pending_writes=true. On timeout the tool answers from the current index and reports index_stale=true in the response _meta.

MARKDOWN_VAULT_MCP_SOURCE_DIR

/data/vault

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+.

MARKDOWN_VAULT_MCP_READ_ONLY

false

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.

MARKDOWN_VAULT_MCP_WRITE_PROTECT_EXISTING

false

No

Set to true to refuse a write that would overwrite an existing file when no if_match etag is supplied. Deliberate replacement (read first, pass if_match) still works, and edit / append / delete / rename are unaffected.

MARKDOWN_VAULT_MCP_DISABLE_APPS_UI

false

No

Hide the MCP Apps UI tools (browse_vault, show_context) from the tool listing for clients that do not render MCP Apps panels.

MARKDOWN_VAULT_MCP_INDEX_PATH

(none)

No

Path to the SQLite FTS5 index file; unset keeps the index in memory. Set it for persistence across restarts.

MARKDOWN_VAULT_MCP_STATE_PATH

(none)

No

Path to the change-tracking state file. Defaults to {SOURCE_DIR}/.markdown_vault_mcp/state.json.

MARKDOWN_VAULT_MCP_EMBEDDINGS_PATH

(none)

No

Path to the numpy embeddings file; required to enable semantic search.

MARKDOWN_VAULT_MCP_INDEXED_FIELDS

(none)

No

Comma-separated frontmatter fields promoted to the tag index for structured filtering. Changing it cold-rebuilds the index once on next startup; SEARCHABLE_FIELDS inherits this value when unset.

MARKDOWN_VAULT_MCP_REQUIRED_FIELDS

(none)

No

Comma-separated frontmatter fields required on every document; documents missing any are excluded from the index.

MARKDOWN_VAULT_MCP_EXCLUDE

(none)

No

Comma-separated glob patterns excluded from scanning (.obsidian/,.trash/).

MARKDOWN_VAULT_MCP_TITLE_FIELD

title

No

Frontmatter field used as the document title (falls back to title, the first H1, then the filename). Changing it cold-rebuilds the index once on next startup.

MARKDOWN_VAULT_MCP_SEARCHABLE_FIELDS

(none)

No

Comma-separated frontmatter fields whose text values become keyword-searchable and enrich first-chunk embeddings. Inherits INDEXED_FIELDS when unset; the sentinel none means filterable but not searchable. Changing it cold-rebuilds the index and re-embeds once on next startup.

MARKDOWN_VAULT_MCP_TEMPLATES_FOLDER

_templates

No

Relative folder where note templates live (used by the create_from_template prompt).

MARKDOWN_VAULT_MCP_PROMPTS_FOLDER

(none)

No

Directory of .md prompt files that extend or override built-in prompts; a relative path is resolved against SOURCE_DIR.

MARKDOWN_VAULT_MCP_CONVENTIONS_FILE

_conventions.md

No

Filename of the per-folder conventions files surfaced to clients at write time (bare .md filename without glob characters). Set to none to disable folder conventions.

MARKDOWN_VAULT_MCP_OKF_MODE

auto

No

OKF (Open Knowledge Format) read semantics. With auto (the default), read annotations switch on when the vault declares an OKF version in its root index.md. Use off to disable OKF semantics entirely, or on to force them for an undeclared vault. Annotations are read-only; write behavior is never affected.

MARKDOWN_VAULT_MCP_OKF_WRITE

false

No

OKF (Open Knowledge Format) enforced write layer. When true on an OKF-active vault, the server stamps generated provenance on each write and clears any verified attestation when a note's content changes. It also keeps each written folder's log.md and index.md current, and exposes the okf_verify tool. Requires OKF_MODE to be auto or on (a true value with OKF_MODE=off is a config error). Off by default.

MARKDOWN_VAULT_MCP_OKF_VERIFY

elicit

No

How the okf_verify tool attributes a human review. This applies only when OKF_WRITE is on, which gates the tool. With elicit (the default), okf_verify asks the human to confirm the review through an MCP elicitation and records the attestation only on an affirmative reply. It fails closed when the client cannot elicit or the human declines, so a model that holds the human's token cannot self-attest. Use trust-auth to attribute to the authenticated caller with no confirmation (safe only when the sole caller is a human-driven UI), or off to hide the tool so attestation happens through external tooling. A non-default value with OKF_WRITE off is a config error.

MARKDOWN_VAULT_MCP_ATTACHMENT_EXTENSIONS

(none)

No

Comma-separated allowed attachment extensions without the dot (such as pdf,png,jpg); use * to allow every non-markdown file. Unset selects the built-in allowlist.

MARKDOWN_VAULT_MCP_MAX_ATTACHMENT_SIZE_MB

1.0

No

Maximum attachment size in MB returned by read / accepted by write; 0 disables the limit.

MARKDOWN_VAULT_MCP_MAX_NOTE_READ_BYTES

262144

No

Maximum bytes returned by a full-document read of a note; use read(path, section=…) for partial reads. 0 disables the limit.

MARKDOWN_VAULT_MCP_DEFAULT_SEARCH_MODE

auto

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.

MARKDOWN_VAULT_MCP_CHUNKS_PER_FILE

2

No

Maximum chunks returned per document in search results.

MARKDOWN_VAULT_MCP_SNIPPET_WORDS

200

No

Width of the snippet window (words) in search results; 0 returns full chunk content.

MARKDOWN_VAULT_MCP_LENGTH_DOWNWEIGHT_ALPHA

0.25

No

Down-weights longer chunks in ranking: score / (1 + alpha * log(chunk_count)).

MARKDOWN_VAULT_MCP_MAX_CHUNK_WORDS

400

No

Word cap per chunk; the adaptive chunker splits at deeper heading levels, then paragraph/word boundaries, to respect it. Match it to the embedding model's context. A reindex applies a new value.

MARKDOWN_VAULT_MCP_MAX_CHUNK_CHARS

(none)

No

Character cap enforced alongside MAX_CHUNK_WORDS to bound token-dense chunks. Unset derives min(1500, model context * 2.8). Set a positive value for an exact cap, or -1 to scale with the model's full context (can exhaust memory on long-context models). A reindex applies a new value.

MARKDOWN_VAULT_MCP_CHUNK_OVERLAP_WORDS

40

No

Words of overlap between adjacent budget-split fragments of the same heading section (0 disables). A reindex applies a new value.

MARKDOWN_VAULT_MCP_FOLDER_WEIGHTS

(none)

No

Folder-prefix score multipliers (prefix:weight pairs, comma-separated, weights > 0) applied to all search modes; the deepest matching prefix wins (sessions:0.5 demotes sessions/**).

MARKDOWN_VAULT_MCP_FTS_WEIGHTS

(none)

No

Per-column BM25 weights (column:weight pairs, comma-separated, weights >= 0) for keyword ranking. Columns: path, title, folder, heading, content, summary.

MARKDOWN_VAULT_MCP_EMBEDDING_PROVIDER

(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.

MARKDOWN_VAULT_MCP_OLLAMA_MODEL

nomic-embed-text

No

Ollama embedding model name.

MARKDOWN_VAULT_MCP_OLLAMA_CPU_ONLY

false

No

Force Ollama to embed on CPU only.

MARKDOWN_VAULT_MCP_VOYAGE_MODEL

voyage-4

No

Voyage AI embedding model name.

MARKDOWN_VAULT_MCP_OPENAI_BASE_URL

https://api.openai.com/v1

No

OpenAI-compatible API base URL for embeddings; the bare OPENAI_BASE_URL is honoured as a fallback.

MARKDOWN_VAULT_MCP_OPENAI_EMBEDDING_MODEL

text-embedding-3-small

No

OpenAI-compatible embedding model name; the bare OPENAI_EMBEDDING_MODEL is honoured as a fallback.

MARKDOWN_VAULT_MCP_FASTEMBED_MODEL

BAAI/bge-small-en-v1.5

No

FastEmbed model name.

MARKDOWN_VAULT_MCP_FASTEMBED_CACHE_DIR

(none)

No

FastEmbed model cache directory (in Docker, stored under /data/state/fastembed).

MARKDOWN_VAULT_MCP_EMBED_CONTEXT

false

No

Enrich embedding input with the note title, chunk heading, and (first chunk) searchable-field values. Flipping it re-embeds the whole vault once on next startup.

MARKDOWN_VAULT_MCP_EMBED_TIMEOUT_S

30.0

No

Per-request wall-clock budget in seconds for a single embedding HTTP call (OpenAI/Ollama). The local FastEmbed backend runs in-process with no network call and ignores this. CPU-only or large-model workloads may need 60-120 s; raise this if batches time out.

MARKDOWN_VAULT_MCP_EMBEDDING_BATCH_SIZE

4

No

Number of chunks sent per embedding request. Smaller batches shorten each request (useful under a tight timeout on slow models) at the cost of more round-trips.

MARKDOWN_VAULT_MCP_GIT_TOKEN

(none)

No

Token/password for HTTPS git auth; remotes must be HTTPS when set.

MARKDOWN_VAULT_MCP_GIT_REPO_URL

(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.

MARKDOWN_VAULT_MCP_GIT_USERNAME

x-access-token

No

Username for HTTPS git auth prompts (x-access-token for GitHub, oauth2 for GitLab, the account name for Bitbucket).

MARKDOWN_VAULT_MCP_GIT_PULL_INTERVAL_S

600

No

Seconds between git fetch + fast-forward update attempts; 0 disables periodic pull.

MARKDOWN_VAULT_MCP_GIT_PUSH_DELAY_S

30.0

No

Seconds of write-idle time before pushing; 0 pushes only on shutdown.

MARKDOWN_VAULT_MCP_GIT_COMMIT_NAME

markdown-vault-mcp

No

Git committer name for auto-commits; set this in Docker where git config user.name is empty.

MARKDOWN_VAULT_MCP_GIT_COMMIT_EMAIL

noreply@markdown-vault-mcp

No

Git committer email for auto-commits.

MARKDOWN_VAULT_MCP_GIT_COMMIT_NAME_CLAIM

(none)

No

OIDC claim key used as the commit author name (such as name); overrides GIT_COMMIT_NAME per request when an OIDC token is present. The claim is resolved when the tool call arrives and carried to the background commit, so it applies on every write.

MARKDOWN_VAULT_MCP_GIT_COMMIT_EMAIL_CLAIM

(none)

No

OIDC claim key used as the commit author email (such as email); overrides GIT_COMMIT_EMAIL per request when an OIDC token is present. Resolved and carried the same way as the name claim.

MARKDOWN_VAULT_MCP_GIT_LFS

true

No

Run git lfs pull on startup to fetch LFS-tracked attachments; set to false for repos without LFS.

MARKDOWN_VAULT_MCP_FILE_WATCHER

true

No

Watch the vault for external filesystem changes; auto-disabled when git pull or the webhook is active. Requires the file-watcher extra.

MARKDOWN_VAULT_MCP_FILE_WATCHER_DEBOUNCE_S

2.0

No

Seconds of quiet after the last filesystem event before reindexing.

MARKDOWN_VAULT_MCP_FILE_WATCHER_ROOT_FLOOR

true

No

Keep the non-recursive watch on the vault root; set false to register zero source-dir-rooted FSEvents streams (avoids repeated macOS access prompts on a home-rooted vault) at the cost of root-level files relying on scans.

MARKDOWN_VAULT_MCP_GITHUB_WEBHOOK_SECRET

(none)

No

Shared secret for the GitHub push-event webhook; when set, mounts POST /github-webhook on HTTP/SSE transports to trigger an immediate pull + reindex on push events.

MARKDOWN_VAULT_MCP_SUMMARIZE_PROVIDER

(none)

No

Summarization backend (only openai is recognised). Unset auto-detects: the backend activates when credentials or an explicit endpoint are present.

MARKDOWN_VAULT_MCP_SUMMARIZE_OPENAI_API_KEY

(none)

No

API key for the OpenAI-compatible summarize endpoint; the bare OPENAI_API_KEY is honoured as a fallback. Unset works for keyless local endpoints (Ollama).

MARKDOWN_VAULT_MCP_SUMMARIZE_OPENAI_BASE_URL

(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.

MARKDOWN_VAULT_MCP_SUMMARIZE_OPENAI_MODEL

gpt-5-mini

No

Chat model id used for summaries.

MARKDOWN_VAULT_MCP_SUMMARIZE_MAX_TOKENS

8192

No

Upper bound on generated tokens per summarize call; on reasoning models this budget also covers internal reasoning tokens.

MARKDOWN_VAULT_MCP_SUMMARIZE_MAX_NOTES

50

No

Cap on the number of notes summarised in one call (subtree expansion truncates to this many).

MARKDOWN_VAULT_MCP_SUMMARIZE_MAX_INPUT_CHARS

200000

No

Aggregate cap on note characters sent to the model in one call; excess is truncated with a flag on the result.

MARKDOWN_VAULT_MCP_SUMMARIZE_TIMEOUT

120.0

No

Per-request wall-clock budget in seconds for a single summarize backend call; keep it below the MCP client's request timeout so the server-side error wins the race.

MARKDOWN_VAULT_MCP_TRANSFER_TTL_DEFAULT_S

3600.0

No

Link lifetime in seconds when the caller requests no explicit TTL.

MARKDOWN_VAULT_MCP_TRANSFER_TTL_MAX_S

86400.0

No

Ceiling in seconds a caller-requested link TTL is clamped to.

MARKDOWN_VAULT_MCP_TRANSFER_GRACE_TTL_S

60.0

No

Post-success grace window in seconds: a served token's TTL shrinks to this so a stalled transfer can retry within it.

MARKDOWN_VAULT_MCP_TRANSFER_LEASE_S

60.0

No

Crashed-handler reclaim window in seconds for an in-flight reservation.

MARKDOWN_VAULT_MCP_TRANSFER_MAX_UPLOAD_BYTES

104857600

No

Maximum size in bytes of a single upload.

MARKDOWN_VAULT_MCP_JOBS_SOFT_DEADLINE_S

25.0

No

Seconds a long-running tool call may run in the foreground before it is promoted to a background job and a job handle is returned instead.

MARKDOWN_VAULT_MCP_JOBS_RESULT_TTL_S

3600.0

No

Seconds a background-job record (working or finished) is retained for polling before it expires from the store.

MARKDOWN_VAULT_MCP_JOBS_MAX_PER_SUBJECT

256

No

Maximum live background jobs per calling subject; further promotions are rejected until older records expire.

Domain-config fields are composed inside src/markdown_vault_mcp/config.py between the CONFIG-FIELDS-START / CONFIG-FIELDS-END sentinels; env reads go through fastmcp_pvl_core.env(_ENV_PREFIX, "SUFFIX", default) so naming stays consistent, and field invariants go in __post_init__ between the CONFIG-VALIDATE-START / CONFIG-VALIDATE-END sentinels. Each field's metadata help and tags generate the table above directly, so keep them accurate and complete.

Key design decisions

  • Document identity is the relative path with .md extension; frontmatter is optional by default (REQUIRED_FIELDS opts into enforcement).

  • Hybrid search uses Reciprocal Rank Fusion over the FTS5 and vector result lists, with diversity-aware ranking capping chunks per document.

  • Tool semantics mirror Claude Code's Read/Write/Edit patterns, so LLM clients drive the vault with habits they already have.

  • The library is synchronous; the MCP layer wraps calls in asyncio.to_thread().

  • Indexing is hash-based: unchanged files are never re-parsed, and any change to how stored rows derive from a note's bytes bumps INDEX_SEMANTICS_VERSION so deployed vaults rebuild themselves once on upgrade.

The full decision log lives in the design document.

Available Tools

38 tools
appendAppend to NoteA

Append text to the end of an existing .md note without reading it.

The cheapest way to add content at the end of a note (log entries, journal additions, checklist items): unlike 'edit', no prior 'read' is needed, so the existing note content never enters the context. Prefer this over 'edit' whenever the change is purely additive at the end of the note.

A newline is inserted between the existing content and the appended text when the file does not already end with one, so the appended text starts on its own line. Include leading blank lines or heading markers in 'content' yourself if you want a separating paragraph or section. The search index is updated immediately; do not call 'reindex' afterward.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path to the document (e.g. "Journal/2026.md").
contentYesText to append (must be non-empty). Added at the end of the file, after frontmatter and all existing content.
if_matchNoOptional 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_missingNoWhen 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Annotations only convey basic hints, so the description carries the burden and succeeds. It discloses the automatic newline insertion behavior, the immediate index update, the unconditional behavior when if_match is omitted, and the failing-loudly behavior for missing files by default.

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

Conciseness5/5

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

The description is front-loaded with the core purpose and the deciding factor (no read needed). Every sentence adds practical value—newline behavior, index updates, and avoid-reindex guidance—without redundancy or filler.

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

Completeness5/5

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

Given the rich output schema and fully covered input schema, the description is complete. It answers the key operational questions an agent needs: when to use it, what happens to formatting, concurrency behavior, missing-file behavior, and post-call indexing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds meaningful behavior beyond the schema: how newlines are handled, that leading blank lines/heading markers are the caller's responsibility, and that a typo in path fails loudly rather than creating a note. This elevates it above the baseline.

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

Purpose5/5

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

The description states a specific action (append text) on a specific resource (an existing .md note) with a precise location (end of the note). It also explicitly distinguishes itself from 'edit' by noting that no prior read is needed, making its purpose unmistakable.

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

Usage Guidelines5/5

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

The description gives clear when-to-use guidance: use for purely additive at-end changes, prefer over 'edit' because it avoids loading the note into context. It also explicitly says not to call 'reindex' afterward, and explains the tradeoff of create_if_missing behavior.

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

browse_vaultBrowse VaultA
Read-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").

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoOptional note path to focus on (e.g. ``"Journal/2024-01-15.md"``).
viewNoWhich 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 EmbeddingsA
Idempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoWhen 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 NoteA
DestructiveIdempotent

Permanently delete a document or attachment.

For .md documents: removes the file and immediately updates all search indices — do not call 'reindex' afterward. For attachments: only the file is deleted (no index to update). IRREVERSIBLE unless git history exists. Confirm the path with the user before calling.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path to the document or attachment to delete.
if_matchNoOptional 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint=true, readOnlyHint=false, idempotentHint=true), the description discloses critical behavior: irreversibility unless git history exists, immediate search-index updates for .md files, and no index update for attachments. This adds substantial context about side effects and recovery options. No contradiction with annotations exists.

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

Conciseness5/5

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

The description is four compact sentences: first states the action and object, then differentiates .md behavior from attachments, then gives irreversibility and confirmation warnings. No filler or repetition; the most important warning is placed last for emphasis.

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

Completeness5/5

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

For a destructive two-parameter tool with an output schema, the description covers what is deleted, index implications, what not to do afterward, irreversibility, and a user-confirmation requirement. Nothing essential is missing for an agent to invoke this tool safely and correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so path and if_match are already fully documented in the input schema. The description adds only user-confirmation guidance about the path, which is more of a usage rule than parameter semantics. Baseline 3 is appropriate when structured schema handles parameter details.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Permanently delete a document or attachment.' This clearly distinguishes it from sibling tools like read, write, edit, append, and rename by naming the destructive action and the object types. The title 'Delete Note' further reinforces the tool's role.

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

Usage Guidelines4/5

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

The description gives explicit usage guidance: after deleting .md files, 'do not call reindex afterward' — an instruction that prevents an unnecessary follow-up action. It also states a precondition that the path must be confirmed with the user before calling. It does not explicitly name alternative tools, but the destructive-purpose distinction is clear among the sibling list.

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

editEdit NoteA

Make a targeted text replacement in an existing .md note (not supported for attachments).

Three edit modes:

  • Exact match (old_text only): pass a portion of the file as old_text — must appear exactly once. Frontmatter can be edited.

  • Line-range (line_start + line_end, no old_text): replace the specified lines with new_text. Lines are 1-based (matching 'read' output). Recommended: pass if_match for safety.

  • Scoped match (old_text + line_start/line_end): search for old_text within the line range only — useful when old_text appears multiple times in the file.

When exact match fails, a normalized comparison is attempted (Unicode NFC, dash/quote normalization, whitespace collapsing). If a unique normalized match is found, it is used and match_type='normalized' is returned.

Always call 'read' first to get the current text and line numbers. The search index is updated immediately; do not call 'reindex'.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path to the document.
if_matchNoOptional 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_endNoLast line to replace (1-based, inclusive). Must be provided together with line_start.
new_textNoReplacement text. May be longer or shorter.
old_textNoText to replace. Must appear exactly once in the document or line range. Get this via 'read'. Optional when using line-range mode.
line_startNoFirst line to replace (1-based, inclusive). Must be provided together with line_end.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only state readOnly=false, idempotent=false, destructive=false. The description adds substantial behavioral context beyond this: frontmatter is editable, line numbers are 1-based, normalized Unicode/comparison fallback may apply, match_type='normalized' can be returned, if_match provides optimistic concurrency, and the search index updates immediately. This is exactly the kind of operational detail an agent needs to avoid surprising edits.

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

Conciseness5/5

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

The description is detailed but efficiently structured: a one-sentence summary, a compact bulleted mode list, a normalization note, and workflow guidance. Every section earns its place, and the most important scoping information is front-loaded. Nothing is redundant with the schema or annotations.

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

Completeness5/5

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

Given six parameters, three modes, normalization behavior, and concurrency control, the description is remarkably complete. It tells the agent how to select modes, how to prepare with 'read', how to stay safe with if_match, and what to expect regarding index updates. An output schema exists, so it is acceptable that return details are not spelled out in the description.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds real value by organizing old_text, line_start, line_end, and new_text into three named modes and explaining valid combinations, uniqueness constraints, and safety recommendations. It does not merely restate the schema; it clarifies how the parameters interact, which is meaningful beyond the property-level descriptions.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Make a targeted text replacement in an existing .md note.' It clearly distinguishes this from sibling tools by noting it applies to existing notes, not attachments, and by defining three concrete replacement modes. An agent can immediately tell this is the in-place modification tool rather than write, append, or delete.

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

Usage Guidelines4/5

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

The description gives explicit mode-selection guidance: exact match when text appears once, line-range for replacing by line numbers, and scoped match when old_text appears multiple times. It also says to call 'read' first and not to call 'reindex.' However, it does not explicitly contrast this tool with write/append/delete for creation or additive changes, so the broader sibling-tool selection guidance is slightly implicit.

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

embeddings_statusEmbeddings StatusA
Read-onlyIdempotent

Check the embedding provider configuration and vector index status.

Use this to diagnose why semantic search is unavailable. Embeddings are built automatically on startup when configured, so chunk_count should normally match the FTS chunk count from 'stats'. If it is lower, call 'build_embeddings' (without force) to embed the missing chunks. Use 'build_embeddings' with force=True only to rebuild from scratch after changing the embedding model.

Returns: Dict with the following fields:

- available (bool): True if semantic search can be used in 'search'.
- provider (str | None): Provider class name when configured
  (e.g. "OllamaProvider"), or null if not configured.
- chunk_count (int): Number of chunks currently in the vector index.
- path (str | None): Vector index file path when persisted, or null.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the agent knows it's a safe read. The description adds behavioral context: it checks configuration and status, and details the return fields (available, provider, chunk_count, path). It does not contradict annotations.

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

Conciseness5/5

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

The description is two paragraphs: first paragraph focuses on usage guidance, second lists return fields. It is front-loaded with the main purpose, and every sentence provides necessary information. No redundant or vague statements.

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

Completeness5/5

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

For a zero-parameter tool with an output schema, the description fully explains the return fields and their semantic meaning. It covers the diagnostic use case and provides actionable guidance. It is complete for the tool's purpose.

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

Parameters4/5

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

There are no parameters, so the baseline is 4. The description adds value by explaining the output fields and their interpretation, which goes beyond the input schema (empty).

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

Purpose5/5

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

The description starts with a clear verb and resource: 'Check the embedding provider configuration and vector index status.' It also specifies the use case: 'diagnose why semantic search is unavailable.' This distinguishes it from sibling tools like build_embeddings.

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool ('to diagnose why semantic search is unavailable') and provides guidance on interpreting the chunk_count field relative to the FTS chunk count from 'stats'. It also directs to call 'build_embeddings' (without force) if chunk_count is lower, and specifies when to use force=True. This provides clear when-to-use and when-not-to-use guidance.

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

fetchFetch to VaultA
Idempotent

Download a file from a URL and save it to the vault.

Fetches content from an HTTP/HTTPS URL and writes it as a note or attachment. Designed for MCP-to-MCP file transfer when content is too large to pass through the LLM context window.

Context cost: zero for the bytes themselves — the file is downloaded server-side and saved to the vault. After a successful fetch, reference the file by its path (call read(path) only for small results, otherwise pass the path to other tools).

For .md paths: the response is decoded as UTF-8 text and saved as a markdown note with optional frontmatter. The search index is updated immediately.

For other paths: the response is saved as a binary attachment. The existing attachment size limit applies.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesSource 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.
pathYesDestination path in the vault (e.g. "notes/report.md" or "assets/diagram.png"). Extension determines handling: .md for notes, anything else for attachments.
if_matchNoOptional etag from a previous 'read' call for optimistic concurrency. Omit to write unconditionally.
timeout_sNoDownload timeout in seconds (default 30). Increase for large files on slow connections.
frontmatterNoOptional YAML frontmatter dict for .md files, e.g. {"title": "Report", "source": "http://..."}. Ignored for attachments.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the annotations, the description discloses key behavioral traits: the download happens server-side so the bytes cost zero context, the search index is updated immediately for .md files, and non-.md files are saved as binary attachments subject to the existing size limit. It also clarifies that after a successful fetch the agent should use the returned path rather than expecting content in the response, which is genuinely useful behavior not covered by the annotations.

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

Conciseness5/5

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

The description is front-loaded with purpose, then moves to context cost, then to path-specific behavior, with each sentence earning its place. It is detailed but not redundant, and the use of short labeled paragraphs makes it easy for an agent to scan.

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

Completeness5/5

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

Given the 5-parameter schema with 100% coverage, the annotations, and the presence of an output schema, the description is complete: it covers the intended use case, when not to use read, how path determines handling, the zero-context-cost property, and the attached security-relevant redirect behavior in the URL parameter. Nothing critical is missing.

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

Parameters4/5

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

The schema already covers all parameters at 100% with detailed descriptions, so the baseline is 3. The tool description adds extra semantic value by explaining how the path extension changes the behavior (.md becomes UTF-8 markdown with frontmatter, other paths become binary attachments) and by clarifying the practical meaning of the path parameter in the post-fetch workflow.

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

Purpose5/5

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

The description opens with a specific verb-resource pair, 'Download a file from a URL and save it to the vault,' and immediately clarifies scope: HTTP/HTTPS URLs, saved as a note or attachment. This clearly differentiates it from sibling file-writing tools like write and edit, whose input would be literal content rather than a remote URL.

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool: for MCP-to-MCP file transfer when content is too large to pass through the LLM context window. It also gives post-fetch guidance, telling the agent to reference the file by path and to only call read(path) for small results, which is actionable and distinguishes the intended workflow from plain read/write usage.

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

get_connection_pathConnection PathA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYesVault-relative path of the starting note (e.g. 'Ideas/spark.md').
targetYesVault-relative path of the destination note.
max_depthNoMaximum number of hops to search. Default 10, max 10.
wait_for_pending_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the mutation safety profile. The description adds meaningful behavioral detail beyond that: links are treated as undirected, the search uses BFS, and max_depth is clamped to [1, 10]. This gives the agent a solid model of how the search behaves.

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

Conciseness5/5

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

The description is compact and front-loaded: the first sentence states the core purpose, the second adds algorithmic behavior, and the third provides a helpful use-case metaphor. Every sentence earns its place without redundancy or padding.

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

Completeness4/5

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

Given the annotations, fully documented parameters, and the presence of an output schema, the description covers the essential aspects: purpose, algorithm, edge-case clamping, and illustrative use case. It could be slightly stronger with explicit guidance on when to prefer it over direct-link tools, but nothing critical is missing for an agent to invoke it correctly.

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

Parameters4/5

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

Schema description coverage is 100%, so the baseline is 3. The description adds extra semantic value by explaining the BFS algorithm and that max_depth is clamped to [1, 10], which is more specific than the schema's 'max 10' note. Source and target are already well documented in the schema.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Find the shortest connection path between two notes in the link graph.' This clearly distinguishes the tool from graph-related siblings like get_similar, get_backlinks, and get_outlinks by emphasizing shortest path between two notes rather than listing links or similar notes.

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

Usage Guidelines4/5

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

The description gives clear context: 'Useful for discovering how two seemingly unrelated notes are connected through the vault's link structure.' This tells the agent when to reach for this tool, though it does not explicitly mention alternatives or state when not to use it.

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

get_contextNote ContextA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path of the document (e.g. "notes/topic.md"). Case-sensitive.
link_limitNoMaximum number of backlinks and outlinks to include each (default 10).
similar_limitNoMaximum 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_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already establish readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds behavioral context by clarifying that this tool aggregates multiple lookups into one response and explicitly lists the categories of information returned, which goes beyond the annotations and helps the agent predict the tool's behavior.

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

Conciseness4/5

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

The description is well-structured, leading with the core purpose, then the relationship to siblings, then the concrete return contents. There is minor redundancy between "Replaces separate calls..." and "Use this instead of making 4-5 separate tool calls...," but the information density is high and each sentence adds relevant detail.

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

Completeness5/5

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

The description is complete for an agent's decision-making: it states what the tool returns, when to use it instead of alternatives, and the exact scope of the 'context' it provides. The input schema and output schema cover parameter details and return structure, so nothing essential is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so each parameter is already well-documented in the input schema. The description itself adds no parameter-level detail beyond the schema, which matches the baseline expectation of 3 when the schema carries the explanatory burden.

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

Purpose5/5

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

The description uses a specific verb and resource: it "gets a consolidated context dossier for a document" and then enumerates exactly what that dossier contains (metadata, backlinks, outlinks, similar notes, same-folder notes, frontmatter tags). It also names the sibling tools it replaces, so an agent can distinguish it from get_backlinks, get_outlinks, and get_similar without opening their schemas.

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

Usage Guidelines5/5

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

The description gives explicit guidance: use get_context instead of making 4-5 separate calls when you need a full picture, and use it instead of get_backlinks, get_outlinks, and get_similar when more than one is needed. This directly tells the agent when to choose this tool over its siblings and when the consolidated call is appropriate.

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

get_conventionsFolder ConventionsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoRelative 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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

The description states a specific verb and resource: "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.

Usage Guidelines4/5

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 DiffA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesVault-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.
limitNoWhen 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_shaNoA commit SHA (full or abbreviated, at least 4 hex digits) to diff from. Mutually exclusive with since_timestamp.
per_commitNoWhen False (default), return a single unified diff from the reference point to HEAD. When True, return one diff per intervening commit.
since_timestampNoISO 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 HistoryA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoVault-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.
limitNoMaximum number of commits to return. Default 20, max 100.
sinceNoISO 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.
untilNoISO 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 StatusA
Read-only

Return background-build state of the FTS index.

Use this when initialize returned but bucket-3/4 calls block longer than expected or surface IndexUnavailableError — the status field distinguishes "still building" from "build failed," and the error field carries the exception message from the last background-build attempt that captured one. error may be populated when status is "queryable" (a successful build followed by a later failed rebuild leaves the captured diagnostic in place until the next successful build clears it) and is always None when status is "building".

Returns: Dict with the following fields:

- status (str): ``"queryable"``, ``"building"``, or
  ``"failed"``.
- documents_indexed (int): Count of documents committed to
  the FTS index right now (rises during ``"building"``).
  ``0`` both for an empty index and when the count could not
  be read — see ``documents_indexed_error`` to tell them apart.
- documents_indexed_error (str | None): ``None`` on a normal
  read; the SQLite error message when the document count
  could not be read (e.g. a locked or closed database), in
  which case ``documents_indexed`` is ``0``.
- error (str | None): ``None`` unless the background build
  raised.
- skipped_files (list[dict]): Files dropped from the index for a
  surfaced deterministic reason. Each entry is
  ``{"path", "category", "detail"}`` where ``category`` is one of
  ``"parse_error"``, ``"encoding_error"``,
  ``"missing_frontmatter"``, or ``"internal_error"`` (an
  unexpected indexer error, vs a content problem). Empty when
  nothing was skipped.
  Distinguishes a parse-dropped note from an unsynced one without
  reading container logs. Exclude-pattern and transient-I/O skips
  are intentionally not listed.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

The description goes beyond annotations (readOnlyHint=true) to disclose critical behavioral details: the error field may be populated even when status is 'queryable' and is always None during 'building'. This helps the agent correctly interpret responses, especially edge cases.

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

Conciseness4/5

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

The description is somewhat lengthy but well-structured with a bullet list for return fields. Every sentence adds value, but it could be slightly more concise without losing clarity. Nonetheless, it effectively communicates the necessary details.

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

Completeness5/5

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

Given zero parameters and the presence of an output schema (described thoroughly), the description is complete. It covers all return fields, their types, possible values, and edge cases (e.g., documents_indexed vs documents_indexed_error). No gaps remain.

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

Parameters4/5

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

The tool has zero parameters, so the parameter semantics dimension gets a baseline score of 4. The description adds no parameter information because none is needed, and the schema coverage is vacuously 100%.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Return background-build state of the FTS index.' This is a specific verb-resource combination, and it distinguishes itself from sibling tools like embeddings_status or build_embeddings which deal with different indexes.

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

Usage Guidelines4/5

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

The description provides explicit when-to-use guidance: 'Use this when initialize returned but bucket-3/4 calls block longer than expected or surface IndexUnavailableError.' It also explains what the status and error fields indicate, aiding correct invocation. It lacks explicit when-not-to-use or alternatives, but the context is sufficiently clear.

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

get_job_resultGet Job ResultA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 NotesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of results to return. Default 10.
wait_for_pending_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds the ranking-by-backlink-count behavior but does not add further behavioral context such as tie-breaking, self-link handling, or index freshness; the latter is addressed in the schema.

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

Conciseness5/5

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

The description is concise, front-loads the primary behavior, includes a concrete use case, and ends with a clear pointer to an alternative. No sentence is wasted.

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

Completeness5/5

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

The tool is a simple read-only query, annotations cover safety, the schema covers all parameters, an output schema exists, and the description adds use-case and sibling context. Nothing important is missing for correct selection and invocation.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema fully documents both limit and wait_for_pending_writes. The description does not need to add parameter details, and the baseline of 3 is appropriate.

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

Purpose5/5

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

The description clearly states the operation: return the documents with the most inbound links ranked by backlink count. It also explicitly distinguishes itself from the sibling tool get_backlinks, making the tool's unique role easy to identify.

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

Usage Guidelines5/5

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

The description explains when to use this tool ('discovering hub notes') and explicitly points to get_backlinks for the alternative case of finding documents that link to a particular note. This gives an agent actionable routing guidance.

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

get_orphan_notesOrphan NotesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
wait_for_pending_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds important behavioral context beyond this: it warns that the tool 'returns ALL orphans with no limit' and advises checking orphan_count first. This is exactly the kind of unbounded-result warning that annotations do not convey.

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

Conciseness5/5

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

The description is compact and front-loaded: the core behavior is stated immediately, followed by the high-value warning, then the precise definition and usage trigger. Every sentence serves a purpose, and there is no redundant filler.

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

Completeness5/5

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

With annotations covering safety, a fully documented optional parameter, an output schema present, and a description that includes the semantics of orphan notes plus a scalability warning, all information an agent needs to select and invoke this tool correctly is present.

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

Parameters3/5

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

Schema description coverage is 100%, and the single parameter wait_for_pending_writes is already thoroughly documented in the schema. The tool description adds no additional parameter-level guidance, but it does not need to because the schema carries the full burden.

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

Purpose5/5

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

The description states a specific verb and resource: 'Return all notes with no inbound or outbound links.' This clearly distinguishes it from sibling tools like get_backlinks or get_outlinks, which return link data for specific notes rather than orphan detection.

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

Usage Guidelines4/5

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

The description gives a concrete trigger condition: 'Call this when stats shows orphan_count > 0.' It also warns to check stats before calling on large vaults, which is useful usage guidance. It does not explicitly name alternative tools or when not to use it, but the context is clear.

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

get_recentRecent NotesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of notes to return (default 20).
folderNoOptional 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_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already establish the read-only, idempotent, non-destructive profile. The description adds the useful behavioral detail that results are sorted by file modification time, most recent first, and clarifies it surfaces recently changed content. It does not discuss index lag or error conditions, but the wait_for_pending_writes parameter schema addresses consistency, so the additional context is sufficient.

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

Conciseness5/5

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

Three tightly written sentences, with the core operation in the first sentence, ordering semantics in the second, and concrete use cases in the third. No wasted words.

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

Completeness5/5

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

With a comprehensive schema and an output schema, the description provides the remaining orienting context: scope is notes, ordering is by modification time, and no search query is needed. That is complete for selecting and invoking the tool. Minor absence of explicit alternative-routing is already accounted for under usage guidelines.

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

Parameters3/5

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

The input schema is fully self-descriptive (100% coverage), including defaults for limit, folder semantics including empty-string root behavior, and an extensive explanation of wait_for_pending_writes. The tool description itself adds no parameter-level guidance, so the baseline 3 applies.

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

Purpose4/5

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

Description leads with a clear verb+object: 'Get the most recently modified notes in the vault' and specifies ordering by file modification time. It distinguishes itself from search via 'without a search query' but does not name sibling tools such as list_documents, so it doesn't fully capitalize on sibling differentiation.

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

Usage Guidelines4/5

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

The description states when it is useful ('summarize recent activity', 'resume work on recently edited notes') and contrasts with a search query. However, it does not explicitly say when not to use it or point to an alternative tool by name, so it falls short of a 5.

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

get_server_infoServer InfoA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 NotesA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path of the reference document (e.g. "notes/topic.md"). Case-sensitive.
limitNoMaximum number of similar notes to return (default 10).
folderNoRestrict 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.
filtersNoFrontmatter 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_fileNoMaximum sections returned per file (default 2). Set to 1 for one best section per file. Must be >= 1.
wait_for_pending_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, the description discloses meaningful behavior: no re-embedding is performed, the reference document is excluded, and an empty list is returned in specific unconfigured or missing-vector cases. It also points to a remediation path via build_embeddings.

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

Conciseness5/5

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

The description is front-loaded with the core purpose and every subsequent sentence adds actionable detail: no re-embedding, exclusion behavior, configuration prerequisites, and failure-mode handling. There is no repetition or filler.

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

Completeness5/5

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

Given the detailed input schema, output schema, and readOnly/idempotent annotations, the description covers the key operational context an agent needs: when the tool works, when it returns empty, and how to make it work via build_embeddings. Nothing essential is missing for correct invocation.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The tool description adds some context around the path parameter (reference excluded, missing vectors) but does not need to compensate for any parameter documentation gaps.

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

Purpose5/5

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

The description opens with 'Find notes most semantically similar to the given document,' which names a specific action, resource, and comparison basis. It clearly distinguishes this from sibling tools like 'search' by emphasizing semantic similarity via stored embeddings.

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

Usage Guidelines4/5

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

The description gives concrete usage context: semantic search must be configured, embeddings_status should be checked, and build_embeddings should be called when vectors are missing. It does not explicitly route to an alternative tool such as 'search' for keyword or non-semantic use, but the conditions are clear enough.

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

get_tocTable of ContentsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesNote path ("a/b.md") or folder prefix ("a/b").
max_levelNoDrop 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_notesNoFolder 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_writesNoWhen True, wait until recent document mutations are applied to the index before answering. Default False answers from the current index; inspect '_meta.index_stale' to tell whether a write was still in flight. Bounded by a server timeout (default 60s).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the bar for added context is lower. The description adds valuable behavioral detail: synthetic H1 in note mode, aggregation and truncation in folder mode, and the parallel to the 'toc://vault/{path}' resource. No contradiction with annotations.

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

Conciseness5/5

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

The description is front-loaded with the core purpose, then branches into clear note vs. folder behavior. Every sentence contributes meaning, and the resource cross-reference is useful without being verbose.

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

Completeness5/5

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

With a rich input schema, annotations, and an output schema present, the description covers the remaining conceptual context: the two path modes, aggregation semantics, and truncation behavior. There are no significant gaps an agent would need to resolve elsewhere.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already explains all four parameters in detail. The description adds only a high-level pointer to the max_level/max_notes controls and the path-mode distinction, which does not materially exceed what the schema provides.

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

Purpose5/5

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

The description names the exact resource ('heading outline') and clearly distinguishes the two operating modes: single note ('.md' path) vs. folder subtree. It also states the return shape for both cases, which makes the tool's purpose unambiguous even among many sibling tools.

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

Usage Guidelines4/5

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

The description gives clear context for when to use the tool: you supply a note path or folder prefix and get a heading outline. It does not explicitly name alternatives or exclusion criteria, but the behavior is specific enough that an agent can infer when it is the right choice.

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

list_documentsList DocumentsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
folderNoReturn only documents in this folder (e.g. "Journal"). Use folder="" for root-level (top-level) documents only.
filtersNoFrontmatter equality filters, ANDed (e.g. {"tags": "craft"}); any frontmatter key works and list fields match by membership. On an OKF bundle three keys carry OKF semantics: status ("draft"/"stable"/"deprecated"; "stable" also matches notes without a status field), stale ("true"/"false" — stale_after passed), and trust_tier ("unverified"/"machine-confirmed"/"human-reviewed"). Use {"status": "deprecated"} or {"stale": "true"} to build triage listings. Any filter excludes attachments (they carry no frontmatter).
patternNoUnix glob matched against relative paths (e.g. "Journal/*.md", "**/*meeting*.md").
include_attachmentsNoWhen 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_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already establish read-only/idempotent behavior, and the description adds the key behavioral constraint 'Does NOT include body content' and the optional-attachments behavior. This is useful beyond the annotations and prevents the agent from expecting full note text.

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

Conciseness5/5

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

Three short sentences: the first states the action/scope, the second gives usage context, and the third states an important exclusion with a pointer to the alternative. No wasted words.

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

Completeness5/5

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

Given the rich input schema, output schema, and annotations, the description fully covers what the tool does, when to use it instead of search/read, and what it deliberately omits. Nothing needed for correct invocation is missing.

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

Parameters3/5

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

Schema description coverage is 100%, with detailed parameter descriptions in the schema itself. The tool description adds little beyond the phrase 'optionally attachments,' so the baseline of 3 is appropriate.

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

Purpose5/5

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

Description opens with a specific verb and resource: 'List documents (and optionally attachments) in the vault.' It also distinguishes from siblings by explicitly contrasting with 'search' (ranked content search) and 'read' (body content), so an agent can select it without ambiguity.

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

Usage Guidelines5/5

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

Provides explicit when-to-use guidance: use for a 'complete listing, not ranked search results,' and names the alternatives 'search' for content and 'read' for full text. This directly routes the agent to the correct sibling tools.

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

list_foldersList FoldersA
Read-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 "".

ParametersJSON Schema
NameRequiredDescriptionDefault
wait_for_pending_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful non-obvious detail beyond annotations, especially that the root folder is represented as an empty string. It does not contradict the annotations.

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

Conciseness5/5

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

The description is short, front-loaded with the action, and every sentence adds value: it states what is listed, why/when to call it, and the non-obvious root-folder convention. There is no redundant restatement of the schema or annotations.

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

Completeness5/5

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

For a simple read-only tool with one fully documented optional parameter and an output schema, the description supplies the key missing semantics: folder names are discoverable pre-filter values and the root folder is an empty string. No additional context is needed for correct selection and invocation.

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

Parameters3/5

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

Schema description coverage is 100%, and the wait_for_pending_writes parameter is already thoroughly documented in the schema. The description does not need to repeat parameter details, so the baseline score of 3 is appropriate.

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

Purpose5/5

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

The description states a specific verb and resource: 'List all folder paths that contain documents.' It also distinguishes this tool from sibling list operations by clarifying that these are folder names meant for filtering search/list_documents.

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

Usage Guidelines4/5

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

The description explicitly instructs when to use the tool: before filtering search or list_documents by folder. It does not enumerate when not to use it or fully compare against list_tags, but the intended call context is clear and unambiguous.

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

list_tagsList TagsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldNoFrontmatter 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_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, covering the safety profile. The description adds meaningful behavioral context beyond that: unsupported fields silently return an empty list rather than an error, which the agent must know to interpret results correctly.

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

Conciseness5/5

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

The description is tight and front-loaded: purpose in the first sentence, usage guidance in the second, and the key indexed-field caveat in the third. Every sentence earns its place and there is no redundant phrasing.

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

Completeness5/5

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

For a simple optional-parameter read tool with an output schema and safety annotations, the description covers the decision-relevant information: what it does, when to use it, and the non-obvious failure mode for invalid fields. It also points to stats for the authoritative list of valid fields.

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

Parameters3/5

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

Schema description coverage is 100%, with detailed parameter descriptions for both field and wait_for_pending_writes. The description reinforces the purpose of field as a filter-discovery mechanism but does not add semantic detail beyond what the schema already provides, so the baseline 3 is appropriate.

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

Purpose5/5

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

The description opens with 'List all distinct values for a frontmatter field across the vault,' naming a concrete operation, resource, and scope. It clearly distinguishes this tool from sibling list tools by focusing on frontmatter field enumeration rather than documents or folders.

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

Usage Guidelines5/5

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

The description explicitly states when to use the tool: 'Use this to discover valid filter values before calling 'search' with the 'filters' argument.' It also gives a critical constraint by directing the agent to stats for indexed_frontmatter_fields and warning that non-indexed fields return an empty list.

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

move_folderMove FolderA
Destructive

Move an entire folder subtree to a new location in one call, rewriting every link across the vault that points into the moved subtree — the folder-level analogue of 'rename'.

Moves all files under old_dir (.md notes, attachments, and any other files) to the matching path under new_dir, preserving structure. Links between documents inside the subtree and backlinks from outside are all rewritten. The search index is updated immediately — do not call 'reindex' afterward.

The move is atomic at the gate: if any destination file already exists, the call fails before moving anything. Link rewrites are best-effort — a source that cannot be rewritten is reported in failed_links rather than aborting the move. Note: an OS error during the move phase itself (permission error, full disk, concurrent file removal) can leave the subtree partially moved with the index unchanged; call 'reindex' to reconcile the index with the on-disk state.

ParametersJSON Schema
NameRequiredDescriptionDefault
new_dirYesRelative 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_dirYesRelative source folder prefix (e.g. "drafts").

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the annotations, the description discloses atomicity at the gate, best-effort link rewrites with failed_links reporting, and the real possibility of a partially moved subtree with an unchanged index on OS errors. This is rich, honest behavioral disclosure that materially helps an agent anticipate side effects.

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

Conciseness5/5

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

The description is front-loaded with the core definition and then adds progressively deeper detail in a logical order. Every sentence carries necessary information about behavior, failure modes, or index handling; there is no filler.

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

Completeness5/5

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

For a destructive, non-idempotent folder operation, the description covers the critical operational concerns: atomicity, link rewriting success/failure, index update timing, and partial-move recovery. The presence of an output schema covers return-value details, so nothing essential is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema: new_dir may be an existing folder with merging, and a per-file name clash aborts the whole move. This extra context justifies a 4.

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

Purpose5/5

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

The description states a specific verb and resource: moving an entire folder subtree to a new location in one call, and explicitly frames it as the 'folder-level analogue of rename,' distinguishing it from the sibling rename tool. The scope (all files under old_dir, links rewritten, structure preserved) is clear.

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

Usage Guidelines5/5

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

The description gives explicit usage context: it is the folder-level equivalent of rename, and it warns not to call reindex afterward because the index is updated immediately. It also instructs to call reindex after a partial OS failure, which is concrete when-to-use guidance.

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

okf_generate_indexOKF: Generate index.mdA
DestructiveIdempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
folderNoVault-relative folder to index (e.g. "guides"). Omit for the bundle root.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

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

The description goes well beyond the annotations by disclosing that it 'writes (or overwrites) the folder's index.md', preserves existing frontmatter, and omits reserved files like index.md and log.md. It also specifies the listing format and that descriptions come from frontmatter, giving a complete picture of the tool's side effects consistent with destructiveHint and idempotentHint.

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

Conciseness5/5

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

The description is front-loaded with the core purpose and then adds precisely targeted details: output format, data source, overwrite behavior, frontmatter preservation, and omitted files. Every sentence earns its place; there is no fluff or repetition.

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

Completeness5/5

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

With only one optional parameter, full schema coverage, an output schema, and annotations covering idempotence and destructiveness, the description supplies the remaining essential context: what gets overwritten, what is preserved, and what is excluded. The agent has everything needed to invoke the tool correctly.

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

Parameters3/5

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

The input schema already describes the only parameter (`folder`) completely, including its meaning and default behavior. The tool description adds context about 'bundle-root' but does not materially expand parameter semantics. Baseline 3 is appropriate given 100% schema description coverage.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Generate a reserved OKF index.md listing from the table of contents.' It then details the exact output format and source, making the tool's purpose unmistakable and distinguishing it from sibling tools like get_index_status or okf_validate.

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

Usage Guidelines3/5

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

The description implies when to use the tool—when you need to generate or regenerate an OKF index.md—but it does not explicitly state when to prefer it over alternatives such as write, reindex, or get_index_status. No exclusions or alternate routing are provided, so the usage context is clear but not fully explicit.

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

okf_seed_logOKF: Seed log.mdA

Seed a reserved OKF log.md change history from git history.

A migration transform (Open Knowledge Format): writes a log.md with newest-first ## YYYY-MM-DD sections built from the vault's git commit history (one bullet per commit). folder both chooses where log.md is written and scopes its content: a folder seeds only the commits that touched that subtree, while the bundle root seeds the whole vault's history. Refuses to overwrite an existing log.md — a change history is hand-maintained after seeding, so it is never clobbered. Requires the vault to be git-backed; with no git history the log is written empty.

ParametersJSON Schema
NameRequiredDescriptionDefault
folderNoVault-relative folder to write log.md into and scope history to (e.g. "guides"). Omit for the bundle root (whole-vault history).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 BundleA
Read-onlyIdempotent

Audit the vault's OKF (Open Knowledge Format) conformance.

Reports conformance as degrees, not a verdict — during a migration this is the progress meter. Reads the vault from disk (works before the index is built and before the vault declares 'okf_version'), and skips paths matching the vault's effective exclude patterns.

Findings come in three severities. Conformance (spec violations): notes missing a non-empty 'type', notes with unparseable frontmatter, and 'okf_version' declared outside the root index.md. Advisory (tolerated but worth fixing): 'status' values outside draft/stable/deprecated, log.md files whose '##' headings are not YYYY-MM-DD dates, and a missing root index.md. Informational (not deviations): notes containing wikilinks (relevant only when exporting; internal links resolve fine either way) and notes lacking the recommended 'title'/'description'. Reserved files (index.md, log.md) are exempt from the 'type' rule.

Returns: Report dict: 'mode', 'declared_version', 'active' (detection state); 'total_notes' and 'conformant_notes' (the progress ratio); per-rule findings each carrying 'count' and up to 20 'examples' paths ('missing_type', 'unparseable_frontmatter', 'misplaced_okf_version', 'unknown_status', 'log_heading_shape', 'wikilink_files', 'missing_recommended'); and 'root_index_missing' (bool).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantial context: reads from disk, respects exclude patterns, reports degrees rather than verdicts, and exempts reserved files. This goes well beyond the structured annotation fields.

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

Conciseness5/5

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

The description is long but every section earns its place: purpose, usage timing, severity taxonomy, and exact return keys. It front-loads core behavior and organizes the detailed enumeration clearly.

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

Completeness5/5

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

For a zero-parameter audit tool with rich output, the description fully covers detection semantics, severity rules, exclusions, and the exact report structure. The presence of an output schema plus this description leaves no ambiguity about what the agent will receive.

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

Parameters4/5

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

The tool takes zero parameters, so there is nothing to document and the empty schema is fully covered. The detailed return-format description is valuable but belongs to contextual completeness rather than parameter semantics, so the baseline of 4 applies.

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

Purpose5/5

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

States a specific verb ('Audit') and resource ('vault's OKF conformance'), and distinguishes itself from sibling okf_* tools by focusing on conformance reporting rather than conversion, index generation, or log seeding. The description clearly defines what validation means in this context.

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

Usage Guidelines4/5

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

Explicitly frames the tool as a migration progress meter and notes it works before the index is built or okf_version is declared, giving clear conditions for use. It does not name sibling alternatives or exclusions, but the context is unambiguous and sufficient for a zero-parameter tool.

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

readRead NoteA
Read-onlyIdempotent

Read the full content of a document or attachment by path.

For .md documents: returns content (the full raw file including frontmatter), plus the parsed frontmatter, title, and folder. For attachments (pdf, png, etc.): returns base64-encoded binary content and MIME type. Use 'list_documents(include_attachments=True)' to discover attachment paths. Use 'stats' to see allowed extensions.

Do not guess paths — look them up first via 'search' or 'list_documents'.

To recover the full text of a specific section returned by 'search', pass section=heading (the value from the result's 'heading' field).

Context cost: every byte returned counts against the LLM's context budget. Reads above MARKDOWN_VAULT_MCP_MAX_NOTE_READ_BYTES (default 256 KB for .md) or MARKDOWN_VAULT_MCP_MAX_ATTACHMENT_SIZE_MB (default 1 MB for binaries) raise ValueError. For partial markdown reads, pass section=heading (use the heading field from a search() result).

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path to the document or attachment (e.g. "Journal/note.md" or "assets/diagram.pdf"). Case-sensitive.
sectionNoWhen provided, return the whole section whose heading matches *section* — every paragraph, list, and sub-section from the heading up to the next heading at the same or higher level (case-sensitive; internal whitespace is collapsed before comparison). Pass the ``heading`` value from a ``search`` result unchanged for guaranteed match. ``None`` (the default) returns the whole document. Ignored for non-.md paths.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, indicating safe read-only operation. The description adds valuable behavioral context: context cost limits and ValueError for large reads, which is not covered by annotations. No contradiction.

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

Conciseness4/5

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

The description is well-structured with bullet points and clear sections, front-loading the main purpose. However, it is somewhat lengthy; the context cost paragraph could be more concise. Still, it effectively communicates key information without excessive redundancy.

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

Completeness5/5

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

Given the tool's complexity (different handling for .md vs attachments, section parameter, size limits, path discovery), the description covers all essential aspects: behavior, error conditions, context cost, and prerequisite steps. The presence of an output schema does not reduce the need for this clarity; the description enhances it.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3. The description adds meaning beyond schema, especially for the 'section' parameter, explaining its matching behavior and how to use search results. It also reinforces case-sensitivity for path.

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

Purpose5/5

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

The description clearly states the tool reads full content of documents or attachments by path, and distinguishes between .md documents (returning content, frontmatter, title, folder) and attachments (returning base64 and MIME type). This specificity and resource differentiation make it highly clear.

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

Usage Guidelines4/5

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

The description explicitly instructs not to guess paths but to use 'search' or 'list_documents' first, and explains when to use the 'section' parameter. While it does not exhaustively list alternatives, it provides sufficient context for when to use this tool versus siblings like 'search'.

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

reindexReindex VaultA
Idempotent

Run an incremental reindex on the writer thread.

Only needed when files are modified outside this server — for example, by a text editor, a sync tool, or another process writing directly to the vault directory. Do NOT call this after using 'write', 'edit', 'delete', or 'rename' — those tools update the index immediately as part of the operation.

Change detection is hash-based, so an unchanged file is never re-parsed. Use force=True to drop the index and re-parse every file regardless of hashes — the repair for index content that no longer matches what the current server would extract. A version upgrade that changes extraction does this by itself on the next start (#1124), so force=True is a manual escape hatch, not routine maintenance. When semantic search is configured, follow a force=True run with 'build_embeddings' (without force) so the vector index converges to the rebuilt chunk set; an ordinary reindex re-embeds as it goes.

To rebuild all embeddings from scratch (e.g. after changing the embedding model), use 'build_embeddings' with force=True.

A fast reindex (the common case — work scales with the drift, not the vault) returns its result inline. A reindex still running at the server's soft deadline continues in the background and returns {"status": "working", "job_id": ...} immediately — fetch the outcome with get_job_result. get_index_status remains the observability view of the index (it also covers boot-time builds and file-watcher reindexes no client call initiated).

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoWhen 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A5/5.0
Behavior5/5

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

The description adds substantial behavioral detail beyond the annotations: hash-based change detection, background execution with job_id, index unavailability during force rebuilds, and the relationship with embedding convergence. It also clarifies that force=True is a 'manual escape hatch, not routine maintenance,' which is exactly the kind of judgment context an agent needs. No contradiction with the idempotentHint or destructiveHint annotations.

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

Conciseness5/5

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

The description is long but every sentence carries operational weight. It front-loads the core purpose immediately and organizes the rest by when-to-use, when-not-to-use, force semantics, follow-up actions, and response behavior. Nothing feels redundant or promotional.

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

Completeness5/5

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

For a tool with one optional parameter, the description fully covers the common path, the force edge case, background job behavior, and how to retrieve results. It also explains the relationship to get_index_status and build_embeddings, so an agent can handle the complete workflow without guessing.

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

Parameters5/5

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

Although the schema already documents the force parameter at 100% coverage, the description goes further by explaining the trade-offs of force=True: it drops every indexed document, re-parses the whole vault, makes the index unqueryable during the rebuild, and scales cost with vault size. It also tells the agent to follow force=True with build_embeddings in semantic-search setups. This adds real decision-making value beyond the schema.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Run an incremental reindex on the writer thread.' It clearly distinguishes reindex from sibling tools like build_embeddings and get_index_status by explaining what reindex does versus what those tools handle. Even without knowing the siblings, an agent understands this is an index-refresh operation.

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

Usage Guidelines5/5

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

The description explicitly states when reindex is needed ('files modified outside this server') and when it is not ('Do NOT call this after using write, edit, delete, or rename'). It also routes the agent to alternatives: build_embeddings for embedding rebuilds, get_job_result for background outcomes, and get_index_status for observability. This is exceptional usage guidance.

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

renameRename NoteA

Rename or move a document or attachment. When renaming a .md note, always pass update_links=True to rewrite links in other documents that point to the old path — omitting this leaves those links broken.

For .md documents: the file and its search index entries are updated immediately — do not call 'reindex' afterward. For attachments: only the file is moved (no index update needed). Parent directories for new_path are created automatically.

ParametersJSON Schema
NameRequiredDescriptionDefault
if_matchNoOptional 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_pathYesTarget relative path (e.g. "projects/idea.md" or "assets/new.png"). Fails if new_path already exists.
old_pathYesCurrent relative path (e.g. "drafts/idea.md" or "assets/old.png").
update_linksNoWhen 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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

With annotations only saying readOnlyHint=false, idempotentHint=false, and destructiveHint=false, the description carries the behavioral burden and does so thoroughly. It discloses immediate index updates for .md files, no index update for attachments, automatic parent directory creation, best-effort link rewriting, and the broken-link risk when update_links is omitted.

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

Conciseness5/5

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

The description is structured with a clear opening, a prominent warning about update_links, then labeled .md and attachment behavior. Every sentence carries actionable information, and the most important usage rule is front-loaded.

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

Completeness5/5

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

The tool has four parameters and non-trivial side effects (link rewriting, index updates, directory creation), and the description covers all of these without needing to explain return values since an output schema exists. It is complete enough for an agent to call this tool correctly and avoid common mistakes.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful parameter context beyond the schema: parent directories are created automatically for new_path, .md files get index updates immediately, and attachments do not. This helps the agent reason about the consequences of the parameters, not just their types.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Rename or move a document or attachment.' It clearly distinguishes the tool from siblings like write/edit (content changes) and move_folder (folders) by restricting scope to documents and attachments.

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

Usage Guidelines4/5

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

The description gives explicit when-to-use guidance: always set update_links=True for .md notes, and it explicitly says not to call reindex afterward. It does not explicitly compare against move_folder or write, but the .md vs. attachment distinction and the reindex exclusion provide clear usage context.

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

show_contextContext CardA
Read-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").

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative note path (e.g. ``"Journal/2024-01-15.md"``).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 StatsA
Read-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'.

ParametersJSON Schema
NameRequiredDescriptionDefault
wait_for_pending_writesNoWhen True, wait until your recent document mutations have been applied to the index before answering, so the results reflect those changes. Use it right after modifying notes when this read must see them (e.g. right after a document mutation whose effect this read should reflect). Default False answers immediately from the current index — almost always already up to date; inspect the response's ``_meta.index_stale`` field to tell whether a write was still in flight. Bounded by a server timeout (default 60s); on timeout it answers from the current index rather than waiting longer.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context by pointing to the semantic_search_available field and how it affects search mode choices, which helps the agent interpret the response. No contradiction exists.

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

Conciseness5/5

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

The description is compact and front-loaded: the first sentence states the purpose, the second gives a concrete usage recommendation, and the third highlights a key response field. Every sentence earns its place with no filler.

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

Completeness5/5

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

For a simple read-only stats tool, the description is complete: it explains when to call it, what it returns at a high level, and which field drives search-mode decisions. The detailed parameter schema and presence of an output schema cover the remaining invocation needs.

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

Parameters3/5

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

The schema description coverage is 100% and the wait_for_pending_writes parameter is fully explained in the schema. The tool description does not add parameter-level meaning beyond the schema, which matches the baseline for full coverage.

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

Purpose4/5

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

The description states a specific verb and resource: 'Get an overview of the vault's size, capabilities, and configuration.' This clearly distinguishes the tool as a vault-level stats endpoint, but it does not explicitly contrast it with related siblings like get_server_info or get_index_status.

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

Usage Guidelines4/5

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

The description gives explicit guidance to call this tool 'at the start of a session' to understand vault contents and available search modes. It does not provide exclusions or when-not-to-use guidance, but the recommended usage context is clear and actionable.

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

writeWrite NoteA
Idempotent

Create or overwrite a document or attachment.

For .md documents: uses 'content' (markdown body) and optional 'frontmatter'. WARNING: replaces the entire file — use 'edit' for targeted changes. The search index is updated immediately; do not call 'reindex' afterward.

For attachments (pdf, png, etc.): uses 'content_base64' (base64- encoded binary). 'content' and 'frontmatter' are ignored. Parent directories are created automatically for both.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path (e.g. "Journal/note.md" or "assets/photo.png"). Extension determines handling.
contentNoFull markdown body for .md files (excluding frontmatter). Ignored for attachments.
if_matchNoOptional etag obtained from a previous 'read' call. When provided, the write only proceeds if the file has not been modified since that read (optimistic concurrency). Omit to write unconditionally.
frontmatterNoOptional YAML frontmatter dict for .md files, e.g. {"title": "My Note", "tags": ["draft"]}. Ignored for attachments.
content_base64NoBase64-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

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior1/5

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

The description warns 'replaces the entire file', which is a destructive overwrite behavior, while the annotations declare destructiveHint=false. This is a direct contradiction: an agent relying on annotations could wrongly assume the operation is non-destructive. Despite useful disclosures like immediate index updates, the contradiction forces a score of 1.

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

Conciseness4/5

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

The description is well-structured and front-loaded: the core purpose appears first, followed by clearly separated markdown and attachment branches. The warning and index-update note are valuable rather than filler. It is slightly long but every section earns its place.

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

Completeness4/5

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

The description covers the two main usage modes, the overwrite warning, index behavior, automatic parent directory creation, and the concurrency option via if_match. Since an output schema exists, return-value details are not required. A small gap is that it does not describe failure behavior when if_match conflicts, but overall the description is complete enough for successful invocation.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema by grouping parameters by file type: content/frontmatter for .md files, content_base64 for attachments, and explicitly noting that content and frontmatter are ignored for attachments. It also adds the base64 token-cost warning, which is helpful context not present in the schema.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Create or overwrite a document or attachment.' It clearly separates markdown documents from binary attachments and explicitly names the sibling alternative 'edit' for targeted changes, so an agent can distinguish write from edit/append/delete without opening schemas.

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

Usage Guidelines5/5

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

The description gives explicit when-to-use guidance: use 'edit' for targeted changes instead of write, and do not call 'reindex' afterward because the search index updates immediately. It also states that parent directories are created automatically, removing any need for a separate mkdir step.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 1 tool updatev4.1.0
    • Changedsearch5 fields changed
      • addedInput schema / properties / mode / anyOf
        Added value: +[
        +  {
        +    "enum": [
        +      "keyword",
        +      "semantic",
        +      "hybrid"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / mode / default
        Previous value: -"keyword"New value: +null
      • changedInput schema / properties / mode / description
        Previous 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."
      • removedInput schema / properties / mode / enum
        Removed value: -[
        -  "keyword",
        -  "semantic",
        -  "hybrid"
        -]
      • removedInput schema / properties / mode / type
        Removed value: -"string"
  2. 30 tool updatesv4.0.0
    • Addedappend
    • Addeddelete
    • Addededit
    • Addedfetch
    • Changedget_backlinks1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_broken_links2 fields changed
      • changedInput schema / properties / folder / description
        Previous 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."
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_connection_path1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_context1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Addedget_conventions
    • Changedget_history1 field changed
      • changedInput schema / properties / path / description
        Previous 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."
    • Addedget_job_result
    • Changedget_most_linked1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_orphan_notes1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_outlinks1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_recent2 fields changed
      • changedInput schema / properties / folder / description
        Previous 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."
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_similar3 fields changed
      • addedInput schema / properties / filters
        Added 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."
        +}
      • addedInput schema / properties / folder
        Added 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."
        +}
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedget_toc1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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)."
    • Changedlist_documents2 fields changed
      • addedInput schema / properties / filters
        Added 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)."
        +}
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedlist_folders1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedlist_tags1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Addedmove_folder
    • Addedokf_convert_links
    • Addedokf_generate_index
    • Addedokf_seed_log
    • Addedokf_validate
    • Changedreindex1 field changed
      • addedInput schema / properties / force
        Added 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"
        +}
    • Addedrename
    • Changedsearch2 fields changed
      • changedInput schema / properties / filters / description
        Previous 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\"}."
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Changedstats1 field changed
      • changedInput schema / properties / wait_for_pending_writes / description
        Previous 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."
    • Addedwrite
  3. 25 tool updatesv3.1.0
    • First observedbrowse_vault
    • First observedbuild_embeddings
    • First observedembeddings_status
    • First observedget_backlinks
    • First observedget_broken_links
    • First observedget_connection_path
    • First observedget_context
    • First observedget_diff
    • First observedget_history
    • First observedget_index_status
    • First observedget_most_linked
    • First observedget_orphan_notes
    • First observedget_outlinks
    • First observedget_recent
    • First observedget_server_info
    • First observedget_similar
    • First observedget_toc
    • First observedlist_documents
    • First observedlist_folders
    • First observedlist_tags
    • First observedread
    • First observedreindex
    • First observedsearch
    • First observedshow_context
    • First observedstats

TDQS

A4.1/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose, with detailed descriptions explaining when to use which. For example, 'get_backlinks' and 'get_outlinks' are separate for inbound vs outbound links, and 'get_context' consolidates multiple calls. No two tools appear to do the same thing.

Naming Consistency4/5

Most tools follow a verb_noun pattern (e.g., 'get_', 'list_', 'read', 'search'). However, 'embeddings_status' and 'stats' use a noun-only format, breaking the pattern slightly. Overall consistent but with minor deviations.

Tool Count4/5

With 25 tools, the server covers a broad range of vault operations. The count is slightly high but each tool addresses a specific need. It earns its place given the complexity of vault management (search, links, git, embeddings, UI).

Completeness2/5

The tool set lacks mutation tools (create, write, edit, delete, rename) which are essential for a vault server. The 'reindex' tool description references these operations, implying they exist but are not in the provided list. This is a significant gap for a complete CRUD surface.

Maintenance

ActivityActive
ResponsivenessResponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP 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.
    7
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Local 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.
    20
    Apache 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pvliesdonk/markdown-vault-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server