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
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.
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 5 |
| docs | docs | 2 |
| scripts | scripts | 4 |
| src | source-code | 34 |
| test | tests | 8 |
| evaluations | folder | 7 |
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
- 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
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 newerRun 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/vaultConfigure 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@2Each 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/PersonalVaultNetwork, 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:
obsidian-mcp serve --vault work=/path \
--recovery-days 14 \
--recovery-max-bytes 536870912Inspect 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.trashfrom 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
npm ci
npm run typecheck
npm test
npm run build
npm run ciEach 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
SECURITY.md
Security policy
Supported versions
The latest 2.x release is supported. Version 1.x is deprecated and contains known path-containment defects.
Reporting a vulnerability
Do not open a public issue for an undisclosed vulnerability. Use GitHub's private vulnerability reporting feature for this repository and include:
affected version and platform;
a minimal reproduction using a disposable vault;
expected and observed behavior;
impact and any known mitigations.
Avoid including real vault contents or personal filesystem paths. Maintainers should acknowledge a complete report within seven days and coordinate disclosure after a fix is available.
Security boundary
An explicit --vault id=/absolute/path grants this local process read/write access to that root. MCP tool paths must remain within it. The server does not authenticate local stdio clients; the launching MCP host controls who can invoke the process and which vault arguments it receives.
73 files · 66 not served here
- .github/ISSUE_TEMPLATE/bug_report.md (not served here)
- .github/ISSUE_TEMPLATE/feature_request.md (not served here)
- .github/dependabot.yml (not served here)
- .github/workflows/ci.yml (not served here)
- .github/workflows/codeql.yml (not served here)
- .gitignore (not served here)
- .prettierignore (not served here)
- .prettierrc.json (not served here)
- ATTRIBUTION.md
- LICENSE
- MIGRATING.md
- README.md
- SECURITY.md
- docs/creating-tools.md
- docs/tool-examples.md
- eslint.config.js (not served here)
- evaluations/README.md (not served here)
- evaluations/fixture-vault/.obsidian/app.json (not served here)
- evaluations/fixture-vault/Architecture/Relay Architecture.md (not served here)
- evaluations/fixture-vault/Meetings/2024-06-15.md (not served here)
- evaluations/fixture-vault/Projects/Orchid Release.md (not served here)
- evaluations/fixture-vault/Projects/Orchid Retrospective.md (not served here)
- evaluations/read-only.xml (not served here)
- example.ts (not served here)
- package-lock.json (not served here)
- package.json (not served here)
- scripts/check-package.mjs (not served here)
- scripts/clean.mjs (not served here)
- scripts/make-executable.mjs (not served here)
- scripts/validate-evaluations.mjs (not served here)
- src/cli.ts (not served here)
- src/constants.ts (not served here)
- src/main.ts (not served here)
- src/resources/index.ts (not served here)
- src/resources/vault/index.ts (not served here)
- src/runtime.ts (not served here)
- src/server.ts (not served here)
- src/tools/add-tags/index.ts (not served here)
- src/tools/create-directory/index.ts (not served here)
- src/tools/create-note/index.ts (not served here)
- src/tools/delete-note/index.ts (not served here)
- src/tools/edit-note/index.ts (not served here)
- src/tools/index.ts (not served here)
- src/tools/list-vaults/index.ts (not served here)
- src/tools/manage-tags/index.ts (not served here)
- src/tools/move-note/index.ts (not served here)
- src/tools/read-note/index.ts (not served here)
- src/tools/remove-tags/index.ts (not served here)
- src/tools/rename-tag/index.ts (not served here)
- src/tools/search-vault/index.ts (not served here)
- src/tools/shared/tag-mutation.ts (not served here)
- src/types.ts (not served here)
- src/utils/diagnostics.ts (not served here)
- src/utils/errors.ts (not served here)
- src/utils/hash.ts (not served here)
- src/utils/links.ts (not served here)
- src/utils/logger.ts (not served here)
- src/utils/schemas.ts (not served here)
- src/utils/search.ts (not served here)
- src/utils/tags.ts (not served here)
- src/utils/tool-factory.ts (not served here)
- src/utils/transaction.ts (not served here)
- src/utils/validation.ts (not served here)
- src/utils/vault.ts (not served here)
- test/cli.test.ts (not served here)
- test/helpers.ts (not served here)
- test/integration/server.test.ts (not served here)
- test/markdown.test.ts (not served here)
- test/schema-contracts.test.ts (not served here)
- test/tool-registry.test.ts (not served here)
- test/transaction.test.ts (not served here)
- test/vault.test.ts (not served here)
- tsconfig.json (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
- Requires Node.js 22 or newer to operate. evidence: README.md
- Tool text responses are capped at 25,000 characters. evidence: README.md
- Requires explicit configuration of vault paths at startup; dynamic discovery is not supported. evidence: README.md
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