Skip to main content
Glama
zoeynine

Obsidian Server MCP

by zoeynine

Obsidian Server MCP

English · 简体中文

A lightweight, general Obsidian Server MCP for filesystem and semantic access to a Vault without a running Obsidian Desktop application. Common tools follow the pinned Local REST 5.3.1 contract as closely as the filesystem backend permits.

The current entry is stdio. Synchronization, remote transport/authentication and deployment configuration are external to this implementation. Vault files are the source of truth; the server sees changes once they reach its filesystem.

The supported deployment target is a Linux headless server/VPS. Windows can be used for local development, but is not a supported deployment platform.

Deployment filesystem permissions are authoritative for what the MCP process may read, write or delete. Configure access through the environment's user, group, ACL, mount or container settings. MCP contains no deployment authorization policy. Local tests use disposable fixtures; Linux filesystem and permissions validation remains a separate platform qualification.

Quick start

Install Node.js 22 or newer with npm on Linux. CI checks Node 22 and 24. Download and extract this repository's source archive, or clone its URL from the repository's Code menu. Open a terminal in the project folder:

npm ci
npm run build

Keep development dependencies installed while building; the TypeScript compiler is a development dependency. sharp installs its native image library for the current platform, so install dependencies on each host instead of copying node_modules between Windows and Linux.

Start with an empty example Vault. In Linux bash or sh:

mkdir -p ./example-vault
printf '# Hello\n' > ./example-vault/Hello.md
OBSIDIAN_VAULT_ROOT="$PWD/example-vault" node ./dist/stdio-main.js

For optional local development in Windows PowerShell:

New-Item -ItemType Directory -Force ./example-vault | Out-Null
Set-Content -LiteralPath ./example-vault/Hello.md -Value '# Hello' -Encoding utf8
$env:OBSIDIAN_VAULT_ROOT = (Resolve-Path ./example-vault).Path
node ./dist/stdio-main.js

A running stdio server waits for MCP messages on standard input; it does not open a web page or print a ready banner. Stop this manual check with Ctrl+C, then let your MCP client launch the process itself.

Connect an MCP client

For clients accepting a mcpServers JSON configuration, add this entry and replace the two absolute paths with your project and Vault paths:

{
  "mcpServers": {
    "obsidian-server": {
      "command": "node",
      "args": ["/absolute/path/obsidian-server-mcp/dist/stdio-main.js"],
      "env": {
        "OBSIDIAN_VAULT_ROOT": "/absolute/path/example-vault"
      }
    }
  }
}

For local Windows development, forward-slash paths such as C:/Projects/obsidian-server-mcp/dist/stdio-main.js and C:/Vaults/example-vault work in JSON. If your client does not inherit the terminal's PATH, use the absolute Node executable as command (find it with (Get-Command node).Source in PowerShell or command -v node on Linux). Clients with form-based settings use the same command, argument and environment variable. Launch node directly so the MCP protocol has exclusive use of stdout.

Reconnect the client and discover 14 tools. First call obsidian_help({"topic":"read"}), then vault_list({"path":""}) and vault_read({"path":"Hello.md"}) against the example Vault. A write-capable client can modify files with this server; choose its Vault and filesystem permissions accordingly.

If startup fails, check that npm run build created dist/stdio-main.js, the Vault directory exists, and the client process receives OBSIDIAN_VAULT_ROOT. No API key or Obsidian Desktop plugin is required for this local stdio entry. HTTPS hosting, authentication, synchronization and signed attachment downloads are supplied by a separate deployment adapter. See binary integration for attachment delivery.

Related MCP server: vault-mcp-server

Architecture and compatibility reference

  • src/core owns filesystem, path, exact-byte version, parser, query and mutation semantics.

  • src/transport owns MCP schemas and error/result mapping; it never accesses files directly.

  • Tests use disposable fixtures. No build or check connects to a real Vault.

This project references and adapts contracts and implementation patterns from Obsidian Local REST API by Adam Coddington. The reference is Local REST 5.3.1, peeled commit 17a9cfd9ff5dd0156b694bf9b13ab36c786b29da, not moving main. See the pinned parity tables for source links, operation/scope tables, exact dependency rationale, limits and deliberate differences. This project is distributed under the MIT License. The upstream copyright and complete MIT notice are retained in third-party notices.

Implemented MCP tools

Default tools have strict input/output schemas. Text-tool success payloads appear once in structuredContent, with empty content. Attachment payloads appear once in native MCP content, with only metadata in structuredContent. Business failures return isError: true and a single JSON text block containing error.code, error.message and optional error.details. They omit structuredContent so the error body is not validated against the success output schema. Unexpected failures reveal no absolute filesystem paths or stacks.

Tool

Behavior

obsidian_help

Topic index when topic is omitted; only the requested usage section otherwise

vault_list

Sorted {files} with directory suffixes; omit path or use "" for the Vault root

vault_read

Whole file or selected heading/block/frontmatter value, with exact-byte version; discover targets with vault_get_document_map

vault_read_binary

Image preview, signed download link or explicit bytes for non-PDF attachments; PDF is unsupported; see obsidian_help topic binary

vault_get_document_map

Nested heading addresses, block IDs and frontmatter keys, including duplicate disambiguators

search_query

JsonLogic over note text, paths and properties, retaining truthy values in {results} within scan/result limits

reference_query

Read-only references to a file/heading/block within explicit source and resolution scopes; matches and uncertainties with source versions

tag_list

Direct tags and nested parents with per-file counts

vault_write

Atomic text create/replace; existing files require ifMatch or ifMatchGuard

vault_append

Atomic append; existing files require ifMatch or ifMatchGuard; missing LF added first as in Local REST

vault_patch

Generic heading/block/frontmatter instruction; requires ifMatch or ifMatchGuard

vault_replace_text

Atomic literal replacement of one unique exact string in an existing text file; requires ifMatch or ifMatchGuard

vault_move

Move a file; destination suffix and optional allowOverwrite follow Local REST

vault_delete

Recoverable Vault-local trash by default; permanent: true permanently deletes a file

The stdio entry exposes thirteen Vault tools plus the static obsidian_help manual. An embedded read-only composition exposes five text/discovery tools plus help, can add the binary reader and reference query, and can omit the mutation store. There are no mutation stubs. search_simple and its unused implementation are removed. Properties use generic patching. Binary upload, copy and Desktop UI tools remain outside this surface.

Properties are edited through vault_patch(targetType=frontmatter); edits preserve unrelated property text/comments, body, BOM and line endings. YAML aliases, anchors, duplicate/complex keys and non-JSON values are refused.

Obsidian's Desktop link graph is unavailable and never fabricated. The separate reference query implements the bounded filesystem reference contract. JsonLogic supports coercion, arithmetic, collections, defaults, glob and bounded regexp; it is no longer predicate-only. There is no search database or whole-Vault snapshot.

Operational note: under the current server parser semantics, malformed or unsupported frontmatter in a single note can make whole-Vault search_query and tag_list fail explicitly.

Optional text-only reading

An embedding host can select a tool profile for each server instance:

Profile

Reading and navigation tools

standard (default)

vault_read, vault_list, vault_get_document_map, search_query

text

vault_read_text, vault_list_text, vault_get_document_map_text, search_query_text

Each alias shares its original tool's strict input schema, use case, limits, path policy, error mapping and version semantics. In the text profile, all tools omit both outputSchema and structuredContent; successful payloads are still validated internally. Ordinary data, help and mutation receipts use compact JSON in one text block. Business errors retain isError: true and their existing payloads. Chinese characters are emitted directly.

vault_read_text presents whole-file reads in two text blocks: the first contains all metadata (path, version, versionGuard, tags, frontmatter, stat) plus textField: "content"; the second is the original content string. Heading/block reads also use two blocks: {path,version,versionGuard,textField:"result"} and the reader's unchanged result string. Empty text remains an empty second block. No trimming, unescaping, newline conversion or code fences are applied. Frontmatter target reads retain single-block {path,version,versionGuard,result} JSON for every value type, including strings. Heading/block reads retain their existing semantic behavior, including relative heading levels; use a whole-file read for exact replacement.

A full composition has 14 tools in either profile. The text profile replaces the four original names rather than adding duplicate choices. The other ten names and all operation semantics are shared. The standard profile's output formats remain unchanged; the standard stdio entry uses that default profile. Every client discovering an endpoint sees that endpoint's selected tool list.

A host serving clients with different presentation needs can select fixed options by endpoint while sharing the same Vault dependencies and mutation store:

const standardServer = createVaultMcpServer(dependencies);
const textServer = createVaultMcpServer(dependencies, {
  toolProfile: "text",
});

Use separate MCP server/transport instances for the endpoints. Register options are local to each instance; the standard instance neither lists nor accepts calls to the four aliases, and the text instance does not expose their four original names. The host owns HTTP routing, authentication and resource discovery; these options do not create routes or separate Vault permissions. Use the same loaded core module and shared store to retain in-process write coordination. No client-side hiding is needed. Binary delivery in the text profile places metadata JSON in the first text block, followed by the unchanged native image, embedded resource or resource link; attachment bytes are never serialized into the metadata. Reference queries use compact JSON like other data tools. Help and recovery instructions refer to the selected profile's available tool names; stable error codes are unchanged.

For existing hosts, enableTextRead: true remains supported: with the default profile it adds only vault_read_text, giving a full composition 15 tools, and retains the original single-block JSON reading contract. The text profile already includes that tool and never registers it twice.

On-demand help

Call obsidian_help({}) for a compact index with Guides and Tools. Guides explain cross-tool workflows; Tools lists the names actually exposed by this endpoint. Ask for obsidian_help({"topic":"search_query"}) for one tool's contract and examples, or obsidian_help({"topic":"search"}) for its workflow. All canonical names and the four text-profile names have manuals, including obsidian_help itself. A known manual does not enable an unavailable tool; its opening notice identifies that situation and any registered counterpart. Unknown topics return a recoverable error with this endpoint's index. Help reads no Vault data, makes no network calls and performs no mutations.

The marked guides below and the canonical tool manual are the documentation sources. Text aliases reuse canonical tool content and add only presentation notes; they do not maintain separate contracts. Edit these sources, run npm run generate:help, and commit the generated module. npm run check:help detects drift; builds also regenerate it. Runtime help uses bundled strings, so a deployed package needs neither Markdown source file.

Finding and reading notes

Start with vault_list to discover paths. For a known note, use vault_get_document_map when you need reliable heading paths, block IDs or property names, then copy its keys unchanged to a targeted vault_read. Use a whole-file read for full context or an exact source slice for replacement. Targeted heading levels are relative; inspect the whole file or map to verify stored nesting after a structural change.

Both map and read return the full exact-byte version and a 16-hex versionGuard. Copy either version into ifMatch or versionGuard into ifMatchGuard for later mutations, never both. The short guard has lower collision strength; see guide write. A read is not a lock on the note. If a write reports a conflict, reread and reconcile before another attempt. maxBytes admits the entire source document, even for a small target; narrowing the target does not bypass file-size limits or frontmatter parsing.

Ask for tool topics vault_list, vault_get_document_map and vault_read for limits, targeted-read examples and size-error recovery. For attachments use guide binary; for selecting notes use search; for edits use write.

Reading attachments

Use vault_read_binary for images and non-PDF attachments. Its default auto mode selects a bounded native raster preview or a short-lived protected HTTPS resource link for another file type. Choose bytes only when the client needs exact bytes within its transfer cap, or link when it needs a download. Generic download delivery requires the embedding host's link provider.

PDF is intentionally unsupported in every mode, including resource reads. Use the client's native file upload or attachment feature for PDFs. This tool does not perform OCR or document extraction. Preview metadata identifies a derived image; it is not evidence that the original bytes were transferred.

Ask for tool topic vault_read_binary for exact limits, delivery metadata, examples and link-unavailable recovery. Guide paths applies to attachments as well as notes.

Searching notes

Choose search_query for content/property conditions, tag_list for tag inventory, or reference_query for bounded link resolution. A literal content match can find link-shaped text but does not establish a backlink. Inspect selected notes with vault_get_document_map and targeted or full vault_read.

JsonLogic evaluates an expression against each Markdown note. An operator has one key; combine conditions with and or or. The returned value is the expression's truthy result, which may be a boolean or data rather than a snippet. Use scope to choose the scan before adding predicates. A path/glob predicate filters matches without reducing scan work; maxTotalBytes counts scanned bytes, not response size. Scan and result overflow fail without partial success; the fixed output cap reports search_query.budget_exceeded.

Ask for tool topic search_query for fields, operators, limits and runnable content/frontmatter/compound examples. Guide tags explains aggregation; references explains source and resolution coverage.

Finding references to a target

Use reference_query when spelling alone cannot decide whether a link points to a particular file, heading or block. Choose a source scope for Markdown bodies and a resolutionScope for the filename inventory used to resolve links. The inventory defaults to the source scope. A recursive root inventory can establish uniqueness for a bare wikilink; a partial inventory cannot prove it.

Treat confirmed matches separately from uncertain occurrences. Uncertain links may be unrelated to the requested target. Completeness describes only the declared scopes and supported syntax: incoming links outside the source scope remain unknown. This is neither a persisted link graph nor an atomic Vault snapshot. The tool performs no repair or mutation.

Ask for tool topic reference_query for target syntax, locators, limits and examples. Use guide search for literal candidate discovery and read to inspect a matched source with its exact version.

Listing tags

Choose tag_list to discover tag names and how many Markdown files contain each tag. It counts repeated occurrences in a file once and aggregates nested parents: a note with a/b contributes to both a/b and a. By contrast, vault_read and search_query expose only direct tags. Use search_query when you need the matching notes or property conditions.

Tags come from frontmatter and inline hashtags. Inline recognition can differ from Obsidian Desktop. Scan/tag limits and malformed or unsupported frontmatter fail explicitly, so an error is not evidence of an empty inventory.

Ask for tool topic tag_list for its limits and result example, or search_query for filtering by direct tags.

Patching headings and properties

Use vault_get_document_map to discover an exact semantic target and its version, then vault_patch to edit that heading, block or property with ifMatch or ifMatchGuard. Choose a scope before writing content: a section body, its marker, the whole section or a move of its parent relationship have different effects. within: 0 selects the first direct body block when child sections should be retained; choose the appropriate index for another body block.

Heading content uses relative levels. In the default content scope, input # becomes a child of the selected heading. With markerAndContent prepend/append it is relative to the target's actual parent; skipped levels can change nesting. Whole-subtree replacement with children fails with vault_semantic.subtree_confirmation_required unless explicitly allowed with allowSubtreeReplacement: true as well as a current ifMatch or ifMatchGuard.

Choose typed value for a frontmatter property and destination for a heading move. For a literal exact source edit use vault_replace_text; for literal Markdown at the file end consider vault_append. After a structural edit, check the map or whole-file vault_read: targeted heading reads normalize displayed levels and cannot by themselves prove nesting.

Ask for tool topic vault_patch for scope/payload combinations, subtree recovery and runnable examples. Guide write compares the mutation tools.

Writing, appending and replacing text

Choose the operation that matches the intended change:

  • vault_write: create a text file or replace its entire content.

  • vault_append: add literal text at the end, creating a missing file.

  • vault_replace_text: replace one unique literal slice from a whole-file read.

  • vault_patch: edit a semantic heading, body block or typed property.

For an existing file, read with vault_read or vault_get_document_map and copy the returned versionGuard unchanged into ifMatchGuard. Alternatively, pass the full version as ifMatch; its strict exact-match contract is unchanged. Supply exactly one: both together fail with vault_mutation.conflicting_preconditions, even when they agree. Exact replacement needs the original slice and token from the same whole-file read. Create with write/append without either token only when the path is missing. A token for a missing file cannot create it.

versionGuard is exactly 16 lowercase hex characters: the first 64 bits of the same file-byte SHA-256, returned by the server so callers need not slice or count characters. It has no session, cache, lease, expiry or authorization meaning. Wrong or stale values conflict; malformed guards are refused. On any conflict, reread and reconcile rather than copying a token from an error or automatically retrying. This is content-based, so restoring identical bytes restores both tokens; neither token tracks intervening edit history.

The short guard is a convenience for non-adversarial edits, not full SHA-256 collision resistance. A random unequal pair collides with probability about 2^-64; birthday collisions become plausible around 2^32 distinct versions. Use full ifMatch when stronger collision resistance is needed. After the initial check, the server pins the full SHA-256 for in-flight revalidation, retaining the existing per-path locking and atomic publication limits.

Successful read/map/search/reference results and text-write receipts include versionGuard wherever they include version. Binary results include both only when complete original bytes were read; download-only links need not have either. Move/delete receipts, directory listings and tag counts gain no token. Both profiles use the same rules; text reads put the guard in metadata.

Successful receipts report both saved tokens and before/after UTF-8 byte sizes. They establish that bytes were committed, not that the edit fulfilled its intent or preserved Markdown structure. Inspect content or a map when that matters. A saved-note cleanup warning means the write succeeded; do not append again.

Ask for each tool's own topic for its contract and examples. Guide patch covers structured editing, paths covers shared path/text limits and files covers moving or deleting files.

Paths and file limits

All tool paths are untrusted Vault-relative paths. The shared sandbox rejects absolute, traversing and noncanonical paths, symbolic-link traversal, escape, reserved Windows names and replacement of the original Vault root. Dot-prefixed components and host-configured internal subtrees are protected; discovery omits them and direct access refuses them. The empty string means root only for inputs that explicitly support it, such as listing and scan directories.

Text operations reject binary extensions, NUL and malformed UTF-8/Unicode while preserving BOM and original newlines. Read and mutation text sizes default to 4 MiB with a 64 MiB hard cap. Each tool also has its own entry, scan or result limits; a smaller returned target does not waive whole-source admission.

Deployment filesystem permissions remain authoritative. These safeguards are not a client authorization policy or a cross-process filesystem lock. Ask for the relevant tool topic for its parameter limits and actionable errors.

The mutation path is deliberately small:

  1. Serialize the relative path across store instances in this process; safely read existing bytes and require ifMatch or ifMatchGuard for existing write/append and every patch/exact replacement. Validate the prepared text before changing files.

  2. Create missing parent directories through the shared sandbox. Write a hidden .obsidian-mcp-<random>.tmp beside the target using exclusive creation. Normal OS creation defaults inherit directory permissions/default ACLs; MCP never calls chown/chmod/setfacl or runs a permissions hook.

  3. Flush the completed temporary file, close it, and revalidate parents, path, temporary identity and the original exact-byte version. No automatic mutation retry.

  4. Atomically rename over an existing file. For a missing file, atomic hard-link publication refuses a concurrent new destination, then removes the temp name. Node rename has no NOREPLACE flag. No unlink-before-replace or copy fallback.

Temporary files are blocked by the same protected-path policy and omitted from list/search/tag discovery. Failed writes remove their exact temp name after identity checks. Unsafe/failed cleanup is reported; a successful create with a leftover temp returns an explicit saved-note warning, not a misleading failure. Missing parent directories can remain after a failed operation. No startup orphan sweeper, parent-directory fsync, durability modes or permission manager is included. A single file fsync is retained before publication; this is not a power-loss durability guarantee.

New file inodes inherit deployment permissions from the destination directory. MCP does not preserve/reassign per-file ownership or ACLs. Linux validation must verify permission inheritance and allowed/denied operations for the actual process identity and deployment filesystem, including directory permissions that govern rename and deletion. It must also qualify native symlink/race and rename behavior. Windows fixtures and injected faults do not validate POSIX ACLs.

Per-path locks are process-local. Final version checks are optimistic checkpoints, not cross-process filesystem CAS; Sync keeps its own conflict handling. Parent identities are revalidated, but native Node path calls do not lock directories against adversarial renames between syscalls. Directory ownership and access must keep the namespace trusted; the remaining platform behavior is qualified on each deployment's operating system and filesystem.

Stdio requires only OBSIDIAN_VAULT_ROOT; no staging-root or policy-module configuration is needed. Protocol output uses stdout; diagnostics use stderr. Write/append/patch/exact-replacement success is a compact message: "OK" receipt with path, exact-byte version, versionGuard, beforeSizeBytes, final sizeBytes, created and any warnings. Exact replacement adds replacementCount: 1; the note body is not echoed.

Moving and deleting files

Use vault_move to relocate a file and vault_delete to delete one. Neither operation updates incoming links or Obsidian Desktop history. If link impact matters, inspect it with reference_query within declared scopes before the move; outside-scope incoming links remain unknown.

Move overwrites require allowOverwrite. Delete defaults to recoverable Vault-local trash; permanent: true is irreversible. Both accept an optional ifMatch or ifMatchGuard for the source, never both (see guide write). Omitting both acts on the current path; on move it never protects the destination's version. Directories and files with additional hard links are refused.

Neither tool automatically retries. Trash failure does not fall back to permanent deletion, and move has no cross-filesystem copy fallback. Recovery from trash requires filesystem access to the receipt's protected trash path.

Ask for tool topics vault_move and vault_delete for destination syntax, receipts, recovery and examples. Guide paths describes shared containment.

Requirements and checks

Node.js 22 or newer. Install with npm ci; npm run check verifies generated help, typechecks, runs disposable-fixture tests and builds. Individual commands are npm run typecheck, npm test and npm run build. GitHub Actions runs the same check on Linux with Node 22 and 24. For ordinary code changes, run the local check once; there is no required manual OS/Node matrix. Additional Linux checks depend on the affected behavior or release needs. The portable test runner discovers compiled test files explicitly and runs them in separate processes, one file at a time. See contributing for the development workflow.

Pinned parser/JSON/YAML/MIME dependencies are documented in the parity table. sharp is the only additional dependency for bounded raster previews; it does not render PDFs. See binary deployment integration for the provider required by generic downloads and deployment acceptance steps. Tests cover compact transport, targeted reads, frontmatter operations, JsonLogic values and limits, shared path/text policy, concurrency, exact byte versions, temp-file/publication ordering, hidden artifacts, races, cleanup and filesystem error propagation. Binary tests cover PDF rejection across all modes/resources, generic download links, explicit exact-byte transfer, previews, limits, resource versions, link-provider boundaries, and a real stdio child process with the MCP SDK client.

Available Tools

14 tools
obsidian_helpB
Read-onlyIdempotent

Usage manual; omit topic for the topic index.

NameRequiredDescriptionDefault
topicNo

Output Schema

NameRequiredDescription
textYes

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds one behavioral trait beyond the annotations: that omitting topic yields a topic index. It discloses nothing about rate limits, output format, or failure modes.

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?

Two short clauses, front-loaded with the tool's identity followed by the parameter instruction; no filler. It is arguably too terse for a help tool, but nothing in it is wasted.

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

Completeness3/5

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

With only one optional parameter and an output schema present, return-value detail is not required, and the annotations carry the safety profile. Still, the definition gives the agent no sense of what topics are available or what the manual covers, leaving discovery entirely to trial calls.

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 0% for the single parameter, so the description must carry the meaning. It does explain the optionality semantics — omitting topic returns the topic index, implying topic selects a specific entry — but it never says what valid topic values look like or how to discover them, so the compensation is partial.

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 names a specific resource (a usage manual / help documentation), which is clearly distinct from the vault-operation siblings like vault_read and vault_write. It stops short of stating an explicit verb or the scope of the manual, but an agent can identify it as the documentation tool 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 Guidelines3/5

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

Usage is only implied — the agent is expected to infer that this is the tool to call when it needs documentation. The clause 'omit topic for the topic index' does give one concrete invocation instruction, but there is no explicit when-to-use vs alternatives guidance beyond that.

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

reference_queryA
Read-onlyIdempotent

Find references to a file/heading/block within explicit source and resolution scopes. Read-only; returns matches plus uncertainties and exact source versions. Outside-scope incoming links remain unknown. See help topic references.

NameRequiredDescriptionDefault
scopeYes
targetYes
maxFilesNo
maxEntriesNo
maxResultsNo
maxFileBytesNo
maxTotalBytesNo
maxOutputBytesNo
resolutionScopeNo

Output Schema

NameRequiredDescription
scopeYes
targetYes
matchesYes
coverageYes
uncertainYes
resolutionScopeYes

TDQS

A3.5/5.0
Behavior4/5

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

Annotations already cover the read-only/idempotent safety profile, so the description earns credit for adding beyond them: it discloses that results include 'uncertainties and exact source versions' and that out-of-scope links are silently omitted—non-obvious behaviors an agent needs.

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 tight sentences with the core operation front-loaded, the key limitation second, and a pointer to help last. Nothing is redundant.

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

Completeness3/5

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

An output schema exists, so return shape needn't be explained, and annotations cover safety. But for a 9-parameter tool with nested scopes and 0% schema coverage, the description leaves the limit parameters and their interaction with results unexplained, a real gap for correct invocation.

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

Parameters2/5

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

Schema description coverage is 0% across 9 parameters, including nested objects. The description maps the conceptual source/resolution scope and target dimensions, but the six max* limit parameters and the recursive flags are never explained, leaving most of the schema meaning undocumented.

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?

Specific verb ('Find references') plus resource ('file/heading/block') and the scoping model make the operation unambiguous. It does not explicitly contrast with siblings like search_query, but the 'references' framing distinguishes it well enough.

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 caveat 'Outside-scope incoming links remain unknown' implies when results are incomplete, and 'See help topic references' routes to more detail. However, it never states when to prefer this over search_query or other siblings, leaving usage largely inferred.

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

search_queryA
Read-onlyIdempotent

Query Markdown with JsonLogic over path, content, tags, frontmatter and stat. Returns truthy values. Only scope limits the scan; query path/glob conditions only filter results. Overflow errors, never truncation. No link graph.

NameRequiredDescriptionDefault
queryYes
scopeNoOptional scan scope; omit for a recursive whole-Vault scan. directory "" is root; recursive=false scans only direct child files.
maxFilesNoOptional scanned-file cap; omit for defaults.
maxEntriesNoOptional scanned-entry cap; omit for defaults.
maxResultsNoOptional match cap, not truncation; omit for defaults.
maxFileBytesNoOptional per-file byte cap; omit for defaults.
maxTotalBytesNoOptional scanned-byte cap, not response size; omit for defaults.

Output Schema

NameRequiredDescription
resultsYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the description earns credit for adding real behavior: truthy-value returns, overflow-errors-instead-of-truncation, and the scan-vs-filter distinction. The explicit 'never truncation' guarantee is exactly the kind of failure-mode disclosure an agent needs before setting caps.

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 short sentences, each carrying a distinct fact (fields, return semantics, scan-vs-filter, overflow behavior), with the core purpose front-loaded. No filler and no repetition of schema content.

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

Completeness3/5

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

With an output schema present, return values need not be described, and the scan/error semantics are well covered for a 7-parameter tool. The gap is the query DSL itself: no mention of which JsonLogic operators or field names are valid, which is the hardest part of invoking this tool 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 coverage is 86%, so the baseline is 3; the description pushes above it by explaining that scope is the sole scan driver and that result caps are not truncation, which clarifies the intent behind maxResults and maxFiles. It still says nothing about the JsonLogic object shape required by the sole required parameter.

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 and resource ('Query Markdown') plus the mechanism and queryable fields (path, content, tags, frontmatter, stat), which lets an agent tell it apart from vault_list, tag_list and reference_query. The trailing 'No link graph' explicitly carves out the graph-query sibling.

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?

Provides one important usage rule -- that only scope limits the scan while path/glob conditions merely filter results -- which shapes how an agent should build a query. However, it never names an alternative tool or states when to prefer vault_list/tag_list over this one; the 'No link graph' clause is the only implied exclusion.

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

tag_listA
Read-onlyIdempotent

List tags and parent tags with per-file counts; names omit #. Scan/result limits fail explicitly. Inline recognition may differ from Obsidian Desktop.

NameRequiredDescriptionDefault
maxTagsNoOptional unique-tag cap including parents; omit for defaults.
maxFilesNoOptional scanned-file cap; omit for defaults.
maxEntriesNoOptional scanned-entry cap; omit for defaults.
maxFileBytesNoOptional per-file byte cap; omit for defaults.
maxTotalBytesNoOptional scanned-byte cap, not response size; omit for defaults.

Output Schema

NameRequiredDescription
tagsYes

TDQS

A3.5/5.0
Behavior4/5

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

Annotations already cover readOnly/idempotent/non-destructive, so the bar is lower, yet the description adds real behavioral context: limits 'fail explicitly' (i.e., errors instead of silent truncation) and inline recognition 'may differ from Obsidian Desktop'. Those caveats are not derivable from the annotations or schema.

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

Conciseness4/5

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

Three tight clauses, no filler, with the core purpose front-loaded before the two caveats. Nothing redundant is present.

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?

An output schema exists so return values needn't be described, annotations cover the safety profile, and the schema documents all five caps. The description covers the surprising edge cases; only the when-to-use gap keeps it from being fully complete.

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

Parameters3/5

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

Schema coverage is 100% and every cap parameter is self-documented in the schema, so the baseline of 3 applies. The description adds no syntax or default guidance beyond the schema's 'omit for defaults'.

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?

States a specific verb and resource: 'List tags and parent tags with per-file counts', and adds a concrete output detail ('names omit #'). It is clearly distinguishable from vault_list and search_query by resource, though it never explicitly contrasts itself with those siblings.

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

Usage Guidelines2/5

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

The description never says when to reach for tag_list versus search_query or vault_list, nor does it state any prerequisites. Usage is only implied by the word 'List'.

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

vault_appendA

Append UTF-8 text; creates missing files. Existing files require ifMatch or ifMatchGuard (copy versionGuard); missing final LF is added first. Binary/NUL refused; no automatic retry.

NameRequiredDescriptionDefault
pathYes
contentYes
ifMatchNo
ifMatchGuardNo

Output Schema

NameRequiredDescription
pathYes
createdYes
messageYes
versionYes
warningsNo
sizeBytesYes
versionGuardYes
beforeSizeBytesYes

TDQS

A4/5.0
Behavior5/5

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

Goes well beyond the annotations: it discloses create-on-miss behavior, mandatory optimistic concurrency on existing files, the LF normalization side effect, binary/NUL rejection, and the absence of automatic retry. These are exactly the mutation traits an agent needs and annotations alone don't 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?

Three compact sentences with the primary action and create-on-miss behavior front-loaded, then constraints. No filler; each clause carries a distinct operational fact.

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?

An output schema exists so return values needn't be described, and the mutation semantics are well covered. The remaining gap is the missing pointer to where ifMatchGuard/versionGuard values come from (presumably vault_read) and what failure looks like when the precondition fails.

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 0%, so the description must carry the load. It clarifies the conditional requirement on ifMatch/ifMatchGuard ('copy versionGuard'), but leaves the sha256 format of ifMatch, the 64MiB content cap, and where a guard token is obtained unexplained.

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?

States a specific verb+resource ('Append UTF-8 text') and adds a key scope fact — missing files are created. The append semantics are self-evidently distinct from siblings like vault_write, vault_patch, and vault_replace_text, though no sibling is named.

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?

Gives real conditions ('Existing files require ifMatch or ifMatchGuard') but frames them as parameter requirements rather than when-to-use-this-vs-alternatives guidance. An agent still must infer that vault_write is the overwrite path and vault_patch the edit path.

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

vault_deleteA
Destructive

Delete a file to recoverable Vault .trash; permanent=true is irreversible. ifMatch or ifMatchGuard (copy versionGuard) checks source. No automatic retry or permanent fallback.

NameRequiredDescriptionDefault
pathYes
ifMatchNo
permanentNo
ifMatchGuardNo

Output 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 declare destructiveHint=true and idempotentHint=false, but the description adds substantive context they don't convey: deletion lands in .trash and is recoverable, permanent=true is irreversible, and there is no automatic retry or fallback to permanent deletion. Permissions/auth requirements are still unstated, keeping it below 5.

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?

Two dense sentences with the recoverability default front-loaded and the irreversible case immediately following — no filler. Slight penalty for telegraphic phrasing ('ifMatch or ifMatchGuard (copy versionGuard)') that reads as notes rather than explanation.

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?

An output schema exists so return values need no explanation, and the description covers the key danger profile for a destructive mutation plus the no-retry caveat. Missing pieces are path resolution semantics and any permission requirements, which matter for a delete operation.

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 0%, so the description must carry parameter meaning. It explains permanent and gestures at ifMatch/ifMatchGuard as source checks, but the phrase 'copy versionGuard' is cryptic and the two conditional parameters are never clearly distinguished (full sha256 digest vs 16-hex guard), and 'path' is left entirely implicit.

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 and resource ('Delete a file') plus the immediate destination semantics ('recoverable Vault .trash'), and clarifies the permanent-mode variant. No sibling tool in the list performs deletion, so the agent can distinguish it without inspecting schemas.

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?

Gives clear conditional guidance: default behavior is recoverable, set permanent=true only when irreversibility is acceptable, and use ifMatch/ifMatchGuard to guard against concurrent modification. It does not explicitly name alternatives (e.g., vault_move as a non-destructive option), so it stops short of full when-not guidance.

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

vault_get_document_mapB
Read-onlyIdempotent

Get heading paths, block IDs, property names, version and versionGuard. Copy returned keys unchanged for targeted reads/patches.

NameRequiredDescriptionDefault
pathYes
maxBytesNo
maxHeadingsNo

Output Schema

NameRequiredDescription
pathYes
blocksYes
versionYes
headingsYes
versionGuardYes
frontmatterFieldsYes

TDQS

B3.1/5.0
Behavior3/5

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

Annotations already declare read-only, idempotent, non-destructive, and closed-world behavior. The description adds useful detail about what the map contains and that its keys are intended to be reused unchanged, but it does not explain truncation behavior, limits, or what happens when maxBytes/maxHeadings are hit.

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 compact sentences with no filler, and the primary purpose is front-loaded before the key-reuse instruction.

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

Completeness2/5

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

The output schema covers return values, and annotations cover safety, but the 0%-described parameters are a significant gap for a tool whose maxBytes and maxHeadings settings affect what the map contains. The description does not compensate for that missing parameter semantics.

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

Parameters1/5

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

Schema description coverage is 0%, with three parameters (path, maxBytes, maxHeadings) and no descriptions in the schema. The description does not mention any parameter, so an agent gets no guidance on what the limits mean or how they affect the returned map.

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 gives a specific verb ('Get') and lists concrete returned artifacts: heading paths, block IDs, property names, version, and versionGuard. This clearly distinguishes it from a plain document read, though it does not explicitly name sibling tools or contrast itself with vault_read/vault_list.

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?

It implies the tool is used before targeted reads/patches by saying to copy returned keys unchanged. However, it does not name the alternative tools or state when not to use this map, leaving the routing decision partially implicit.

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

vault_listA
Read-onlyIdempotent

List a Vault directory; omit path or use "" for root. Directory names end in /. Protected/symlink entries are omitted; overflow errors, never truncation.

NameRequiredDescriptionDefault
pathNo
maxEntriesNo

Output Schema

NameRequiredDescription
filesYes

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and closed-world, so the safety profile is covered. The description adds real behavior beyond that: trailing '/' on directory names, omission of protected/symlink entries, and a failure mode where overflow errors rather than truncates. That error-over-truncation guarantee is exactly the kind of context an agent needs and could not get from 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?

A single tight sentence pair: the core action and root-addressing rule come first, then the behavioral caveats. No filler, no repetition of the schema, and the most decision-relevant constraint (root path) is front-loaded.

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

Completeness4/5

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

With an output schema present, return-shape explanation is unnecessary, and the annotations carry the safety profile. The description adds the filtering rules and the error-not-truncation contract, which is most of what an agent needs; only the maxEntries semantics remain undocumented in prose.

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 0%, so the description has to carry both parameters. It explains path well (omitting it or passing "" selects root), and 'overflow errors, never truncation' indirectly implies maxEntries caps results and errors when exceeded, but maxEntries is never named or bounded in prose. Partial compensation for a coverage gap, hence a mid score.

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 gives a specific verb+resource ('List a Vault directory') and immediately pins down the scope ('omit path or use "" for root'), which is enough for an agent to distinguish it from vault_read, vault_get_document_map, and search_query without opening a schema. It stops short of naming a sibling alternative explicitly, so it falls just below the top mark.

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?

It tells the agent how to address the root directory ('omit path or use ""'), which is useful invocation guidance, but it never states when to choose vault_list over search_query or tag_list, nor any exclusions or prerequisites. Usage is implied by the name rather than argued.

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

vault_moveA
Destructive

Move a file; no link/history updates. Creates parents; trailing / retains filename. Overwrite requires allowOverwrite. ifMatch or ifMatchGuard (copy versionGuard) checks source only. No retry or cross-filesystem fallback.

NameRequiredDescriptionDefault
pathYes
ifMatchNo
destinationYes
ifMatchGuardNo
allowOverwriteNo

Output Schema

NameRequiredDescription
messageYes
newPathYes
oldPathYes

TDQS

A4/5.0
Behavior5/5

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

Despite annotations already flagging destructiveHint=true, the description adds substantial non-redundant behavior: parent auto-creation, trailing-slash filename retention, the overwrite flag requirement, the fact that ifMatch/ifMatchGuard validate the source only, and the absence of retry or cross-filesystem fallback. These are exactly the operational caveats an agent needs before a destructive move.

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 definition is tightly packed with semicolon-delimited clauses and leads with the core action, so no sentence is filler. The telegraphic style is dense but each clause conveys distinct operational information.

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?

With annotations covering the destructive/non-idempotent safety profile and an output schema handling return values, the description fills the important behavioral gaps (parents, overwrite, precondition scope, no fallback). It is nearly complete, missing only explicit guidance on failure behavior when overwrite is not permitted.

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 0%, so the description carries the burden and does so well: it explains destination trailing-slash semantics, allowOverwrite's role, and that ifMatch vs ifMatchGuard are source-only precondition checks (with a note that ifMatchGuard mirrors copy's versionGuard). Only 'path' is left unelaborated, which is reasonable given its obviousness.

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 opens with a specific verb+resource ('Move a file') and immediately scopes it ('no link/history updates'), which distinguishes it from copy-style or link-maintaining operations among the siblings. It stops short of naming a sibling outright, but the scope statement makes the tool's identity unambiguous.

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

Usage Guidelines3/5

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

Usage is implied through conditional rules ('Overwrite requires allowOverwrite') rather than explicit when-to-use versus alternatives. It never states when an agent should pick vault_move over vault_write or vault_delete, so the agent must infer selection from the sibling names.

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

vault_patchC
Destructive

Patch a heading/block/property with ifMatch or ifMatchGuard (copy versionGuard) from a read/map. Copy map keys unchanged. Heading content without within: # is one level below the target for content (default), or the target's actual parent for markerAndContent prepend/append. No automatic retry.

NameRequiredDescriptionDefault
pathYes
scopeNo
valueNo
targetYes
withinNo
contentNo
ifMatchNo
operationYes
targetTypeYes
destinationNoHeading move only: operation=replace, scope=parent; omit content.
ifMatchGuardNo
createTargetIfMissingNo
allowSubtreeReplacementNoExplicitly allow heading content/whole-section replace to remove child sections; the version precondition still applies.
rejectIfContentPreexistsNo

Output Schema

NameRequiredDescription
pathYes
createdYes
messageYes
versionYes
warningsNo
sizeBytesYes
versionGuardYes
beforeSizeBytesYes

TDQS

C2.6/5.0
Behavior3/5

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

The annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=false. The description adds useful context that a version precondition (ifMatch/ifMatchGuard) must be copied from a read/map and that no automatic retry occurs, but omits conflict/error behavior and permission requirements.

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

Conciseness3/5

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

It is short, but structured as a dense run-on of cryptic clauses like 'Copy map keys unchanged' and 'markerAndContent prepend/append' that are not interpretable without additional context. The core verb/resource is front-loaded, but the rest is hard to parse.

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

Completeness2/5

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

For a complex mutation tool with 14 parameters, nested objects, and very low schema coverage, the description does not explain most parameter semantics, prerequisites for obtaining the version guard, or error/conflict behavior. An output schema exists, so return values needn't be covered, but the input-side gaps are large.

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

Parameters2/5

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

Schema description coverage is only 14% across 14 parameters, so the description must compensate, but it only touches ifMatch, ifMatchGuard, within, and some scope semantics. Most parameters (path, target, targetType, operation, value, content, destination, createTargetIfMissing, allowSubtreeReplacement, rejectIfContentPreexists) get no explanatory help.

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

Purpose3/5

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

It states a verb ('Patch') and resource types (heading/block/property), but 'property' does not match the schema's targetType enum (heading/block/frontmatter), and the phrasing is cryptic. It does not clearly distinguish itself from siblings such as vault_replace_text, vault_append, or vault_write.

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

Usage Guidelines2/5

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

There is no explicit guidance on when to use this tool versus vault_replace_text or vault_write. Only oblique hints exist ('from a read/map', 'No automatic retry') without a clear decision rule.

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

vault_readA
Read-onlyIdempotent

Read a Vault text file or target with version and versionGuard. Discover targets via vault_get_document_map; targeted heading levels are relative. No link graph.

NameRequiredDescriptionDefault
pathYes
scopeNoRequires a target; defaults to content.
targetNoPair with targetType. Heading: full map path, e.g. ["Root","Child"]; block: ID without ^; property: key.
maxBytesNo
targetTypeNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already cover readOnly, idempotent and non-destructive behavior, so the description only needs to add beyond that. "No link graph" is a useful disclosure about what is not returned, and "targeted heading levels are relative" clarifies resolution semantics, but the mention of "version and versionGuard" is confusing since no such parameters exist in the schema, and nothing is said about maxBytes truncation behavior.

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

Conciseness3/5

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

Very short and front-loaded, which is good, but the phrase "with version and versionGuard" consumes limited space on parameters that don't exist in the schema, creating noise in an otherwise tight definition. The remaining clauses each carry real information.

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

Completeness3/5

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

An output schema exists, so return-value explanation is rightly absent. However, for a 5-parameter read tool the description does not address maxBytes/truncation, the content-vs-marker scope behavior, or clarify the phantom version parameter, leaving gaps an agent must guess at.

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 only 40%, but the schema itself already documents scope ("Requires a target; defaults to content") and target formats. The description adds the useful note that heading levels are relative and points to vault_get_document_map for building target paths, yet leaves maxBytes and the interaction between target/targetType and scope largely unexplained, and references a version parameter that isn't in the schema.

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?

States a specific verb and resource ("Read a Vault text file or target") and adds a scope exclusion ("No link graph"). The word "text" implicitly separates it from vault_read_binary, but the contrast is never made explicit.

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?

Gives an actionable routing hint: "Discover targets via vault_get_document_map," which tells the agent how to obtain the target value this tool requires. It lacks an explicit when-not statement (e.g. when to prefer vault_read_binary or search_query), so it stops short of full alternative coverage.

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

vault_read_binaryA
Read-onlyIdempotent

Read images and non-PDF attachments. auto: raster preview or signed HTTPS download link. bytes: original data up to 4 MiB. PDF is unsupported in every mode; use the client's native file upload/attachments.

NameRequiredDescriptionDefault
asNo
pathYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

The annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false. The description adds useful behavior beyond annotations: the 4 MiB limit for bytes mode, the preview-or-link behavior of auto mode, and the PDF exclusion.

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, and every sentence carries operational value: supported file type, mode behavior, size limit, and PDF exclusion. There is no wasted text.

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

Completeness3/5

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

The output schema exists, so return values need not be explained, and annotations cover safety traits. However, with zero schema parameter descriptions, the missing link mode and unexplained path parameter leave the definition only partially complete for correct invocation.

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

Parameters2/5

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

With 0% schema description coverage, the description must fully explain the parameters. It describes auto and bytes modes, but omits the link enum value entirely, and it does not explain the required path parameter. This leaves a significant gap in mode selection semantics.

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: read images and non-PDF attachments. It clearly excludes PDFs, but it does not explicitly distinguish this tool from sibling vault_read for text files. The purpose is still clear and actionable.

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 this tool versus native file handling, especially by stating that PDFs are unsupported in every mode. It also explains the auto and bytes modes, though it does not explicitly route text reads to vault_read.

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

vault_replace_textA
Destructive

Replace one unique, case-sensitive literal match in an existing UTF-8 file. Copy exact oldText from a whole-file vault_read; copy version as ifMatch or versionGuard as ifMatchGuard. Empty newText deletes. No automatic retry.

NameRequiredDescriptionDefault
pathYes
ifMatchNo
newTextYes
oldTextYes
ifMatchGuardNo

Output Schema

NameRequiredDescription
pathYes
createdYes
messageYes
versionYes
warningsNo
sizeBytesYes
versionGuardYes
beforeSizeBytesYes
replacementCountYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and idempotentHint=false; the description adds real context beyond them: the match must be unique and case-sensitive, empty newText deletes the match, and there is no automatic retry on conflict. It does not say what error surfaces when the match is missing or non-unique, which is the remaining gap for a destructive tool.

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 short sentences, zero filler, with the core operation and its uniqueness constraint front-loaded before the workflow notes. Every sentence adds a distinct fact an agent needs.

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?

An output schema exists so return values need not be described, and the description covers the match semantics, guard parameters, delete-by-empty-newText, and retry behavior. The only meaningful omission is failure-mode detail for a non-unique or absent match on a destructive edit.

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

Parameters4/5

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

With 0% schema description coverage, the description carries the burden and largely succeeds: oldText must be an exact literal from vault_read, newText may be empty to delete, and both ifMatch and ifMatchGuard are explained as version-carrying guards. Only 'path' is left unstated, which is self-evident.

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 and resource with the exact matching semantics: 'Replace one unique, case-sensitive literal match in an existing UTF-8 file.' The uniqueness and case-sensitivity constraints implicitly separate it from vault_patch, vault_write and vault_append, so an agent can pick it without opening a schema.

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

Usage Guidelines4/5

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

Gives the required workflow upfront: copy exact oldText from a whole-file vault_read, and carry version into ifMatch or versionGuard into ifMatchGuard. 'No automatic retry' tells the caller it must handle failure. It stops short of naming when to use vault_patch or vault_append instead, so no explicit exclusion is stated.

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

vault_writeA
DestructiveIdempotent

Create or replace UTF-8 text. Existing files require ifMatch or ifMatchGuard (copy versionGuard). Creates parents. Binary/NUL refused; no automatic retry.

NameRequiredDescriptionDefault
pathYes
contentYes
ifMatchNo
ifMatchGuardNo

Output Schema

NameRequiredDescription
pathYes
createdYes
messageYes
versionYes
warningsNo
sizeBytesYes
versionGuardYes
beforeSizeBytesYes

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare destructiveHint and idempotentHint, but the description adds genuinely new behavioral facts: parent directories are created automatically, binary/NUL content is refused, and there is no automatic retry after a failure, which matters for an agent retry strategy. The overwrite-guard requirement on existing files is also disclosed. It stops short of stating permission/auth requirements or what happens on a failed guard mismatch, keeping it short of a 5.

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?

Extremely front-loaded: capability first, then preconditions, then side effects and failure behavior. Every clause carries information, with no filler. The telegraphic style ('copy versionGuard', 'Binary/NUL refused') trades some readability for density, which keeps it slightly below a perfect score.

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

Completeness4/5

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

Since an output schema exists, return values need not be described, and the annotations carry the safety profile. Given those, the description covers the key gaps an agent needs: parents auto-created, overwrite guard requirement, content-type limits, and no retry. Residual ambiguity about how to obtain versionGuard and about path format is minor but 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 0%, so the description must carry the load. It explains the otherwise opaque ifMatch/ifMatchGuard parameters in terms of purpose (required to overwrite existing files) and even hints at the source ('copy versionGuard'), which is real added value. But path and content semantics, and the accepted sha256 format versus 16-hex guard format, are left entirely to the schema's regex patterns.

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?

States a specific verb pair and resource: 'Create or replace UTF-8 text', which implicitly separates it from sibling tools like vault_append and vault_patch that modify rather than replace full content. It never names those siblings explicitly, so a reader must infer the boundary from the verbs.

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 precondition 'Existing files require ifMatch or ifMatchGuard' gives clear context for overwrites, which implies when this tool succeeds versus fails. However, there is no explicit guidance on when to choose vault_write over vault_append, vault_patch, or vault_replace_text, so the selection logic is inferred from the description rather than stated.

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

Tool Schema Changelog

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

  1. 11 tool updatesv0.2.0
    • Changedreference_query9 fields changed
      • addedOutput schema / properties / matches / items / properties / source / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / properties / matches / items / properties / source / required
        Previous value: -[
        -  "path",
        -  "version"
        -]New value: +[
        +  "path",
        +  "version",
        +  "versionGuard"
        +]
      • removedOutput schema / properties / target / additionalProperties
        Removed value: -false
      • addedOutput schema / properties / target / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "block": {
        +        "pattern": "^[a-zA-Z0-9-]+$",
        +        "type": "string"
        +      },
        +      "fileExists": {
        +        "type": "boolean"
        +      },
        +      "heading": {
        +        "items": {
        +          "maxLength": 1024,
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "maxItems": 32,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "reason": {
        +        "type": "string"
        +      },
        +      "status": {
        +        "enum": [
        +          "resolved",
        +          "ambiguous",
        +          "unresolved",
        +          "unsupported",
        +          "unknown"
        +        ],
        +        "type": "string"
        +      },
        +      "version": {
        +        "pattern": "^sha256:[0-9a-f]{64}$",
        +        "type": "string"
        +      },
        +      "versionGuard": {
        +        "maxLength": 16,
        +        "minLength": 16,
        +        "pattern": "^[0-9a-f]{16}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "fileExists",
        +      "status",
        +      "reason",
        +      "version",
        +      "versionGuard"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "block": {
        +        "pattern": "^[a-zA-Z0-9-]+$",
        +        "type": "string"
        +      },
        +      "fileExists": {
        +        "type": "boolean"
        +      },
        +      "heading": {
        +        "items": {
        +          "maxLength": 1024,
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "maxItems": 32,
        +        "minItems": 1,
        +        "type": "array"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "reason": {
        +        "type": "string"
        +      },
        +      "status": {
        +        "enum": [
        +          "resolved",
        +          "ambiguous",
        +          "unresolved",
        +          "unsupported",
        +          "unknown"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "fileExists",
        +      "status",
        +      "reason"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedOutput schema / properties / target / properties
        Removed value: -{
        -  "block": {
        -    "pattern": "^[a-zA-Z0-9-]+$",
        -    "type": "string"
        -  },
        -  "fileExists": {
        -    "type": "boolean"
        -  },
        -  "heading": {
        -    "items": {
        -      "maxLength": 1024,
        -      "minLength": 1,
        -      "type": "string"
        -    },
        -    "maxItems": 32,
        -    "minItems": 1,
        -    "type": "array"
        -  },
        -  "path": {
        -    "type": "string"
        -  },
        -  "reason": {
        -    "type": "string"
        -  },
        -  "status": {
        -    "enum": [
        -      "resolved",
        -      "ambiguous",
        -      "unresolved",
        -      "unsupported",
        -      "unknown"
        -    ],
        -    "type": "string"
        -  },
        -  "version": {
        -    "type": "string"
        -  }
        -}
      • removedOutput schema / properties / target / required
        Removed value: -[
        -  "path",
        -  "fileExists",
        -  "status",
        -  "reason"
        -]
      • removedOutput schema / properties / target / type
        Removed value: -"object"
      • addedOutput schema / properties / uncertain / items / properties / source / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / properties / uncertain / items / properties / source / required
        Previous value: -[
        -  "path",
        -  "version"
        -]New value: +[
        +  "path",
        +  "version",
        +  "versionGuard"
        +]
    • Changedsearch_query2 fields changed
      • addedOutput schema / properties / results / items / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / properties / results / items / required
        Previous value: -[
        -  "filename",
        -  "version",
        -  "result"
        -]New value: +[
        +  "filename",
        +  "version",
        +  "versionGuard",
        +  "result"
        +]
    • Changedvault_append4 fields changed
      • addedInput schema / properties / ifMatchGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • addedOutput schema / properties / beforeSizeBytes
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "message",
        -  "path",
        -  "version",
        -  "sizeBytes",
        -  "created"
        -]New value: +[
        +  "message",
        +  "path",
        +  "version",
        +  "versionGuard",
        +  "beforeSizeBytes",
        +  "sizeBytes",
        +  "created"
        +]
    • Changedvault_delete1 field changed
      • addedInput schema / properties / ifMatchGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
    • Changedvault_get_document_map2 fields changed
      • addedOutput schema / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "path",
        -  "version",
        -  "headings",
        -  "blocks",
        -  "frontmatterFields"
        -]New value: +[
        +  "path",
        +  "version",
        +  "versionGuard",
        +  "headings",
        +  "blocks",
        +  "frontmatterFields"
        +]
    • Changedvault_move1 field changed
      • addedInput schema / properties / ifMatchGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
    • Changedvault_patch7 fields changed
      • addedInput schema / properties / allowSubtreeReplacement
        Added value: +{
        +  "description": "Explicitly allow heading content/whole-section replace to remove child sections; the version precondition still applies.",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / content / description
        Removed value: -"Heading target without within: # is a child in content scope, a sibling with markerAndContent prepend/append."
      • addedInput schema / properties / ifMatchGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "path",
        -  "targetType",
        -  "target",
        -  "operation",
        -  "ifMatch"
        -]New value: +[
        +  "path",
        +  "targetType",
        +  "target",
        +  "operation"
        +]
      • addedOutput schema / properties / beforeSizeBytes
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "message",
        -  "path",
        -  "version",
        -  "sizeBytes",
        -  "created"
        -]New value: +[
        +  "message",
        +  "path",
        +  "version",
        +  "versionGuard",
        +  "beforeSizeBytes",
        +  "sizeBytes",
        +  "created"
        +]
    • Changedvault_read1 field changed
      • changedOutput schema / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "content": {
        -        "type": "string"
        -      },
        -      "frontmatter": {
        -        "additionalProperties": {
        -          "$ref": "#/$defs/__schema0"
        -        },
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "path": {
        -        "type": "string"
        -      },
        -      "stat": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "ctime": {
        -            "type": "number"
        -          },
        -          "mtime": {
        -            "type": "number"
        -          },
        -          "size": {
        -            "maximum": 9007199254740991,
        -            "minimum": 0,
        -            "type": "integer"
        -          }
        -        },
        -        "required": [
        -          "ctime",
        -          "mtime",
        -          "size"
        -        ],
        -        "type": "object"
        -      },
        -      "tags": {
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "version": {
        -        "pattern": "^sha256:[0-9a-f]{64}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "path",
        -      "version",
        -      "content",
        -      "tags",
        -      "frontmatter",
        -      "stat"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "path": {
        -        "type": "string"
        -      },
        -      "result": {
        -        "$ref": "#/$defs/__schema1"
        -      },
        -      "version": {
        -        "pattern": "^sha256:[0-9a-f]{64}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "path",
        -      "version",
        -      "result"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "content": {
        +        "type": "string"
        +      },
        +      "frontmatter": {
        +        "additionalProperties": {
        +          "$ref": "#/$defs/__schema0"
        +        },
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "stat": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "ctime": {
        +            "type": "number"
        +          },
        +          "mtime": {
        +            "type": "number"
        +          },
        +          "size": {
        +            "maximum": 9007199254740991,
        +            "minimum": 0,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "ctime",
        +          "mtime",
        +          "size"
        +        ],
        +        "type": "object"
        +      },
        +      "tags": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "version": {
        +        "pattern": "^sha256:[0-9a-f]{64}$",
        +        "type": "string"
        +      },
        +      "versionGuard": {
        +        "maxLength": 16,
        +        "minLength": 16,
        +        "pattern": "^[0-9a-f]{16}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "version",
        +      "versionGuard",
        +      "content",
        +      "tags",
        +      "frontmatter",
        +      "stat"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "path": {
        +        "type": "string"
        +      },
        +      "result": {
        +        "$ref": "#/$defs/__schema1"
        +      },
        +      "version": {
        +        "pattern": "^sha256:[0-9a-f]{64}$",
        +        "type": "string"
        +      },
        +      "versionGuard": {
        +        "maxLength": 16,
        +        "minLength": 16,
        +        "pattern": "^[0-9a-f]{16}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "version",
        +      "versionGuard",
        +      "result"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Changedvault_read_binary2 fields changed
      • addedOutput schema / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "delivery": {
        +        "const": "image",
        +        "type": "string"
        +      },
        +      "firstFrameOnly": {
        +        "type": "boolean"
        +      },
        +      "height": {
        +        "exclusiveMinimum": 0,
        +        "maximum": 9007199254740991,
        +        "type": "integer"
        +      },
        +      "mimeType": {
        +        "type": "string"
        +      },
        +      "outputMimeType": {
        +        "const": "image/webp",
        +        "type": "string"
        +      },
        +      "outputSizeBytes": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "preview": {
        +        "const": true,
        +        "type": "boolean"
        +      },
        +      "sizeBytes": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "version": {
        +        "pattern": "^sha256:[0-9a-f]{64}$",
        +        "type": "string"
        +      },
        +      "versionGuard": {
        +        "maxLength": 16,
        +        "minLength": 16,
        +        "pattern": "^[0-9a-f]{16}$",
        +        "type": "string"
        +      },
        +      "width": {
        +        "exclusiveMinimum": 0,
        +        "maximum": 9007199254740991,
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "mimeType",
        +      "sizeBytes",
        +      "version",
        +      "versionGuard",
        +      "delivery",
        +      "outputMimeType",
        +      "outputSizeBytes",
        +      "width",
        +      "height",
        +      "preview",
        +      "firstFrameOnly"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "delivery": {
        +        "const": "bytes",
        +        "type": "string"
        +      },
        +      "mimeType": {
        +        "type": "string"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "sizeBytes": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "uri": {
        +        "type": "string"
        +      },
        +      "version": {
        +        "pattern": "^sha256:[0-9a-f]{64}$",
        +        "type": "string"
        +      },
        +      "versionGuard": {
        +        "maxLength": 16,
        +        "minLength": 16,
        +        "pattern": "^[0-9a-f]{16}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "mimeType",
        +      "sizeBytes",
        +      "version",
        +      "versionGuard",
        +      "delivery",
        +      "uri"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "delivery": {
        +        "const": "link",
        +        "type": "string"
        +      },
        +      "expiresAt": {
        +        "type": "string"
        +      },
        +      "mimeType": {
        +        "type": "string"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "reason": {
        +        "enum": [
        +          "requested",
        +          "download",
        +          "too_large",
        +          "image_preview_unavailable"
        +        ],
        +        "type": "string"
        +      },
        +      "sizeBytes": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "uri": {
        +        "type": "string"
        +      },
        +      "version": {
        +        "pattern": "^sha256:[0-9a-f]{64}$",
        +        "type": "string"
        +      },
        +      "versionGuard": {
        +        "maxLength": 16,
        +        "minLength": 16,
        +        "pattern": "^[0-9a-f]{16}$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "mimeType",
        +      "sizeBytes",
        +      "delivery",
        +      "uri",
        +      "expiresAt",
        +      "reason",
        +      "version",
        +      "versionGuard"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "delivery": {
        +        "const": "link",
        +        "type": "string"
        +      },
        +      "expiresAt": {
        +        "type": "string"
        +      },
        +      "mimeType": {
        +        "type": "string"
        +      },
        +      "path": {
        +        "type": "string"
        +      },
        +      "reason": {
        +        "enum": [
        +          "requested",
        +          "download",
        +          "too_large",
        +          "image_preview_unavailable"
        +        ],
        +        "type": "string"
        +      },
        +      "sizeBytes": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "uri": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "path",
        +      "mimeType",
        +      "sizeBytes",
        +      "delivery",
        +      "uri",
        +      "expiresAt",
        +      "reason"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedOutput schema / oneOf
        Removed value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "delivery": {
        -        "const": "image",
        -        "type": "string"
        -      },
        -      "firstFrameOnly": {
        -        "type": "boolean"
        -      },
        -      "height": {
        -        "exclusiveMinimum": 0,
        -        "maximum": 9007199254740991,
        -        "type": "integer"
        -      },
        -      "mimeType": {
        -        "type": "string"
        -      },
        -      "outputMimeType": {
        -        "const": "image/webp",
        -        "type": "string"
        -      },
        -      "outputSizeBytes": {
        -        "maximum": 9007199254740991,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "path": {
        -        "type": "string"
        -      },
        -      "preview": {
        -        "const": true,
        -        "type": "boolean"
        -      },
        -      "sizeBytes": {
        -        "maximum": 9007199254740991,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "version": {
        -        "pattern": "^sha256:[0-9a-f]{64}$",
        -        "type": "string"
        -      },
        -      "width": {
        -        "exclusiveMinimum": 0,
        -        "maximum": 9007199254740991,
        -        "type": "integer"
        -      }
        -    },
        -    "required": [
        -      "path",
        -      "mimeType",
        -      "sizeBytes",
        -      "version",
        -      "delivery",
        -      "outputMimeType",
        -      "outputSizeBytes",
        -      "width",
        -      "height",
        -      "preview",
        -      "firstFrameOnly"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "delivery": {
        -        "const": "bytes",
        -        "type": "string"
        -      },
        -      "mimeType": {
        -        "type": "string"
        -      },
        -      "path": {
        -        "type": "string"
        -      },
        -      "sizeBytes": {
        -        "maximum": 9007199254740991,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "uri": {
        -        "type": "string"
        -      },
        -      "version": {
        -        "pattern": "^sha256:[0-9a-f]{64}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "path",
        -      "mimeType",
        -      "sizeBytes",
        -      "version",
        -      "delivery",
        -      "uri"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "delivery": {
        -        "const": "link",
        -        "type": "string"
        -      },
        -      "expiresAt": {
        -        "type": "string"
        -      },
        -      "mimeType": {
        -        "type": "string"
        -      },
        -      "path": {
        -        "type": "string"
        -      },
        -      "reason": {
        -        "enum": [
        -          "requested",
        -          "download",
        -          "too_large",
        -          "image_preview_unavailable"
        -        ],
        -        "type": "string"
        -      },
        -      "sizeBytes": {
        -        "maximum": 9007199254740991,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "uri": {
        -        "type": "string"
        -      },
        -      "version": {
        -        "pattern": "^sha256:[0-9a-f]{64}$",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "path",
        -      "mimeType",
        -      "sizeBytes",
        -      "delivery",
        -      "uri",
        -      "expiresAt",
        -      "reason"
        -    ],
        -    "type": "object"
        -  }
        -]
    • Addedvault_replace_text
    • Changedvault_write4 fields changed
      • addedInput schema / properties / ifMatchGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • addedOutput schema / properties / beforeSizeBytes
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / versionGuard
        Added value: +{
        +  "maxLength": 16,
        +  "minLength": 16,
        +  "pattern": "^[0-9a-f]{16}$",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "message",
        -  "path",
        -  "version",
        -  "sizeBytes",
        -  "created"
        -]New value: +[
        +  "message",
        +  "path",
        +  "version",
        +  "versionGuard",
        +  "beforeSizeBytes",
        +  "sizeBytes",
        +  "created"
        +]
  2. 1 tool update
    • Changedsearch_query1 field changed
      • addedInput schema / properties / scope
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Optional scan scope; omit for a recursive whole-Vault scan. directory \"\" is root; recursive=false scans only direct child files.",
        +  "properties": {
        +    "directory": {
        +      "type": "string"
        +    },
        +    "recursive": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "directory",
        +    "recursive"
        +  ],
        +  "type": "object"
        +}
  3. 13 tool updatesv0.1.0
    • First observedobsidian_help
    • First observedreference_query
    • First observedsearch_query
    • First observedtag_list
    • First observedvault_append
    • First observedvault_delete
    • First observedvault_get_document_map
    • First observedvault_list
    • First observedvault_move
    • First observedvault_patch
    • First observedvault_read
    • First observedvault_read_binary
    • First observedvault_write

TDQS

A3.6/5.0

Scored across 14 tools

Disambiguation4/5

Most tools target distinct resources or operations, and the descriptions clarify boundaries between read, write, append, patch, replace, move, and delete. The main possible confusion is among the several text-modification tools, especially vault_patch vs vault_replace_text and vault_write vs vault_append, but the stated preconditions and scopes help distinguish them.

Naming Consistency4/5

The set is overwhelmingly snake_case and follows a resource-oriented pattern such as vault_read, vault_write, vault_move, and tag_list. Minor deviations like obsidian_help and the longer vault_get_document_map are readable and do not meaningfully hinder selection.

Tool Count5/5

At 14 tools, the server is well-scoped for Obsidian vault management, covering listing, reading, searching, writing, patching, moving, deleting, references, tags, and help. Each tool appears to serve a distinct vault workflow rather than bloating the surface.

Completeness4/5

Core vault text workflows are well covered: CRUD-like file operations, targeted reads/patches, document maps, search, references, tags, and binary reads. Minor gaps remain around binary/attachment writing, explicit directory operations, copy operations, and PDF handling, but most agent workflows can proceed without dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers