second-brain-mcp
Provides tools to read, search, write, and manage notes in an Obsidian vault, including capturing thoughts with appropriate frontmatter and managing tasks in Tasks.md.
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., "@second-brain-mcpCapture a thought: schedule dentist appointment"
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.
second-brain-mcp
An MCP server that exposes an Obsidian vault to Claude — read, search, and write notes, capture
voice thoughts into the right folder with the right frontmatter, and manage Tasks.md.
Built so the vault's filing rules live in code rather than in a prompt that can be forgotten.
Status
Phase | State |
1. Local, stdio, five primitives | Done, 119 tests |
2. HTTP transport + bearer auth | Done, verified locally |
2b. Container image | Written but never built — no Docker daemon on the dev machine |
3. Expose via DDNS + reverse proxy | Not started — needs NAS access, see Deployment |
4. Semantic tools | Done |
Related MCP server: Vault MCP Server
Quick start
Requires uv. Python comes from uv; the system python3 is too old.
uv sync
# Point at a COPY of your vault first. Never the real one until you trust it.
rsync -a ~/Library/CloudStorage/SynologyDrive-Mergoth/Notes/PersonalObsidian/ /tmp/vault-copy/
VAULT_PATH=/tmp/vault-copy uv run python -m second_brain_mcpThat starts the stdio server. It will refuse to start without VAULT_PATH — there is no default,
deliberately, because a default is how a test run reaches the real vault.
Connect it to Claude Desktop
{
"mcpServers": {
"second-brain": {
"command": "uv",
"args": ["run", "--directory", "/Users/vladislav/work/second-brain-mcp",
"python", "-m", "second_brain_mcp"],
"env": { "VAULT_PATH": "/Users/vladislav/work/vault-sandbox/PersonalObsidian" }
}
}
}HTTP transport
VAULT_PATH=/tmp/vault-copy MCP_AUTH_TOKEN=$(openssl rand -hex 32) \
uv run python -m second_brain_mcp --transport httpServes on 127.0.0.1:8000, MCP endpoint at /mcp. Every request needs
Authorization: Bearer <token>; unauthenticated requests get a 401 with a WWW-Authenticate
header pointing at /.well-known/oauth-protected-resource (RFC 9728).
Configuration
All configuration is environment variables. None have defaults.
Variable | Required for | Notes |
| always | Absolute path to the vault root. Resolved and frozen at startup; never re-read. |
|
| Static bearer token. Compared with |
Tools
Primitives — no vault knowledge
Tool | Signature |
|
|
|
|
|
|
|
|
|
|
Semantic — encodes the vault's rules
Tool | Signature |
|
|
|
|
|
|
|
|
|
|
add_task requires an explicit section and raises listing the available ones if it doesn't
match. It does not guess and has no default section. This is deliberate: the vault's own
CLAUDE.md says "Sections are a view, not a taxonomy. Re-sort when reality moves", so any
hardcoded section table would silently misfile tasks the next time you reorganise. Call
list_task_sections() first.
add_task never invents a date or priority, and reports back any marker it added that you did not
state.
capture_thought rejects a domain outside the closed list (work finance legal health
trips home plants smart-home projects learning) rather than inventing one.
Security model
The server is a plain local-filesystem server. Its one real control is path confinement.
Every caller-supplied path becomes a real path in exactly one function,
vault/paths.py::resolve(). Nothing else in the package opens a file by a caller-supplied path.The vault root is resolved once at startup and frozen. It is not a tool argument and cannot be changed at runtime.
resolve()takes one parameter. There is no bypass flag, no per-call root, no trusted-path list, no follow-symlinks toggle.Containment is checked by path ancestry, never string prefix — with root
/vault, the sibling/vault-evilmust not pass.Rejected:
.., absolute paths, null bytes, empty paths, and symlinks that resolve outside the root even when the link itself lives inside the vault.Glob patterns and search scopes are validated too, and the search query goes to
rgafter-eso it can never be parsed as a flag.
That last point is not theoretical. An early build appended the caller's query to rg as a bare
positional argument, so a query of --pre=<script> executed arbitrary commands — with a
model-controlled argument, which is exactly the prompt-injection threat the design exists to stop.
See factory/adr/0002-single-path-resolution-chokepoint.md.
No hard delete anywhere. Archiving is move_note into raw/archive/.
Every mutation appends a line to meta/audit.log (machine-readable, append-only). That is
deliberately a different file from meta/log.md, which stays human-curated so an unexplained line
in it is still a usable tripwire.
Development
uv run --frozen pytest -q # 119 tests
uv run ruff check .Tests run against a synthetic fixture vault copied into tmp_path. An autouse guard fails the
session if the resolved vault root is not under tmp_path, so the suite cannot reach a real vault.
Design documents:
factory/briefs/vault-mcp-server.md— why it is built this way, and what was rejectedfactory/adr/— binding architecture decisionsspecs/— what each increment buildsdocs/initial_spec.md— the original design record
Deployment
Phase 3 is not done. What remains is NAS and browser work, not code:
Fix the advertised metadata URLs first — this is a blocker, not a nicety.
__main__.pycallsbuild_auth_settings()with no arguments, so it advertises the defaultsresource_url="http://127.0.0.1:8000"andissuer_url="https://auth.example.com". Behind a reverse proxy those are wrong: a remote client is told the resource lives on loopback. Make both read from the environment (e.g.MCP_RESOURCE_URL,MCP_ISSUER_URL) before exposing anything.Build the container.
deploy/Dockerfileanddeploy/compose.yamlare written — non-root user, read-only rootfs,ripgrepinstalled, port bound to127.0.0.1— but have never been built or run.Resolve container UID vs. vault file ownership.
Tasks.mdandmeta/log.mdare mode600on the real vault, so a non-root container with a mismatched UID getsEACCESon exactly the two highest-value writes while reads ofraw/keep working — a partial failure that looks like a tool bug.DSM reverse proxy, Let's Encrypt cert, rate limit, auto-block on failed auth. Never publish the container port directly.
Register as a custom connector and test from Android.
On auth
docs/initial_spec.md assumed custom connectors require OAuth 2.1 with dynamic client
registration. That is out of date: DCR is deprecated in the current MCP spec (Client ID
Metadata Documents replace it), and static bearer tokens are first-class on Anthropic's MCP client
surfaces. So this ships a static bearer.
The honest caveat: that is evidence about Anthropic's API surfaces. Whether the claude.ai
custom connector UI accepts a static bearer is a product question that needs a live test. If it
turns out to demand OAuth, auth.py is the only module that changes — transport and auth are
confined to the entrypoint by factory/adr/0003.
Known limitations
The container image is unbuilt and unverified.
RFC 9728 metadata URLs are hardcoded defaults (see Deployment step 1).
list_notes(since)filters on filesystem mtime, which on a Synology-synced folder is sync time, not edit time. The vault'sCLAUDE.mdsayscreated:in frontmatter is the real recency anchor.No end-to-end test drives a JSON-RPC tool call over HTTP; tools are covered over stdio and via direct calls.
propose_wiki_pagefrom the original spec is deliberately not built — its arguments were never specified and it serves deep work at the desk, where nothing is blocked.Synology sync conflicts are not handled. Writes are atomic (temp file +
os.replace), but there is no merge logic. The original spec cited conflict files as evidence this was urgent; there are none inPersonalObsidian/, so the risk is real but unproven and was not paid for.
Available Tools
10 toolsadd_taskC
Add a task under an existing section in Tasks.md. section is matched case-insensitively against live headers.
| Name | Required | Description | Default |
|---|---|---|---|
| due | No | ||
| link | No | ||
| text | Yes | ||
| section | Yes | ||
| priority | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does disclose one real trait — section matching is case-insensitive against live headers — but says nothing about what happens if the section does not exist, where the task is inserted within the section, or whether the write is additive/reversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no filler, with the matching rule front-loaded immediately after the core action. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, but for a 5-parameter mutation tool with zero annotation coverage and 0% schema coverage, the description leaves failure modes, insertion position, and four parameters entirely undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 5 parameters, and the description only touches 'section' (case-insensitive matching). The required 'text' and the optional due, link, and priority fields get no explanation of format or expected values anywhere.
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 ('Add a task') and names the target file and container ('under an existing section in Tasks.md'). It is clear enough to distinguish from get_tasks and list_task_sections, but it does not explicitly position itself against sibling write tools like append_log or capture_thought.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by requiring an existing section, but never states when to reach for add_task versus append_log, capture_thought, or write_note. No prerequisites or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
append_logC
Append an entry to human meta/log.md.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. 'Append' implies a mutation, but it says nothing about whether the log file is created if absent, whether entries are timestamped, or what permissions are needed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no waste. It is efficiently sized, though its brevity borders on under-specification given the disclosure burden.
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?
An output schema exists, so return values need not be explained. For a one-parameter append tool the description is minimally adequate, but with no annotations it should say more about file creation and entry format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single 'line' parameter has 0% schema description coverage, so the description must compensate but does not. It implies the argument is the log entry text, but gives no format, length, or content guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (append) and target resource (an entry in human meta/log.md), so an agent can tell what it does. It does not, however, distinguish itself from the sibling write_note, which could also add 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 when-to-use guidance, no prerequisites, and no mention of alternatives such as write_note. The agent must infer that this is for logging rather than note authoring.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capture_thoughtC
Capture a raw thought into raw/thoughts/ with frontmatter and tags.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| domain | No | ||
| source | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose useful behavior: content lands in raw/thoughts/ and is wrapped with frontmatter and tags. However, it says nothing about overwrite/duplicate handling, whether a new file is always created, or what source/domain affect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the key destination front-loaded and no filler. It is efficient, though the brevity contributes to the coverage gaps noted elsewhere.
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?
An output schema exists, so return values need not be explained, but with zero schema coverage and no annotations the description should clarify the required source and optional domain parameters. It leaves an agent guessing about the most important invocation details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description names none of the three parameters (text, source, domain). 'frontmatter and tags' alludes to metadata handling but does not explain what source or domain mean or how tags are derived, so it fails to compensate for the undocumented 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 (capture) and resource (raw thought) plus the destination path raw/thoughts/, which implicitly separates it from write_note's general note writing. It does not explicitly name a sibling or contrast with write_note, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus write_note, which is the obvious alternative for persisting text in the vault. The destination folder hints at a 'quick capture' workflow but no condition, prerequisite, or exclusion is stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tasksC
Get structured tasks parsed from Tasks.md with overdue flags.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full behavioral burden. It does add useful context (data is parsed from Tasks.md, results carry overdue flags), but never states that this is a read-only operation, how parsing failures are surfaced, or how the optional filter affects 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 front-loaded sentence with no filler; the source and the overdue-flag behavior come first. Efficient, though the terseness is partly what leaves the filter unexplained.
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?
An output schema exists, so return values need not be described, and for a simple one-param read tool the description is close to adequate. It falls short because the only parameter is undocumented and the parsing/read semantics of the Tasks.md source are unstated.
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?
One parameter ('filter') with 0% schema description coverage and no mention anywhere in the description. The agent cannot tell whether filter accepts a status, a date, a section name, or free text, which is a real gap for a tool whose sole knob is this filter.
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 (Get) and resource (structured tasks) plus the source (Tasks.md) and a derived field (overdue flags). It distinguishes itself from add_task, list_task_sections, and the note-oriented siblings. Not a 5 only because 'structured tasks' is slightly vague about output shape, though the output schema covers that.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance and no alternatives named. It does not say how this differs from list_task_sections or when a caller should prefer this over that sibling, leaving the agent to infer routing from names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_notesB
List notes matching a glob pattern. Returns paths and mtimes only, no bodies. Excludes dotfiles and dotdirs.
| Name | Required | Description | Default |
|---|---|---|---|
| glob | No | **/*.md | |
| since | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden, and it does add real value: it discloses the return shape ('paths and mtimes only, no bodies') and a filtering rule (excludes dotfiles/dotdirs). It says nothing about ordering, limits, or pagination, so it's useful but incomplete for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero waste, front-loading the operation and immediately qualifying the return contents and the exclusion rule.
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?
An output schema exists, so return-value documentation is arguably redundant, yet 'since' is left wholly undescribed in both schema and description. Adequate for a simple read-only listing but with a real gap in filter semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, but it only implicitly covers 'glob' and never explains 'since' (presumably an mtime cutoff) despite it being a nullable number with a default of null. Half the parameters remain uninterpretable from the description alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List notes') plus the matching mechanism ('glob pattern'), which is enough to distinguish it from read_note/write_note/move_note. It doesn't explicitly name an alternative such as search_vault, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no exclusion of overlapping siblings (search_vault could plausibly return notes too), and no indication of when the 'since' filter should be used. The glob mention implies usage but says nothing about context or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_task_sectionsB
List current section headers (##) in Tasks.md live from the file.
| 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?
With no annotations, the description carries the full burden, but 'live from the file' usefully signals it reads the current on-disk state rather than a cache. It does not mention behavior when Tasks.md is missing, is empty, or has no ## sections.
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?
One tight sentence with the scope and source front-loaded and no filler. It is perhaps a touch terse, but nothing is wasted.
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?
An output schema exists so return structure is covered, and there are no parameters to explain. However, edge cases like a missing or unreadable Tasks.md file, and whether headers are returned with or without the '##' prefix, are unaddressed.
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?
Zero parameters, so there is nothing to document and the baseline is 4. The description correctly implies no inputs are needed.
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 (section headers in Tasks.md), so an agent knows it retrieves section headings rather than notes. It is distinguishable from note-oriented siblings, though it does not explicitly name an alternative tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus get_tasks, list_notes, or read_note. The agent must infer the use case from the resource name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_noteC
Move a note from one path to another. Both paths are relative to vault root.
| Name | Required | Description | Default |
|---|---|---|---|
| to_path | Yes | ||
| from_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that paths resolve against the vault root, but is silent on the critical mutation questions: what happens if to_path already exists (overwrite, error, or merge), whether intermediate folders are created, and whether the source is deleted or copied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the core action front-loaded and the path-resolution caveat immediately after. Nothing redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, but this is a destructive-style mutation tool with no annotations and no description of collision or failure behavior. For a move/overwrite-capable operation, that is a significant omission an agent could get wrong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does partially by establishing that both paths are vault-relative rather than absolute. However, it adds nothing about path format (extensions, folder separators), or validity constraints for either path, leaving meaningful gaps for both 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?
States a specific verb and resource ('Move a note') and names both endpoints of the operation, so it is clearly distinguishable from read_note, write_note, and list_notes in the sibling set. It stops short of explicitly contrasting itself with those siblings, but the verb 'move' carries the meaning on its own.
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 guidance on when to choose this tool over write_note (e.g., rename vs. content change) or any precondition such as the source note needing to exist. The agent is left to infer the use case entirely from the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_noteB
Read the full content of a note at the given relative path.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It says only that the note content is read in full; it does not disclose whether this is read-only, whether any permissions are needed, whether missing paths error, or any other behavioral trait. The verb 'Read' implies no mutation, but no explicit context is added.
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 sentence with zero filler. The essential operation and its scope are front-loaded and immediately clear.
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?
The tool is simple (one parameter) and has an output schema, so return values need not be explained. However, the lack of usage guidance and the thin parameter semantics leave gaps for an agent choosing between this and sibling retrieval tools. The description is minimally adequate but not rich.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds that the path is relative and points to a note, which is useful beyond the schema's bare 'Path' title. It does not give format examples or clarify path syntax, but the added meaning is enough for a minimal 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 states a specific verb and resource: 'Read the full content of a note.' It clearly implies a single-note retrieval operation, distinguishing it from list_notes and search_vault. However, it does not explicitly name any sibling tool or state when this is preferred over alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no when-to-use guidance, no prerequisites, and no alternatives. An agent must infer from the verb 'Read' that this is for retrieving a known note, but nothing routes it between read_note, list_notes, or search_vault.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_vaultB
Search the vault using ripgrep. Returns matching lines with file paths.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| scope | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. Disclosing 'using ripgrep' implies regex/case-sensitive line-based matching and 'returns matching lines with file paths' describes output shape, but it omits auth requirements, result limits, and whether the search is read-only in practice.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the core action front-loaded and the return format trailing it. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no elaboration, and the ripgrep mention covers the search mechanic. However, the fully undocumented 'scope' parameter and absent usage routing leave gaps for a tool with a sibling that also lists notes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description explains neither parameter. 'query' is self-evident from its name, but 'scope' is an undocumented optional string with a null default, leaving the agent unable to tell what values it accepts or what it constrains.
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 ('Search the vault') plus the underlying mechanism (ripgrep) and the return shape. This clearly separates it from read/list/move siblings, though it never names an alternative directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when this tool is preferred over list_notes or read_note, nor any exclusions or prerequisites. The agent must infer that this is for pattern matching rather than enumerating or fetching files.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_noteC
Write content to a note. mode: 'create' | 'overwrite' | 'append'.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | ||
| path | Yes | ||
| content | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not disclose that 'overwrite' destroys existing content, that 'create' may fail on an existing path, or whether any permissions are required — the most safety-relevant facts for a write tool are absent.
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 terse sentences with the core action front-loaded and the mode list appended. Efficient, though the mode list is under-explained rather than over-long.
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?
An output schema exists, so return values need not be described, but for a three-parameter write tool with no annotations the description omits the semantics of the destructive modes and the meaning of path/content. Not enough for an agent to call 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 coverage is 0%, so the description must compensate. It adds the three legal mode values (genuinely useful, since the schema has no enum), but says nothing about 'path' or 'content' format, and the mode values are listed without explaining their 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 ('write') and resource ('a note'), and the mode enumeration signals the write variants. It is distinguishable from read_note/list_notes/move_note by the verb alone, but it never explicitly contrasts itself with siblings that also mutate notes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to choose create vs overwrite vs append, or what happens if the target already exists or does not exist. The agent must guess which mode is appropriate for its situation.
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.
10 tool updates
v0.1.0- First observed
add_task - First observed
append_log - First observed
capture_thought - First observed
get_tasks - First observed
list_notes - First observed
list_task_sections - First observed
move_note - First observed
read_note - First observed
search_vault - First observed
write_note
TDQS
Scored across 10 tools
Tools are largely distinct: note operations (list/read/write/move), search, task management, and logging each have clear purposes. However, write_note overlaps with capture_thought and append_log (all write operations), and list_notes vs search_vault both retrieve note information, requiring careful reading to choose correctly.
All tool names follow a consistent verb_noun snake_case pattern (list_notes, read_note, write_note, search_vault, move_note, capture_thought, list_task_sections, add_task, get_tasks, append_log). Minor singular/plural variation (note vs notes) exists but the pattern is predictable and readable.
10 tools is well-scoped for a personal knowledge management server. Each tool covers a distinct function within note handling, search, task management, or logging, with no redundant tools and sufficient breadth for the domain.
Missing delete_note and update_note (write_note can overwrite but no delete), and task management lacks complete/update/delete task operations. No way to create a new task section either. These gaps will force agents to fall back to generic write_note for editing Tasks.md, which is error-prone.
Maintenance
Related MCP Connectors
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
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.
Google Keep-style notes app with an MCP server for AI agents to read/write notes.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA local MCP server that enables AI applications like Claude Desktop to securely access and work with Obsidian vaults, providing capabilities for reading notes, executing templates, and performing semantic searches.831MIT
- FlicenseNot gradedqualityCmaintenanceBuilt on Obsidian Vault, this MCP server integrates with Claude Code to provide personal knowledge management including note saving, full-text search, code graph extraction, and context resumption.1-
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives Claude AI direct access to your Obsidian vault, enabling natural language search, note creation, file management, and automated workflows.3,893 npm10MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that provides full read/write access to an Obsidian vault, enabling searching, task management, wiki-link graph analysis, and attachment organization from an MCP client like Claude Code.-