Skip to main content
Glama

obsidian-cli-mcp

An MCP server that gives Claude and other MCP clients full control of a running Obsidian vault through the official Obsidian CLI (Obsidian 1.12+), with fast direct filesystem reads where correctness allows it.

Companion project to things-for-mac-mcp.

What makes this different?

Most Obsidian MCP servers either talk to a community REST plugin or read the vault folder directly. The first requires installing and trusting a plugin. The second silently breaks wikilinks the moment it moves or renames a file, because only Obsidian knows about every link, alias, and embed pointing at it.

This server routes every operation by capability:

Typical filesystem-only MCPs

obsidian-cli-mcp

Full-text search across thousands of notes

Fast

Fast (filesystem)

Move or rename a note

Breaks every inbound link

Link-safe (Obsidian CLI)

Backlinks, aliases, unresolved links

Guesswork

Obsidian's own resolver

Bases queries, template variables

Impossible

Runtime evaluation via the app

Writes land in Obsidian's index and file recovery

No

Yes

iCloud evicted files

Read as empty notes

Detected, read through Obsidian

Requires a community plugin

Sometimes

No

The architecture mirrors its sibling project exactly:

things-for-mac-mcp

obsidian-cli-mcp

Fast reads

SQLite direct

Filesystem direct

Authoritative writes

AppleScript

Obsidian CLI

Convenience creates

URL scheme

Obsidian CLI

The rule behind the split: bulk reads go to the filesystem because they need throughput, and anything that moves, renames, deletes, or depends on link resolution or app state goes through the CLI because it needs Obsidian's knowledge. The filesystem adapter structurally cannot mutate the vault, it exports no writing function at all.

Requirements

  • macOS, Windows, or Linux desktop with Obsidian 1.12 or later

  • The Obsidian CLI enabled: Obsidian, Settings, General, Command line interface

  • Obsidian must be running. The CLI is a client to the app, not a standalone binary. This is desktop only, mobile is not supported.

  • Node.js 18 or later

Installation

git clone https://github.com/jabaho9523/obsidian-cli-mcp.git
cd obsidian-cli-mcp
npm install
npm run build

Connect to an MCP client

Claude (Desktop / Code)

Add to claude_desktop_config.json (Claude Desktop) or run claude mcp add (Claude Code):

{
  "mcpServers": {
    "obsidian": {
      "command": "/absolute/path/to/node",
      "args": ["/absolute/path/to/obsidian-cli-mcp/dist/index.js"],
      "env": {
        "OBSIDIAN_VAULT": "YourVaultName"
      }
    }
  }
}

Use the absolute path to node, not the bare word. GUI-launched apps do not inherit your shell's PATH, so "command": "node" fails silently in many clients. Find yours with which node.

Set OBSIDIAN_VAULT if you have more than one vault. The CLI otherwise targets whichever vault was focused last, which is a terrible property for automated writes. With a single vault the server pins it automatically at startup.

Configuration

Variable

Default

Purpose

OBSIDIAN_BIN

/usr/local/bin/obsidian

Path to the Obsidian CLI binary

OBSIDIAN_VAULT

auto-pinned if exactly one vault exists

Vault name every command targets

OBSIDIAN_VAULT_PATH

auto-detected via the CLI

Vault folder for the filesystem adapter

OBSIDIAN_MCP_TIMEOUT

20000

Per-command timeout in ms

OBSIDIAN_MCP_ALLOW_DANGEROUS

unset

Set to 1 to unlock tier 3 commands

OBSIDIAN_MCP_READONLY

unset

Set to 1 to reject every mutating tool

Guardrails

Three tiers, enforced before the binary is ever spawned:

  • Tier 1, free: reads, searches, and additive writes (create_note, append_note, append_daily, set_property, update_task, capture).

  • Tier 2, requires confirm: true in the tool call: delete_note, move_note, rename_note, remove_property, run_obsidian_command, and through the passthrough: history:restore, publish:*, plugin:enable/disable/reload, theme:*, snippet:*, sync, sync:restore, reload, template:insert, workspace:save/delete. Any call carrying an overwrite or permanent flag is escalated to tier 2 as well.

  • Tier 3, blocked unless the server runs with OBSIDIAN_MCP_ALLOW_DANGEROUS=1: eval, restart, plugin:install, plugin:uninstall, plugins:restrict, devtools, dev:cdp, dev:debug, dev:mobile, and delete_note with permanent: true.

An honest note on what these are. Tier 2 is a speed bump against accidental calls, not security: the calling model can set confirm: true itself. Tier 3 is a real boundary, because only whoever configures the server environment can unlock it. If you point an autonomous agent at a vault you care about, run with OBSIDIAN_MCP_READONLY=1, which rejects every mutating command before dispatch regardless of tier.

The single most important rule in this project: files are never moved, renamed, or deleted through the filesystem. Obsidian updates every wikilink in the vault when it performs the operation. A plain mv does not.

Before, with Projects/Roadmap.md linked from three notes:

Weekly Review.md:   Progress on [[Roadmap]] is on track.
Team Notes.md:      See [[Roadmap#Q3]] for the plan.
Index.md:           - [[Roadmap|2026 roadmap]]

After move_note with to: "Archive/2026 Roadmap.md":

Weekly Review.md:   Progress on [[2026 Roadmap]] is on track.
Team Notes.md:      See [[2026 Roadmap#Q3]] for the plan.
Index.md:           - [[2026 Roadmap|2026 roadmap]]

All three links updated, including the heading anchor and the alias, because Obsidian did the move. A filesystem move would have left three broken links and no error.

Why hybrid? The performance rationale

Every CLI invocation is one full IPC round trip through the running Obsidian app. That is correct but slow: reading 2,000 notes via obsidian read is 2,000 round trips, minutes of wall time. Reading them from disk is one directory walk, well under a second on any SSD.

So bulk reads (search, listings, tag and property scans, exports, digests) hit the filesystem, and the CLI is reserved for what only Obsidian can answer (links, aliases, Bases, templates, app state) and for every write. To compare on your own vault, time search_notes against the passthrough obsidian_cli with ["search", "query=..."].

Troubleshooting

"Obsidian is not running." The most common failure. The CLI needs the app open and fully loaded. Start Obsidian and retry.

"Could not find the Obsidian CLI binary." Enable the CLI in Obsidian under Settings, General, Command line interface, or point OBSIDIAN_BIN at the binary.

Timeouts on the first command. A cold Obsidian start can exceed the 20s default. Raise OBSIDIAN_MCP_TIMEOUT.

Notes read as missing or the server falls back to the CLI a lot. If your vault lives in iCloud with Optimize Mac Storage on, evicted files exist only as .name.icloud stubs. The server detects these and reads them through Obsidian, which re-downloads them, instead of reporting empty notes. Bulk scans skip evicted files and say so in their output.

Writes land in the wrong vault. You have multiple vaults and no OBSIDIAN_VAULT set. The server warns about this on stderr at startup. Pin one.

Tools do not appear in the client. Check the client's MCP logs, and check the absolute node path issue above.

Staying up to date

git pull && npm install && npm run build

The server checks for updates at startup, at most once per 24 hours, caching the result in ~/.config/obsidian-cli-mcp/update-check.json. It fails silently offline and prints a single stderr line when a newer version exists.

Tools (39 total)

Read tools (18)

Tool

Adapter

Description

read_note

Filesystem, CLI fallback

Read a note by wikilink-style name or exact path

search_notes

Filesystem

Full-text search with folder, case, context, and limit options

list_notes

Filesystem

List files, filtered by folder and extension

list_folders

Filesystem

List folders

get_note_info

CLI

Path, size, created and modified dates

get_outline

Filesystem

Heading tree with line numbers

get_backlinks

CLI

Inbound links, resolved by Obsidian

get_outgoing_links

CLI

Outbound links

get_tags

Filesystem

All tags with counts, frontmatter and inline

get_properties

Filesystem

Vault-wide frontmatter keys with counts

read_property

Filesystem

One frontmatter key on one note

get_vault_info

CLI

Vault name, path, stats

get_recents

CLI

Recently opened files

list_bases

CLI

All .base files

query_base

CLI

Run a Bases view query, evaluated by the app

list_templates

CLI

Templates in the configured folder

read_template

CLI

Template content, optionally with variables resolved

get_word_count

Filesystem

Words and characters, excluding frontmatter

Write tools (16)

All writes go through the CLI. Every one requires an explicit file or path target, none can fall through to the currently active file.

Tool

Guard tier

Description

create_note

1, 2 with overwrite

Create a note, optionally from a template

append_note

1

Append content

prepend_note

1

Prepend content after frontmatter

read_daily

1

Read today's daily note

append_daily

1

Append to today's daily note

prepend_daily

1

Prepend to today's daily note

get_daily_path

1

Path of today's daily note

set_property

1

Set a frontmatter property

remove_property

2

Remove a frontmatter property

move_note

2

Link-safe move

rename_note

2

Link-safe rename

delete_note

2, 3 with permanent

Delete to trash, or permanently

list_tasks

1

List markdown tasks with refs

update_task

1

Toggle or set task status by ref or line

open_note

1

Open in the Obsidian UI, navigation only

run_obsidian_command

2 to execute

List or run command palette commands, including plugin commands

run_obsidian_command is the widest door in the server: it reaches every command palette action, including those registered by community plugins. It is exposed deliberately and gated at tier 2.

Workflow tools (4)

Tool

Description

capture

Timestamped append to today's daily note, the highest frequency operation in practice

daily_digest

Aggregate a date range of daily notes into one document

export_notes

Export a folder as JSON, Markdown, or CSV, inline or to a file outside the vault

vault_health

Orphans, dead ends, unresolved links, and empty notes in one report. Deliberately scoped to the link graph

Escape hatch (1)

Tool

Description

obsidian_cli

Run any CLI command. Takes args as a pre-split array of strings, never a shell string, so the server spawns without a shell and content cannot break out of quoting. All guard tiers apply

MCP Resources

Client support for resources varies, Claude Desktop does not currently surface them.

Resource

Content

obsidian://vault

Vault info

obsidian://daily

Today's daily note

obsidian://tags

All tags with counts

obsidian://recents

Recently opened files

obsidian://orphans

Notes with no inbound links

obsidian://note/{path}

Any note by vault-relative path

MCP Prompts

Prompt

Purpose

daily_note_review

Summarize a daily note, surface open tasks, suggest follow-ups

vault_cleanup

Walk the vault health report and propose link-safe fixes

note_from_source

Turn pasted material into a note using an existing template

weekly_digest

Summarize a week of daily notes into a digest note

Architecture

src/
├── index.ts              MCP server entry, stdio transport
├── config.ts             Environment configuration
├── adapters/
│   ├── cli.ts            execFile wrapper, vault injection, error contract
│   └── filesystem.ts     Read-only vault access, iCloud stub detection
├── tools/
│   ├── common.ts         Shared note loading with CLI fallback
│   ├── read.ts           18 read tools
│   ├── write.ts          16 write tools
│   ├── workflow.ts       4 composite tools
│   └── passthrough.ts    obsidian_cli escape hatch
├── resources/
│   └── vault.ts          MCP resources
├── prompts/
│   └── workflows.ts      MCP prompts
└── utils/
    ├── guardrails.ts     Tier policy, readonly allowlist
    ├── markdown.ts       Frontmatter, headings, tags, word counts
    ├── output.ts         Truncation at 60,000 characters
    └── update-check.ts   Daily update check

Tests run against a stub binary that scans its full argv and can be told to fail, hang, or emit oversized output, so the whole suite passes with no Obsidian installed:

npm test

Support

Issues and feature requests: GitHub issues.

More from the author

License

MIT

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Read and write your Fresh Jots notes from Claude, Cursor, and any MCP client.

  • Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.

  • Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jabaho9523/obsidian-cli-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server