Cursidian
Cursidian is a local MCP server that gives AI agents full read/write access to an Obsidian markdown vault, with structured tools for note management, search, graph navigation, and vault maintenance.
Note Management (note tool)
Read notes by path, title, or frontmatter alias — returns content, frontmatter, outgoing links,
revisionHash, andcontentHashCreate notes with optional frontmatter and overwrite support
Update notes via surgical modes:
patch(find/replace),replace_section(by heading),append,prepend, or fullreplace; supports simultaneous frontmatter updates in one journaled operationDelete (requires
confirm: true) and rename notes with optional backlink/index updatesEdit frontmatter independently via
set,merge, ordeletePass
expectedRevisionto prevent concurrent edit conflicts (optimistic concurrency)
Search & Discovery (search tool)
Full-text search with keyword AND logic, OR fallback, and typo correction
Tag-based filtering, folder listing (optionally recursive), recent notes, and full tag vocabulary with counts
All paginated with cursor-based pagination and compact/full output formats
Graph Navigation (graph tool)
Retrieve a note's one-hop link neighborhood: resolved/unresolved outgoing wikilinks and paginated backlinks
Vault Maintenance (vault tool)
Health check — report of orphaned notes, broken links, index drift, and stale pages
Sync index — regenerate
index.mdfrom frontmatter (supportsdryRun)Slop check / Deslop — detect and auto-fix LLM typography artifacts (em dashes, curly quotes, decorative emoji) in note bodies and frontmatter (journaled, supports
dryRun)Folder operations — create, list, and delete folders
Log — append entries to
log.mdand optionallyhot.mdOperation history & undo — list recent journaled operations and reverse any mutation by
operationIdManifest — read/update the
_meta/manifest.mdingest ledger for tracking ingested sources and projects
Safety & Reliability
Atomic file writes, path containment, optimistic concurrency via
revisionHash, multi-file rollback, and pre-write backups to.cursidian-trashfor easy recovery.
Provides tools for reading, writing, searching, and managing notes in an Obsidian vault, including safe note editing, tag management, and graph neighborhood exploration.
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., "@Cursidiansearch my vault for notes about MCP servers"
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.
Cursidian
Implementation of the Obsidian llm-wiki concept for Cursor, using an MCP designed to minimise token consumption and maximise relevant results. Includes slop removal tools.
Getting Started:
Download Obsidian, create an empty vault, make a note of its location.
Install the "LLM Slop Detector" plugin in your Cursor (thias-se.llm-slop-detector)
Install this MCP and the skills into your Cursor.
Restart / Reload Cursor.
Enter this prompt: "I have just created an empty obsidian vault at vault location, please set up my wiki there"
Let it do its thing, it will take about 5 minutes and burn like 30k tokens. Auto is fine, you don't need Claude for this! At this point you don't even need to be running Obsidian any more, the point of it was just to create the vault structure.
Once it is set up you can just ask Cursor agents for stuff like "create pages in my wiki about my project, as many as you need to capture everything." Or "refactor my ui to be more colourful, using the design notes in my wiki" etc. The sky is the limit. The more effort you ask agents to put into your wiki, the more you get out of it.
And notice the distinction there. the more effort you ask your agents to put in, you don't write this thing yourself. Have the Cursor agents do everything, they write the wiki, they read it, they lint it, check it and maintain it. You can dump entire ebooks into it, or have it review your most recent 100 cursor chat transcripts and save any relevant information it finds to your wiki. Optionally, ask it to "remove all slop from my wiki" once in a while.
You can dip in to read it using Obsidian whenever you like, but really its a resource for Cursor agents to store information about your projects, your goals, your design desisions and rules and so on.
Credits
I took the "Obsidian Wiki" concept from Andrej Karpathy, and I drew inspiration from this existing Obsidian MCP: @istrejo/obsidian-mcp. But really the credit goes to Fable, Grok and Composer 2.5, I am just their conductor, and I used Cursor to create this.
Anyway that's the end of the human-written portion of the readme, the rest is by Agents and for Agents really, but feel free to keep reading if you want.
Emjoy! John.
Related MCP server: Obsidian MCP Server
Features
4 MCP tools -
note,search,graph,vault(action-dispatch surface)Safe writes -
patchinferred whenold_string/new_stringare set;replace_sectionfor heading editsAgent-friendly search - default limit 10, compact format, stopwords stripped, token-AND with OR/typo fallback; hits include
title/summary/tagsAuto timestamps -
notecreate/update/frontmatter setcreated/updatedautomaticallyOptimistic concurrency -
revisionHashon read (full note),expectedRevisionon write;contentHash/expectedHashremain as body-only / deprecated aliasOperation journals + undo - mutating calls return
operationId;vaulthistory/undoreverse journaled workTyped manifest -
vaultmanifestfor_meta/manifest.md(no hand-edited ledger lines)Signature-based caches - index and search snapshots invalidate when files change on disk (including Obsidian edits)
Deslop gate -
npm run buildrunsslop:checkfirst; strips AI typography and decorative emoji from the repo (and optionally the wiki vault)Wiki skills - nine Cursor skills that drive the MCP tools for ingest, query, lint, capture, update, status, and deslop
Skill contract gate -
npm run skills:checkrejects retired tool names, phantom health fields, and read-only write leaks
Tools
Tool | Actions | Purpose |
|
| Note CRUD, safe edits, metadata; returns |
|
| Find and enumerate notes (paginated; may report |
| - | One-hop neighborhood (resolved + unresolved outgoing, paginated backlinks) |
|
| Health, catalog, deslop, folders, bookkeeping, undo, ingest ledger |
Requirements
Node.js >= 20
An absolute Obsidian vault path via
OBSIDIAN_VAULT_PATH
Quick start (published package)
Add to ~/.cursor/mcp.json (Windows: %USERPROFILE%\.cursor\mcp.json):
{
"mcpServers": {
"cursidian": {
"command": "npx",
"args": ["-y", "cursidian"],
"env": {
"OBSIDIAN_VAULT_PATH": "C:\\Users\\you\\Documents\\MyVault"
}
}
}
}Unix:
"OBSIDIAN_VAULT_PATH": "/Users/you/Documents/MyVault"Reload Cursor. The config key "cursidian" appears as MCP server user-cursidian.
See also examples/cursor-mcp.json.
Local development setup
git clone https://github.com/CoolJohn-lab/Cursidian.git
cd Cursidian
npm install
npm run build
npm testPoint Cursor at the built entrypoint:
{
"mcpServers": {
"cursidian": {
"command": "node",
"args": ["/absolute/path/to/Cursidian/dist/index.js"],
"env": {
"OBSIDIAN_VAULT_PATH": "/absolute/path/to/your/vault"
}
}
}
}Wiki skills + MCP
Cursidian is a two-layer product:
Layer | Role | Where |
MCP server | Runtime vault I/O for agents | Published |
Wiki skills | Workflow instructions (ingest, query, lint, ...) |
|
The MCP server is the only way agents read or write vault markdown. Skills do not open vault files with the IDE filesystem tools or shell - they call user-cursidian (note, search, graph, vault). If an MCP call fails, the skill reports the failure and stops (no silent filesystem fallback).
Source documents outside the vault (PDFs, repo files, URLs) may be read with normal tools for ingest; the moment content enters the vault, it is MCP-only.
How agents use both
Cursor loads skills from
~/.cursor/skills/when the user asks something matching a skill description (e.g. "add this to the wiki", "what do I know about X").The skill tells the agent which MCP actions to call, in what order (cheap search first, full
noteread only when needed).Writes follow the safe-write protocol:
noteread->revisionHash-> narrowestnoteupdatewithexpectedRevision. Mutating skills keep an operation-ID stack and callvaultundoin reverse on failure after writes.After multi-page edits, skills typically call
vaultsync_index(rebuildindex.md) andvaultlog(appendlog.md/ optionalhot.md), then verify withsync_indexdryRun: trueexpectingwouldWrite: false.
Shared schema and the full MCP contract live in the llm-wiki skill.
Install skills
npm run skills:install
# or from the published package:
npx cursidian-skillsThat removes then copies the nine skill folders into ~/.cursor/skills/ (never symlink; copying into an existing folder nests skill/skill/SKILL.md). Full steps: skills/wiki/INSTALL.md. Re-run after skill or MCP tool-surface changes, then start a new agent chat so Cursor re-discovers them.
Exception: none for vault writes. wiki-slop uses MCP vault slop_check / deslop for the vault; npm slop:* remains for the repo build gate (and optional human/CI *:wiki CLIs).
Skill | Purpose | Typical MCP use |
| Theory, schema, MCP contract | Reference for other skills |
| Read-only Q&A |
|
| Vault health / consolidate |
|
| Bootstrap vault structure |
|
| Distill docs/URLs into pages |
|
| Save session findings |
|
| Sync a project into the wiki | git delta outside vault; writes via |
| Delta / what next / hot.md |
|
| Deslop repo or vault | Repo: npm |
Deslop (LLM-slop)
Keeps AI typography (em/en dashes, curly quotes, ellipsis, arrows) and decorative emoji out of the package and, when you ask, the Obsidian vault. Uses llm-slop-detector with this repo's .llmsloprc.json. Vault MCP deslop covers bodies and all frontmatter string fields so index drift stays clear. By default MCP skips operational files (index/log/hot/_raw/_archives/_meta); pass includeOperational: true to include them. Human/CI slop:*:wiki still scans the full tree.
Command / tool | Purpose |
| Scan this repo; exit non-zero if dirty |
| Auto-fix chars/emoji in this repo |
| Read-only vault slop report (body + frontmatter; |
| Journaled vault char/emoji fix ( |
| Human/CI CLI vault scan (agents prefer MCP) |
| Human/CI CLI vault fix (agents must use MCP |
|
|
Wiki scans use the same rules but do not gate build (the vault lives outside the package). Phrase-pack hits need a manual rewrite; chars/emoji are auto-fixed. Prefer the wiki-slop skill over ad-hoc CLI flags.
Safe write workflow
Read -
notewithaction: "read"; note therevisionHash(full note) and legacycontentHash(body only).Edit -
notewithaction: "update"using the safest mode for surgical edits (patch,replace_section,append,prepend). For wholesale page rewrites, use a singlereplace. Prefer one combinedupdatethat also passesfrontmatter(merge) so body + metadata share oneoperationId.Pass
expectedRevisionfrom step 1 to detect concurrent edits (including frontmatter-only changes).expectedHashstill works as a deprecated body-hash alias.On success, record
operationIdwhen present and replace any cachedrevisionHashfor that path with the response value. To reverse:vaultundowithoperationIdandconfirm: true.
Same-path edits in one session
Never fire parallel
notemutations for the same path.Pattern:
read-> immediate write with thatrevisionHash-> use the responserevisionHashfor any further write to that path.Prefer combined body +
frontmatteron oneupdateover a body write then a separatefrontmattercall.On
hash_mismatch, preferdetails.currentRevisionfor frontmatter-only / full-replaceretries; re-read when re-deriving apatch/replace_section.
Undo example
{ "action": "history", "limit": 10 }{ "action": "undo", "operationId": "<id-from-mutation>", "confirm": true }Manifest example
{
"action": "manifest",
"manifestOperation": "upsert_source",
"sourceKey": "C:/abs/path/paper.pdf",
"sourceIngested": "2026-07-13T00:00:00Z",
"sourcePages": ["concepts/foo"]
}Security model
Cursidian is a local stdio MCP server. It trusts the Cursor process that launches it and the OS user that owns the vault directory. There is no network attack surface in normal use; hardening focuses on path containment, bounded I/O, and recoverable writes when agents or external editors touch the vault.
Layer | What it guarantees |
Lexical containment | Resolved paths must stay under |
Real-path containment | Symlinks/junctions that resolve outside the vault are rejected before reads and writes. |
Symlink-safe discovery | Vault scans use |
Atomic single-file writes | Creates use exclusive open; updates use same-directory temp + rename under a per-path lock. |
Optimistic concurrency |
|
Multi-file rollback | Rename (including source backup), backlink rewrites, and |
For untrusted agents or shared machines, run with OBSIDIAN_READ_ONLY=true and restrict vault directory ACLs to least privilege.
Backups (.cursidian-trash)
When OBSIDIAN_BACKUP_ENABLED is true (default), each mutating MCP call journals under .cursidian-trash/<operationId>/ (prior snapshots for every affected path, including creates so undo can remove them):
Operation | Journaled |
| Yes |
| Yes |
| Yes |
| Yes (source + each rewritten backlink/index file) |
| Yes |
| Yes ( |
| Yes (each changed note; |
| Yes ( |
| Yes |
Legacy .obsidian-mcp-trash entries are migrated into .cursidian-trash/_legacy-migrated/ on first backup (not deleted). Retention keeps the newest 50 operation folders by default; older folders are pruned automatically. With backups disabled, mutations still succeed but return undoAvailable: false.
Environment variables
Variable | Required | Description |
| Yes | Absolute path to your Obsidian vault ( |
| No | Set to |
| No | Max file size in bytes (default 10 MB) |
| No | Pre-write backups to |
| No |
|
Development
npm run dev # run server directly (stdio)
npm test # vitest with coverage
npm run test:file -- tests/tools/read-note.test.ts # focused test file, no coverage threshold
npm run test:clean # coverage run through npm env cleanup for Cursor sandboxes
npm run lint # eslint
npm run typecheck
npm run build # slop:check (prebuild), then tsc
npm run verify # lint + typecheck + test + build + MCP integration + skills check + fixture smoke
npm run smoke # live smoke against OBSIDIAN_VAULT_PATH (unique path, finally cleanup)
npm run skills:check
npm run mcp:test -- suite smokeIn Cursor agent sandboxes, npm may inherit a deprecated npm_config_devdir value. Use
npm run verify or npm run test:clean so child processes run through the repository's
npm environment cleanup. On Windows PowerShell, prefer these scripts over manual &&
command chains.
Isolated tool calls:
npm run mcp:test -- note --action read --path index
npm run mcp:test -- search --query "wiki index" --limit 10
npm run mcp:test -- --listLicense
MIT - see LICENSE.
Available Tools
4 toolsgraphA
Return a note's link neighborhood: resolved outgoing wikilinks, unresolved outgoing links, plus paginated backlinks (notes linking here). Depth 1 only. Path accepts vault-relative paths, titles, and frontmatter aliases.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-relative path, title, or frontmatter alias of the note | |
| limit | No | Maximum backlinks per page | |
| cursor | No | Pagination cursor from a prior graph response |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description discloses the tool's behavior: it returns both resolved and unresolved outgoing links, paginated backlinks, and depth restriction. It does not mention any destructive actions or permissions, but for a read-only graph tool, the description is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the output components and constraints. Every word adds value; there is no fluff.
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?
Without an output schema, the description could be more detailed about the structure of the returned data (e.g., how links are organized). It mentions the types of links but not the format, leaving some ambiguity for a complex response.
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 adds value by specifying that 'path' accepts vault-relative paths, titles, and frontmatter aliases, which is not fully detailed in the schema. This gives the agent useful flexibility hints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a note's link neighborhood, specifying resolved outgoing wikilinks, unresolved outgoing links, and paginated backlinks. It distinguishes from siblings like 'note' (returns note content) and 'search' (full-text search) by focusing on graph connectivity.
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 mentions depth is limited to 1 and accepted path formats, giving clear constraints. However, it does not explicitly state when to use this tool over siblings, though the purpose is distinct enough that it's implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
noteA
Read, create, update, delete, rename a note, or edit its frontmatter. action=read returns content+frontmatter+contentHash+revisionHash+outgoingLinks. Path accepts vault-relative paths, titles, and frontmatter aliases (except create, which writes the literal path). update: prefer patch (old_string/new_string) or replace_section (heading); replace is size-guarded; optional frontmatter merge on the same update (one journaled op for body + metadata). Pass expectedRevision from read to detect concurrent edits (expectedHash remains a deprecated body-hash alias). Mutations return operationId/undoAvailable when journaling is enabled; use vault undo to reverse.
| Name | Required | Description | Default |
|---|---|---|---|
| keys | No | Used by frontmatter action delete operation only | |
| mode | No | Used by update action only; patch inferred when old_string and new_string are set | |
| path | Yes | Note path, title, or frontmatter alias (rename source when action=rename; create uses literal path) | |
| force | No | Used by update action replace mode only | |
| action | Yes | Operation: read, create, update, delete, rename, or frontmatter | |
| confirm | No | Used by delete action only; must be true | |
| content | No | Used by create and update actions | |
| heading | No | Used by update action replace_section mode only | |
| newPath | No | Used by rename action only | |
| overwrite | No | Used by create action only | |
| new_string | No | Used by update action patch mode only | |
| old_string | No | Used by update action patch mode only | |
| replaceAll | No | Used by frontmatter action set operation only | |
| fmOperation | No | Used by frontmatter action only | |
| frontmatter | No | Used by create, frontmatter set/merge, and update (merge into existing frontmatter in the same journaled op) | |
| updateIndex | No | Used by rename action only | |
| expectedHash | No | Deprecated alias of contentHash from read; used by update, frontmatter, delete, rename, and create with overwrite:true | |
| updateBacklinks | No | Used by rename action only | |
| expectedRevision | No | revisionHash from read; used by update, frontmatter, delete, rename, and create with overwrite:true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully bears the transparency burden. It comprehensively details behavioral traits: what read returns (content, frontmatter, hashes, outgoingLinks), path resolution caveats (except create), update mode specifics (size guard for replace), concurrency detection via expectedRevision, and mutation return values (operationId/undoAvailable). The deprecated expectedHash alias is also noted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then provides necessary details in a logical flow. It is not overly verbose given the complexity (19 parameters, many conditional). However, it could be slightly more structured (e.g., bullet points) for easier scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 19 parameters, no output schema, and nested objects, the description is remarkably complete. It covers all actions, path resolution, update strategies, concurrency, return values, and even deprecated fields. No gaps are evident for an AI agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds significant context beyond the schema, such as the meaning of 'action' values, path resolution rules, preferred update modes, and concurrency usage. This elevates it above baseline but not to a 5 as some parameter-specific details (like max constraints) are already 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?
The description lists specific actions (read, create, update, delete, rename, frontmatter) on the 'note' resource, clearly distinguishing it from sibling tools like graph, search, and vault. The verb+resource combination is explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides detailed usage guidance, such as preferring 'patch' or 'replace_section' for updates, explaining path resolution behavior, and advising to pass 'expectedRevision' for concurrency control. However, it does not explicitly compare to sibling tools or state when not to use this tool, which would elevate it to a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchA
Find notes. action=content (default): full-text search, prefer 2-3 keywords, token-AND with OR fallback and typo correction, format=compact for index-only results. action=by_tags: frontmatter tag filter (AND). action=list: enumerate notes by folder (missing folder -> not_found). action=recent: newest first. action=tags: full tag vocabulary with counts; accepts no other arguments. content/by_tags/list/recent support cursor/truncated/nextCursor (stale cursor -> structured error with details.changedPaths). Responses may set incomplete+skipped when the vault scan could not read every file. list/recent/content exclude index/log/hot/_raw/_archives unless includeOperational=true.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Used by by_tags and content actions | |
| limit | No | Used by content, by_tags, list, and recent actions. Not valid for action=tags | |
| query | No | Used by content action only | |
| action | No | Selects content, by_tags, list, recent, or tags action; defaults to content | content |
| cursor | No | Used by content, by_tags, list, and recent actions. Not valid for action=tags | |
| folder | No | Used by list and recent actions | |
| format | No | Used by content action only | |
| verbose | No | Used by content action only | |
| recursive | No | Used by list action only | |
| caseSensitive | No | Used by content action only | |
| includeOperational | No | Used by content, list, and recent actions |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully bears the burden. It details full-text search behavior (token-AND with OR fallback, typo correction), pagination (cursor/truncated/nextCursor, stale cursor errors), response flags (incomplete, skipped), and folder exclusions (includeOperational). This exceeds typical 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?
The description is efficient and well-organized. It starts with the core purpose ('Find notes.'), then systematically enumerates actions with their specific settings. Every sentence provides distinct information without redundancy, and the format is easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (11 parameters, 5 actions, no output schema), the description is highly complete. It covers behavior, error conditions, and parameter groupings. It lacks a detailed specification of the response structure (e.g., fields in item objects), but the format parameter and mention of 'compact for index-only results' partially compensate. Overall, it is stronger than typical descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so each parameter has a description. However, the tool description adds significant cross-parameter context (e.g., which actions use which parameters), behavioral details (e.g., stale cursor error), and usage constraints (e.g., 'accepts no other arguments' for tags action). This adds value beyond the schema, justifying a score above the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool finds notes and lists multiple distinct actions (content, by_tags, list, recent, tags), each with a specific purpose. It differentiates from sibling tools (graph, note, vault) by focusing on search and enumeration operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance for each action (e.g., 'prefer 2-3 keywords' for content, 'frontmatter tag filter (AND)' for by_tags). It also explains cursor handling and error cases. However, it does not explicitly exclude alternatives among sibling tools, but the context makes it clear that search is for finding notes while graph is for relationships and vault for vault-level operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vaultA
Vault maintenance. action=health: structured report (orphans, broken links, index drift, stale pages). action=sync_index: regenerate index.md from frontmatter. action=slop_check: read-only LLM-slop report (body + frontmatter). action=deslop: journaled char/emoji auto-fix (confirm: true; dryRun preview). action=create_folder/list_folders/delete_folder: folder ops (delete requires confirm, empty folders only). action=log: append to log.md and optionally hot.md (wiki bookkeeping). action=history: list journaled operations. action=undo: reverse a journaled operation (requires confirm: true). action=manifest: typed read/upsert/remove for _meta/manifest.md ingest ledger.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Used by create_folder, list_folders, and delete_folder actions | |
| force | No | Used by undo action only | |
| limit | No | Used by history action only | |
| action | Yes | Selects a vault maintenance action | |
| dryRun | No | Used by sync_index and deslop actions | |
| confirm | No | Used by delete_folder, undo, and deslop actions; must be true | |
| logLine | No | Used by log action only | |
| removeKey | No | Used by manifest remove only | |
| sourceKey | No | Used by manifest upsert_source and remove (source) | |
| staleDays | No | Used by health action only | |
| projectCwd | No | Used by manifest upsert_project only | |
| removeKind | No | Used by manifest remove only | |
| hotActivity | No | Used by log action only | |
| operationId | No | Used by undo action only | |
| projectName | No | Used by manifest upsert_project and remove (project) | |
| sourceMtime | No | Used by manifest upsert_source only | |
| sourcePages | No | Used by manifest upsert_source only | |
| projectSynced | No | Used by manifest upsert_project only | |
| sourceIngested | No | Used by manifest upsert_source only | |
| expectedHotHash | No | Used by log action only | |
| expectedLogHash | No | Used by log action only | |
| expectedRevision | No | Used by manifest mutations only | |
| manifestOperation | No | Used by manifest action only | |
| projectLastCommit | No | Used by manifest upsert_project only |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must fully disclose behaviors. It notes that slop_check is read-only, deslop is journaled with confirmation, and delete_folder requires confirm and empty folders. However, it doesn't consistently label actions as read-only or write (e.g., sync_index, undo are mutating but not flagged), and side effects like index regeneration are implied rather than explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph that front-loads 'Vault maintenance' but quickly becomes a list of actions without visual separation. While information-dense, it could be more readable with bullet points or sections. Each sentence earns its place, but structure is suboptimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 24 parameters and no output schema, the description covers action semantics, parameter usage, and key constraints for each action. It explains what each action does (e.g., 'regenerate index.md from frontmatter') and which parameters apply. Missing details include the structure of the health report and exact output of manifest read, but overall it's comprehensive for a complex 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?
Parameter descriptions in the schema achieve 100% coverage. The description adds value by mapping parameters to specific actions (e.g., 'Used by create_folder, list_folders, and delete_folder actions') and imposing additional constraints (e.g., 'confirm must be true'). This extra context helps agents correctly select and combine parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Vault maintenance' and enumerates 11 specific actions with brief explanations, providing a clear overview of the tool's purpose. It distinguishes from sibling tools (graph, note, search) as a maintenance utility, though the high-level purpose is fragmented across actions.
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 implicitly guides usage by listing available actions and their constraints (e.g., 'delete requires confirm, empty folders only'), but it lacks explicit statements about when to use this tool versus siblings or alternative approaches. The context is clear enough for an agent to infer appropriate use cases.
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.
4 tool updates
v2.11.4- First observed
graph - First observed
note - First observed
search - First observed
vault
TDQS
Scored across 4 tools
Each tool has a distinct domain: graph handles link relationships, note manages note CRUD, search provides various search/list functions, and vault performs maintenance and operational tasks. No overlap in purpose.
All four tool names are single lowercase nouns (graph, note, search, vault), following a consistent and predictable pattern.
4 tools is well-scoped for a note-taking vault server, covering core operations without unnecessary bloat.
The tool set covers essential CRUD, search, graph, and maintenance operations. Minor gaps include lack of export/import or batch operations, but the core workflows are adequately supported.
Maintenance
Related MCP Connectors
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
Open-source Obsidian for MDX - edit local docs with agent assistance
Securely search and manage workspace context files for AI agents and teams.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI agents to explore, search, and manage local Obsidian vault documents with tools for document search, automatic frontmatter property generation, and attachment organization.520 npm2ISC
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Obsidian vaults through direct filesystem access, supporting note management, lightning-fast search with SQLite indexing, image analysis, tag/link management, and bulk operations.MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to interact with local Obsidian vaults through direct filesystem access for reading, creating, and managing notes. It features high-performance SQLite indexing for fast searches, regex support, and tools for organizing tags and links without requiring additional plugins.271MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to manage Obsidian vaults through full CRUD operations, wikilink management, and section-level manipulation. It supports frontmatter editing, tag-based searching, and automated link updates to maintain vault integrity.MIT