obsidian-mcp (Python)
A Python MCP (Model Context Protocol) server giving an LLM client (e.g. Claude Desktop) read/write access to local Obsidian vaults, via direct filesystem access — no Obsidian Local REST API plugin, no HTTP, no auth token required.
This is a Python port of obsidian-mcp (TypeScript), functionally equivalent with a few deliberate fixes and simplifications — see Plans/review-the-typescript-obsidian-mcp-parsed-shamir.md and ISA.md for the full rationale.
Warning: This server has read/write access to your vault. Back up your notes (e.g. via git) before use.
Requirements
- Python 3.11+
uv- An Obsidian vault (a directory that has been opened by Obsidian at least once, i.e. contains a
.obsidian/app.json) - macOS or Linux (Windows is not supported — see ISA "Out of Scope")
Install & run
The PyPI distribution is named py-obsidian-mcp (the obsidian-mcp name was already taken by an unrelated project) — the installed command is still obsidian-mcp.
uvx --from py-obsidian-mcp obsidian-mcp /path/to/your/vault [/path/to/another/vault ...]
# or: pip install py-obsidian-mcp && obsidian-mcp /path/to/your/vault
From source (development)
uv sync
uv run obsidian-mcp /path/to/your/vault [/path/to/another/vault ...]
Vault names are auto-derived from each directory's basename (lowercased, non-alphanumeric characters become hyphens, duplicates get a numeric suffix). Up to 10 vaults; vault paths must not be nested inside one another.
Claude Desktop configuration
Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"obsidian": {
"command": "uvx",
"args": ["--from", "py-obsidian-mcp", "obsidian-mcp", "/path/to/your/vault"]
}
}
}
Or, running from a local clone instead of the published package:
{
"mcpServers": {
"obsidian": {
"command": "uv",
"args": ["run", "--directory", "/path/to/py-obsidian-mcp", "obsidian-mcp", "/path/to/your/vault"]
}
}
}
Tools
read-note, create-note, edit-note (append/prepend/replace/delete), delete-note (soft-delete to .trash/ by default), move-note, create-directory, search-vault (content/filename/tag search, with an optional max_results), add-tags, remove-tags, rename-tag (vault-wide, hierarchy-preserving), list-available-vaults.
Also exposes an obsidian-vault:// resource scheme (vault listing/info) and a list-vaults prompt.
Development
uv sync --all-extras
uv run pytest -q
uv run ruff check src tests
Security notes
- Every tool validates that target paths stay within the vault (
src/obsidian_mcp/utils/path_safety.py), including symlink-aware containment checks. - The TypeScript original had a confirmed bug where this containment check was effectively a no-op (an async validation function was called without
await). This port's path-safety functions are all synchronous, structurally preventing that class of bug.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_obsidian_mcp-0.1.1.tar.gz.
File metadata
- Download URL: py_obsidian_mcp-0.1.1.tar.gz
- Upload date:
- Size: 27.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f40ec8642fba43e6c75f7c87a3835068f06747c2d9d4f7ee9d8d31bc45ed4db0
|
|
| MD5 |
65ee7b7db480fd01f0d7937215218683
|
|
| BLAKE2b-256 |
651f4ae9ad1d7281592a88411779f14315df30c49ff9a6aa0685dac250331e10
|
Provenance
The following attestation bundles were made for py_obsidian_mcp-0.1.1.tar.gz:
Publisher:
release.yml on ubahmapk/py-obsidian-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_obsidian_mcp-0.1.1.tar.gz -
Subject digest:
f40ec8642fba43e6c75f7c87a3835068f06747c2d9d4f7ee9d8d31bc45ed4db0 - Sigstore transparency entry: 2572844100
- Sigstore integration time:
-
Permalink:
ubahmapk/py-obsidian-mcp@ad436c48765685ee4ba816707e128021e10fe01e -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ubahmapk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ad436c48765685ee4ba816707e128021e10fe01e -
Trigger Event:
push
-
Statement type:
File details
Details for the file py_obsidian_mcp-0.1.1-py3-none-any.whl.
File metadata
- Download URL: py_obsidian_mcp-0.1.1-py3-none-any.whl
- Upload date:
- Size: 44.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88bdae5b22bbdbcea5c90a897ddd5c4766d7e8f0b52dbbf920f28bf7882ba3f0
|
|
| MD5 |
9a99f467c528770c4f84062468528471
|
|
| BLAKE2b-256 |
3592654288c7e42842b63ce7c921eb4e432c6f2ce5b8e28a0f006f46b7c44bb3
|
Provenance
The following attestation bundles were made for py_obsidian_mcp-0.1.1-py3-none-any.whl:
Publisher:
release.yml on ubahmapk/py-obsidian-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_obsidian_mcp-0.1.1-py3-none-any.whl -
Subject digest:
88bdae5b22bbdbcea5c90a897ddd5c4766d7e8f0b52dbbf920f28bf7882ba3f0 - Sigstore transparency entry: 2572844844
- Sigstore integration time:
-
Permalink:
ubahmapk/py-obsidian-mcp@ad436c48765685ee4ba816707e128021e10fe01e -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ubahmapk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ad436c48765685ee4ba816707e128021e10fe01e -
Trigger Event:
push
-
Statement type: