vaults
Provides tools for managing Obsidian-style Markdown vaults on disk: listing vaults and notes, reading and writing notes with frontmatter, wiki-links and backlinks, full-text search, tag counts, and version history/restore via local git.
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., "@vaultssearch my vaults for meeting notes from yesterday"
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.
vaults-hub
A Python MCP server that exposes your Obsidian-style Markdown vaults to MCP clients (e.g. OpenCode).
Keep each project's docs as plain Markdown on disk, and let an agent read and maintain them through a small, predictable tool API — no Obsidian plugins, windows, ports, or API keys. Every change is auto-versioned with local git, so nothing is ever truly lost.
Quickstart
The fastest way — no clone, no venv. Published on npm as
vaults-hub:
npx -y vaults-hubThis needs Python 3.10+ on PATH (or VAULTS_HUB_PYTHON set to its
path); CI tests 3.10, 3.12 and 3.14. On first run it bootstraps the pinned
dependencies from requirements.txt into a cached venv (one-time, ~30s;
later runs start instantly); see Configuration for the
cache location.
From source (offline/dev alternative) — prereqs are Python 3.10+
(developed/tested on 3.14), a POSIX platform (Linux/macOS — locking uses
fcntl), and optionally ripgrep
(rg) for faster search (a pure-Python fallback is used when rg is
absent):
git clone https://github.com/ishaan-jindal/vaults-hub.git vaults-hub
cd vaults-hub
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python server.py # stdio MCP server (no HTTP port)Vaults live in ~/.vaults by default (each subdir is one vault, e.g.
~/.vaults/MyProject/), auto-created on startup when missing. To use a
different location:
export VAULTS_ROOT="$HOME/my-notes"
python server.py --vaults-root "$HOME/my-notes" # flag wins over env varRegister with OpenCode
Add to your opencode.jsonc (adjust paths to your machine — do not
copy any hardcoded home directory). The npx form is recommended:
{
"mcp": {
"vaults": {
"type": "local",
"command": "npx",
"args": ["-y", "vaults-hub"],
// Pick ONE way to point at your vaults (flag wins over env var):
"environment": {
"VAULTS_ROOT": "<path-to-your-vaults>"
}
}
}
}The local-venv form is the offline/dev alternative (replace with the actual paths on your machine):
{
"mcp": {
"vaults": {
"type": "local",
// Replace with the actual paths on your machine:
"command": ["<path-to-vaults-hub>/.venv/bin/python", "<path-to-vaults-hub>/server.py"],
// Pick ONE way to point at your vaults (flag wins over env var):
"args": ["--vaults-root", "<path-to-your-vaults>"],
"environment": {
// ...or via env var instead of "args" above:
"VAULTS_ROOT": "<path-to-your-vaults>"
}
}
}
}Related MCP server: obsidian-kb
Usage examples
Vault layout: each project is a directory directly under VAULTS_ROOT
containing .md files, e.g. <VAULTS_ROOT>/MyProject/MyProject.md.
With the server registered as vaults:
List vaults: call
list_vaults→[{"name": "MyProject", "path": "...", "notes": 12}]Read a note:
read_note(vault="MyProject", path="MyProject.md")→ frontmatter, content, wiki-links, backlinksWrite safely:
read_note→ edit →write_note(..., expected_sha256="<sha from read>")to avoid clobbering concurrent editsSearch:
search_notes(query="build command", vault="MyProject", before=1, after=1)Recover a note:
history(vault="MyProject", path="Notes.md")→ pick asha→restore(vault="MyProject", path="Notes.md", rev="<sha>")
Tools
14 tools (see vaults/server.py for exact descriptions). Read-only tools are
marked R, mutating tools M (write_note/append_note/move_note/restore
honor expected_sha256 for optimistic concurrency — read first, then pass the
sha back; delete_note has no sha guard and delete_vault
is gated on confirm instead):
Tool | R/M | What it does |
| R | List all project vaults with note counts |
| R | Server version, Python/platform, git + ripgrep availability, |
| M | Create a new vault ( |
| M | Delete a whole vault including git history (irreversible; |
| R | List dirs/notes under a vault path ( |
| R | Read a note: frontmatter, content, wiki-links, backlinks, unresolved links |
| M | Create or atomically overwrite a note ( |
| M | Append text to a note (created if missing), atomic write, optional |
| M | Delete a note ( |
| M | Move/rename a note (copy+delete, not atomic); errors if src missing or dst exists; honors |
| R | Tag counts per vault from cached frontmatter (one vault or all) |
| R | Full-text search of |
| R | Version history for a note ( |
| M | Restore a note from a past revision (snapshots dirty state first; recreates deleted notes); echoes the revision as |
Also built in: YAML-frontmatter parsing with auto-refreshed updated: dates,
file locking (fcntl), atomic writes via temp-file + rename, backlink/tag
indexes with mtime invalidation, and optional debug logging to file.
Tool annotations
Every tool declares all four MCP ToolAnnotations hints explicitly, so
hosts that gate on them (OpenAI's tool directory rejects a tool where any
hint is missing or non-boolean) accept the whole set:
Hint | Meaning here | Value |
| does not modify the vault |
|
| may destroy or overwrite existing data |
|
| repeat calls add no further effect |
|
| touches entities outside the vaults root |
|
The hints are hints, not guarantees: a client must not make trust decisions
from them alone. They matter because the stdio writer serializes tool
payloads with exclude_none=True, so an unset hint is dropped from
tools/list entirely rather than sent as null. smoke_test.py asserts
all four are present booleans on all 14 tools, so a new tool cannot
silently reintroduce the gap.
Reliability
How the server avoids losing or corrupting notes:
Atomic writes. Every note write goes to a temp file in the same directory (
fsynced, thenos.replace), with the parent directoryfsynced afterwards — readers never see a half-written note. Existing file permissions are preserved.Locking. Mutations serialize per note (
flockread-modify-write cycles across processes) and git operations serialize per vault, with a consistent lock order everywhere (note lock first, git lock inside it), so concurrent writes and restores cannot deadlock. Read-onlyhistorytakes no locks and never blocks writers; truncation flags are computed by the core library, not the tool boundary.Optimistic concurrency.
write/append/move/restoreacceptexpected_sha256; a stale sha is rejected instead of clobbering someone else's edit.delete_notehas no sha guard;delete_vaultis instead gated onconfirmexactly equaling the vault name.Fail-open versioning. The write itself is the source of truth — a missing git binary or failed commit warns (surfaced as
commit_error) but never blocks the write.Search parity.
search_notesprefersrg --jsonand falls back to pure Python when ripgrep is absent; both sides search only.mdnotes, skip dotfiles,.obsidian/and symlinks, and ignore.gitignore, so results match whichever backend runs. Regex syntax is the exception: ripgrep uses Rust regex, the fallback Pythonre, so lookarounds and backreferences are not portable.No lossy rewrites.
append_note,move_noteandrestorerefuse content that is not valid UTF-8 instead of replacing bytes, and keep existing CRLF line endings.No surprise frontmatter. Notes without a frontmatter block stay that way;
updated:is only refreshed (or inserted) when a block exists.Fresh indexes. Backlink/tag indexes are invalidated by mtime, so external edits are picked up on the next read. Like listings and search, they skip notes in hidden folders such as
.obsidian/and.trash/.Symlink confinement. Symlink targets resolving outside the vault are rejected — a link can never pull reads or writes out of the vault. Escaping wiki-link path targets (e.g.
[[../Outside.md]]) are treated as unresolved;list_notesskips escaping symlink entries instead of failing. A vault directory that is itself a symlink is not listed, searched, or counted inlist_tags.
Configuration
Variable | Default | Purpose |
|
| Root dir; each immediate subdir is one vault |
| unset | Set to |
| unset (versioning on) | Set to |
Precedence for the vaults root: --vaults-root <dir> flag > VAULTS_ROOT
env var > default ~/.vaults. Whatever wins is auto-created on startup
when missing.
Notes:
ripgrep is optional. If
rgis onPATH,search_notesusesrg --json; otherwise a pure-Python fallback with the same results is used. No configuration needed either way.POSIX-only. File locking uses
fcntl, so Windows is not supported.npx launcher.
VAULTS_HUB_PYTHONoverrides which Python thevaults-hubbin uses (elsepython3, thenpythononPATH; must be 3.10+). When that interpreter lacks the pinned dependencies, the bin installs them once into a cached venv under$XDG_CACHE_HOME/vaults-hub(else~/.cache/vaults-hub), keyed by Python minor version, and reuses it silently while therequirements.txthash matches.
Versioning
Each vault is a local git repo (one per vault root), maintained automatically:
Default-on. The repo is lazily
git init -b mainon the first mutation; every write/append/delete/move commits path-scoped with aSha256:trailer (e.g.vaults: write Notes.md). The write itself is the source of truth — a missing git binary or failed commit warns but never blocks the write.Local-only, no push. Versioning never pushes, pulls, or fetches; identity is per-invocation (
vaults-hub), never written to gitconfig. Lock/tmp files and.obsidian/are excluded via$GIT_DIR/info/exclude(no visible.gitignore). A vault already nested inside an external repo is left alone.Opt-out. Set
VAULTS_HUB_GIT=0to disable init/commits;historyandrestorethen return clear errors.history(vault, path?, limit?)lists[{sha, date, message}](newest first, limit clamped 1–200) plus atruncatedflag when more commits exist beyond the page; a deleted note keeps its history, and a path that was never committed returns[]withuntracked:true.restore(vault, path, rev, expected_sha256?)writesgit show rev:pathback to disk atomically (snapshotting dirty state first), echoes the revision asrestored_from, and can recreate deleted notes.
Testing
No test framework — one end-to-end smoke test over a temporary stdio server:
source .venv/bin/activate
python smoke_test.pyIt creates fixture vaults in a temp dir, exercises all tools (including versioning and its opt-out), and exits non-zero with a traceback on failure.
Architecture (brief)
opencode (MCP client, stdio) <-> vaults/server.py (FastMCP "vaults", 14 tools) <-> ~/.vaults/<project>/*.mdvaults/is the whole server:config.py(vaults root, logging, CLI),notes.py(path validation, UTF-8 checks,fcntllocks, atomic writes, SHA-256 optimistic concurrency, frontmatter/wiki-link helpers, note CRUD, vault creation),indexes.py(in-memory backlink/tag indexes with mtime-based invalidation),search.py(ripgrep + Python-fallback search),versioning.py(per-vault git layer), andserver.py(FastMCP app, 14 tools). Rootserver.pyis a thin shim sopython server.pykeeps working.server.pykeeps the event loop responsive: every tool runs its blocking library call in a worker thread viaanyio.to_thread. Errors are sanitized at the tool boundary (client-safeValueErrors pass through; anything else becomes a plain failure notice) while the server log keeps the full traceback; request logging records only vault/path.smoke_test.pyspawnsserver.pyover stdio withVAULTS_ROOTpointed at a temp dir.
Limitations
Private SDK pin: dependencies are pinned in
requirements.txt(anyio==4.15.1,mcp==1.30.0,PyYAML==6.0.3); bump deliberately and re-runpython smoke_test.py.Move is copy + delete, not one atomic rename:
move_notewrites the destination atomically, then unlinks the source — a crash between the two steps can leave both copies behind. A failed move cleans up the partial destination. It also refuses to overwrite an existing destination.Wiki-link resolution is name-based: bare
[[Name]]links resolve via a stem index (shortest path wins on collision); only[[path/with/slash]]links resolve as paths. Self-links are excluded from backlinks.POSIX-only (
fcntllocking); no Windows support.No authentication: the stdio transport trusts the local client; do not expose vault contents beyond your machine without adding your own access controls.
License
MIT — see LICENSE.
Contributing
See CONTRIBUTING.md for setup, checks, and the PR flow.
Available Tools
14 toolsappend_noteADestructive
Append text to a note (created if missing) via an atomic write. Optionally pass expected_sha256 to prevent appending to a changed note. Refreshes the frontmatter updated: date (inserted when a frontmatter block exists without one).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-root-relative note path | |
| text | Yes | Text to append | |
| vault | Yes | Vault name | |
| expected_sha256 | No | SHA-256 from a prior read/write; rejects stale appends |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations (readOnlyHint=false, destructiveHint=true, idempotentHint=false) by disclosing auto-creation on missing notes, atomic write semantics, optimistic-concurrency rejection via expected_sha256, and the frontmatter side effect of refreshing/inserting the `updated:` date. These are exactly the mutation behaviors an agent needs before calling.
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, front-loaded with the core action, then the concurrency guard, then the side effect. No filler and no 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 mutating tool with no output schema, the description covers creation-on-missing, atomicity, the stale-write guard, and frontmatter side effects. It stops short of saying what a successful call returns or how a sha256 mismatch surfaces, which is a minor remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so path/text/vault/expected_sha256 are already documented, and the schema's own text ('rejects stale appends') nearly duplicates the description's sha256 note. Baseline 3 is appropriate since the description adds framing but no new parameter detail.
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 ('Append text to a note') plus the important edge case that the note is created when missing. The append semantics cleanly separate it from write_note/delete_note even without naming a sibling.
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 purpose rather than stated: nothing tells the agent when to prefer append_note over write_note, or when appending is inappropriate. The one conditional it does give ('Optionally pass expected_sha256 to prevent appending to a changed note') is helpful but parameter-level, not tool-level routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_vaultAIdempotent
Create a new vault (one subdirectory of the vaults root). Idempotent: returns created=False when the vault already exists.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes | Vault name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, so the description's restatement of idempotency adds little. However, it does contribute the concrete return behavior 'returns created=False when the vault already exists', which is valuable given there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight clauses, front-loaded with the action and followed immediately by the idempotency/return behavior. No filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, low-complexity tool with full schema coverage and no output schema, the description covers purpose, idempotency, and the key return signal. It omits any naming/permission constraints, but nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (the 'vault' parameter is documented as 'Vault name'), so the schema already carries the burden. The description's note that a vault is a subdirectory of the vaults root adds minor semantic context but no naming rules or constraints, matching the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a new vault') and grounds it with a definition ('one subdirectory of the vaults root'), so an agent understands what is being created. It does not explicitly contrast with siblings like delete_vault or list_vaults, so it lands at clear-but-undifferentiated.
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 is implied by the name and the word 'new', but there is no explicit when-to-use or when-not-to-use guidance and no mention of alternatives (list_vaults, delete_vault). Implied usage only.
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 file. Errors when missing unless missing_ok=True. Lock files are intentionally left in place.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-root-relative note path | |
| vault | Yes | Vault name | |
| missing_ok | No | Return success when already absent |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds genuinely non-obvious behavior: the default error-on-missing contract and the deliberate decision to leave lock files in place after deletion. It stops short of stating irreversibility or any required permission/confirmation, which for a destructive tool would be the remaining gap.
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, with zero filler. Each sentence carries a distinct and useful fact (action, error contract, side effect).
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 single-target delete with no output schema, the description covers the action, the failure mode, the opt-out flag, and the notable lock-file side effect. It omits confirmation/permission expectations and recovery options, but nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all three parameters. The description nonetheless adds meaning by expressing missing_ok as 'Errors when missing unless missing_ok=True', which makes the tool's default error behavior explicit in a way the schema's 'Return success when already absent' only implies.
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 file'), which cleanly separates it from delete_vault and from non-destructive siblings like write_note or move_note. The agent knows exactly what the call does 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?
Usage is implied by the purpose and the description does give the failure condition ('Errors when missing unless missing_ok=True'), which helps the caller decide how to invoke it. However, there is no explicit when-to-use/when-not guidance or routing to an alternative (e.g. restore, move_note) for a destructive operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_vaultADestructive
Delete a whole vault: removes every note, lock file and the git history. Irreversible with no undo in this server; confirm must exactly equal the vault name.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes | Vault name | |
| confirm | Yes | Must exactly equal the vault name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and non-idempotent, but the description goes further by specifying exactly what is destroyed (notes, lock files, git history) and that the action is irreversible with no in-server undo. That is precisely the extra context annotations cannot carry.
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 compact sentences: destruction scope first, then the irreversible warning and the confirm requirement. Zero filler and the riskiest information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and none is needed for a delete. The description covers destruction scope, reversibility, and the confirmation guard, which is everything an agent needs to invoke this safely.
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 both the vault and confirm parameters, including confirm's exact-match rule. The description repeats the confirm constraint without adding syntax or format detail 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?
States a specific verb (delete), a specific resource (a whole vault), and enumerates the blast radius: every note, lock file, and git history. An agent can distinguish this from the sibling delete_note at a glance.
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?
Clearly frames this as an irreversible last-resort operation with no undo, and states the exact confirm guard required to proceed. It does not explicitly name delete_note or other safer siblings as alternatives, so the when-not guidance is implied rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
historyARead-onlyIdempotent
Show version history for a note (or the whole vault) from the local git repo: [{sha, date, message}] with a truncated flag when more commits exist beyond limit (clamped 1-200). An untracked path returns an empty list with untracked:true.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| limit | No | Max commits (default 50) | |
| vault | Yes | Vault name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the safe read-only, idempotent, non-destructive profile, and the description adds real value beyond them: the return shape [{sha, date, message}], the 'truncated' flag when commits exceed limit, and the untracked-path edge case returning an empty list. Only minor gaps remain (pagination semantics beyond clamping).
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 dense sentence that front-loads the purpose and then layers return format and edge cases. Every clause carries information, though the run-on structure with parentheticals slightly hurts 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?
With no output schema, the description correctly fills that gap by describing the returned list structure and the untracked/truncated edge cases. It is nearly complete for a read-only history tool, missing only richer pagination guidance.
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 67%, with path and limit already documented (including min/max). The description largely restates the schema's vault-vs-note semantics and the 1-200 clamp, adding little param meaning beyond it, though it does reinforce the omission behavior.
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 ('Show') and resource ('version history for a note (or the whole vault)') and names the git source, clearly separating it from siblings like read_note or restore. An agent can tell what it does 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?
It implies when it applies by distinguishing note-level from vault-level history ('or the whole vault', 'omit path'), but it never names an alternative tool or states when not to use it. Usage is inferable rather than explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_notesARead-onlyIdempotent
List directories and notes under a vault path (vault-root-relative, '' for root). Pass recursive=True to list all descendant notes flat (dirs=[]). Paginate with offset/limit (default limit 200, max 500); the response carries total (full match count), truncated, and next_offset (None when done).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Vault-root-relative dir; '' for root | |
| limit | No | Max entries (default 200) | |
| vault | Yes | Vault name | |
| offset | No | Skip this many entries | |
| recursive | No | Flat recursive listing (dirs=[]) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the recursive flattening side effect (dirs=[]), default/pagination bounds (limit 200, max 500), and the shape of the response (total, truncated, next_offset).
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 sentences ordered purpose → recursion behavior → pagination/return fields, with no filler. Every clause carries operational information and the most important scoping detail is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly shoulders the burden of explaining returns (total, truncated, next_offset, dirs on recursion), which is the critical piece for a paginated list tool. It omits result ordering/sort behavior, which matters for offset-based pagination, preventing a 5.
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 ('Vault-root-relative dir', 'Max entries', 'Skip this many entries', 'Flat recursive listing'). The description largely restates these and adds only the interaction between recursive mode and dirs being emptied, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource combination ('List directories and notes under a vault path') with explicit scoping ('vault-root-relative, '' for root'), which clearly separates it from search_notes and list_vaults. It stops short of naming a sibling tool, so an agent must infer the browsing-vs-search distinction from the scope wording alone.
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?
Conditional usage is implied through 'Pass recursive=True to list all descendant notes flat (dirs=[])' and the pagination instructions, which tell the agent how to operate the tool. However, it never states when to prefer this over search_notes (e.g., exact browsing vs. query matching) or when not to use it, leaving tool selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tagsARead-onlyIdempotent
List tag counts per vault from cached frontmatter. Pass vault for one vault, or omit for all vaults.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | No | Vault name; omit for all vaults |
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 genuinely useful context by disclosing the data source is 'cached frontmatter', hinting that results may be derived/stale rather than live. It stops short of describing the returned shape or whether counts reflect cached vs current state.
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 with zero filler; the core behavior is front-loaded and the parameter guidance follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter read-only tool with no output schema, the description covers purpose, scope, and filtering. It could briefly sketch the return shape (tag→count map) since no output schema exists, but 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?
Schema description coverage is 100% and the single parameter is already documented as 'Vault name; omit for all vaults'. The description's 'Pass vault for one vault, or omit for all vaults' restates the schema rather than adding format or naming details. 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?
Specific verb ('List') plus a precise resource ('tag counts per vault'), with the data origin ('cached frontmatter') stated. No sibling tool returns tag data, so it is trivially distinguishable from read_note, list_notes, search_notes, etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly describes the two usage modes: pass a vault for a single vault, omit for all vaults. It does not, however, state when to prefer this over search_notes for tag lookups or any exclusion conditions, so it stops short of full alternative routing.
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 all project vaults with their note counts.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered without the description. The description adds only that note counts are included; it says nothing about ordering, pagination, or scope limits on 'all', and an output schema already covers the return shape.
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 the verb first and the payload detail second. Every word earns its place 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?
With no parameters, full annotation coverage, and an output schema handling return values, the description carries almost no burden and is adequate. It could be marginally better by noting the scope of 'all' (e.g., that it is unimpeded by filters), but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so there is no parameter semantics to explain and the baseline is 4. The description does not need to compensate for any 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 (List) and resource (project vaults) plus the payload detail (note counts), so the agent immediately knows what it returns. It is clearly distinct from list_notes and list_tags by resource, though it never names a sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: a zero-argument listing tool for vaults, so the intent is inferable from the name. However, there is no explicit when-to-use, when-not-to-use, or routing to alternatives such as list_notes when the agent actually wants note-level data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_noteADestructive
Move/rename a note via copy+delete (not atomic): the destination is written atomically, then the source is unlinked, and a partial destination is cleaned up on failure. Errors if src is missing or dst exists. Honors expected_sha256 against src. Refreshes updated:.
| Name | Required | Description | Default |
|---|---|---|---|
| vault | Yes | Vault name | |
| dst_path | Yes | New note path (must not exist) | |
| src_path | Yes | Existing note path | |
| expected_sha256 | No | SHA-256 of src from a prior read; rejects stale moves |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations: disclose non-atomicity, the exact ordering (destination written, then source unlinked), partial-destination cleanup on failure, refusal when src missing or dst exists, and the updated: refresh. These are exactly the behaviors an agent needs for a destructiveHint=true, non-idempotent mutation.
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 dense sentences with the mechanism and precondition front-loaded and zero filler. Every clause — atomicity caveat, ordering, cleanup, error conditions, hash check, metadata refresh — 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 no output schema, the description carries the full burden and does so: success behavior, failure semantics, preconditions, atomicity guarantees, and side effects are all covered, on top of annotations that already flag destructiveness and non-idempotency.
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 adds real semantic value: expected_sha256 is described as being honored against src to reject stale moves, which clarifies concurrency intent beyond the schema's 'rejects stale moves' phrasing. Syntax-level detail of paths is left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (move/rename) plus the resource (a note) and even discloses the mechanism (copy+delete). An agent can immediately distinguish this from write_note, delete_note, or append_note in the sibling list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete preconditions — errors if src is missing or dst exists — which tells the agent when the call will succeed, but never names alternatives (e.g., did you mean write_note + delete_note?) or states when to prefer this over them. Usage is implied rather than guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_noteARead-onlyIdempotent
Read a note: frontmatter, content, wiki-links, backlinks, unresolved links.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-root-relative note path | |
| vault | Yes | Vault name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds real value by disclosing the returned payload (frontmatter, content, wiki-links, backlinks, unresolved links), which is important given there is no output schema; it omits note-size or truncation behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence that front-loads the verb and resource before enumerating outputs. Every clause earns its place, though it reads as a fragment rather than a structured description.
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 with no output schema, enumerating the returned fields is the key missing piece and it is provided. Nothing about error handling or missing-note behavior, but the core is 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?
With 100% schema description coverage for both parameters (path as vault-root-relative note path, vault as vault name), the schema carries the semantics. The description adds nothing about parameter format or edge cases, 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 ('read a note') and enumerates exactly what the read covers: frontmatter, content, wiki-links, backlinks, unresolved links. It does not, however, distinguish itself from siblings like list_notes or search_notes that also surface note content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this versus list_notes, search_notes, or history — the agent must infer usage from the tool name alone. No prerequisites, no exclusions, no alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restoreADestructive
Restore a note's content from a past revision (git rev, e.g. a history sha); the response echoes the revision as restored_from. Snapshots dirty worktree state first; recreates deleted notes. Honors expected_sha256 against current content.
| Name | Required | Description | Default |
|---|---|---|---|
| rev | Yes | Git revision (e.g. a history sha) | |
| path | Yes | Vault-root-relative note path | |
| vault | Yes | Vault name | |
| expected_sha256 | No | SHA-256 of current content; rejects stale restores |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive and non-idempotent, but the description adds real beyond-annotation behavior: it snapshots dirty worktree state before restoring, recreates deleted notes, enforces expected_sha256 as a stale-restore guard, and reports restored_from in the response. These are non-obvious side effects an agent must know before calling.
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 core action, then packs side effects into compact clauses. Dense with semicolons but every clause earns its place; only minor trimming possible.
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 mutation with no output schema, the description covers the safety snapshot, the concurrency guard, deleted-note handling, and the returned restored_from field. 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 description coverage is 100%, so rev, path, vault, and expected_sha256 are already documented. The description restates the git-rev meaning and the expected_sha256 staleness check without adding syntax or format detail beyond the schema, so 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 (restore), resource (a note's content), and source (a past revision / git rev). This cleanly separates it from siblings like history (inspect) and write_note (author new content), so an agent can route to it without opening any 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 clear selecting conditions: it operates on a past revision, and it will recreate deleted notes and snapshot dirty worktree state. However it never names an alternative ('if you only want to view revisions, use history') or states when not to use it, 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_notesARead-onlyIdempotent
Search .md note contents with ripgrep across one vault or all vaults. regex=True uses ripgrep's Rust syntax (Python re when ripgrep is absent), so lookarounds and backreferences are not portable. limit is clamped 1-200 and the response carries a truncated flag; before/after (0-10) add context lines. With context each hit keeps text (= match_line) plus before_lines/match_line/after_lines, otherwise only text.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Context lines after each hit | |
| limit | No | Max matches (default 50) | |
| query | Yes | Search text (or regex with regex=True) | |
| regex | No | Treat query as a regular expression | |
| vault | No | Vault name; omit to search all | |
| before | No | Context lines before each hit | |
| case_sensitive | No | Case-sensitive matching |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/non-destructive, and the description adds substantial behavioral context beyond them: the ripgrep backend with Python re fallback, the regex engine's lack of lookarounds/backreferences, limit clamping and a truncated flag, and the shape of returned hits with and without context. It stops short of full disclosure on error/authorization behavior, hence a 4.
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 core action and scope, then value-dense detail on regex, limits, and output shape. Every sentence carries information, though the result-format sentence is somewhat packed.
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 usefully compensates by describing the returned hit structure (text plus before_lines/match_line/after_lines). Coverage of search semantics, limits, and results is strong, with only minor gaps around error/pagination behavior.
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 the schema lacks: the regex engine semantics for regex=True, the fact that limit is clamped (with a truncated signal), and exactly how before/after alter the result structure. This goes beyond the terse schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Search'), resource ('.md note contents'), mechanism (ripgrep), and scope (one vault or all vaults). This clearly distinguishes it from siblings like list_notes and read_note without needing to name them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The scope note ('one vault or all vaults') and the regex portability warning imply appropriate usage, but the description never states when to choose this tool over read_note or list_notes, nor any prerequisite conditions. Usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
server_infoARead-onlyIdempotent
Report server version, Python/platform, git and ripgrep availability, whether git versioning is enabled, the local vaults root path, and the vault count. This is a local stdio server; the vaults root path is intentionally exposed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false, and destructiveHint=false, so the safety profile is covered. The description adds context annotations cannot: it is a local stdio server and the vaults root path is intentionally exposed, which tells an agent about the trust boundary and privacy expectations.
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, no filler. The enumeration is front-loaded immediately after the verb, and the second sentence adds only the non-obvious local/stdio exposure caveat.
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 parameters and no output schema, the description effectively serves as the return-value contract by listing every reported field, so an agent knows exactly what it will get. Nothing needed to invoke or interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters and the schema is an empty object, so there is nothing for the description to disambiguate. The baseline for a no-parameter tool 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?
Names a specific verb ('Report') plus an explicit enumeration of the resources returned: server version, Python/platform, git/ripgrep availability, git versioning state, vaults root path, and vault count. This clearly distinguishes it from siblings like list_vaults (which enumerates vaults) or read_note (which reads content).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the content: an agent can infer this is for diagnostics/environment introspection before attempting vault operations. However, it never states when to prefer it, nor does it mention siblings (e.g., use list_vaults when you need the vault names rather than a count). Adequate but with a clear gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_noteADestructive
Create or atomically overwrite a note (vault-root-relative path). Pass sha256 from a prior read/write as expected_sha256 to prevent overwriting a changed note. Refreshes the frontmatter updated: date (inserted when a frontmatter block exists without one); notes without a frontmatter block stay that way.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-root-relative note path | |
| vault | Yes | Vault name | |
| content | Yes | Full new note content | |
| expected_sha256 | No | SHA-256 from a prior read/write; rejects stale writes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the safety profile is covered. The description adds genuinely non-redundant behavior: it refreshes the frontmatter `updated:` date and intentionally leaves notes without a frontmatter block untouched, plus the stale-write rejection semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action, followed by concurrency and side-effect details in priority order. 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?
No output schema exists, and the description adequately covers the mutation semantics, concurrency control, and frontmatter side effect. Return value expectations and path validation behavior are the only modest gaps for a destructive write 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 all four parameters are already documented in the schema, including expected_sha256's stale-write purpose. The description restates the sha256 usage but adds no syntax or format detail beyond it, 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 pair ('create or atomically overwrite') and resource ('note'), plus the path convention (vault-root-relative). The 'atomically overwrite' phrasing distinguishes it from the sibling append_note without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent when to pass expected_sha256 (from a prior read/write, to prevent overwriting a changed note), which is actionable usage guidance. It stops short of naming append_note or stating when not to use this tool, so not a 5.
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.
14 tool updates
v0.2.1- First observed
append_note - First observed
create_vault - First observed
delete_note - First observed
delete_vault - First observed
history - First observed
list_notes - First observed
list_tags - First observed
list_vaults - First observed
move_note - First observed
read_note - First observed
restore - First observed
search_notes - First observed
server_info - First observed
write_note
TDQS
Scored across 14 tools
Each tool maps to a distinct operation: read/list per entity, create/delete/move notes, git history/restore, and search/tags. Overlaps like write_note vs append_note are clearly distinguished by overwrite semantics, and list_vaults/list_notes/list_tags target different scopes.
Consistent verb_noun snake_case throughout (read_note, list_vaults, create_vault, delete_note, move_note, list_tags, search_notes). Single-word tools like history, restore, and server_info are intuitive and fit the pattern.
14 tools is well-scoped for a vault/notes server, covering CRUD, navigation, versioning, and search without redundancy. Every tool earns its place.
Full lifecycle coverage: vault create/delete/list, note read/write/append/delete/move/list, git history/restore, tags, search, and server_info. No obvious dead ends for the stated domain.
Maintenance
Related MCP Connectors
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
Google Keep-style notes app with an MCP server for AI agents to read/write notes.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that provides read and write access to an Obsidian vault by interacting directly with markdown files on disk. Supports searching, listing, reading, creating, editing, and appending notes without requiring any Obsidian plugins.1,967 npmISC
- FlicenseCqualityDmaintenanceGit-backed MCP server for creating and maintaining an Obsidian-style markdown knowledge base with full CRUD, search, and git sync.7-
- FlicenseCqualityCmaintenanceMCP server to query and modify an Obsidian vault or any folder of markdown files. It provides search, tag filtering, backlinks, and CRUD operations on notes, with path traversal protection.11-
- AlicenseNot gradedqualityBmaintenanceMCP server for browsing Obsidian-compatible Markdown vaults, searching notes, viewing backlinks and knowledge graphs, and adding selected content to chat context.13 npmMIT