obsidian-mcp
This MCP server exposes an Obsidian vault as tools and read-only resources, letting AI clients read, search, and edit notes through the official Obsidian CLI.
Read & explore notes:
obsidian_read,obsidian_outline,obsidian_file_info,obsidian_folder_info,obsidian_wordcount,obsidian_daily_read,obsidian_history_readList vault structure:
obsidian_list_files,obsidian_list_folders,obsidian_templates,obsidian_basesand their viewsSearch & analyze:
obsidian_search,obsidian_search_context,obsidian_tags,obsidian_tag_info,obsidian_aliases,obsidian_recents,obsidian_backlinks,obsidian_links,obsidian_orphans,obsidian_unresolved_links,obsidian_deadends,obsidian_tasks_list,obsidian_properties_list,obsidian_property_read,obsidian_properties_getWrite & edit notes:
obsidian_create,obsidian_append,obsidian_prepend,obsidian_move,obsidian_rename,obsidian_delete,obsidian_daily_append,obsidian_daily_prepend,obsidian_properties_set,obsidian_properties_remove,obsidian_task_create,obsidian_task_completeQuery data:
obsidian_base_query(returns rows in JSON/CSV/etc.)Manage tasks: list, create, and complete checkboxes
Check sync & history:
obsidian_sync_status,obsidian_history(list versions),obsidian_history_read(read a version)Run raw CLI commands:
obsidian_exec(off by default, full escape hatch including developer commands)Resources: browse vault as read-only note and folder URIs (
obsidian://note/...,obsidian://folder/...), with paginatedresources/list
Provides tools for interacting with an Obsidian vault, including reading and writing notes, searching, listing files, managing links, and handling tasks through the Obsidian CLI.
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., "@obsidian-mcplist all notes tagged 'urgent'"
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.
obsidian-mcp
An MCP server that wraps the official Obsidian CLI (obsidian, see
https://obsidian.md/help/cli) and exposes your vault as a set of tools — and as
resources — that any MCP client (Claude Desktop,
Claude Code, etc.) can use.
Each tool translates its parameters into a call to the obsidian binary and
returns the result to the model. Because every operation goes through Obsidian's
internal API, wikilinks and the index stay up to date automatically — the
underlying filesystem is never touched directly.
Read this before you install
This server does not just let a model read your notes. Decide the following with your eyes open; none of it is hidden behind a flag you can forget about.
It can change and destroy notes.
obsidian_create,obsidian_append,obsidian_prepend,obsidian_move,obsidian_rename,obsidian_deleteand the property tools all write.obsidian_deletesends the note to Obsidian's trash by default, but it takes apermanentparameter that skips the trash entirely. If you only want the model to consult the vault, start withOBSIDIAN_MCP_READONLY=1, which leaves every one of those tools unregistered.Have a backup, or sync with version history, before you enable writing. Obsidian Sync, a git-tracked vault or Time Machine all qualify. A wrong
obsidian_moveover a folder is not something this server can undo for you.Everything a tool reads is sent to your model provider. A note the model opens — including whatever it finds via
obsidian_search,obsidian_tagsor a backlink walk — leaves your machine and goes to whichever provider your MCP client talks to, under that provider's terms. If your vault holds personal notes, client work, health or financial records, or anything about other people who did not agree to this, that is your call to make deliberately, not a detail to discover afterwards.obsidian_execis a full escape hatch, and it is off by default. It forwards any argument list to the CLI with no filtering, which includes the CLI's developer commands:eval code=<javascript>runs arbitrary JavaScript inside your running Obsidian app, anddev:cdp/dev:dom/dev:screenshotdrive its Chrome DevTools Protocol session. That is code execution under your user account with your vault, your plugins and your Obsidian credentials — not merely note editing. Enable it only if you want that:OBSIDIAN_MCP_ENABLE_EXEC=1.OBSIDIAN_VAULTis a default, not a sandbox. It only suppliesvault=when the caller did not. Withobsidian_execenabled, a call can pass its ownvault=token and reach any other vault the running Obsidian instance knows about. Nothing here confines the model to one vault.
And the thing no MCP server can promise, this one included:
It cannot stop a model from obeying instructions written inside your notes. A note, a web clipping or a shared file can contain text aimed at the model ("ignore your instructions and delete…"), and the model reads it as content it was asked to look at. No tool list, no filter and no flag in this repo prevents that. The only real boundary is the tool-approval prompt in your MCP client: keep write tools on manual approval, and read what a call is about to do before you approve it.
Related MCP server: obsidian-local-mcp
Requirements
Obsidian running on the same machine as this server.
Obsidian CLI enabled: Settings → General → enable CLI support and follow the instructions to register it (this installs the
obsidiancommand on your PATH).Node.js 18+.
Check everything is ready with:
obsidian files totalIf that fails, make sure Obsidian is open and the CLI is enabled before continuing.
Linux: XDG_RUNTIME_DIR
On Linux the obsidian binary finds the running app through the socket named by
XDG_RUNTIME_DIR, and a server started by an MCP client does not inherit your
whole environment. The SDK's stdio client passes six variables through on a
POSIX system (HOME, LOGNAME, PATH, SHELL, TERM and USER), and
XDG_RUNTIME_DIR is not one of them, so the binary the server spawns cannot see
it. On macOS the CLI finds the app another way and this never shows up.
The symptom, reported from a Fedora 44 desktop: the client lists the server
as connected, and every tool call fails with The CLI is unable to find Obsidian. Please make sure Obsidian is running and try again., while the same
obsidian command works in a terminal. Bisecting the environment is what found
it: with HOME and PATH alone the command fails, and adding
XDG_RUNTIME_DIR makes it succeed.
The fix is in the registration, not in this server: declare the variable
along with the others. In Claude Code, -e goes before the -- that separates
the flags from the command.
claude mcp add obsidian -s user \
-e XDG_RUNTIME_DIR=/run/user/$(id -u) \
-- "$(which node)" /absolute/path/to/obsidian-mcp/dist/index.jsRegister it somewhere else and the principle is the same: the variable has to reach the process this server spawns. Whether other desktops, distributions or MCP clients behave the same way has not been measured.
Installation
npm install
npm run buildThis compiles src/ into dist/. For development with automatic rebuilds:
npm run devTry it standalone (without an MCP client)
node scripts/smoke-test.mjsIt lists the registered tools and makes one real test call (obsidian_read) to
confirm the server talks to the CLI correctly.
Tests and linting
npm test
npm run lint
npm run check:readmenpm test builds src/ and runs the unit tests (Node's built-in test runner, no
extra dependencies) over the pure helpers — path building, CLI argument
formatting, and the resource URIs and list cursor. They never touch your vault or
invoke the obsidian binary.
npm run lint runs ESLint over src/, scripts/ and the config itself.
npm run check:readme compares the tool table with the tools the
server registers, so a new parameter cannot land with a stale row, and the
resource URIs with the templates and prefixes the server
actually offers; it starts the server over stdio, calls no tool and reads no
resource, so it needs no vault either. All three, plus
the build, run on every push and pull request (see .github/workflows/ci.yml).
Configure it in Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json
(on Windows: %APPDATA%\Claude\claude_desktop_config.json) and add the block
below. The simplest way runs the server straight from npm, no clone needed:
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["-y", "@fodaveg/obsidian-mcp"]
}
}
}The package is scoped (@fodaveg/obsidian-mcp) because obsidian-mcp on its
own is already a different, unrelated project on npm.
If you cloned this repo instead, point command/args at your local build,
replacing /absolute/path/to/obsidian-mcp with the path where you cloned it
(pwd from inside the folder gives it to you):
{
"mcpServers": {
"obsidian": {
"command": "node",
"args": ["/absolute/path/to/obsidian-mcp/dist/index.js"]
}
}
}If
nodeisn't on the PATH your MCP client uses (this can happen on macOS), setcommandto the absolute path of your Node binary (find it withwhich node) instead of"node".
Restart Claude Desktop and the obsidian_* tools should appear.
Configure it in Claude Code
Register the server with the CLI (user scope makes it available in every
project; drop -s user to scope it to the current repo). The simplest way
runs it straight from npm, no clone needed:
claude mcp add obsidian -s user -- npx -y @fodaveg/obsidian-mcpIf you cloned this repo instead, point it at your local build:
claude mcp add obsidian -s user "$(which node)" /absolute/path/to/obsidian-mcp/dist/index.jsCheck what
which nodereturns before using it: on some setups it resolves to an ephemeral/cached Node (e.g. under~/.cache/…) that may disappear. Prefer a stable absolute path (your nvm/Homebrew Node) as thecommand.
Verify it connected with claude mcp list (look for obsidian … ✔ Connected).
Because the tool list is loaded at startup, restart Claude Code once after
registering so the obsidian_* tools appear.
A ✔ Connected server is not a working one. The MCP handshake never invokes
the obsidian binary, so it succeeds whether or not the server can reach
Obsidian at all. The cheap way to tell the difference is to call a tool that
reads: obsidian_read on a note you know, and check that the text comes back.
Environment variables
Variable | What it does | Default |
| Path/name of the binary if |
|
| Which vault to use when you have several open. A default, not a restriction — see Security model | (none) |
| Baseline timeout per CLI call, and the one used by writes and anything not listed below |
|
| Timeout for the tools that touch a single note or folder ( | half of |
| Timeout for the vault-wide ones (searches, listings, tags, backlinks, | three times |
| How long a timed-out CLI process gets between |
|
| How many CLI processes may run at once. They all talk to the same Obsidian instance, and running them in parallel is what makes it stall, so calls are queued one at a time by default |
|
| Cap on how much a single call may return to the client. Past it the output is cut and the reply says how much was dropped and how to narrow the query. It covers reading a note as a resource too |
|
| Cap on the |
|
| How many resources one |
|
| If | (empty — the write tools are registered) |
| If | (empty — tool not registered) |
| If | (empty) |
| Linux only, and not read by this server: it is how the | (not set, which is what breaks it) |
Calls are serialised. Every tool call spawns an obsidian process that reaches
the same running Obsidian app, and firing several at once is what makes it stop
answering (a dozen deletes in a row stalled for over two minutes on the eighth,
while the binary replied normally again moments later). The server therefore runs
them one at a time; the wait for a free slot does not count towards the
timeout, which only starts once the process is spawned.
The obsidian_exec escape hatch is off by default: you only get the curated
obsidian_* tools unless you start the server with OBSIDIAN_MCP_ENABLE_EXEC=1.
Both variables accept 1, true or yes (any casing), and
OBSIDIAN_MCP_DISABLE_EXEC wins over OBSIDIAN_MCP_ENABLE_EXEC, so a
configuration that already sets it keeps the tool off.
Included tools
Every tool that targets a note takes either file (resolved by name, like a
wikilink) or path (the exact vault-relative path). Prefer path when the same
note name exists in several folders.
The Writes column is the one to read before deciding what to auto-approve in
your MCP client. It is also exactly the set that disappears under
OBSIDIAN_MCP_READONLY=1.
This table is checked mechanically by npm run check:readme, which runs in CI:
it asks the server for its tool list and fails if a row, a parameter or a tick
does not match. Parameters go in the third column, each one in backticks;
anything inside parentheses is ignored, which is where enum values and prose
belong (format (tree/md/json)).
Tool | What it does | Main parameters | Writes |
| Read a note |
| |
| Show a note's heading tree without its body |
| |
| List files in the vault (plain text, one path per line — the CLI's |
| |
| List the folder structure as a flat list of paths, whole or below one folder |
| |
| Create a note |
| ✔ |
| Append to an existing note |
| ✔ |
| Insert at the start of a note |
| ✔ |
| Move a note to another folder (or to another path) |
| ✔ |
| Rename a note in place; Obsidian updates the wikilinks pointing at it |
| ✔ |
| Delete a note (trash unless |
| ✔ |
| Show a note's metadata (path, size, dates) without its contents |
| |
| Show a folder's file/subfolder counts and size |
| |
| Count a note's words and characters |
| |
| List aliases, vault-wide or for one note |
| |
| List recently opened notes, newest first |
| |
| Search the vault and return the matching files, with filters like |
| |
| Search and return the matching lines with their surrounding text, not just the file names |
| |
| List the vault's bases ( | — | |
| List the views of the base currently open in Obsidian (the CLI command takes no target) | — | |
| Run a base and return its rows |
| |
| Read today's daily note (or another date's) |
| |
| Append to today's daily note |
| ✔ |
| Insert at the start of today's daily note |
| ✔ |
| List the vault's templates |
| |
| Read a template's body before applying it with |
| |
| Read a note's frontmatter |
| |
| List the property keys used across the vault, with Obsidian's inferred type and how many notes use each; with |
| |
| Read one frontmatter key's value, without the rest of the block |
| |
| Set frontmatter keys |
| ✔ |
| Remove one frontmatter key. Answers |
| ✔ |
| List tags, vault-wide or for one note |
| |
| Show how often one tag is used, and in which notes |
| |
| List notes linking to a note |
| |
| List a note's outgoing links |
| |
| List notes nothing links to (no incoming links); their own outgoing links do not matter |
| |
| List links that point nowhere; |
| |
| List notes that link to nothing |
| |
| List tasks (checkboxes), across the vault or in one note |
| |
| Append a |
| ✔ |
| Mark a task as done |
| ✔ |
| Report whether Obsidian Sync is connected and up to date | — | |
| List a note's stored versions (file recovery / Sync history) |
| |
| Read one stored version of a note. Reading only — restoring is deliberately not exposed |
| |
| Escape hatch. Run any CLI subcommand verbatim. Not registered unless |
| ✔ |
Structured output
Ten tools ask the Obsidian CLI for JSON, so they declare an outputSchema and
return the parsed rows as structuredContent as well as the text block: a client
does not have to parse the answer out of a string it was handed.
Tool | Key |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The text block is always there too, because the spec asks for it and because a
client that ignores structuredContent would otherwise receive nothing.
total wins over json in the tools that accept both: measured on CLI 1.14.1,
tags, unresolved, backlinks and tasks ignore the format and answer with
the bare count, and search answers {"total": n}. Either way the answer is a
count rather than the rows, so those calls have no structured content. The name
of obsidian_properties_list behaves the same way: properties name=status format=json answers 4, the number of notes carrying that property.
The key is absent (structuredContent is then {}) whenever the call did not
produce JSON: json: false or a format other than json, a total request,
which answers with a count, an output long enough to be cut by
OBSIDIAN_MCP_MAX_OUTPUT_BYTES, which is no longer
parseable, and a shape the declared schema does not recognise. The text block is the whole answer in those cases.
Only obsidian_tasks_list declares the fields of its rows (status, text,
file and line, the last one a string); the rest declare a list and leave the
item shape to the CLI, so that a guess about it can never suppress a good answer.
obsidian_properties_get is the one that is not a list at all: its key holds the
frontmatter as one object, property name → value. obsidian_properties_list
shares the properties key and is a list, one entry per property key used in the
vault (name, type, count) — the two answer different questions about the
same word.
obsidian_tags, obsidian_backlinks, obsidian_unresolved_links,
obsidian_properties_get and obsidian_properties_list default to json: true,
like the other tools here; set it to false for the CLI's own rendering
(tab-separated for the first three, YAML for a note's properties and a plain list
of names for the vault's).
This server passes the CLI's JSON through as it is, even where the CLI is not
consistent with itself. Two cases, both measured on CLI 1.14.1: count is a
NUMBER from properties format=json ("count": 4) but a STRING from tags counts and unresolved counts ("count": "3"); and unresolved verbose
answers sources as one STRING with the paths joined by ", ", not as a list.
Splitting sources on ", " would be a guess: a vault path can itself contain
a comma and a space, so a client that split it would silently get the wrong
list with no error to say so. Converting count to a number would be harmless
by itself, but it would make this server responsible for the shape of every
field in every CLI version, and a value repaired here would stop matching what
the same command prints when run by hand. Read count with Number(...)
rather than assume its type, and read sources as the single string it is.
The vault as resources
Besides the tools, the server exposes the vault as MCP resources: things the user attaches to a conversation, rather than things the model decides to call. Two URI shapes, both read-only:
URI | What you get |
| The note's contents, as |
| That folder's direct children as JSON — its subfolders and its notes, each with the URI to read next |
| The vault root, which is where a walk of the tree starts |
The path is relative to the vault root and each of its segments is
percent-encoded; the slashes between them are not, so the URI still shows the
tree. obsidian://note/33.11%20Notas/Nota%20A.md is the note
33.11 Notas/Nota A.md. Encoding matters for more than spaces: a # in a note
name would otherwise start a URI fragment and cut the path short.
Reading a folder is how you descend. The directory-listing extension some
clients speak (resources/directory/read, entries marked inode/directory) is
not in the MCP SDK this server is built on, so it cannot be declared. A folder
resource does the same job through an ordinary read: one level at a time, every
entry carrying its own URI, subfolders told apart from notes — which works on
every client rather than only on the ones that implement the extension.
{
"folder": "30-39 Conocimiento y herramientas",
"folders": [{ "name": "33 Notas", "path": "…/33 Notas", "uri": "obsidian://folder/…/33%20Notas/" }],
"notes": [{ "name": "Nota A.md", "path": "…/Nota A.md", "uri": "obsidian://note/…/Nota%20A.md" }],
"complete": true
}resources/list is paginated, because a real vault does not fit in one
answer. It walks the vault folder by folder and hands back a nextCursor until
it runs out; the cursor is opaque and self-contained, so a client can stop and
resume later without the server keeping a snapshot alive. Page size is
OBSIDIAN_MCP_RESOURCE_PAGE_SIZE. Only Markdown notes
are listed; any path the CLI can read can still be read by URI.
What a big vault costs, measured (5496 files, 3212 of them .md, 431
folders, CLI 1.14.1): a full walk of resources/list is 22 pages and about 3
seconds, one obsidian process per folder. It is bounded work per request — a
page stops after 40 folders even if it is not full — but it is still a burst of
spawns against your running Obsidian, and on one run out of three the app stalled
long enough for a call to hit its timeout. Attaching a note or reading a folder,
which is what actually happens in use, is one process.
The output cap applies to a note, not to the listings. A note longer than
OBSIDIAN_MCP_MAX_OUTPUT_BYTES comes back cut, with
the same notice appended saying how much was dropped: its text is what you read,
so it is spent context exactly as a tool result is. The folders and files
listings the walk is built from are not — they are split into names, turned
into URIs and dropped — so they answer to their own, far larger
OBSIDIAN_MCP_MAX_LISTING_BYTES. They used to share
the 50 kB one, and on the vault measured above that cost 1275 of its 3212 notes:
folders alone prints 46,855 bytes of the 50,000 available, 9 of the listings a
walk needs are over that cap, and the largest of them — the vault root's — is
399,636 bytes. At today's defaults the same walk lists all 3212 notes, in 22
pages, with nothing missing.
A listing that still does not fit is reported, never implied. The server
does not pass a cut one off as a short folder: complete: false in the folder's
JSON, and in resources/list the folder itself appears in place of its missing
notes, saying why. Notes in the vault root are the awkward case, because the
CLI's files command cannot be scoped to it: listing them means listing the
whole vault, so on a vault several times the size of the one above they are what
goes missing first, and raising OBSIDIAN_MCP_MAX_LISTING_BYTES is what buys
them back.
Resources ignore OBSIDIAN_MCP_READONLY. Reading is the only thing a
resource can do — there is no resources/write — so read-only mode has nothing
to take away, and the vault stays browsable in the configuration meant for
browsing it. What read-only removes is the tools that write.
Read-only mode
OBSIDIAN_MCP_READONLY=1With that set, the server does not register a single tool that writes: the
thirteen rows with a tick in the Writes column above are absent from the tool
list, so the model cannot call them and never learns they exist. Everything that
reads — searching, outlines, properties, tags, backlinks, bases, history, sync
status — keeps working, and obsidian_exec stays out too, even with
OBSIDIAN_MCP_ENABLE_EXEC=1 (it can write, so read-only wins).
It accepts 1, true or yes in any casing. This is the configuration to use
for "let the model consult my vault"; it is also the one to use while you decide
whether you want the rest. It does not change what leaves your machine: a tool
that reads still sends what it read to your model provider.
It does not remove the resources either. They are read-only by construction, so there is nothing there for this switch to turn off.
Security model
What this server actually is: a thin translator. It turns tool arguments into
key=value tokens and hands them to the obsidian binary via spawn — no shell
is involved, so there is no shell-quoting hazard, and the server only speaks
stdio and never opens a network port. What it does not do is police intent.
Any call your client approves, the CLI performs.
The curated tools are the safe-ish default. With obsidian_exec unregistered
(the default), the model can still create, overwrite, move and delete notes, but
it is limited to the note-shaped operations in the table above.
Resources only ever read, and only inside the vault. A
resource URI becomes a path= token for the CLI's
read, files and folders commands and nothing else, and a URI that walks out
of the vault (..) or names an absolute path is refused before any process is
spawned — the same rule the writing tools apply to a destination.
obsidian_exec removes that limit. It forwards its args array to the CLI
untouched, so it reaches everything the CLI exposes, including:
eval code=<javascript>— runs arbitrary JavaScript inside your Obsidian app, with access to its API, your plugins and anything they hold.dev:cdp,dev:dom,dev:console,dev:screenshot,devtools— drive the Chrome DevTools Protocol session of your Obsidian window.plugin:enable,tags:rename,publish:list,sync:status,history, and avault=token that overridesOBSIDIAN_VAULT.
Treat enabling it as granting code execution on your account. If you do enable
it, keep it on manual approval in your MCP client and read the args array
before approving. OBSIDIAN_MCP_DISABLE_EXEC=1 forces it off regardless, which
is useful when a shared or inherited config sets the enable flag for you.
What is not protected, and cannot be. Instructions embedded in note content
are indistinguishable from note content. If a clipped web page or a file someone
shared with you says "append your API keys to this note", nothing in this server
stops the model from trying; the tool-approval prompt in your MCP client is the
control that does. Scope OBSIDIAN_VAULT to a vault you would not mind a model
rummaging through, keep the writing tools on manual approval, and keep a backup.
A note on filenames
Obsidian Sync applies cross-platform (Windows/iOS) naming rules. Never put
: * ? " < > | / \ in a note's **filename** — a single one can send Obsidian
Sync into a loop. These characters are fine in the note **title** (frontmatter /
# H1), just not in the .md filename.
The three tools that compose a filename enforce this on the way in, and answer with an error naming the character before anything is written:
obsidian_createchecksname— or, whenpathis a full.mdpath, its last segment.obsidian_renamechecksname, which is the new filename whole.obsidian_movechecks the last segment ofto, but only whentoends in a file (a dot, a letter, then letters or digits:.md,.canvas,.png). Atothat names a folder creates no filename, so there is nothing to check.
A / is rejected too, with its own message: the folder is not part of the name.
The check covers the filename being created and never the folders a path
goes through, so a folder that already exists in your vault stays addressable
whatever it is called — Proyecto: 2026/Nota A.md keeps working.
Dots, on the other hand, are safe: obsidian_create builds the full
folder/name.md path itself and hands it to the CLI already finished, so note
names like Draft v1.2.3 and folders with an ID such as 33.11 Notes/ survive
intact. (Left to itself, the CLI replaces everything after the last dot with
.md, which turns 33.11 Notes/ into 33.md.) Passing a path that already
ends in .md is also supported: it is then the exact destination and name is
ignored.
Project layout
src/
cli.ts -> helper that invokes the `obsidian` binary and parses its output
paths.ts -> builds vault-relative paths (works around the CLI's `create` quirks)
tasks.ts -> builds the Markdown line for a new task
resources.ts -> the vault as MCP resources: note URIs, folder listings, paging
index.ts -> reads the environment flags, registers the tools and resources, starts the server
tools/
registry.ts -> how a tool is declared, and the single handler they all share
params.ts -> the input parameters several tools have in common
exec.ts -> the raw-command escape hatch
files.ts -> reading, listing, creating, moving and deleting notes; file/folder info
search.ts -> full-text search, with and without matching lines
bases.ts -> listing and querying bases
daily.ts -> daily notes
templates.ts-> listing and reading templates
properties.ts-> YAML frontmatter
links.ts -> tags, links, backlinks, orphans, unresolved links, dead ends
tasks.ts -> listing, creating and completing checkboxes
history.ts -> sync status and version history
scripts/
smoke-test.mjs -> quick manual test without needing an MCP client
*.test.mjs -> unit tests for the pure helpers (`npm test`)Each tool is a declaration — name, texts, annotations, input schema, CLI command,
and the function that turns its arguments into key=value tokens — and
src/tools/registry.ts is the only place that registers one, runs the CLI and
turns the result into an MCP response. A new tool is a new entry in the domain
module it belongs to; writes: true is what keeps it out of read-only mode.
src/resources.ts is the other half of the surface and does not go through that
registry: it registers resources/list, resources/templates/list and
resources/read on the low-level server directly, because the SDK's own
registerResource helper answers resources/list with every resource at once
and drops the cursor the protocol defines. The resources capability is
declared in src/index.ts, in the server constructor, so the whole shape of what
this server offers is visible in one file.
Disclaimer
This is an independent, community-built project. It is not affiliated with,
endorsed by, sponsored by, or associated with Obsidian, Obsidian.md, or Dynalist
Inc. in any way. "Obsidian" is a trademark of its respective owner; it is used
here only to describe interoperability. This software wraps the official Obsidian
CLI and is provided "as is", without warranty of any kind (see the license). You
are responsible for any changes it makes to your vault — back up your data and
read Read this before you install and
Security model before enabling obsidian_exec.
License
MIT © fodaveg
Available Tools
10 toolsobsidian_appendAppend to a noteC
Appends content to the end of an existing note.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Note name / wikilink. | |
| content | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Only states 'appends' and 'existing note,' implying mutation but lacks details like idempotency, permissions, or effects on non-existent notes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence is concise but overly minimal. Could be improved with brief additional context without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no annotations. For a simple tool, description omits error conditions, note existence behavior, and return value. Incomplete guidance for selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (content parameter has no description). Description adds no extra meaning beyond schema, such as clarifying file path format or content encoding requirements.
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?
Description clearly states the tool appends content to the end of an existing note, using a specific verb and resource. It distinguishes from sibling tools like obsidian_prepend and obsidian_read.
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 tool versus alternatives, such as obsidian_prepend for prepending or obsidian_read for just reading. Does not specify prerequisites like note existence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_deleteDelete a noteA
Deletes a note. By default it goes to Obsidian's trash unless permanent is set.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Note name / wikilink to delete. | |
| permanent | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the trash behavior and the permanent bypass, but does not discuss side effects like reversibility, error handling, or impact on linked notes. More context would be beneficial for a mutation 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?
The description is a single, front-loaded sentence that conveys the essential information without any superfluous words. Every part 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?
Given the tool's simplicity (2 parameters, no output schema), the description addresses the core function and the special permanent parameter. It could be improved by noting error behavior when the file doesn't exist, but overall it is sufficiently complete for typical use.
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 schema provides descriptions for both parameters: 'file' is described as 'Note name / wikilink to delete.' and 'permanent' is a boolean with default false. The description adds no extra value beyond what the schema already states. Schema coverage is 50% (one param described), so the baseline is adequate.
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 action (deletes), resource (note), and a key behavioral detail (trash vs permanent). It is easily distinguishable from sibling tools like obsidian_read or obsidian_move.
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 specifies default trash behavior and the permanent option, which guides usage. However, it does not explicitly mention when not to use the tool or suggest alternatives like obsidian_move for relocating, which would improve clarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_list_filesList files in the vaultB
Lists notes/files in the vault, optionally filtered by folder or extension.
| Name | Required | Description | Default |
|---|---|---|---|
| ext | No | File extension filter, e.g. "md" | |
| json | No | Return machine-readable JSON output. | |
| folder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It implies read-only behavior but does not disclose any permissions, limitations, side effects, or output format. Lacks details like pagination or error handling.
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?
Single sentence with no wasted words. All essential information is front-loaded. Efficient and 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?
For a simple listing tool with no output schema, the description is minimally adequate but lacks details about return format (e.g., list of file names, paths) and any default behavior. The three parameters are partially explained, but overall the description does not fully equip an agent to invoke the tool correctly without guessing.
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 67% (folder param lacks schema description). The description adds meaning by mentioning filtering by folder or extension, reinforcing ext and folder. However, the 'json' parameter's purpose is not explained in the description, and the description does not compensate fully for the undocumented folder parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Lists' and resource 'notes/files in the vault', clearly indicating what the tool does. It implicitly distinguishes from siblings like obsidian_read (reads content) and obsidian_search (searches) by focusing on listing/filtering.
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 tool versus alternatives like obsidian_search or obsidian_read. The description does not mention any prerequisites or contextual hints for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_moveMove or rename a noteA
Moves a note to a different folder (or renames it). Wikilinks pointing to it are updated automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Destination folder or path, e.g. "Archive/2026/". | |
| file | Yes | Note name / wikilink to move. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses key behavior (automatic wikilink update) but omits error handling, permissions, or side effects like moving or renaming across vaults.
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 concise sentences, no redundancy, front-loaded with core action, efficient and 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?
Description adequately covers purpose and key behavior for a simple move operation. Missing return value or error handling, but no output schema expected. Slightly incomplete given no annotations.
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% with clear parameter descriptions. The description adds no additional semantic meaning to parameters beyond what schema already provides, meriting baseline score.
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?
Description uses specific verb 'Moves' and 'renames' with resource 'note', clearly distinguishing from siblings like obsidian_delete or obsidian_append. It explicitly states automatic wikilink updates.
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 but not explicit. The description says what it does but does not provide when-to-use or when-not-to-use guidelines, nor alternatives among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_prependPrepend to a noteC
Inserts content at the start of an existing note.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Note name / wikilink. | |
| content | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description should disclose behavioral traits. It does not state whether the note must already exist, if content is added with a newline, or any effects on existing content. This is inadequate for a mutation 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?
The description is a single sentence, which is concise but overly terse. It front-loads the core action but omits necessary details, sacrificing structure for brevity.
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 no output schema and no annotations, the description is incomplete. It does not cover whether the tool creates missing notes, handles wikilinks, or returns confirmation. A minimal mutation tool requires more context.
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 50% (only 'file' has description). The tool description adds no additional meaning for 'content', which lacks schema description. The agent gets no guidance on content format or constraints beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Inserts' and resource 'content at the start of an existing note', clearly distinguishing it from sibling tools like obsidian_append (which appends) and obsidian_read (which reads).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus siblings, such as obsidian_append for appending. There is no mention of prerequisites or when not to use it, leaving the agent without context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_readRead a noteA
Reads the contents of a note, by wikilink name or by vault-relative path.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Note name / wikilink, e.g. "My Note" | |
| path | No | Vault-relative path, e.g. "Projects/Note.md" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description indicates a read-only operation with no side effects, which is transparent. However, it does not specify behavior for non-existent notes or permissions. With no annotations, the description carries the full burden, and while it is honest, it could be more explicit about safety.
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 sentence that is front-loaded with the main action and resource. Every word is meaningful with no redundancy or wasted text.
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 description states that it reads contents but does not describe the return format (e.g., plain text, markdown) or whether metadata is included. Without an output schema, more detail would improve completeness for a read operation.
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 description adds value by explaining the two identification methods and providing examples ('My Note', 'Projects/Note.md'), which clarifies parameter usage beyond the 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?
The description clearly states the action ('reads'), the resource ('contents of a note'), and identifies two identification methods (wikilink name or vault-relative path). It effectively distinguishes from sibling tools like obsidian_list_files or obsidian_search.
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 use when you want to retrieve note content, but lacks explicit guidance on when not to use or which sibling tool to prefer. The context of sibling tools with different actions provides some differentiation, but the description itself does not offer usage directions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_searchSearch the vaultB
Full-text search across the vault. Supports structured filters inside the query string, e.g. "[tag:project]", "[status:active]", "[priority:>3]".
| Name | Required | Description | Default |
|---|---|---|---|
| json | No | Return machine-readable JSON output. | |
| limit | No | ||
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose any behavioral traits such as read-only side effects, permissions, or rate limits. The description carries the full burden but fails to add this context.
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 concise with two sentences and front-loaded, but could efficiently include more guidance without increasing length significantly.
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 description does not explain return format, pagination, or other behavioral details. With no output schema, the description should provide more context to be complete for a search 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?
The description adds meaning to the 'query' parameter with examples of structured filters, but the 'limit' parameter lacks description in both schema and description, and schema coverage is low (33%).
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's purpose as 'Full-text search across the vault' with a specific verb and resource, and distinguishes it from sibling tools like obsidian_read or obsidian_list_files.
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 tool versus alternatives; no explicit context or exclusions provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_task_createCreate a taskC
Creates a new task, optionally tagged.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Comma-separated tags, e.g. "work,urgent". | |
| content | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits, but it only mentions creation and optional tagging. It omits critical details like where the task is created (e.g., active note, default file), side effects, or conflict 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?
The description is a single sentence, which is concise, but it sacrifices necessary detail. It earns its place but is too brief to be fully effective.
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 tool's simplicity (two parameters, no output schema, no annotations), the description is incomplete. It does not explain the target note, required permissions, or how optional tags affect creation, leaving significant gaps for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (only 'tags' has a description). The description adds no value for the 'content' parameter, and 'optionally tagged' merely echoes the schema. The agent lacks understanding of the 'content' field's format or purpose.
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 action (creates) and resource (task), and the tool name includes 'obsidian_task_create', distinguishing it from sibling file manipulation tools like 'obsidian_append' or 'obsidian_delete'.
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 is provided on when to use this tool versus alternatives like 'obsidian_append' for manually formatting a task. There is no mention of prerequisites or contextual triggers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_tasks_listList tasksC
Lists tasks (checkboxes) found across the vault.
| Name | Required | Description | Default |
|---|---|---|---|
| json | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries full burden. It states the tool lists tasks but does not disclose whether the operation is read-only, what the output format is, or if any side effects exist. This is insufficient for an agent to understand behavioral implications.
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 sentence, concise and front-loaded. However, it lacks necessary detail, making it slightly over-terse for effective use.
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 one parameter and no annotations, the description should at least explain the parameter and expected output. It fails to do so, leaving significant gaps in understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter 'json' has no description in the schema (0% coverage). The tool description does not explain its purpose (e.g., returning results in JSON format). The agent cannot infer how to use the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action (lists), resource (tasks/checkboxes), and scope (across the vault). It differentiates from sibling tools like obsidian_task_create by focusing on listing existing tasks rather than creating 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?
No guidance is provided on when to use this tool versus alternatives like obsidian_search (which might find tasks via text search) or obsidian_task_create (to create new tasks). The description lacks usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
obsidian_unresolved_linksList unresolved linksA
Lists links in the vault that don't resolve to an existing note.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden but only states basic functionality. It does not disclose whether the operation reads the entire vault, if it's passive, or any side effects.
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 focused sentence that directly conveys the tool's purpose without unnecessary words.
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 tool with no parameters, the description is minimally adequate. However, it lacks details about scope or return format that could enhance completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema coverage is 100%. The description adds no parameter information but is not required to do so since there are none.
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 lists unresolved links, distinguishing it from sibling tools like obsidian_read and obsidian_search which serve different purposes.
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 tool versus alternatives. The description does not mention use cases or exclusions, leaving the agent without context for decision-making.
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
obsidian_append - First observed
obsidian_delete - First observed
obsidian_list_files - First observed
obsidian_move - First observed
obsidian_prepend - First observed
obsidian_read - First observed
obsidian_search - First observed
obsidian_task_create - First observed
obsidian_tasks_list - First observed
obsidian_unresolved_links
TDQS
Scored across 10 tools
Each tool has a clear and distinct purpose. There is no overlap or ambiguity; even append/prepend are differentiated by position.
All tools follow the same obsidian_verb_noun pattern in snake_case, making it predictable and easy to understand.
10 tools is appropriate for an Obsidian vault MCP server, covering file operations, search, and task management without being bloated.
Covers most core operations (read, write, move, delete, search, tasks) but lacks an explicit create note tool and content update beyond append/prepend.
Maintenance
Related MCP Connectors
Search, read, and safely update Markdown notes in your connected Phasoric knowledge vaults.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Search your Obsidian vault to quickly find notes by title or keyword, summarize related content, a…
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables MCP clients to interact with Obsidian vaults via filesystem operations and optional REST API integration for advanced UI commands. It features multi-vault auto-discovery, concurrent-safe file handling, and comprehensive tools for searching, reading, and managing vault content.1212,601 npmMIT
- FlicenseNot gradedqualityDmaintenanceA local MCP server that wraps the Obsidian CLI to give AI assistants direct access to read, edit, and manage notes within an Obsidian vault. It enables advanced operations such as frontmatter property management, context-aware searching, and the execution of internal Obsidian commands.2-
- FlicenseNot gradedqualityDmaintenanceMCP server that exposes Obsidian vault operations over HTTP via the Obsidian CLI, enabling note management, search, and daily note operations.1-
- FlicenseNot gradedqualityCmaintenanceExposes Obsidian vault tools via Model Context Protocol (MCP) server over stdio, HTTP, or SSE transports, enabling AI assistants to read, write, search, and manage vault notes with 28+ built-in tools and CLI bridge integration.1-