Generated banner for Obsidian MCP
Generated logo for Obsidian MCP

Obsidian MCP

Memory server

Created by Steven Stavrakis

Published in StevenStavrakis/obsidian-mcp. Publisher page

750 GitHub stars

What it is

A safe, local MCP server for working with Obsidian vaults
— the description by Steven Stavrakis

AutoGineer overview, from the brain’s own files

Obsidian MCP is a Model Context Protocol server designed to provide AI agents with controlled, persistent access to local Obsidian vaults. It operates as a local server that allows agents to perform CRUD operations on markdown files, manage tags, and execute search queries within configured vaults. The system prioritizes safety and data integrity by implementing strict path validation, transactional file mutations, and built-in recovery mechanisms. It does not require Obsidian to be running, as it interacts directly with the underlying markdown files. The server is designed for integration into MCP-compatible agent workflows, offering a structured way to treat a personal knowledge base as an agent's memory layer.

How it works

Memory model: Markdown vault

AutoGineer overview, from the brain’s own files

The server runs as a local process that exposes a set of tools to an MCP client. Users configure one or more vault paths at startup, which the server then treats as authorized root directories. All file operations are relative to these roots and undergo strict path validation to prevent unauthorized access. Mutations are handled through a transaction manager that supports conflict checking via etags and provides recovery snapshots. The server includes tools for reading, creating, editing, moving, and deleting notes, as well as comprehensive tag management. It also provides a recovery system to restore files from a local trash or transaction log.

Folders
FolderRoleFiles
.githubagent-config5
docsdocs2
scriptsscripts4
srcsource-code34
testtests8
evaluationsfolder7

Requirements

Apps: Obsidian

Runtimes: Node.js >=22

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)

Set it up

  1. Not scanned by AutoGineerIts dependencies are installed by npm when you run it and were not scanned by AutoGineer (3 declared). https://www.npmjs.com/package/obsidian-mcp
  2. Created by Steven Stavrakis. Published in StevenStavrakis/obsidian-mcp. Licence: MIT License.

Usage

AutoGineer overview, from the brain’s own files

  • Configure an MCP client to launch the server with specific vault paths.
  • Use agent tools to read notes and retrieve etags for version control.
  • Perform atomic edits or note creations with conflict detection.
  • Manage vault organization by moving notes and updating internal links.
  • Execute tag operations across multiple notes atomically.
  • Recover deleted or modified content using the built-in transaction recovery system.
“Read the note titled 'Project-Alpha' from my work vault.”
The agent uses obsidian_read_note to fetch the content and an etag, allowing it to display the note or prepare it for editing.
“Add the tag #status/active to all notes in the 'Project-Alpha' folder.”
The agent uses obsidian_add_tags to atomically update the frontmatter or inline tags of the specified notes.
“Rename 'Meeting-Notes' to 'Q1-Meeting-Notes' and update all links.”
The agent uses obsidian_move_note, which renames the file and automatically updates internal Wikilinks and embeds pointing to the original note.
“Restore the note I accidentally deleted yesterday.”
The agent or user utilizes the recovery tools to list transactions and restore the note from the .obsidian-mcp/trash directory.

Documentation by Steven Stavrakis

Obsidian MCP

A local Model Context Protocol 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:

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.

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

ToolPurpose
obsidian_list_vaultsList configured vault ids without exposing host paths.
obsidian_read_noteRead a bounded page of a note and return its SHA-256 etag.
obsidian_create_noteAtomically create a note without overwriting.
obsidian_edit_noteAppend, prepend, or replace exact note content.
obsidian_delete_noteMove a note to MCP trash or permanently delete it with explicit confirmation.
obsidian_move_noteMove or rename a note and update unambiguous backlinks transactionally.
obsidian_create_directoryTransactionally create a directory inside a vault.
obsidian_search_vaultSearch content, filenames, or tags with bounded cursor pagination.
obsidian_add_tagsAdd tags to one or more notes atomically.
obsidian_remove_tagsRemove exact, nested, or wildcard-selected tags atomically.
obsidian_rename_tagRename a tag across the vault atomically.
obsidian_manage_tagsUnified 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:

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:

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.

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

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 for the 1.x migration and 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.

License

MIT

MIGRATING.md

Migrating from 1.x to 2.0

Version 2 is an intentional security, CLI, and tool-contract release. Existing v1 startup configurations continue to work during the transition and print their exact replacement to stderr. The server also accepts both 2025-era and 2026-07-28 MCP clients by default.

After changing configuration, fully restart the MCP client or open a new session so it starts the new process and refreshes its cached tool catalog.

Copy-paste configuration migration

Old v1 configuration:

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

New v2 configuration:

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

For a global install, use "command": "obsidian-mcp" and begin args with "serve". For multiple vaults, repeat "--vault", "id=/absolute/path". Vault ids are the values agents pass to tools.

Required changes

  1. Install Node.js 22 or 24 LTS.

  2. Replace positional vault paths with serve --vault id=/absolute/path arguments.

  3. Update stored prompts and hard-coded calls to the new prefixed snake_case tool names and fields.

  4. Restart the MCP client so it rediscovers tools. Protocol upgrades can happen independently because v2 serves both MCP eras by default.

Unsupported Node.js

UNSUPPORTED_NODE_VERSION means the MCP client launched v2 using Node.js older than 22. Running node --version in a terminal is not sufficient if the client has a different PATH.

  1. Install Node.js 22 or 24 LTS.

  2. Restart the MCP client completely.

  3. If the error remains, configure the client with the absolute path to the upgraded npx or obsidian-mcp executable.

  4. Verify the executable from the same environment with node --version and obsidian-mcp --version.

V1 positional vault paths

V1_POSITIONAL_CONFIG_DEPRECATED is a warning, not a startup failure. The Detected section shows how each old path was mapped to a v2 vault id. Copy the JSON argument array from Fix into the MCP server's args setting, preserving any npx -y obsidian-mcp prefix owned by the client configuration.

Do not mix positional paths with --vault; CLI_MIXED_CONFIG_SYNTAX explains which complete form to use. A positional path is made absolute and ~ is expanded before its replacement is printed.

Legacy MCP clients

LEGACY_MCP_PROTOCOL means the server is working, but the MCP host opened a 2025-era connection. Upgrade the host when it supports MCP 2026-07-28. Until then, no flag is required.

STRICT_PROTOCOL_REJECTION means the configuration contains --legacy reject but the client still uses the legacy handshake. Remove that pair or change it to --legacy serve, restart the client, and upgrade the client before enabling strict mode again.

Tool and argument changes

1.x2.0
list-available-vaultsobsidian_list_vaults
read-noteobsidian_read_note
create-noteobsidian_create_note
edit-noteobsidian_edit_note
delete-noteobsidian_delete_note
move-noteobsidian_move_note
create-directoryobsidian_create_directory
search-vaultobsidian_search_vault
add-tagsobsidian_add_tags
remove-tagsobsidian_remove_tags
rename-tagobsidian_rename_tag
unregistered manage-tagsobsidian_manage_tags

The principal payload changes are:

  • Note tools use one vault-relative path instead of filename plus folder.

  • edit-note no longer accepts operation: "delete"; use obsidian_delete_note.

  • Search uses scope, mode, case_sensitive, limit, and cursor fields instead of path, searchType, and caseSensitive. Use mode: "tag" rather than a tag: query prefix.

  • Tag operations use paths instead of files. Former nested options fields are flattened and use snake_case, such as include_children and expected_etags.

  • Rename fields are old_tag and new_tag. Results now include structured content and machine-readable errors.

Old tool names are not advertised as aliases because translating stale mutation payloads could perform an unintended write. Restarting the client lets an agent see and use the new schemas.

Vault configuration errors

CodeWhat to fix
INVALID_VAULT_IDUse a lowercase id beginning with a letter, up to 64 characters.
DUPLICATE_VAULT_IDGive each --vault a different id.
VAULT_PATH_NOT_ABSOLUTEReplace the path with its full absolute path.
VAULT_PATH_NOT_FOUNDCorrect a missing or misspelled directory.
VAULT_PATH_NOT_DIRECTORYSelect the vault directory, not a file.
VAULT_NOT_INITIALIZEDOpen the directory as a vault in Obsidian to create .obsidian.
VAULT_PERMISSION_DENIEDGrant the MCP client process read and write permission.
VAULT_ROOTS_OVERLAPRemove duplicate or nested vault roots.

Run obsidian-mcp doctor with the same --vault arguments after applying the suggested fix.

Diagnostic reference

Every startup diagnostic has a stable code and five useful parts: Problem, Detected, Fix, optional Verify, and More help. Diagnostics go to stderr so MCP stdout remains valid JSON-RPC. Usage errors exit with status 2; environment, configuration, and runtime startup failures exit with status 1.

Common CLI codes include CLI_UNKNOWN_COMMAND, CLI_UNKNOWN_OPTION, CLI_MISSING_OPTION_VALUE, CLI_INVALID_VAULT_ARGUMENT, CLI_VAULT_REQUIRED, and CLI_MIXED_CONFIG_SYNTAX. Typo diagnostics suggest the closest command or option. STARTUP_FAILED is reserved for unexpected failures; rerun with --log-level debug to include a stack trace.

Do not post logs without reviewing them: diagnostics can contain configured filesystem paths. They never include note contents or credentials intentionally.

Recovery changes

Version 2 uses .obsidian-mcp for transaction journals and MCP trash. It does not automatically modify or delete legacy .backup or .trash directories. Those directories are excluded from v2 scans and can be archived or removed manually after verifying their contents.

Version 1.x is deprecated, and its tool API receives no compatibility bridge. Upgrade promptly because its vault-containment implementation can permit access outside configured roots.

73 files · 66 not served here

Advantages

  • Provides transactional file mutations with conflict checking to prevent data loss. evidence: README.md
  • Implements strict filesystem safety, including path canonicalization and rejection of symlinks. evidence: README.md
  • Supports atomic tag management and automatic link rewriting during note moves. evidence: README.md

Limitations

Security

Risk level: Medium risk

This brain runs

MCP servers (1)

  • README.md (obsidian): npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/vault
  • Medium risk: runs-mcp-server-unpinned-runner (README.md:26)
  • Low risk: scripts-present (scripts/make-executable.mjs)

Attribution and licence

Created by
Steven Stavrakis
Declared authors
  • Steven Stavrakis (declared in package.json)
Publisher
Steven Stavrakis (Community)
Source
StevenStavrakis/obsidian-mcp · commit bd90097
Licence
MIT License (files served here)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Steven Stavrakis.

Install from source

66 of its files are not served here, so there is no ZIP. StevenStavrakis/obsidian-mcp at bd90097