vault-memory
This MCP server exposes a local, read/write agentic knowledge layer over one or more Obsidian vaults, covering hybrid retrieval, graph navigation, memory/provenance, briefs, and task contracts.
Search & retrieval: semantic, BM25 full-text, hybrid RRF with optional rerank/recency/authority boosts, section-level search, memory recall, and OB1-compatible search/fetch.
Read & inspect notes: read full note + frontmatter, query frontmatter predicates, suggest frontmatter, list recent notes, vault stats, index runs, audit log.
Graph & document navigation: backlinks, forward links, broken links, outlines, document bundles, typed-edge expansion, Louvain clustering, and dossiers.
Write safely with provenance: create/overwrite notes with expected_hash, edit frontmatter, delete notes; MemorySink-guarded observations and supersede chains.
Compiled briefs & contracts: compile/get briefs, describe/instantiate/register YAML task contracts that agents can discover and run.
Embedding model management: list models, start shadow indexes, switch active models, vacuum orphaned embeddings.
Multi-vault & MCP resources: work across configured vaults; deprecated tools remain callable while MCP Resources expose vaults, models, recent, stats, backlinks, memory/brief/contract discovery.
Allows AI agents to query, retrieve, and write to Obsidian notes with provenance tracking, enabling agentic workflows over a local knowledge base.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@vault-memoryPull me a brief for tomorrow's 1:1 with Alice."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
vault-memory
Local-first, source-agnostic-ready agentic knowledge layer over your Obsidian notes, exposed to any MCP-aware agent.
See CHANGELOG.md for release history. Latest: v2.5.0 — additive over v1.x; the 23 v1 tool names + input schemas are preserved byte-identical.
30-second example
Install the CLI from npm, register a vault, and start the MCP server:
npm install -g @owrede/vault-memory
vault-memory add-vault "/path/to/your/obsidian/vault" --name notes
vault-memory servePoint an MCP-aware client at the vault-memory binary. For Claude Desktop, drop this
into ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"vault-memory": {
"type": "stdio",
"command": "vault-memory",
"args": ["serve"]
}
}
}Restart the client. Ask the agent something like: "Pull me a brief for tomorrow's
1:1 with Alice." The agent discovers the bundled meeting-prep task contract via
describe_contract, instantiates it with instantiate_contract, and the result —
attendees, recent shared notes, last decisions, open action items — is written into
your vault's _memory/_briefs/ folder with full provenance. The brief is a regular
note; you can read it, edit it, link to it, or delete it.
That is the full agentic-knowledge-layer loop: discover a contract, instantiate it, get a cited document back. Memory writes are labeled and provenance-tracked; user notes are never modified silently.
Related MCP server: Brainstem
What this is
vault-memory turns one or more Obsidian vaults into a queryable, agent-native knowledge layer running entirely on your machine. It indexes your notes with local embeddings (via Ollama), keeps the index live as you edit, and exposes the result to any MCP-aware agent — Claude Code, Claude Desktop, ChatGPT Custom Connectors, the MCP Inspector, or any other client speaking the Model Context Protocol.
v1.0.0 was a strong retrieval substrate: hybrid search (semantic + BM25 + RRF, optional cross-encoder rerank), live indexing, multi-vault, hash-protected writes. v2.0.0 evolves it into a full agentic knowledge layer — memory namespace with provenance, document-tree assembly (bundles, outlines, dossiers), graph-as-retrieval (typed edges, expand, cluster), a compiled-brief layer with a staleness daemon, and a task-contract DSL that any MCP-aware agent can discover and instantiate.
Obsidian is the v2 source connector; the same MCP tool surface backs any future
adapter (Notion, Logseq, ...) via the SourceConnector / DeliveryAdapter /
ChangeFeed seams introduced in Phase 1. The memory namespace is a non-negotiable
safety invariant: agents never write silently into user notes; every agent-authored
document carries provenance properties and lives in a labeled MemorySink.
Nothing leaves your machine. No cloud sync, no API keys, no telemetry.
Architecture
One SQLite database per vault under ~/.vault-memory/vaults/<name>.db. Layers L0
through L4 sit on top of an Adapter tier that abstracts the source-of-truth. v2.0.0
ships exactly one adapter implementation (obsidian-fs); v3.0.0 adds notion-api
without touching the layers above the seam.
+-----------------------------------------------------------------------------+
| L4 Compiled briefs + Task contracts (Phases 5, 6) |
| compile_brief . get_brief . instantiate_contract . staleness daemon |
+-----------------------------------------------------------------------------+
| L3 Assembly (bundles, outlines, dossiers, authority + staleness) |
| get_document_bundle . get_outline . search_sections . |
| assemble_dossier . authority + staleness signals (Phases 3, 4) |
+-----------------------------------------------------------------------------+
| L2 Memory namespace + provenance (Phase 2) |
| record_observation . recall . supersede . MemoryContract |
+-----------------------------------------------------------------------------+
| L1 Graph as retrieval (Phase 4) |
| typed edges . expand . cluster . backlink walks |
+-----------------------------------------------------------------------------+
| L0 Retrieval substrate (v1, behavior unchanged) |
| hybrid search (semantic + BM25 + RRF + rerank) . chunker |
+-----------------------------------------------------------------------------+
| Adapter tier (Phase 1) |
| SourceConnector . DeliveryAdapter . ChangeFeed . Registry |
+-----------------------------------------------------------------------------+
| Implementations |
| obsidian-fs (v2.0.0) | notion-api (v3, Phase 10) |
+-----------------------------------------------------------------------------+The Adapter tier is the only horizontal seam in the stack. Every layer above it
consumes canonical Document objects resolved through the registry; no upper layer
holds a reference to a concrete adapter module. L0 keeps direct database access
because it is substrate, not a consumer of Documents. See
docs/v2/ARCHITECTURE.md for the full layer model, the
adapter conformance suite, and the read/write data-flow diagrams.
What's new in v2
Phase 2 — Memory namespace + provenance. Three new tools (
record_observation,recall,supersede); labeledMemorySinkwrite guard; default folder sink at_memory/; superseded-doc handling. See docs/v2/MEMORY_CONTRACT.md.Phase 3 — Assembly + authority/staleness. Four new tools (
get_outline,search_sections,get_document_bundle,assemble_dossier); citation packets on every result; recency/authority rescore params onsearch_hybrid; superseded-doc filtering at SQL level. See docs/v2/PHASE-3-SIGN-OFF.md.Phase 4 — Graph-as-retrieval. Two new tools (
expand,cluster); typed edges table (wikilink,mention,frontmatter-ref,hyperlink);search_hybridgains an additiveexpandparam attaching the typed-edge neighborhood to each hit. See docs/v2/PHASE-4-SIGN-OFF.md.Phase 5 — Compiled brief layer + staleness daemon.
compile_brief,get_brief, andlist_briefs; per-briefsource_hashesmap; daemon marks briefs stale when any source's hash drifts. See docs/v2/PHASE-5-SIGN-OFF.md.Phase 6 — Task contract DSL + reference contracts. Declarative YAML contracts under
_contracts/<name>.yaml; three new tools (describe_contract,instantiate_contract,register_contracts_as_tools); three reference contracts (meeting-prep,project-status,code-review-brief). See docs/v2/PHASE-6-SIGN-OFF.md.Phase 7 — Obsidian plugin (default OFF). Variant-C visual contract editor, settings tab, secrets via OS keyring, manual reindex + stats panel, peer-MCP connectors. Adds 6 gated tools when enabled. See docs/v2/plugin/README.md.
Tool surface delta. 23 v1 tools become 32 canonical tools + 5 DEPRECATED entries in
tools/list(the 5 promoted list-style tools remain callable through v2.x with aDEPRECATEDnotice in theirdescription; removal scheduled for v3.0.0). The rawtools/listtherefore returns 37 entries; canonical (non-deprecated) count = 32. Plugin OFF is the baseline; +6 gated tools when enabled.Resources delta. 5 MCP Resources become 10 MCP Resources in v2.0.0 (
vaults,models,recent,stats,backlinksadded alongside the pre-existing memory/brief/contract resources).
Roadmap
Phase 9 — Pre-Phase-10 premise check (hard gate). Before any v3 code is
written, a dedicated phase verifies that the architectural premise for the v3
multi-source line still holds: all Phase 1 CI greps (no chokidar, no
gray-matter, no raw paths, no Claude leak, no obsidian:// literal outside
adapters) return zero hits on main; an adversarial-review sub-agent confirms
ADRs 001-004 remain unviolated by code shipped in Phases 2-8; the stub-adapter
conformance suite is green; capability-descriptor test coverage meets the
plugin-architecture threshold; the maintainer signs off explicitly. Without that
sign-off, no v3 code is written.
v3.0.0 — Notion connector + multi-source proof. Ship the first non-Obsidian source/delivery/change-feed adapter (Notion), promoting the adapter seams from "interfaces with one implementation" to a real plugin architecture. Resolve the 14 open ADRs (005-01x) covering identity stability, link resolution, property equivalence, granularity, write semantics, auth, watch, rate limits, embedding strategy, cross-source memory, caching, sync, Notion sinks, and capability discovery. Tracked requirements: NOT-01 through NOT-07; DMN-01 through DMN-03 (MCP daemon mode, v2.1.x or v3); TPC-01 through TPC-03 (third-party connectors, post-v3). Status: deferred — gated by Phase 9 sign-off.
Beyond v3 (ideas, not commitments). A v3.x postgres-fs storage adapter is
sketched in the roadmap for users whose vaults outgrow local SQLite, with explicit
non-goals: still single-user-runtime, not a managed service, not pgvector
evangelism. A v4.0.0 multi-user direction is anticipated in the roadmap so v2's
opaque DocIds, adapter seams, content-stable ChunkIds, and provenance-on-every-
agent-write read as deliberate choices in service of that path. Neither is
committed work. See .planning/ROADMAP.md for the full
phase plan and the v3/v4 deferred sections.
Install and docs
Guided install (recommended)
Ask your agent to "install vault-memory" (or run /vmem:install). The
installer asks two questions — which retrieval engine, and which vault(s) — then
installs every missing dependency for the chosen path, registers the vault(s),
builds the index, and wires the MCP server. See
docs/v2/CONTEXTFIT-BACKEND.md for the engine
comparison.
Choose a retrieval engine
vault-memory supports two engines, selectable per vault:
Ollama (vector / embeddings) — best semantic search; needs Ollama + an embedding model resident (GPU recommended).
ContextFit (CPU-only) — token-native BM25 + Semantic-IDs; no GPU, no model, ~41 MB deps. Ideal for resource-limited / non-GPU hosts (e.g. a Synology NAS). Requires the
contextfitCLI (pipx install contextfit).
Prerequisites
Node.js 22–25 (
>=22 <26) — runtime for the MCP server (brew install node@22). Node 26+ is not yet supported: the nativebetter-sqlite3dependency has no prebuild for the new ABI and building from source currently fails.One or more Obsidian vaults; an MCP-aware client.
Ollama engine only: Ollama on
localhost:11434(brew install ollama && brew services start ollama) + thebge-m3model (~1.1 GB,ollama pull bge-m3). Optional ONNX reranker (bge-reranker-v2-m3, ~570 MB) viabash scripts/download-reranker.sh.ContextFit engine only: Python 3.10+ and
pipx install contextfit.
Tested on macOS. Linux should work; Windows untested.
Manual install
npm install -g @owrede/vault-memory
# Ollama (default) vault:
vault-memory add-vault "/path/to/your/obsidian/vault"
# OR a CPU-only ContextFit vault (no Ollama/GPU):
vault-memory add-vault "/path/to/your/obsidian/vault" --backend contextfit
vault-memory serveThe add-vault command appends a [[vaults]] block to
~/.vault-memory/config.toml, writes a .mcp.json into the vault root, and runs
the initial index. Idempotent — re-running on a known path fills in whatever is
missing. Flags: --name <slug>, --backend ollama|contextfit, --write
(enable MCP writes; default read-only), --no-index (skip the initial index).
Documentation
Plugin install — docs/v2/plugin/INSTALL.md
Plugin README — docs/v2/plugin/README.md
Migration v1 to v2 — docs/v2/MIGRATION-V1-TO-V2.md
Architecture deep-dive — docs/v2/ARCHITECTURE.md
Memory contract — docs/v2/MEMORY_CONTRACT.md
Agent-agnostic statement — docs/v2/AGENT_AGNOSTIC.md
ADR index — docs/v2/adr/README.md
Changelog — CHANGELOG.md
SemVer-locked tool API per the v1.0.0 declaration. v2.0.0 is additive: the 23 v1
tool names + input schemas are preserved byte-identical, and the 5 list-style
tools promoted to MCP Resources remain callable through v2.x with a DEPRECATED
notice in their tool description (removal scheduled for v3.0.0). See
CHANGELOG.md for full history.
Document locks
Set the Boolean frontmatter field locked: true to protect a reviewed note:
locked: trueThe delivery adapters reject overwrites, updates, frontmatter changes,
deletion and supersede with { "ok": false, "reason": "document_locked" }.
The lock is checked against the currently stored document, so a matching
expected_hash, an omitted frontmatter payload or an incoming locked: false
cannot bypass it. Locked notes remain readable and searchable.
You can create a locked note or set the lock on an editable note. To unlock an
existing note, remove the field or set it to false directly in Obsidian or a
text editor, then read the note again to obtain its current hash. There is no
agent override. Only the Boolean true locks; the string "true", false,
null and an absent field do not.
The lock is an application-level editing rule. Existing read-only, path, MemorySink, provenance and concurrency protections still apply. Rejected operations leave the file, SQLite index, write audit and watcher suppression unchanged. External editors retain normal access to Markdown files.
Optional document editing
Enable the separately versioned edit module in config.toml:
[server]
features = ["document_edit"]This adds edit_document to MCP discovery. Call it with doc_id, the
expected_hash obtained by reading the document, and either
patch: {kind: "replace", old_text: "Old", new_text: "New"} or
patch: {kind: "section", heading_path: ["Project", "Decision"], content: "New decision\n"}.
Replacement text must occur exactly once; duplicate heading paths are refused.
Section edits replace that heading's body, including nested subsections, while
retaining the heading line and surrounding bytes. ATX headings are recognized
outside fenced code blocks; Setext headings are not supported.
Body-only edits preserve existing frontmatter comments and formatting. Same-text
edits still run delivery guards and hash checks but do not write or add an audit
entry. document_locked, hash_mismatch, ambiguous_target and
target_not_found are structured refusals. MemorySink provenance remains required.
Without the feature flag, the standard MCP catalog is unchanged.
Successful edits invalidate stale derived data and refresh chunks, sections,
edges and the configured retrieval backend before returning. If refresh fails,
the edit still returns ok: true with index_refresh: "pending" and a warning;
normal indexing/catchup retries the invalidated index. With no embedding model
registered, refresh builds the lexical index without contacting Ollama.
Compact v2 context
get_document_bundle, assemble_dossier and search_sections accept optional
projection, heading_paths and max_chars. Existing requests, including
projection: "full" without a budget, keep their previous response.
Use projection: "metadata" to omit body snippets. For selected source text:
{"doc_id":"obsidian-fs://work/project.md","projection":"sections","heading_paths":[["Project","Decisions"]],"max_chars":2000}Bundles and dossiers select from the anchor document; section search selects
matching paths from its query candidate sections. Each context.slices entry
contains the complete citation packet, exact body offsets and 1-based body line
range, text, original_chars and truncated. Sections include their nested
subsections. Offsets and line ranges refer to the complete source range even
when the returned text is shortened. Source hashes describe the full document.
One budget covers all body excerpts in the response. Section projection defaults
to 6000 UTF-16 code units and avoids splitting emoji surrogate pairs. Metadata
has a body budget of zero; citation fields and properties are retained separately.
budget_used, budget_limit, truncated and excluded show what was shortened
or omitted. max_chars: 0 excludes nonempty excerpts explicitly. With full
projection, an explicit budget limits the existing link/chunk snippets.
Missing selectors return target_not_found, duplicate source heading paths
return ambiguous_target, and invalid/missing selection arguments return
invalid_projection. For section search, missing means absent from the query's
candidate sections. No files or provenance are changed. No configuration flag
or database migration is required; the original 23 v1 input schemas are frozen
separately from additive v2 schema snapshots.
Categorized statements
Explicit Markdown list items such as - [fact] The rollout starts in June,
- [decision] Use a local model and - [preference] Write asynchronously are
indexed as statements within their source document. Indented continuation lines
belong to the same statement; nested list items stay separate. Code examples,
checkboxes and ordinary prose are ignored. Unknown explicit categories remain
available. This parser performs no inference or provenance promotion.
Pass include_observations: true to the three v2 assembly tools to retrieve
statements with category, full source citation, document hash and body line
range. The default responses stay unchanged. Selected section projections
include only statements within the selected ranges; metadata projection returns
counts and exclusions without statement text. Excerpts share the global body
budget and disclose truncation or exclusion.
SQLite migration 17 adds a derived statement table and a source-hash marker.
Existing sources initially report state: "unindexed"; normal indexing/catchup
fills the marker, including documents without statements. A source change not
yet indexed reports state: "stale" and returns no old statements. Direct writes
publish the note and statement snapshot together; delete/rename removes the old
rows. Repeated identical snapshots preserve statement IDs. Markdown remains
authoritative and its source, evidence and confidence are retained as-is.
record_observation continues writing whole MemorySink documents under its
existing provenance contract.
Domain relation roles
Declare directed roles in a Relations section, for example:
## Relations
- owns [[Atlas#Plan|Roadmap]]
- depends_on [[Budget]]Only complete explicit list declarations are roles. Ordinary wikilinks and
code examples carry no inferred role; unknown underscore-separated role names
are retained. Roles enrich Edge.rel on the existing wikilink edge, preserving
anchors, source body lines, parallel roles and unresolved targets. Markdown is
authoritative. Run a full reindex to backfill existing notes; no migration or
configuration flag is needed.
The v2 expand tool accepts rels: ["owns"] and direction: "outgoing" or
"incoming". Existing forward/backward remain equivalent aliases; omitted
direction stays both. Omitted roles retain all edges; an empty role array
selects none. Filters apply on every hop and combine with edge_types.
via discloses the role, body line, declaring source DocId and canonical hash;
the result packet still cites the reached document and preserves its provenance.
A changed declaring source returns stale_relation and excludes its indexed
role until reindexing. Traversal never invents an inverse role or confidence.
The original v1 graph-tool schemas stay unchanged.
Read-only schema candidates, validation and drift
Enable the separate module explicitly:
[server]
features = ["document_edit", "schema_inspection"]inspect_schema accepts mode: "infer" | "validate" | "diff", doc_ids, an
optional named MemoryContract and strict (default false). Infer returns
candidate-only field types/prevalence, category/role prevalence, sample size
and complete fresh source citations. It neither marks empirical fields required
nor saves or changes a contract. A supplied contract retains all of its explicit
required keys, including keys absent from the sample. The adapter's derived
wikilinks property is excluded from filesystem field profiles/validation;
citation properties retain their original adapter shape.
Validate and diff require an explicit contract. Registered MemoryContracts,
including default-memory-v1, use their existing Zod validators and required-key
lists. Missing required provenance, wrong types and cross-field violations are
always errors. Additional undeclared fields are warnings permissively and errors
with strict: true; passed means no errors. Diagnostics cite the source hash,
field path, and source line for body declarations. Structured headings, lists
and nested sections are inspected through a Markdown projection; body_projections
and line_basis: "rendered_markdown" mark its lines as rendered coordinates.
The source citation/hash remains the original document. Diff reports required missing
in any sampled document, unexpected fields and new observed types.
An unregistered name loads its existing _contracts/memory/<name>.yaml from the
single filesystem vault named by the samples. The existing process-wide named
MemoryContract cache remains in use; multiple vaults cannot select an ambiguous
disk fallback. Author contracts explicitly and version them yourself. Optional
observation_categories: [fact, decision] and relation_roles: [owns, depends_on]
restrict inspection vocabularies. Omitted vocabularies are unrestricted; declared
empty arrays allow no values. Unknown declarations become warnings or strict
errors and appear in category/role drift. These vocabularies apply to inspection;
they do not change MemorySink write validators or promote observations.
Inspections work on readonly/locked sources, mutate no files or SQLite, and
fail closed for unavailable samples. The existing suggest_frontmatter tool and
the default catalog remain compatible. No database migration is required.
License
MIT.
Business validity (F07)
Optional valid_from / valid_to define a half-open business interval, independently of required observed_at: start inclusive, end exclusive, missing or null bounds open. Use quoted ISO timestamps with an explicit timezone and at most millisecond precision. Retrieval defaults to the current time. v2 recall, search_sections, and get_document_bundle accept as_of; recall also requires include_superseded: true to retrieve superseded memories historically. Invalid bounds yield invalid_validity; imported invalid documents stay indexed with a diagnostic and are excluded from search. Migration 18 backfills UTC milliseconds without rewriting Markdown.
Individual categorized statements inherit document bounds. A trailing explicit annotation can override only those bounds: - [fact] January rule <!-- validity: {"valid_from":"2026-01-01T00:00:00Z","valid_to":"2026-02-01T00:00:00Z"} -->. Null resets a bound to open. Malformed annotations are excluded with invalid_validity. Source identity, hash, evidence and confidence remain those of the original document. Direct bundle reads retain the anchor with valid_at even outside its interval; their statement list is filtered at as_of, allowing explicit statement overrides. Search filters indexed bounds before limits; external edits become searchable after indexing.
Knowledge CLI and manuals (F08)
vault-memory search --vault main --query "Budget" --json searches the existing index. vault-memory read --doc-id "obsidian-fs://main/A.md" --projection metadata --json retrieves source identity and hash; --projection full includes up to 6000 characters with truncation metadata. Both support --as-of ISO. JSON stdout contains one complete object; diagnostics use stderr.
Enable server.features=["document_edit"] to use vault-memory edit --doc-id ID --expected-hash HASH --patch-file patch.json --json. The patch is the same validated replace/section payload as edit_document. No implicit stdin input. Exit codes: 0 success, 2 invalid input, 3 missing document/topic, 4 conflict or guarded refusal, 5 unavailable backend. Successful edits refresh the index; refresh failures retain the successful edit with index_refresh: pending.
vault-memory man edit_document --json and MCP template vault-memory://man/{topic} return the same versioned manual, including schema, activation and operation hints. Tool discovery now advertises operation annotations without changing input schemas. VM_CONFIG_DIR=/path/to/isolated-config selects both config.toml and the vaults/ database directory; default remains ~/.vault-memory. No client configuration is written.
Local ONNX embeddings (F09)
Ollama remains the default. Set [server] embedding_provider="onnx" and model_path="/absolute/local/model-directory" to enable CPU-only ONNX embeddings. The directory must contain a schema_version=1 manifest plus locally supplied, SHA256-pinned model.onnx, tokenizer.json and tokenizer_config.json. Nothing downloads automatically. The manifest declares model/revision/dimensions, mean pooling, normalization, max_tokens, pad_token_id, query_prefix, passage_prefix, output name and license. See tests/fixtures/tiny-embedding/manifest.json for the format (the tiny model is a deterministic test graph, not a useful language embedding). Only self-contained float32 hidden-state ONNX exports are supported; batch size is one per inference, input_ids/attention_mask and optional token_type_ids. Inputs truncate deterministically to max_tokens.
For multilingual-e5-small, the author's model card specifies query: and passage: prefixes, masked mean pooling and normalization; supply the chosen export's exact dimensions, revision and asset hashes. Model instructions, ONNX Runtime API. The manifest hash is included in the revision namespace, preventing silent mixing after tokenization changes.
On an existing index, build ONNX using start_shadow_index with the manifest model name (or full namespace); it returns the canonical modelName. Existing vectors and active model remain intact. Verify the shadow, then call switch_active_model explicitly. A direct reindex to a different ONNX identity is refused until this migration is complete. New vaults can index directly. ContextFit keeps its embedding-free path. Source-only CLI reads work without ONNX assets. No multilingual quality or speed claim is made: the default suite uses the original MIT tiny fixture; an optional local-model paraphrase test runs only with VM_ONNX_QUALITY_MODEL_PATH.
Explicit session lifecycle (F10)
Enable session_lifecycle in [server].features to expose the additive start_session and record_checkpoint tools and local CLI commands. Existing tools and default configuration stay compatible. This feature reads existing briefs and records explicitly supplied summaries; it does not capture conversations or change host configuration.
vault-memory session start --vault main --topic project --sink _memory/_briefs --max-chars 3000 --json
vault-memory session checkpoint --input checkpoint.json --jsonstart_session accepts vault, topic, optional brief sink, max_chars and as_of. It validates the brief's source chunk hashes against freshly read documents and the derived index. Missing/changed/unindexed sources make the result stale:true with an empty context body; citations remain available. A current brief's body is clipped to the character budget while retaining source IDs and hashes. No brief is compiled automatically. CLI vault selection is automatic only with one configured vault.
Checkpoint input:
{"session_id":"session-42","event_id":"checkpoint-1","sink":"memory","summary":"Implemented and verified the selected change.","source_doc_ids":["obsidian-fs://main/Project.md"],"observed_at":"2026-10-03T10:00:00Z"}The existing record_observation controller and DeliveryAdapter author the summary inside an existing, provisioned MemorySink. Provenance is source:agent, confidence:inferred, type:summary, with explicit observed_at, source evidence and session/event IDs. Sources must be readable. Sentinel and readonly guards remain active. Commands do not provision sentinels or load embedding assets.
The SHA256 session/event key is scoped to the sink. Repeating an identical event returns the canonical checkpoint with reused:true; changing its payload returns checkpoint_mismatch. Parallel events return checkpoint_in_progress for the contending caller: retry with the same IDs. SQLite migration 19 adds atomic derived reservations. On retry, canonical checkpoint properties reconstruct idempotence after index loss or a crash following an atomic Markdown write. Expired reservations are reclaimed only after the owning process has ended. A previously completed but deleted checkpoint returns checkpoint_missing; it is not recreated implicitly. CLI exit codes are 0 success, 2 invalid input, 4 checkpoint conflict, 5 configuration/backend error.
The optional portable host adapter is examples/hooks/neutral-session.mjs. Run it explicitly with a JSON event file:
{"schema_version":1,"event":"session_start","input":{"vault":"main","topic":"project","sink":"_memory/_briefs","max_chars":3000}}For a checkpoint, use event:"session_checkpoint" and place the checkpoint input above in input. Unknown fields, unsupported versions and transcript fields are rejected. node examples/hooks/neutral-session.mjs event.json invokes the built CLI with a 25-second deadline (VM_HOOK_TIMEOUT_MS:100–25000); VM_CONFIG_DIR can isolate configuration. Timeout emits hook_timeout: retry the same event because the process may have completed an atomic write just before termination. Only this explicitly versioned neutral payload is supported; configure host-specific event translation yourself. No Claude/Codex config is edited and no background loop is installed.
Reviewed conversation imports (F11)
Enable conversation_import in [server].features for the additive preview_conversation_import, commit_conversation_import and promote_conversation tools, and corresponding CLI commands. The initial supported input is neutral-v1: an array of {provider,external_id,messages:[{id,role,text,at?}]}. Roles are user, assistant, system, tool; IDs must be unique, optional times explicit ISO timestamps, attachments unsupported. No timestamps or user authorship are invented. Example:
[{"provider":"neutral","external_id":"chat-42","messages":[{"id":"m1","role":"user","text":"Two pilots"},{"id":"m2","role":"tool","text":"Tool result"}]}]vault-memory import --format neutral --input conversation.json --target obsidian-fs://main/imports/ --json > manifest.json
# Inspect the saved manifest before applying it:
vault-memory import --commit manifest.json --json
vault-memory promote-conversation --input promotion.json --jsonPreview is the default and writes no source or memory document. It captures each existing source's canonical expected hash (null for a new destination) and uses a deterministic SHA256 identity from provider/external ID for safe filenames. External IDs are never filesystem paths. The versioned manifest includes full rendered text, content hash, conversation identity, destination and explicit import time. Commit validates these fields against each other and refuses edited/inconsistent manifests. Existing exports require the captured hash; source changes or deletions after preview produce a conflict. Locks and readonly checks remain active. Identical canonical imports reuse their source without an additional audit write. An updated export retains the original imported_at; message timestamps remain unchanged.
Imported sources carry source:imported, import_source_id, import_hash, imported_at and validated conversation metadata. They must be outside MemorySinks. Commit uses the existing DeliveryAdapter; a batch reports completed per-document results if a later write fails, so inspect the result before retrying. Normal indexing builds searchable derived data; no model inference runs during import.
Promotion is a separate explicit write through record_observation into an existing provisioned sink:
{"doc_id":"obsidian-fs://main/imports/conversation-HASH.md","expected_hash":"CANONICAL_SOURCE_HASH","message_ids":["m1"],"claim":"Two pilots","mode":"quote","sink":"memory","observed_at":"2026-10-03T12:00:00Z"}The canonical source must still match its import metadata and caller hash; missing messages and fabricated quotes are rejected. quote requires exact selected text and records confidence:direct; inference records confidence:inferred. Both write source:agent with concrete DocId#message-id evidence, source hash and original roles. Tool messages remain tool messages. Repeating an explicit promotion creates another observation; promotion is not advertised as idempotent. Source imports and agent-derived claims remain separately inspectable.
Provider export parsers are enabled only against a documented, verified compatibility profile. OpenAI documents data export, but does not provide a stable JSON mapping schema or public versioned original fixture. Therefore --format chatgpt currently returns unsupported_format; branching or attachments are never silently flattened. Convert to neutral-v1 explicitly. The synthetic neutral fixture contains no private exported conversation. No existing v1 schemas, default tool catalog or global host configuration are changed. CLI exit codes:0 success,2 invalid/unsupported input,4 write conflict,5 configuration/backend error.
Available Tools
37 toolsassemble_dossierARead-onlyIdempotent
Resolve a {type, key} pair to an anchor document and walk its backlinks into a structured dossier: { anchor (citation packet), linked_documents (citation packets + relation), property_rollups (linked_count, linked_types, status_distribution) }. Strict properties.type match (D-03). The key matches the candidate's title OR any entry in properties.aliases (D-04). v2.0.0 returns relation:"wikilink" on every linked_documents entry (the v1 wikilinks table is the only edge source); Phase 4 (GRA-04) widens to typed edges. Superseded backlinks are NOT filtered — dossiers show the whole picture (CONTEXT D-04).
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Candidate key — matches the document's title OR any entry in properties.aliases (D-04) | |
| type | Yes | Exact-match value for properties.type on the anchor document (D-03 — no fuzzy match) | |
| vaults | No | Restrict to these vault names; defaults to all configured | |
| max_chars | No | Global UTF-16 body character budget. Sections defaults to 6000; zero excludes body text. Metadata is always body-free. | |
| projection | No | Optional v2 projection; sections requires heading_paths. Defaults to the legacy response. | |
| heading_paths | No | Exact heading paths on the anchor, or filters on section-search results. | |
| include_observations | No | Include explicitly categorized statements when the derived source hash is fresh; preserves provenance and shares the body budget. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/no-destruction, but the description adds real behavioral context: strict properties.type matching (no fuzzy match), key matching against title or aliases, the guarantee that relation is always "wikilink" in v2.0.0, the Phase 4 widening plan, and the notable decision that superseded backlinks are NOT filtered. That last point is exactly the kind of non-obvious behavior 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, which is good, but the prose is dense with internal ticket references (D-03, D-04, GRA-04, CONTEXT D-04) that convey little to an invoking agent, and the embedded output-shape enumeration could be tighter. It is informative but not economically written.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description appropriately fills that gap by enumerating anchor, linked_documents, and property_rollups fields. Combined with the behavioral caveats (unfiltered superseded backlinks, single edge source), an agent has enough to call and interpret it, though projection/heading_paths interplay is only lightly touched.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all six optional params carry their own descriptions, so the schema does the heavy lifting. The description restates the type/key semantics and outlines the property_rollups shape but adds no syntax or format detail beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a precise verb+resource: resolve {type, key} to an anchor document, walk backlinks, and build a dossier with named output sections. This clearly separates it from siblings like list_backlinks or get_document_bundle, which do not synthesize a structured multi-section dossier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied through the resolution/backlink-walking mechanics. It never says when to prefer this over list_backlinks, get_document_bundle, or expand, nor when a dossier is the wrong tool. The strict-match and alias rules hint at input expectations but do not guide tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audit_logBRead-onlyIdempotent
Query the write audit trail for a vault. Filterable by note path, operation type, or time. Default limit 50.
| Name | Required | Description | Default |
|---|---|---|---|
| op | No | ||
| limit | No | ||
| since | No | ||
| vault | Yes | ||
| note_path | No | ||
| is_memory_sink_write | No |
TDQS
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 usefully adds that this is specifically the *write* audit trail (create/update/delete events) and gives the default limit of 50, but says nothing about retention, ordering, or how far back the trail goes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler; the core purpose comes first and the filter/default details follow. Slightly terse for a six-parameter tool but structurally sound.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter, no-output-schema tool, the description covers the main query concept but leaves two parameters (including the required vault and the opaque is_memory_sink_write flag) and the timestamp semantics undocumented. Adequate to attempt a call, but the agent will likely need to guess on those fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description carries the full burden, and it only partially does so: it maps note_path, op, and time (since), and states the limit default. The required 'vault' parameter and 'is_memory_sink_write' are never mentioned, and 'since' is left ambiguous (epoch seconds vs ms) despite the numeric format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Query') and resource ('write audit trail for a vault'), and the filter dimensions (note path, operation type, time) make the scope concrete. It does not, however, distinguish itself from lookalike siblings such as index_runs or recent_notes, so the agent must infer which log this reads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no alternatives named, and no exclusions. The mention of what it can be filtered by is a capability statement, not routing guidance, so the agent gets no signal on why it would pick this over recent_notes or index_runs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clusterARead-onlyIdempotent
Community detection over the typed-edge graph via Louvain modularity (Blondel et al. 2008) using graphology + graphology-communities-louvain. Deterministic: same input produces byte-identical cluster_id assignment via DocId-sorted node insertion + seeded RNG (vault-memory-cluster-v1). cluster_id = smallest member DocId per community. Hard-capped at 5000 nodes; pass force: true to override. Either query (composes search_hybrid + expand 1-hop) OR seed_doc_ids (uses provided seeds + induced 1-hop neighborhood); not both — passing both returns {ok:false, reason:'both_seeds_and_query'}. On the query path with multiple vaults configured, the vault field is required so search scope is deterministic; single-vault setups may omit it (returns {ok:false, reason:'vault_required'} otherwise). Returns per-cluster {cluster_id, size, members[], summary: {top_types, top_titles, edge_density}}. No LLM enrichment — summary fields are pure-deterministic computations (LLM enrichment is Phase 5 brief layer's job). _memory opacity inherited from expand() (Plan 04-03).
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | ||
| query | No | ||
| vault | No | ||
| method | Yes | ||
| query_top_k | No | ||
| seed_doc_ids | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/idempotent annotations by disclosing deterministic byte-identical assignment, the seeded RNG tag, cluster_id derivation, the 5000-node hard cap, exact error reasons, and that summaries are pure computations with no LLM enrichment.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded, with the algorithm and determinism guarantees stated first and the path rules following. The parenthetical citation and library/plan references add minor noise but each sentence conveys operative detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 6 params, 0% schema coverage, and no output schema, it fully describes the return shape ({cluster_id, size, members[], summary}) and all routing constraints. An agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden; it explains the query/seed_doc_ids exclusivity, vault requirement, and force override. It does not explain query_top_k's role or the method const, leaving those only visible in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific operation (community detection over the typed-edge graph) with the exact algorithm (Louvain modularity) and libraries used. It distinguishes itself from siblings by naming search_hybrid and expand as components of its own query path rather than alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly defines the two mutually exclusive input paths (query vs seed_doc_ids), states that passing both returns an error, and specifies that vault is required on the query path when multiple vaults exist. It also states the force override condition for the 5000-node cap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compile_briefADestructive
Compile a brief from caller-supplied source documents and write it to the briefs sink. Resolves the LLM via the D-10 capability-first ladder (MCP Sampling → local Ollama → caller prepared_text → structured error). Enforces D-11 wikilink emission per source (appends a ## Sources footer when the LLM omits them) and writes through DeliveryAdapter. On target collision, auto-supersedes the prior brief via the Phase 2 supersede chain (D-12).
| Name | Required | Description | Default |
|---|---|---|---|
| sink | No | Override the default `_memory/_briefs` sink | |
| vault | Yes | Vault name (registered in [vaults] config block) | |
| target | Yes | Stable cross-version handle for the brief (e.g. 'atlas-q3') | |
| purpose | Yes | Free-form purpose; bounded so list_briefs stays scannable | |
| max_tokens | No | Hint for the LLM ladder; default 2000 | |
| prepared_text | No | D-10 tier 3 fallback when no LLM is reachable — verbatim body to stitch in | |
| source_doc_ids | Yes | DocIds the brief is compiled from; deduped, capped at 50 (D-03) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and non-idempotent, and the description earns credit by explaining the destruction: on target collision it auto-supersedes the prior brief via the D-12 supersede chain. It also discloses the wikilink footer enforcement and DeliveryAdapter write path. Missing only return/error shape nuance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first clause, which is good, but the paragraph is dense with opaque internal references (D-10, D-11, D-12, 'Phase 2 supersede chain') that consume space an external agent cannot decode. Every sentence is doing work, but the jargon lowers scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation tool with no output schema, the description covers the write target, the fallback ladder, link-footer enforcement, and collision semantics. It stops short of describing the return value or structured-error shape, but the behavioral picture is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds real meaning beyond the schema by situating prepared_text as the D-10 tier-3 fallback and max_tokens as a ladder hint, which clarifies how these two parameters interact at runtime.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Compile a brief from caller-supplied source documents') and names the sink destination. An agent can distinguish this from get_brief (retrieve) or assemble_dossier (compose a multi-bundle dossier) without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is rich context about the internal LLM resolution ladder and collision handling, but no explicit statement of when to choose this over get_brief, assemble_dossier, or write_note. Usage is implied by the mechanics rather than routed against alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_noteADestructive
Delete a note. Requires write_enabled=true AND expected_hash (no blind deletes).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| vault | Yes | ||
| client_id | No | ||
| expected_hash | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false and non-idempotency. The description adds behavior beyond that: the write_enabled gate and the mandatory expected_hash concurrency guard, which tells the agent this is a guarded, non-blind delete. It could still say what happens on hash mismatch, but the added context is substantive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, action stated first, preconditions immediately after. No filler and nothing buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with no output schema, the key facts an agent needs — the write gate and the required hash — are present. Missing details are secondary: failure behavior on hash mismatch and confirmation that deletion is irreversible.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across four parameters, so the description must carry the load. It explains why expected_hash exists (prevents blind deletes) but never defines vault, path, or client_id, and even references write_enabled, which is not a parameter in the schema at all. Compensation is only partial.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Delete a note'), which is unambiguous and clearly distinct from siblings like write_note or update_frontmatter. It does not explicitly name a sibling alternative, so it falls short of the top tier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states preconditions for use: write_enabled=true and expected_hash required, with the constraint 'no blind deletes'. That is clear context and effectively an exclusion (you cannot delete without knowing the current hash), though it does not route the agent to any alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_contractARead-onlyIdempotent
Return the input JSON Schema + an auto-generated markdown summary for a contract (Q-DESCRIBE). Pure function — does not execute the contract. Summary lists Inputs / Sources / Sinks / Assembly (numbered) / write_back / Output Shape. Omit vault on single-vault setups; on multi-vault setups, pass vault to disambiguate (returns {ok:false, reason:'ambiguous_vault'} otherwise).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Registered contract name (see register_contracts_as_tools) | |
| vault | No | Vault name; omit on single-vault setups |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered. The description adds genuinely new behavior: it will not execute the contract, and it returns {ok:false, reason:'ambiguous_vault'} on ambiguous vaults, plus the exact contents of the generated summary.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the primary behavior, then packs the summary contents and vault rules into tight clauses. Dense with parentheticals but nearly every clause carries actionable information; no padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description compensates by enumerating the return structure (Inputs/Sources/Sinks/Assembly/write_back/Output Shape) and the error shape. Combined with the annotations, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description goes beyond the schema's 'omit on single-vault setups' by defining the multi-vault requirement and the precise error result, adding real semantic value for the vault parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return the input JSON Schema + an auto-generated markdown summary for a contract') and immediately scopes it as a pure, non-executing function. This cleanly distinguishes it from execution-oriented siblings like instantiate_contract.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit conditional usage for the vault parameter (omit on single-vault, pass on multi-vault) and describes the failure mode otherwise. It implies when to use this versus executing a contract ('does not execute'), but never names a sibling alternative outright, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expandARead-onlyIdempotent
Typed-edge BFS retrieval. Returns the typed-edge neighborhood of one or more seed documents as a flat array of citation packets, each carrying via: {seed_doc_id, hop, edge_type, direction} provenance. Hops hard-capped at 2 (v2.0.0). Default direction = 'both'. Filterable by edge_type and by document properties (strict equality, no operators). Memory-sink documents (_memory/...) surface only when they are already linked from a user note in the result set (per ADR-004 memory-namespace opacity rule). Frontmatter-ref edges are extracted heuristically: [[...]] syntax in any property value OR allowlisted property names (assignee, owner, project, related, parent, child, attendees, superseded_by) matched against note_aliases. include_superseded defaults to false (Phase 2 D-03 forward-only supersede). Unknown seed_doc_ids do not throw — they are returned in a warnings: [{seed_doc_id, reason: 'unknown_doc'}] array. Shortest path wins on dedup; ties broken by (seed_doc_id, edge_type, direction).
| Name | Required | Description | Default |
|---|---|---|---|
| hops | Yes | Hop cap (1 or 2). v2.0.0 hard-caps at 2. | |
| rels | No | Domain role filter; omitted = all, empty = no edges. | |
| direction | No | Edge traversal direction; default 'both'. | both |
| edge_types | No | Optional filter on edge types; default = all four types. | |
| seed_doc_ids | Yes | 1+ opaque DocIds (e.g. obsidian-fs://<vault>/<path>) — seeds of the BFS. | |
| filter_properties | No | Strict-equality predicate on document properties (e.g. {type: 'Project'}). | |
| include_superseded | No | When false (default), docs whose properties.status === 'superseded' are dropped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover safety (readOnly/idempotent/non-destructive), and the description goes well beyond: hard hop cap, default direction, dedup rule with tie-breaking, the memory-namespace opacity rule (ADR-004), supersede default behavior, and the non-throwing unknown-seed warning contract. This is rich, non-obvious behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, but the description is a dense wall of clauses and parenthetical rule IDs (ADR-004, Phase 2 D-03) that padding readability. Most sentences earn their place, but the packing is heavy for a single paragraph.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Very complete for a complex graph-expansion tool with nested filter_properties and 7 params: hop cap, direction, dedup, supersede, warnings, and namespace rules are all covered. Lacking an output schema, the description still describes the packet shape, so only minor gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema: it clarifies filter semantics ('strict equality, no operators'), explains when memory-sink docs are surfaced, and documents the default-false supersede rule and the unknown-seed warning handling.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific retrieval algorithm (typed-edge BFS) and the exact resource (typed-edge neighborhood of seed documents), and describes the return shape (flat array of citation packets with via provenance). An agent can immediately distinguish this from siblings like list_backlinks, list_forward_links, or recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly this is the graph-expansion tool vs the search_* tools, but the description never names an alternative or states when to prefer expand over list_backlinks/list_forward_links/fetch. Usage is inferable from the algorithm name but not explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetchARead-onlyIdempotent
OB1-compatible fetch adapter. Resolves an opaque id (from search) to {id, title, text, url, metadata}. Backed by read_note.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is covered. The description adds that it is an 'OB1-compatible fetch adapter' backed by read_note, which hints at delegation, but says nothing about id validity, failure modes, or whether it re-indexes. Adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler: identity, input-to-output mapping, backing implementation. Tight and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description compensates by enumerating the returned fields, and the only parameter's meaning is explained. What remains missing is error behavior and relationship to sibling resolvers, a minor gap for a single-parameter adapter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the single param has no schema description, so the description must carry the burden. It does so well by defining the parameter as an 'opaque id (from `search`)', telling the agent both the type of value expected and its provenance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Resolves') and resource ('opaque id') and gives the exact return shape {id, title, text, url, metadata}. 'Backed by read_note' and 'id (from search)' partially differentiate it from the many sibling retrieval tools, though the distinction is implied rather than spelled out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'from `search`' implies this tool is used to resolve ids produced by search, which is useful routing context. However, there is no explicit when-to-use/when-not statement and no guidance on choosing fetch over read_note, expand, or get_document_bundle.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_broken_linksBRead-onlyIdempotent
List all wikilinks in a vault that point to non-existent notes.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds useful context by defining what a 'broken' link is (a wikilink whose target note does not exist), but says nothing about output shape or scale.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with no waste, front-loading the verb and the resource scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with one parameter and no output schema, the definition is functional but thin: it omits any explanation of the vault parameter and gives no hint about what the returned broken-link list contains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single required parameter (vault) at 0% schema description coverage, and the description never explains it. It is presumably the vault to scan, but the description should have compensated for the schema's silence and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and a precisely scoped resource (wikilinks pointing to non-existent notes). This distinguishes it from related siblings like list_backlinks and list_forward_links by its filter on brokenness, though it doesn't explicitly name those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides no when-to-use or when-not-to-use guidance. An agent must infer that this is a diagnostic tool distinct from list_backlinks/list_forward_links; nothing in the text tells it when to prefer this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_briefARead-onlyIdempotent
Look up a brief by target slug. D-13 decision tree: staleness dominates; age is independent; follow the supersede chain to the terminal brief. Returns null when the caller MUST recompile (stale + !allow_stale OR too_old + !allow_stale).
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes | Vault name (registered in [vaults] config block) | |
| target | Yes | Stable cross-version handle for the brief | |
| allow_stale | No | When true, return briefs flagged stale or too_old with annotation rather than null | |
| max_age_days | No | Reject briefs older than this many days unless allow_stale=true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safe-read profile (readOnly, idempotent, non-destructive), yet the description adds real behavioral value: the null contract under stale/too_old plus !allow_stale, and the supersede-chain resolution. The 'D-13 decision tree' reference is internal jargon the agent cannot resolve, which caps this 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core verb+resource, then the decision rule and the null contract. Dense and mostly waste-free, though the unexplained 'D-13 decision tree' label costs a little clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a retrieval tool with no output schema, the description covers the null contract and chain-following, which are the essential behaviors. It leaves gaps on what a brief actually contains and how the supersede chain is traversed, and leans on an unexplained internal decision-tree reference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description goes further by explaining how allow_stale and max_age_days interact with staleness to produce null versus an annotated brief. That interaction is not spelled out in the schema and is the key calling decision.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Look up a brief by target slug') and adds scope detail (supersede chain to the terminal brief) that separates it from a plain note fetch. It does not name its closest sibling (compile_brief) explicitly, so the differentiation is implied rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The null-return clause tells the agent when this tool will not yield a brief and that the caller must recompile, which is an actionable routing cue. It stops short of naming the alternative tool (compile_brief) or stating exclusions, so it is clear context rather than explicit alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_document_bundleARead-onlyIdempotent
Document-tree retrieval. Returns a structured bundle for a single document: { anchor (citation packet + optional status/superseded_by), outline (section tree via buildOutlineTree — same shape as get_outline.root), backlinks (citation packets + property_snippet + relation:"wikilink"), forward_links (same shape; broken links omitted), recent_edits (≤10 most recent audit_log rows mapped to {at, op, client_id, is_memory_sink_write?}) }. Every citation packet is the full 8-field D-01 shape from src/memory/citation-packet.ts. v2.0.0 accepts only depth:1 (one-hop links); the field is zod-pinned to z.literal(1) for forward compatibility. recent_edits is keyed by the anchor's CURRENT note path — pre-rename history is preserved in audit_log but not surfaced here (Phase 4 widens). Unknown doc_id returns { isError: true, error: "doc_not_found", doc_id }.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | ||
| depth | No | Link-walk depth. v2.0.0: only 1 (one-hop). Phase 4 may widen. | |
| doc_id | Yes | Opaque DocId (obsidian-fs://<vault>/<path>) of the anchor document | |
| vaults | No | Optional vault filter; usually omitted (the DocId names a vault) | |
| max_chars | No | Global UTF-16 body character budget. Sections defaults to 6000; zero excludes body text. Metadata is always body-free. | |
| projection | No | Optional v2 projection; sections requires heading_paths. Defaults to the legacy response. | |
| heading_paths | No | Exact heading paths on the anchor, or filters on section-search results. | |
| include_observations | No | Include explicitly categorized statements when the derived source hash is fresh; preserves provenance and shares the body budget. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/non-destructive, and the description still adds substantial behavioral detail: the unknown-doc_id error shape, that broken links are omitted, that recent_edits is capped at 10 and keyed by the CURRENT anchor path (pre-rename history hidden), and that depth is zod-pinned for forward compatibility. This is context well beyond what structured fields provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and the bundle shape is given before the caveats, so an agent can skim the first sentence for routing. It is dense but earns most of its length; minor redundancy appears in the repeated depth:1/'same shape' statements.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description substitutes by specifying the exact return structure, field shapes, error contract, and known limitations. For an 8-parameter tool this is sufficiently complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 88%, so the schema already documents params thoroughly. The description largely restates schema content (depth:1, max_chars budget) rather than adding new meaning; the only incremental semantics are the depth-literal versioning caveat and the ≤10 recent_edits bound, which is modest additive value at this coverage level.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Document-tree retrieval', returns a bundle for a single document) and then enumerates the exact bundle components (anchor, outline, backlinks, forward_links, recent_edits). It also distinguishes itself from siblings by noting the outline 'same shape as get_outline.root' and that it consolidates what list_backlinks/list_forward_links/audit_log expose separately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the enumeration of collected artifacts signals that this tool replaces several narrow sibling calls for one document. However, there is no explicit 'use this instead of X when Y' guidance, and no when-not conditions beyond the depth:1 versioning note.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_outlineARead-onlyIdempotent
Return the navigable section tree for a document. Each OutlineNode carries an anchor (the section's citation token), heading_path (root → leaf), heading_text, level, and chunk_ids (v1 chunk-table IDs in that section). Consume anchor + heading_path as the section-level half of the citation packet. Unknown doc_id returns an error response with {error:'doc_not_found', doc_id}.
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes | Opaque DocId (obsidian-fs://<vault>/<path>) of the document | |
| vaults | No | Optional vault filter; usually omitted (the DocId names a vault) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive, closed-world), so the description's added value is behavioral detail it does supply: the exact failure mode 'Unknown doc_id returns {error:'doc_not_found', doc_id}'. It doesn't cover pagination or ordering of the tree, so it's not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core purpose, then return fields, then the error case — every sentence earns its place. The field enumeration is dense but justified since there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so: it lists every OutlineNode field and their citation-role. Combined with annotations covering the safety profile and an explicit error contract, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both `doc_id` and the optional `vaults` filter are already documented in the schema, and the description adds no parameter-level syntax or format guidance (e.g., when the vault filter matters). The mention of `chunk_ids` describes return data, not inputs, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Return the navigable section tree for a document,' which is distinguishable from siblings like search_sections, get_document_bundle, or read_note. It does not explicitly name an alternative or contrast with them, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: 'Consume `anchor` + `heading_path` as the section-level half of the citation packet' hints at a downstream citation workflow, but there is no explicit when-to-use, when-not-to-use, or named alternative among the many search/bundle siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
index_runsBRead-onlyIdempotent
List recent index runs for a vault — what was scanned, when, how long, errors.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| vault | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is fully covered structurally. The description adds value by disclosing the payload contents (scan scope, timestamps, duration, errors), but says nothing about result volume, ordering, or that the list is capped.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that names the action first and then the returned fields. No filler words; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description usefully previews the returned fields, which is the right move. However, for a tool with two undocumented parameters and no guidance on result limits or ordering, an agent still lacks enough to invoke it confidently beyond the simplest call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter burden. It implies vault scoping via 'for a vault' but never explains the 'limit' parameter (default 20, max 200) or what the vault string should be, leaving both partially or wholly undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List recent index runs') with the scope qualifier 'for a vault', and enumerates the content returned (what was scanned, when, duration, errors). It does not compare itself against siblings like audit_log or vault_stats, which is the only thing keeping it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No indication of when to reach for this tool versus audit_log, vault_stats, or start_shadow_index, and no stated prerequisites. Usage is only implied by the semantics of listing index runs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
instantiate_contractA
Execute a registered contract end-to-end. Zod-validates inputs against the contract's inputZodSchema (additionalProperties:false rejects typos). Resolves source/sink overrides per D-A4b default chain (explicit → config → contract literal → error if required); sinks are MemorySink-only per D-A4c (MEM-05 invariant un-bypassable). Runs each assembly step through verbDispatcher with template resolution + named-binding accumulation. write_back routes through DeliveryAdapter.write() (MEM-05 chokepoint). Returns the Q-OUTPUT bundle {steps, write_back} on success OR a structured InstantiateError envelope (12 sealed reasons per ADR-006 §Decision 7). Omit vault on single-vault setups; multi-vault setups require it (returns ambiguous_vault otherwise).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Registered contract name | |
| vault | No | Vault name; omit on single-vault setups | |
| inputs | No | Contract inputs; validated against the contract's inputZodSchema | |
| sink_overrides | No | Override declared sink handles by handle name. Targets MUST resolve through MemorySinkRegistry (D-A4c). | |
| source_overrides | No | Override declared source handles by handle name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover safety flags (readOnly=false, openWorld=true, idempotent=false, destructive=false); the description adds substantial non-obvious behavior: Zod validation against the contract schema, the D-A4b override resolution chain, MemorySink-only sinks enforced by the MEM-05 invariant, write_back routed through DeliveryAdapter.write(), and a structured InstantiateError envelope with 12 sealed reasons.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core action is front-loaded in the first sentence, but the rest is one dense run-on paragraph laden with internal references (D-A4b, D-A4c, MEM-05, ADR-006 §Decision 7) that an agent without domain context must parse. Much of it earns its place, but the jargon and length dilute scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by describing the return bundle {steps, write_back} and the failure envelope. It also covers the vault ambiguity error, though it does not enumerate the 12 InstantiateError reasons, leaving a small gap for a complex mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters — baseline 3. The description adds only marginal value beyond the schema (typo rejection via additionalProperties:false, sink override constraints, and the vault ambiguity rule, the latter of which is arguably behavioral rather than parameter semantics).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Execute a registered contract end-to-end.' An agent can distinguish this from describe_contract and register_contracts_as_tools without opening schemas, since this is the execution/run tool rather than a metadata or registration tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives one concrete usage rule (omit `vault` on single-vault setups; required otherwise, returns `ambiguous_vault`), which is real guidance. But it never states when to use this tool versus siblings like describe_contract or compile_brief, so the run-vs-inspect choice is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_backlinksARead-onlyIdempotent
Find all notes that link TO a given note. DEPRECATED since v2.0.0 — prefer MCP Resource vault-memory://backlinks/{vault}/{+docId} for agent discovery. The tool remains callable through v2.x; removal scheduled for v3.0.0.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| vault | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds genuine value the annotations cannot: deprecation status, the callable window, and the scheduled removal version. It does not describe the return shape, but for a deprecated read tool that gap is minor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero filler, and the core purpose is front-loaded ahead of the deprecation notice. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a small deprecated read tool with annotations covering safety and no output schema, the description is serviceable. The notable gap is that the two required parameters remain unexplained anywhere, leaving an agent to guess at vault/path semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for two required parameters (vault, path), so the description must carry the burden and does not: 'a given note' never clarifies which parameter identifies the note, nor what vault/path formats are expected (relative path? absolute? docId?). Nothing here helps an agent fill the required fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with directional scope made explicit ('notes that link TO a given note'), which cleanly separates it from the sibling list_forward_links. An agent can select it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent away from the tool: 'DEPRECATED since v2.0.0 — prefer MCP Resource vault-memory://backlinks/{vault}/{+docId}', and gives the lifecycle window (callable through v2.x, removal in v3.0.0). This is exactly the when/when-not/alternative guidance the dimension asks for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_forward_linksARead-onlyIdempotent
List all wikilinks FROM a given note. Optionally include broken links.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| vault | Yes | ||
| include_broken | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds that it lists forward links and can optionally include broken links, which is useful context, but it doesn't disclose return format, pagination, or any behavioral nuances beyond what annotations and schema imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no waste, front-loading the core action and then the optional parameter. Perfectly sized for a simple list tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with no output schema, the description covers the basic purpose and option. However, it lacks details about the return format (e.g., what a wikilink looks like) and does not compensate for the complete absence of parameter descriptions in the schema, leaving some ambiguity for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It implies that 'path' and 'vault' identify the note and vault, and that 'include_broken' toggles broken links, covering all parameters at a high level. However, it doesn't clarify the distinction between vault and path, nor does it note the default value (true) for include_broken, leaving gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('wikilinks FROM a given note'), clearly distinguishing it from backlink tools by direction. However, it does not explicitly name sibling tools or contrast alternatives, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the phrase 'FROM a given note' and the optional broken links, but there is no explicit guidance on when to use this tool versus alternatives like list_backlinks or find_broken_links. The description provides context but not decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_modelsARead-onlyIdempotent
List all embedding models registered for a vault, with dim, active flag, and how many chunks have been embedded under each. Use before start_shadow_index / switch_active_model. DEPRECATED since v2.0.0 — prefer MCP Resource vault-memory://models/{vault} for agent discovery. The tool remains callable through v2.x; removal scheduled for v3.0.0.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint false, and openWorldHint false. The description adds meaningful context beyond annotations: the returned fields (dim, active, embedded chunk counts) and the deprecation lifecycle through v2.x with removal in v3.0.0. It does not cover edge cases such as an unknown vault, but the added lifecycle and output detail are substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the tool's purpose and return fields, followed by usage guidance and deprecation details. Every sentence earns its place; there is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with no output schema, the description usefully summarizes return fields and clearly communicates deprecation and an alternative resource. The main remaining gap is the undocumented vault parameter, but overall the definition is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the only parameter (vault) is not explained in the schema. The description says the models are registered 'for a vault' but does not specify the expected vault identifier format or behavior for an invalid/missing vault, so it fails to compensate for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: listing embedding models registered for a vault, including the fields dim, active flag, and embedded chunk counts. It also names related sibling tools (start_shadow_index, switch_active_model), making it easy to distinguish from other list/search tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use the tool before start_shadow_index / switch_active_model, and it clearly states that the tool is deprecated in favor of the MCP Resource vault-memory://models/{vault} for agent discovery. This gives both when-to-use and when-to-prefer-an-alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_vaultsARead-onlyIdempotent
List configured vaults with their status (note count, last indexed run). DEPRECATED since v2.0.0 — prefer MCP Resource vault-memory://vaults for agent discovery. The tool remains callable through v2.x; removal scheduled for v3.0.0.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the description adds the deprecation lifecycle and migration path, which is genuinely useful non-schema context. It stops short of describing pagination or exact status shape, so not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste; the concrete capability is front-loaded and the deprecation notice follows. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read tool with an empty schema and no output schema, the description supplies the returned fields, the safety-relevant status, and the deprecation replacement. Nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4. There is nothing for the description to clarify beyond noting there are no inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (configured vaults) and enumerates the returned status fields (note count, last indexed run). An agent can distinguish it from siblings like vault_stats or index_runs 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when NOT to use it – prefer the MCP Resource `vault-memory://vaults` for agent discovery – and gives the lifecycle window (callable through v2.x, removed in v3.0.0). This is precise when/when-not/alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_frontmatterBRead-onlyIdempotent
Filter notes by their YAML frontmatter. Supports equality, $in, $exists, $contains predicates. Multiple keys are AND-combined.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| vault | Yes | ||
| where | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered without the description. The description adds the AND-combination behavior of multiple keys, which is genuinely useful, but says nothing about limits, result ordering, or behavior on unknown keys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, each earning its place: purpose first, then predicate support, then combination semantics. Nothing redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a nested-object query tool with no output schema and 0% schema coverage, the description covers the core filtering semantics but omits anything about the shape of results, how `limit` behaves, or what an empty/malformed `where` does. It is minimally sufficient rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It does explain the predicate operators ($in, $exists, $contains) and equality, plus the AND semantics of the complex `where` object, which is the hardest parameter. However, `vault` and `limit` (with its default and cap) receive no explanation at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Filter notes by their YAML frontmatter'. It is distinguishable from the search_* siblings in concept, but it never explicitly contrasts itself with search_text/search_semantic, so the division of labor is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no mention of alternatives, despite several plausible substitutes (search_text, search_semantic, search_hybrid, list_vaults) in the sibling set. The agent must infer that frontmatter-based filtering is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_noteBRead-onlyIdempotent
Read the full content + frontmatter of a note by its vault-relative path.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| vault | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds useful return-content context ('full content + frontmatter'), but does not describe error behavior, pagination, or what happens with missing notes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. It states the action, returned data, and input format directly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read tool, the description states what is returned and the path semantics, and annotations cover safety. However, the vault parameter remains undefined in both schema and description, and there is no output schema to clarify return shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry parameter meaning. It clarifies that path is vault-relative, but says nothing about the required vault parameter. One of two parameters is explained, leaving a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: read the full content plus frontmatter of a note. It clearly identifies the input as a vault-relative path. It does not, however, distinguish itself from sibling read/search tools such as fetch or search_text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like fetch, get_brief, recall, or the search_* tools. The vault-relative path requirement implies usage, but alternatives and exclusions are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallARead-onlyIdempotent
Retrieve memory documents from one or more labeled MemorySinks, filtered by provenance (min_confidence, types, max_age_days) and ranked by recency (observed_at DESC). Returns citation packets (doc_id, source_handle, title, heading_path, mtime, hash, display_url, properties) — the same 8-field shape Phase 3 assembly tools use. Superseded documents are hidden by default.
| Name | Required | Description | Default |
|---|---|---|---|
| sink | No | Memory sink name OR full obsidian-fs://… handle. Defaults to all configured sinks. | |
| as_of | No | ||
| limit | No | Maximum results AFTER filter+sort; default 20 | |
| query | Yes | Natural-language query; routes through hybrid (semantic + BM25) search | |
| types | No | Restrict to docs whose `type` property is in this set | |
| vaults | No | Restrict to these vault names; defaults to all configured | |
| max_age_days | No | Exclude docs whose `observed_at` is older than this many days | |
| min_confidence | No | Exclude docs whose confidence ordinal is lower than this (direct=3, inferred=2, uncertain=1) | |
| include_superseded | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare safe read-only, idempotent, non-destructive behavior. The description adds useful behavioral context beyond annotations: it names the exact citation-packet fields returned, states that results are ranked by observed_at DESC, and notes that superseded documents are hidden by default.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tightly structured and front-loaded: the retrieval purpose comes first, followed by the return shape and default behavior. Every sentence adds useful information, and the parenthetical parameter grouping and field list are efficient rather than wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter retrieval tool with no output schema, the description does important work by documenting the return packet shape and superseded-document default. It remains incomplete around as_of semantics and explicit sibling routing, but the core invocation and return context are adequately covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 78%, so the schema does most of the parameter documentation. The description reinforces the provenance-filtering parameters min_confidence, types, and max_age_days, but it does not add meaningful semantics for sink, vaults, as_of, or include_superseded beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: retrieve memory documents from labeled MemorySinks. It also clarifies the retrieval mode through provenance filtering and recency ranking, but it does not explicitly distinguish this tool from sibling search tools such as search_hybrid or search_semantic.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what recall does, including filters and default hiding of superseded documents, but it gives no explicit when-to-use guidance or guidance on when another sibling tool should be preferred. It lacks the kind of routing advice that would help an agent choose between recall, search_hybrid, or search_semantic.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recent_notesARead-onlyIdempotent
List recently modified notes (mtime DESC). Use for agent self-orientation: 'what has the user been working on lately?'. No vector search, just SQL. DEPRECATED since v2.0.0 — prefer MCP Resource vault-memory://recent/{vault} for agent discovery. The tool remains callable through v2.x; removal scheduled for v3.0.0.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | No | ||
| vault | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the description only needs to add context. It does: SQL-backed rather than vector retrieval, ordered by mtime, and the full deprecation lifecycle (callable through v2.x, removal in v3.0.0). It does not mention result limit behavior or return shape, 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the core purpose and routing/deprecation guidance, with the deprecation note placed before the removal schedule. Minimal waste, though 'No vector search, just SQL' is slightly peripheral.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Deprecation and migration path are thoroughly covered, which is the most important context here. However, with no output schema and 0% parameter coverage, the ambiguity around 'since' and 'vault' semantics leaves an agent unable to call the tool precisely without experimentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for all 3 parameters, so the description carries the full burden and it does not compensate. 'since' is undocumented (timestamp? seconds vs milliseconds? inclusive?) and 'vault' scope is never explained; only the mtime DESC hint loosely gestures at the ordering. Most of the parameter meaning is left to guesswork.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List recently modified notes') plus the ordering (mtime DESC), and explicitly disclaims a sibling capability ('No vector search, just SQL'), which separates it from search_semantic/search_hybrid. An agent can identify what this returns without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives the exact motivating question ('what has the user been working on lately?') and names the preferred alternative (the vault-memory://recent/{vault} resource) along with the deprecation timeline. When-to-use and when-to-prefer-something-else are both explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_observationB
Record a new memory observation under the labeled MemorySink for a vault. Required provenance properties (source, confidence, evidence, status, observed_at, type, superseded_by) are auto-filled from arguments; properties is an escape hatch for contract-allowed extras and overrides any sugar default (D-02 — caller-last merge). Writes route through DeliveryAdapter.write() and pass through the centralized provenance validator.
| Name | Required | Description | Default |
|---|---|---|---|
| sink | No | Memory sink name OR full obsidian-fs://… handle. Defaults to the vault's default sink. | |
| type | Yes | Observation type per the sink contract (e.g. 'observation', 'hypothesis', 'decision') | |
| claim | Yes | Short natural-language statement of the observation (becomes title + body) | |
| vault | Yes | Vault name (registered in [vaults] config block) | |
| evidence | Yes | DocIds or quoted source spans supporting the claim; empty array allowed | |
| confidence | Yes | How the agent arrived at this claim | |
| properties | No | Escape-hatch: contract-allowed extra properties; merged AFTER sugar args (caller wins) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-idempotent, non-destructive write. The description goes beyond that by disclosing that provenance fields are auto-filled from arguments, that `properties` overrides sugar defaults under a caller-last merge (D-02), and that the write routes through DeliveryAdapter.write() and a centralized provenance validator. That is genuine behavioral context an agent cannot get from the annotations, though the internal component names add little for invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then mechanics, then the override rule. The 'D-02' ticket reference and 'DeliveryAdapter.write()' class name are internal jargon that does not help an agent decide or invoke, but the text is otherwise tight and waste-free.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-parameter mutation tool with no output schema, the definition covers the write path and provenance handling but omits what a successful call returns (a handle? an id?) and says nothing about failure modes such as contract or validator rejection. Annotations cover the safety profile, so the gap is moderate rather than severe.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all seven parameters are already documented in the schema, which sets the baseline at 3. The description's note on the `properties` escape hatch and merge order largely restates the schema's own wording, adding no new per-parameter syntax or format guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: recording a new memory observation under a labeled MemorySink for a vault. It is distinguishable from read-oriented siblings like recall or search, but it never differentiates itself from the other write-side tools (write_note, supersede, update_frontmatter), so an agent must still guess which mutation path applies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains mechanics but never states when to use this tool versus siblings such as write_note or supersede, nor any preconditions (e.g. that the vault must be registered, or that provenance fields are derived rather than supplied). Usage must be inferred entirely from the name and the required-parameter list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
register_contracts_as_toolsA
Explicit-control escape valve (D-A1) — scans the per-vault contract registry and updates the dynamic MCP tool list (registers new contracts as vm_ tools, unregisters removed ones) regardless of the [contracts.auto_register_tools] config gate. Always callable. Returns a per-vault diff of {registered, unregistered}. Omit vault to apply to every configured vault.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Vault name; omit to apply to all vaults |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare the safety profile (not read-only, open-world, not idempotent, not destructive), and the description adds real context beyond that: it mutates the dynamic tool list, bypasses a config gate, and returns a per-vault diff. It does not explain reversibility or what happens to existing dynamically registered tools that are still valid, which would have rounded it out.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the tool's role and effect, and the return value and scoping rule follow in order. It is dense and mostly earns its sentences, though identifiers like '(D-A1)' and the config-key bracket are noise for an agent selecting a tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by specifying the return shape (per-vault diff of {registered, unregistered}). Combined with the scope rule and the config-gate bypass, an agent has everything needed to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and schema description coverage is 100%, so the schema already documents `vault`. The description restates the omission semantics ('omit vault to apply to every configured vault'), which duplicates the schema's own description rather than adding new meaning. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verbs and resources: scans the per-vault contract registry and updates the dynamic MCP tool list, naming both effects (registers new contracts as vm_<name>, unregisters removed). This clearly distinguishes it from siblings like describe_contract and instantiate_contract, which operate on individual contracts rather than the tool registry.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It tells the agent when this is needed (the explicit-control escape valve that works regardless of the [contracts.auto_register_tools] gate, and is always callable) and the vault-scoping option. It does not name an alternative tool or state when *not* to call it, so it stops just short of a full when/when-not guide.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-onlyIdempotent
OB1-compatible search adapter. Returns a flat list of {id, title, url, snippet} for connector ecosystems (ChatGPT Custom Connectors, Claude.ai, Deep-Research). Backed by hybrid (semantic+BM25+RRF) search. For richer output use search_hybrid.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already covering read-only, idempotent, and non-destructive behavior, the description adds valuable context beyond them: the exact return shape (flat list of fields) and the underlying hybrid search backend (semantic+BM25+RRF). It doesn't cover auth needs or rate limits, but those are less critical given the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four compact sentences with no filler. It front-loads the tool's identity and return format, then adds backend and alternative details. The opening 'OB1-compatible' is somewhat jargon-heavy, but overall it is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with no output schema, the description usefully documents the return fields and backend. However, it omits any parameter guidance and fails to distinguish this generic search from many sibling search tools beyond search_hybrid, leaving an agent with incomplete routing information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the two parameters (query, limit). The description does not mention either parameter or their semantics, so it fails to compensate for the lack of schema-level documentation. The agent must infer from parameter names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies the tool as an OB1-compatible search adapter that returns a flat list of {id, title, url, snippet} for connector ecosystems. It distinguishes itself from search_hybrid by output richness, but does not explain how it differs from other search siblings like search_semantic or search_text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear usage context ('for connector ecosystems') and explicitly names the alternative for richer output ('use search_hybrid'). However, it provides no when-not guidance or distinction from other search tools in the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_hybridARead-onlyIdempotent
Hybrid search: combines semantic (embedding) and BM25 (full-text) results via Reciprocal Rank Fusion. Best general-purpose query. Pass expand: {hops: 1} to auto-attach 1–2 hop typed-edge neighbors as expansions[] per hit (preserves ranking; runs after recency/authority rescore).
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| rrf_k | No | ||
| top_k | No | ||
| expand | No | ||
| rerank | No | ||
| vaults | No | ||
| exclude_paths | No | ||
| half_life_days | No | ||
| recency_weight | No | ||
| authority_weight | No | ||
| frontmatter_boosts | No | ||
| frontmatter_filter | No | ||
| include_superseded | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower. The description adds real behavioral detail: RRF fusion, that expansions preserve ranking and run after recency/authority rescore. However, it leaves the behavior of ~11 tuning knobs (rerank, recency_weight, authority_weight, half_life_days, include_superseded, frontmatter filters) undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense, front-loaded sentences with zero filler: mechanism first, positioning second, the one parameter worth elaborating last. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 13 parameters, a nested `expand` object, 0% schema description coverage, and no output schema, the description is far too thin to let an agent configure the tool confidently. It documents the optional expansion path well but omits any hint about scoring, filtering, or supersession parameters that materially change results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 13 parameters, so the description must carry the parameter burden and it only explains one: `expand` (hops 1–2, expansions[] per hit, ordering). The other twelve parameters — rrf_k, top_k, rerank, half_life_days, recency_weight, authority_weight, frontmatter_boosts/filter, include_superseded, vaults, exclude_paths — get no semantic explanation at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Hybrid search') and names the exact mechanism (semantic/embedding + BM25 fused via RRF), which immediately distinguishes it from the sibling search_semantic and search_text tools. The claim 'Best general-purpose query' further positions it relative to alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Best general-purpose query' gives clear positive guidance on when to reach for this tool over the specialized siblings. It lacks an explicit when-not or a named alternative for narrow cases (e.g. when to use search_text instead), so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_sectionsARead-onlyIdempotent
Section-level retrieval. Composes the v1 hybrid (semantic + BM25 + RRF) pipeline with a chunk-to-section promotion step: runs hybrid with an inflated top_k = limit × 5, promotes each chunk hit to its enclosing section, dedupes by (note, section anchor), scores each section as the MAX of its constituent chunks, tie-breaks by chunk_id_first ASC, and returns the top limit sections. Each hit carries an 8-field citation packet (D-01) with a non-empty section heading_path PLUS the section anchor, score, contributing chunk_ids, and an optional snippet from the best-scoring chunk. Use when you want WHOLE-SECTION context, not a chunk window.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | ||
| limit | No | ||
| query | Yes | ||
| vaults | No | ||
| max_chars | No | Global UTF-16 body character budget. Sections defaults to 6000; zero excludes body text. Metadata is always body-free. | |
| projection | No | Optional v2 projection; sections requires heading_paths. Defaults to the legacy response. | |
| heading_paths | No | Exact heading paths on the anchor, or filters on section-search results. | |
| recency_weight | No | ||
| authority_weight | No | ||
| include_superseded | No | ||
| include_observations | No | Include explicitly categorized statements when the derived source hash is fresh; preserves provenance and shares the body budget. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), yet the description adds substantial behavior: the inflated top_k, chunk-to-section promotion, MAX scoring, tie-break rule, dedupe key, and the 8-field citation packet. Much of the algorithm detail is more implementation than behavioral guidance, but the output shape and scoring semantics are genuinely useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, but the bulk is a single dense sentence enumerating pipeline internals (RRF, promotion, dedupe keys, tie-break) that an agent rarely needs to invoke the tool. Sizeable trimming would lose little.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with no output schema and low schema description coverage, the description does cover the return shape (citation packet) but leaves most parameters undocumented. It is adequate for a knowledgeable caller but incomplete given the complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 36%, so the description must carry the load, but it only clarifies `limit` (via the top_k = limit × 5 note) and lightly touches scoring. It never explains max_chars, projection, heading_paths, recency_weight, authority_weight, include_superseded, include_observations, as_of, or vaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Section-level retrieval") and explains the retrieval pipeline plus its distinguishing scope (whole-section context). It contrasts implicitly with chunk-window tools rather than naming a sibling like search_hybrid, so differentiation is strong but not fully explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use when you want WHOLE-SECTION context, not a chunk window" gives a clear selection condition against chunk-based retrieval. It stops short of naming the alternative tools (search_hybrid / search_semantic) or stating when NOT to use this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_semanticCRead-onlyIdempotent
Semantic search via embedding cosine similarity. Searches all vaults by default.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| top_k | No | ||
| vaults | No | ||
| exclude_paths | No |
TDQS
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 the useful scoping default ('searches all vaults by default'), but says nothing about ranking, limits, or performance characteristics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with no filler. Efficient, though minimal content means it is not doing much work.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no parameter documentation; for a 4-parameter search tool with rich siblings, the definition leaves too much unspecified about scoping, ranking, and result limits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for all four parameters. The description only hints at the vaults parameter's default behavior ('all vaults by default') and says nothing about query, top_k, or exclude_paths, leaving the agent to infer semantics from names alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource (semantic search) and explains the mechanism (embedding cosine similarity), which distinguishes it from the sibling search_text and search_hybrid tools. It is clear, though it doesn't explicitly name those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives no when-to-use or when-not guidance relative to search_text, search_hybrid, or recall. The only contextual cue is the implicit 'semantic' framing, which the agent must infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_textBRead-onlyIdempotent
Full-text BM25 search via SQLite FTS5. Best for exact-word and phrase matches.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| top_k | No | ||
| vaults | No | ||
| exclude_paths | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds only implementation flavor (BM25 via FTS5); it says nothing about result ordering, scoring, or behavior with empty/no matches beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no waste, with the core purpose and the differentiator front-loaded. Nothing could be trimmed without losing signal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter search tool with no output schema and zero schema descriptions, the two-sentence description leaves top_k, vaults, and exclude_paths entirely unexplained. An agent cannot know how to scope the search or how many results it will get.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description explains none of the four parameters. 'Query' is inferable from 'full-text search', but top_k, vaults, and exclude_paths are completely undocumented in both the schema and the description, so the tool fails to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (full-text search) plus the underlying mechanism (SQLite FTS5), and 'exact-word and phrase matches' implicitly distinguishes it from the semantic/hybrid siblings. It stops short of naming those alternatives outright, so sibling differentiation is only implied.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Best for exact-word and phrase matches' gives a usage signal that helps an agent pick between this and search_semantic/search_hybrid. However, it never names those alternatives or states when NOT to use it, leaving the routing decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_shadow_indexB
Backfill embeddings for a secondary (shadow) model over every chunk in the vault. The active model is untouched — search keeps working during the run. Idempotent (resumable). Run switch_active_model once complete to promote the shadow.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | ||
| vault | Yes | ||
| batch_size | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly claims 'Idempotent (resumable)', but the annotations declare idempotentHint=false — a direct contradiction on the same behavioral property, which could cause an agent to assume repeated invocations are no-ops. Although the description valuably notes the active model is untouched and search stays live, the explicit conflict with structured metadata forces a 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each carrying a distinct fact (what it does, safety during run, resumability, next step). The core action is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter mutation tool with no output schema and 0% schema description coverage, the description omits all parameter semantics and does not describe progress reporting or error behavior. It covers the operational narrative well but leaves too much undocumented for an agent to invoke it reliably.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for all three parameters (vault, model, batch_size). The description only indirectly implies what 'model' means (the shadow model) and says nothing about vault scoping or batch_size limits, so it fails to compensate for the documentation gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — backfilling embeddings for a secondary/shadow model across every chunk in the vault — and explicitly differentiates the shadow model from the active one. An agent can immediately tell this apart from sibling tools like switch_active_model or vacuum_embeddings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear sequencing guidance: run this, then run switch_active_model once complete to promote the shadow. It also clarifies the run is safe to do concurrently with search. It stops short of stating when NOT to use it or what to do on failure, so it is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_frontmatterARead-onlyIdempotent
Suggest frontmatter fields for a note based on folder-conventions, wikilink-neighborhood, and title/body content-heuristics. Returns {existing, suggestions, conflicts}. Two input modes: (1) existing note via {path}; (2) draft via {content, folder_hint, title}. At least one of path/content required. Suggestions sorted by confidence DESC; conflicts list disagreements between sources.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| title | No | ||
| vault | Yes | ||
| content | No | ||
| folder_hint | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds genuine behavioral context beyond that: the return shape ({existing, suggestions, conflicts}), confidence-DESC sorting, and the meaning of the conflicts list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, then modes, then return contract. Dense and every sentence adds information, though the parenthetical clauses make it slightly packed versus a fully scannable form.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no schema descriptions, the description supplies the return shape and the input-mode contract, which is most of what an agent needs. The undocumented required 'vault' parameter is the remaining hole.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load, and it does for path, content, folder_hint, and title by grouping them into named input modes. The 'vault' parameter (the only required one) is never explained, leaving one gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Suggest frontmatter fields for a note') and enumerates the three evidence sources (folder-conventions, wikilink-neighborhood, content heuristics), which cleanly separates it from query_frontmatter and update_frontmatter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete selection criteria between two input modes (existing note via {path} vs. draft via {content, folder_hint, title}) plus the 'at least one of path/content required' rule. It does not, however, say when to prefer this over siblings like query_frontmatter or update_frontmatter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
supersedeADestructive
Mark an existing memory document as superseded by a replacement document. Forward-only — the replacement doc is NOT touched; back-links are derived by the Phase 4 graph layer at query time. Atomic single OCC update on the OLD doc; sets status="superseded", superseded_by, and superseded_reason.
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes | DocId of the document being superseded | |
| reason | Yes | Why the old document is being retired; written to superseded_reason | |
| replacement_doc_id | Yes | DocId of the replacement document |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses important behavior: the replacement document is not touched, back-links are derived at query time, and the operation is an atomic single OCC update on the old document that sets status, superseded_by, and superseded_reason. This is rich operational context for a destructive update.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded, with no wasted sentences. It immediately names the operation and follows with the most important constraints and effects.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter destructive mutation with full schema coverage and safety annotations, the description supplies the necessary behavioral context: forward-only semantics, OCC atomicity, and the fields updated on the old document.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented. The description adds only a light mapping by noting that the operation writes superseded_by and superseded_reason, but it does not add syntax or format details beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: "Mark an existing memory document as superseded by a replacement document." It is clear what the tool does, but it does not explicitly distinguish itself from similar document-mutation siblings such as update_frontmatter or delete_note.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context (retiring an old document in favor of a replacement) and clarifies the forward-only direction, but it offers no explicit when-to-use guidance or alternatives to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
switch_active_modelA
Atomically promote a registered model to active. Fails with ok:false / reason:'incomplete' if any chunk is missing a shadow embedding for the target model.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes | ||
| model_name | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it is a write (readOnlyHint=false), non-idempotent, and non-destructive, so the safety profile is covered. The description adds real value beyond that: it discloses atomicity and the exact failure contract (ok:false / reason:'incomplete' when a chunk lacks a shadow embedding). It omits what happens to the previously active model and whether auth is needed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, zero waste, with the core action front-loaded and the failure semantics immediately after. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema and 0% parameter coverage, the description covers the success effect and failure mode reasonably but leaves the vault parameter and the post-switch state of the prior active model undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the burden. It clarifies that model_name must be a *registered* model with shadow embeddings, but says nothing about 'vault' and adds no format, naming, or value detail for either parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('promote a registered model to active') with the added qualifier 'atomically', so the effect is unambiguous. It does not explicitly differentiate itself from siblings like list_models or start_shadow_index, but the action is distinct enough to select on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the mention of a required 'shadow embedding for the target model' hints at a precondition (shadow index must exist) but never states when to call this versus alternatives or what state must hold. No explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_frontmatterADestructive
Modify a note's frontmatter only. The body is preserved bytegenau. Merge DSL: scalar=set, {$unset:true}=delete, {$push:x}=array append, {$pull:x}=array remove.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| merge | Yes | ||
| vault | Yes | ||
| client_id | No | ||
| expected_hash | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the body is preserved byte-exact, scoping the blast radius to frontmatter, and it documents the merge DSL operations. It does not mention idempotency (annotation says false) or required permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly packed sentences: purpose front-loaded, then the DSL reference. Every clause earns its place with zero filler, and the higher-value scoping statement precedes the operator table.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation with a nested merge object and no output schema, the description covers the core (what changes, what is preserved, merge semantics). However, it omits expected_hash concurrency behavior, the client_id/vault roles, and any note about the return, 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 5 parameters, so the description must compensate. It thoroughly documents the 'merge' parameter's DSL value semantics (scalar=set, $unset, $push, $pull), which is the most complex nested field, but leaves path, vault, client_id, and expected_hash entirely undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Modify a note's frontmatter only') plus a scope constraint that separates it from write_note, which would rewrite body and frontmatter. It does not name the sibling tools it is distinct from, but the 'frontmatter only' framing makes the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, and no alternatives are named (e.g. write_note, suggest_frontmatter). The 'frontmatter only' phrase is the sole implicit signal that this is for partial edits, matching the no-guidance severity seen in comparable update tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vacuum_embeddingsBDestructive
Drop orphaned embedding rows whose chunk_id no longer exists in the chunks table. Safe and idempotent; does not touch live data. Useful after migrations from pre-v0.7.0 schemas where chunk deletion did not always cascade to the derived layer.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description asserts the operation is 'Safe and idempotent,' but the annotations declare idempotentHint=false and destructiveHint=true. The idempotency claim directly contradicts the structured metadata, and calling a row-deleting operation 'safe' undercuts the destructiveHint. This is an annotation contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences: the action first, then safety/scope, then the migration use case. Every sentence carries information and nothing is repeated from structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent cleanup tool with no output schema, the description explains what is removed and why, which is the core need. But it leaves the sole required parameter undocumented and its safety framing conflicts with the annotations, so an agent lacks a trustworthy behavioral picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, 'vault', has 0% schema description coverage and is never mentioned in the description. The agent is told what vacuuming does but not which vault to target or what form that identifier takes, so the description does not compensate for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (drop) and resource (orphaned embedding rows) with the exact condition that qualifies them (chunk_id no longer present in the chunks table). An agent can distinguish this cleanup operation from sibling search/read/write tools without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear triggering context: run it after migrations from pre-v0.7.0 schemas where chunk deletion did not cascade. It does not, however, state when NOT to run it or name an alternative cleanup path, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vault_statsARead-onlyIdempotent
Vault overview for agent self-orientation: note/word counts, top tags, top frontmatter keys, embedding model, last index run. Omit vault to get all configured vaults. DEPRECATED since v2.0.0 — prefer MCP Resource vault-memory://stats/{vault} for agent discovery. The tool remains callable through v2.x; removal scheduled for v3.0.0.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and non-destructive, so the safety profile is covered. The description adds genuinely new behavioral context: the deprecation lifecycle (v2.x callable, removal in v3.0.0) and the all-vaults default, which an agent cannot infer from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: capability first, scope/usage second, deprecation last. Every clause carries information (return contents, default scope, migration target, timeline) with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must carry return-value semantics, and it does so by listing the metrics returned. Combined with the deprecation notice and usage routing, an agent has everything needed to decide whether to call this or switch to the resource.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the single `vault` parameter is undocumented in the schema. The description compensates by explaining its omission semantics ("Omit `vault` to get all configured vaults"), which is real meaning beyond the structured field, though it never states the accepted identifier format for the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates exactly what the tool returns (note/word counts, top tags, frontmatter keys, embedding model, last index run) and frames it as agent self-orientation, which is far more specific than a restatement of the name. It lacks an explicit verb, and overlap with siblings like list_models/index_runs/list_vaults is only implicitly resolved by the enumerated contents, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use the tool (agent self-orientation/discovery), how to widen scope ("Omit `vault` to get all configured vaults"), and routes the agent to a named alternative (the `vault-memory://stats/{vault}` MCP Resource), including the migration timeline. Nothing about tool selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_noteADestructive
Atomically create or overwrite a note. Requires write_enabled=true. Use expected_hash for safe overwrites (read the note first, pass its hash). Omit expected_hash only when creating a new note.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| vault | Yes | ||
| content | Yes | ||
| client_id | No | ||
| frontmatter | No | ||
| expected_hash | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is known; the description adds what annotations cannot, namely atomicity and the write_enabled=true permission gate. It stops short of 5 because it does not say what happens to existing frontmatter or content on overwrite.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and scope, with each remaining sentence carrying a distinct rule (permission gate, safe-overwrite pattern, create case). No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive write tool with no output schema, it covers the critical operational facts: permission requirement, atomicity, and hash-based concurrency safety, while annotations cover the destructive/idempotency profile. The gap is the undocumented frontmatter and client_id parameters and their effect on overwrite.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for 6 parameters, so the description must compensate. It adds real meaning for expected_hash (read the note, pass its hash) and implies content/path/vault usage, but leaves frontmatter and client_id completely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Atomically create or overwrite a note'), which clearly separates it from read_note, delete_note and update_frontmatter. It does not explicitly name a sibling or a boundary case, so it stops short of the top band.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite (write_enabled=true) and a precise when/when-not rule for the risky mode: use expected_hash for overwrites by reading first, omit it only when creating a new note. An agent can pick the correct call pattern without inference.
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.
6 tool updates
v2.5.0- Changed
assemble_dossier4 fields changed- added
Input schema / properties / heading_pathsAdded value: +{ + "description": "Exact heading paths on the anchor, or filters on section-search results.", + "items": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / include_observationsAdded value: +{ + "description": "Include explicitly categorized statements when the derived source hash is fresh; preserves provenance and shares the body budget.", + "type": "boolean" +} - added
Input schema / properties / max_charsAdded value: +{ + "description": "Global UTF-16 body character budget. Sections defaults to 6000; zero excludes body text. Metadata is always body-free.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / projectionAdded value: +{ + "description": "Optional v2 projection; sections requires heading_paths. Defaults to the legacy response.", + "enum": [ + "full", + "metadata", + "sections" + ], + "type": "string" +}
- Changed
expand2 fields changed- changed
Input schema / properties / direction / enumPrevious value: -[ - "forward", - "backward", - "both" -]New value: +[ + "forward", + "backward", + "both", + "outgoing", + "incoming" +] - added
Input schema / properties / relsAdded value: +{ + "description": "Domain role filter; omitted = all, empty = no edges.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" +}
- Changed
get_document_bundle5 fields changed- added
Input schema / properties / as_ofAdded value: +{ + "type": "string" +} - added
Input schema / properties / heading_pathsAdded value: +{ + "description": "Exact heading paths on the anchor, or filters on section-search results.", + "items": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / include_observationsAdded value: +{ + "description": "Include explicitly categorized statements when the derived source hash is fresh; preserves provenance and shares the body budget.", + "type": "boolean" +} - added
Input schema / properties / max_charsAdded value: +{ + "description": "Global UTF-16 body character budget. Sections defaults to 6000; zero excludes body text. Metadata is always body-free.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / projectionAdded value: +{ + "description": "Optional v2 projection; sections requires heading_paths. Defaults to the legacy response.", + "enum": [ + "full", + "metadata", + "sections" + ], + "type": "string" +}
- Changed
query_frontmatter1 field changed- changed
Input schema / properties / where / additionalProperties / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "properties": { - "$in": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - } - ] - }, - "type": "array" - } - }, - "required": [ - "$in" - ], - "type": "object" - }, - { - "properties": { - "$exists": { - "type": "boolean" - } - }, - "required": [ - "$exists" - ], - "type": "object" - }, - { - "properties": { - "$contains": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "$contains" - ], - "type": "object" - } -]New value: +[ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "properties": { + "$in": { + "items": { + "type": [ + "string", + "number", + "boolean", + "null" + ] + }, + "type": "array" + } + }, + "required": [ + "$in" + ], + "type": "object" + }, + { + "properties": { + "$exists": { + "type": "boolean" + } + }, + "required": [ + "$exists" + ], + "type": "object" + }, + { + "properties": { + "$contains": { + "type": [ + "string", + "number", + "boolean", + "null" + ] + } + }, + "required": [ + "$contains" + ], + "type": "object" + } +]
- Changed
recall2 fields changed- added
Input schema / properties / as_ofAdded value: +{ + "type": "string" +} - added
Input schema / properties / include_supersededAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
search_sections5 fields changed- added
Input schema / properties / as_ofAdded value: +{ + "type": "string" +} - added
Input schema / properties / heading_pathsAdded value: +{ + "description": "Exact heading paths on the anchor, or filters on section-search results.", + "items": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / include_observationsAdded value: +{ + "description": "Include explicitly categorized statements when the derived source hash is fresh; preserves provenance and shares the body budget.", + "type": "boolean" +} - added
Input schema / properties / max_charsAdded value: +{ + "description": "Global UTF-16 body character budget. Sections defaults to 6000; zero excludes body text. Metadata is always body-free.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / projectionAdded value: +{ + "description": "Optional v2 projection; sections requires heading_paths. Defaults to the legacy response.", + "enum": [ + "full", + "metadata", + "sections" + ], + "type": "string" +}
1 tool update
v2.4.1- Changed
search_hybrid2 fields changed- added
Input schema / properties / frontmatter_boostsAdded value: +{ + "items": { + "properties": { + "key": { + "minLength": 1, + "type": "string" + }, + "value": { + "type": "string" + }, + "weight": { + "type": "number" + } + }, + "required": [ + "key", + "value", + "weight" + ], + "type": "object" + }, + "type": "array" +} - added
Input schema / properties / frontmatter_filterAdded value: +{ + "items": { + "properties": { + "key": { + "minLength": 1, + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" +}
37 tool updates
v2.0.0-rc.5- First observed
assemble_dossier - First observed
audit_log - First observed
cluster - First observed
compile_brief - First observed
delete_note - First observed
describe_contract - First observed
expand - First observed
fetch - First observed
find_broken_links - First observed
get_brief - First observed
get_document_bundle - First observed
get_outline - First observed
index_runs - First observed
instantiate_contract - First observed
list_backlinks - First observed
list_forward_links - First observed
list_models - First observed
list_vaults - First observed
query_frontmatter - First observed
read_note - First observed
recall - First observed
recent_notes - First observed
record_observation - First observed
register_contracts_as_tools - First observed
search - First observed
search_hybrid - First observed
search_sections - First observed
search_semantic - First observed
search_text - First observed
start_shadow_index - First observed
suggest_frontmatter - First observed
supersede - First observed
switch_active_model - First observed
update_frontmatter - First observed
vacuum_embeddings - First observed
vault_stats - First observed
write_note
TDQS
Scored across 37 tools
Several search/retrieval tools overlap (search_semantic, search_text, search_hybrid, search, search_sections, fetch, recall) and five deprecated tools parallel MCP resources, causing potential misselection despite detailed descriptions differentiating them.
All tools use lowercase snake_case, but the pattern is not strictly verb_noun: several are single verbs (recall, expand, cluster, fetch, search) or nouns (audit_log, index_runs). Consistent style with minor deviations.
37 tools is too many for the scope, including five deprecated aliases, multiple overlapping search adapters, and several graph/retrieval functions. The surface is heavy and hard to navigate, exceeding the 25+ threshold for 'too many'.
Covers notes CRUD, multiple search modes, memory sinks, briefs, contracts, indexing, audit, and graph retrieval. Missing a body-only update or rename/move operation, but overall the lifecycle is well represented.
Maintenance
Related MCP Connectors
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server for local-first RAG over Obsidian vaults, enabling AI agents to search and ask questions about notes with grounded citations.MIT
- AlicenseNot gradedqualityCmaintenanceLocal-first knowledge backend for AI agents that connects MCP hosts to an Obsidian-compatible vault with indexed retrieval, token-budgeted memory recall, and secure ingestion.1MIT
- AlicenseNot gradedqualityDmaintenanceA local-first RAG, MCP, REST, and CLI bridge for Obsidian vaults that enables AI agents to retrieve cited knowledge from notes without uploading the vault.1MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to persist, search, and evolve knowledge through a Markdown vault with a typed knowledge graph and MCP interface.20 PyPI15Apache 2.0