obsidian-mcp

by StevenStavrakis

Recommended
440 stars
55 downloads
Not rated
GitHub

About

Enables AI assistants to interact with Obsidian vaults, providing tools for reading, creating, editing and managing notes and tags.

Details

Author
StevenStavrakis
Repository
StevenStavrakis/obsidian-mcp
GitHub stars
440
Downloads
55
License
MIT License
Categories
Productivity, Other, Knowledge Base, AI

- Read and search notes in your vault
- Create new notes and directories
- Edit and delete existing notes
- Move notes between locations
- Manage tags (add, remove, rename)
- Support for multiple vaults

Setting up with Highlight

Follow these steps to add this server as a custom Highlight plugin:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name obsidian-mcp
    Command (node, npx, python, etc.) npx
    Arguments
    • Argument 1 -y
    • Argument 2 obsidian-mcp@2
    • Argument 3 serve
    • Argument 4 --vault
    • Argument 5 notes=/absolute/path/to/vault

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Node.js 22 or newer is required:

node --version # v22 or newer

Run with npx without installing the package globally. Pinning the major version receives compatible 2.x updates without automatically crossing a future major version:

npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/vault

Configure an MCP client to launch the same command over stdio:

{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": ["-y", "obsidian-mcp@2", "serve", "--vault", "notes=/absolute/path/to/vault"]
    }
  }
}

Alternatively, install the package globally and use "command": "obsidian-mcp" with the same arguments beginning at "serve":

npm install -g obsidian-mcp@2

Each vault must already contain an .obsidian directory and must be configured using an absolute path.

Both protocol eras are served from the same tool definitions. After confirming that your MCP client negotiates 2026-07-28, you may opt into modern-only mode by adding "--legacy", "reject" to args.

Vault ids use lowercase letters, digits, _, and -, must begin with a letter, and are the values assistants pass to tools. Up to ten vaults may be configured. Repeat --vault to expose more than one vault:

obsidian-mcp serve \
  --vault work=/Users/me/Documents/WorkVault \
  --vault personal=/Users/me/Documents/PersonalVault

Network, removable, hidden, and synced locations are allowed because an explicit --vault is treated as authorization; the same containment protections apply to every location.

obsidian_list_vaults

List configured vault ids without exposing host paths.

obsidian_read_note

Read a bounded page of a note and return its SHA-256 `etag`.

obsidian_create_note

Atomically create a note without overwriting.

obsidian_edit_note

Append, prepend, or replace exact note content.

obsidian_delete_note

Move a note to MCP trash or permanently delete it with explicit confirmation.

obsidian_move_note

Move or rename a note and update unambiguous backlinks transactionally.

obsidian_create_directory

Transactionally create a directory inside a vault.

obsidian_search_vault

Search content, filenames, or tags with bounded cursor pagination.

obsidian_add_tags

Add tags to one or more notes atomically.

obsidian_remove_tags

Remove exact, nested, or wildcard-selected tags atomically.

obsidian_rename_tag

Rename a tag across the vault atomically.

obsidian_manage_tags

Unified add/remove tag workflow using the same implementation.

| Tool | Purpose |
| --------------------------- | ----------------------------------------------------------------------------- |
| obsidian_list_vaults | List configured vault ids without exposing host paths. |
| obsidian_read_note | Read a bounded page of a note and return its SHA-256 etag. |
| obsidian_create_note | Atomically create a note without overwriting. |
| obsidian_edit_note | Append, prepend, or replace exact note content. |
| obsidian_delete_note | Move a note to MCP trash or permanently delete it with explicit confirmation. |
| obsidian_move_note | Move or rename a note and update unambiguous backlinks transactionally. |
| obsidian_create_directory | Transactionally create a directory inside a vault. |
| obsidian_search_vault | Search content, filenames, or tags with bounded cursor pagination. |
| obsidian_add_tags | Add tags to one or more notes atomically. |
| obsidian_remove_tags | Remove exact, nested, or wildcard-selected tags atomically. |
| obsidian_rename_tag | Rename a tag across the vault atomically. |
| obsidian_manage_tags | Unified add/remove tag workflow using the same implementation. |

All schemas are strict JSON Schema 2020-12 contracts generated from Zod. Mutating results include a transaction id; tool failures return isError: true with an actionable error code.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "obsidian-mcp": {
            "env": {},
            "args": [
                "-y",
                "obsidian-mcp@2",
                "serve",
                "--vault",
                "notes=/absolute/path/to/vault"
            ],
            "command": "npx"
        }
    }
}

Linux

{
    "env": [],
    "args": [
        "-y",
        "obsidian-mcp@2",
        "serve",
        "--vault",
        "notes=/absolute/path/to/vault"
    ],
    "command": "npx"
}

Macos

{
    "env": [],
    "args": [
        "-y",
        "obsidian-mcp@2",
        "serve",
        "--vault",
        "notes=/absolute/path/to/vault"
    ],
    "command": "npx"
}

Windows

{
    "env": [],
    "args": [
        "/c",
        "npx",
        "-y",
        "obsidian-mcp@2",
        "serve",
        "--vault",
        "notes=/absolute/path/to/vault"
    ],
    "command": "cmd"
}
# Obsidian MCP A local [Model Context Protocol](https://modelcontextprotocol.io/) server that lets MCP-compatible assistants safely read and modify explicitly configured Obsidian vaults. Version 2 supports both MCP `2026-07-28` and 2025-era clients by default, and requires Node.js 22 or newer. It works directly with Markdown files, so Obsidian does not need to be open. Legacy protocol and v1 positional-path compatibility are deprecated and print exact migration instructions to stderr. > [!IMPORTANT] > MCP clients can invoke destructive tools. Back up important vaults, review client permission prompts, and use revision preconditions for concurrently edited notes. ## Quick start Node.js 22 or newer is required: ```bash node --version # v22 or newer ``` Run with `npx` without installing the package globally. Pinning the major version receives compatible 2.x updates without automatically crossing a future major version: ```bash npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/vault ``` Configure an MCP client to launch the same command over stdio: ```json { "mcpServers": { "obsidian": { "command": "npx", "args": ["-y", "obsidian-mcp@2", "serve", "--vault", "notes=/absolute/path/to/vault"] } } } ``` Alternatively, install the package globally and use `"command": "obsidian-mcp"` with the same arguments beginning at `"serve"`: ```bash npm install -g obsidian-mcp@2 ``` Each vault must already contain an `.obsidian` directory and must be configured using an absolute path. Both protocol eras are served from the same tool definitions. After confirming that your MCP client negotiates `2026-07-28`, you may opt into modern-only mode by adding `"--legacy", "reject"` to `args`. Vault ids use lowercase letters, digits, `_`, and `-`, must begin with a letter, and are the values assistants pass to tools. Up to ten vaults may be configured. Repeat `--vault` to expose more than one vault: ```bash obsidian-mcp serve \ --vault work=/Users/me/Documents/WorkVault \ --vault personal=/Users/me/Documents/PersonalVault ``` Network, removable, hidden, and synced locations are allowed because an explicit `--vault` is treated as authorization; the same containment protections apply to every location. ## Design principles - Vault access is explicitly allowlisted at process startup. - Every tool path is vault-relative, segment-checked, and blocked from symlinks and reserved state. - File mutations are journaled, conflict-checked, atomically replaced, and rolled back as one transaction. - The server never listens on a network interface or sends telemetry. - stdout is reserved exclusively for MCP messages; structured diagnostics go to stderr. - Results are bounded, paginated where appropriate, and available as both text and structured content. ## Tools | Tool | Purpose | | --------------------------- | ----------------------------------------------------------------------------- | | `obsidian_list_vaults` | List configured vault ids without exposing host paths. | | `obsidian_read_note` | Read a bounded page of a note and return its SHA-256 `etag`. | | `obsidian_create_note` | Atomically create a note without overwriting. | | `obsidian_edit_note` | Append, prepend, or replace exact note content. | | `obsidian_delete_note` | Move a note to MCP trash or permanently delete it with explicit confirmation. | | `obsidian_move_note` | Move or rename a note and update unambiguous backlinks transactionally. | | `obsidian_create_directory` | Transactionally create a directory inside a vault. | | `obsidian_search_vault` | Search content, filenames, or tags with bounded cursor pagination. | | `obsidian_add_tags` | Add tags to one or more notes atomically. | | `obsidian_remove_tags` | Remove exact, nested, or wildcard-selected tags atomically. | | `obsidian_rename_tag` | Rename a tag across the vault atomically. | | `obsidian_manage_tags` | Unified add/remove tag workflow using the same implementation. | All schemas are strict JSON Schema 2020-12 contracts generated from Zod. Mutating results include a transaction id; tool failures return `isError: true` with an actionable error code. ### Reading and concurrency `obsidian_read_note` returns an `etag`. Pass it as `if_match` to edit, move, or delete when avoiding lost updates matters. Batch tag operations accept an `expected_etags` map. A changed note returns `REVISION_CONFLICT` rather than being overwritten. Large notes are paginated using an opaque cursor bound to the path and `etag`. Search uses an opaque cursor bound to the query and options. Tool text responses are capped at 25,000 characters. ### Deletion and recovery Trash is the default. Deleted note bytes and metadata are stored separately under `.obsidian-mcp/trash`; metadata is never injected into the note. Permanent deletion requires `confirm_path` to exactly match the canonical relative path. Transactions and recovery snapshots live in `.obsidian-mcp/transactions`. Completed data is retained for 30 days and pruned oldest-first above 1 GiB by default: ```bash obsidian-mcp serve --vault work=/path \ --recovery-days 14 \ --recovery-max-bytes 536870912 ``` Inspect or restore a completed transaction while the MCP server is stopped: ```bash obsidian-mcp recovery list --vault work=/path obsidian-mcp recovery restore --vault work=/path --id <transaction-id> ``` Recovery refuses to overwrite content changed since the selected transaction. Permanent deletion snapshots are purged after commit and cannot be restored. ## Path and filesystem safety The server: - canonicalizes configured vault roots and rejects duplicate or nested roots; - rejects absolute, UNC, Windows-drive, NUL, backslash, empty, and dot-segment tool paths; - reserves `.obsidian`, `.obsidian-mcp`, `.git`, `.backup`, and `.trash` from tool access; - checks existing targets and the nearest existing ancestor for new targets; - rejects symlinks, junctions, and reparse-point paths, and skips them during scans; - performs no shell execution for filesystem validation; - strictly decodes UTF-8 and does not silently replace invalid bytes. The process needs read and write access to each configured vault. `obsidian-mcp doctor --vault id=/path` validates startup readiness and recovery state. ## Link and tag behavior Moves recognize Obsidian Wikilinks, embeds, Markdown links, aliases, URL-encoded destinations, headings, and block anchors. A link is rewritten only when it resolves unambiguously to the source note; ambiguous links are reported and left unchanged. Deletion preserves backlinks unless `backlink_action: "mark_broken"` is requested. Tags follow Obsidian's case-insensitive rules and support Unicode, emoji, `_`, `-`, `/`, and nested tags. Frontmatter tags are written as YAML lists. Inline tag processing ignores fenced/inline code and HTML comments. Wildcards use a bounded matcher rather than regular expressions. ## Development ```bash npm ci npm run typecheck npm test npm run build npm run ci ``` Each tool owns a typed definition under `src/tools/<tool>/index.ts`; the small registry in `src/tools/index.ts` applies shared MCP registration and response behavior. Filesystem, transaction, Markdown, link, and search behavior live in reusable utilities. A new tool must use `VaultFs` for every path, `TransactionManager` for mutations, strict input/output schemas, structured results, annotations, and security/integration tests. See [MIGRATING.md](MIGRATING.md) for the 1.x migration and [SECURITY.md](SECURITY.md) for vulnerability reporting. Startup errors and compatibility warnings are written only to stderr with a stable code, the detected problem, an exact fix, a verification step, and a link to the matching migration section. If the server does not appear, find the code in the MCP client logs and use the [diagnostic reference](MIGRATING.md#diagnostic-reference). ## License MIT
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.