MCP server to interact with Obsidian via the Local REST API plugin
Project description
MCP server for Obsidian
MCP server providing tools to interact with Obsidian via the Local REST API community plugin, including active note operations, periodic notes management, and command execution.
Note: This is a maintained fork of MarkusPfundstein/mcp-obsidian.
Roadmap to v1.0.0
This fork is in active development (v0.x.x). The v1.0.0 release will mark the first stable API. Expect things to be in flux. I am adding tool coverage but will attempt to streamline them to keep our context footprint as small as possible. Currently, I am just exposing REST endpoints I think might be useful as tools, but expect some of these to change.
Current Status (v0.4.x)
- 26 tools covering file operations, active notes, periodic notes, and commands
- Template-aware heading insertion
- Robust path encoding for special characters and Unicode
Planned for v1.0.0
- Streamlined tool surface — Reduce token footprint by consolidating convenience wrappers (e.g.,
patch_active→get_active+patch_content) - Stable API contract — Tool names, parameters, and behaviors locked for backwards compatibility
- Comprehensive test coverage — All tools tested with CI
- Published to PyPI — Available via
uvx mcp-obsidian-ekwith version pinning
Breaking Changes Expected
The v1.0.0 release will likely remove convenience tools that can be accomplished with two-step workflows:
obsidian_post_active,obsidian_put_active,obsidian_patch_active,obsidian_delete_activeobsidian_post_periodic,obsidian_put_periodic,obsidian_patch_periodic,obsidian_delete_periodic
These operations will still be possible using get_active/get_periodic_note followed by the corresponding file operation.
Requirements
Obsidian Plugins
| Plugin | Required | Notes |
|---|---|---|
| Local REST API | Yes | v3.0+ recommended |
| Periodic Notes | Optional | Required for weekly/monthly/quarterly/yearly notes |
| Dataview | Optional | Required for get_recent_changes tool |
The core Daily Notes plugin (built into Obsidian) is sufficient for daily periodic notes.
Tools
The server implements 26 tools to interact with Obsidian, organized by functionality:
File & Content Operations
- obsidian_list_files_in_vault: Lists all files and directories in the root directory of your Obsidian vault
- obsidian_list_files_in_dir: Lists all files and directories in a specific Obsidian directory
- obsidian_get_file_contents: Return the content of a single file in your vault
- obsidian_batch_get_file_contents: Return the contents of multiple files in your vault, concatenated with headers
- obsidian_simple_search: Search for documents matching a specified text query across all files in the vault
- obsidian_complex_search: Complex search for documents using JsonLogic queries with glob and regexp support
- obsidian_patch_content: Insert content into an existing note relative to a heading, block reference, or frontmatter field. Automatically creates missing headings with template-aware positioning
- obsidian_append_content: Append content to a new or existing file in the vault
- obsidian_put_content: Create a new file or update the content of an existing file in your vault
- obsidian_delete_file: Delete a file or directory from your vault
Active Note Operations
- obsidian_get_active: Get content of the currently active note in Obsidian
- obsidian_post_active: Append content to the currently active note
- obsidian_put_active: Replace entire content of the currently active note
- obsidian_patch_active: Insert/replace content in active note relative to a heading, block reference, or frontmatter field
- obsidian_delete_active: Delete the currently active note
Periodic Notes Management
- obsidian_get_periodic_note: Get current periodic note for specified period (daily/weekly/monthly/quarterly/yearly)
- obsidian_post_periodic: Append content to the current periodic note
- obsidian_put_periodic: Replace entire content of the current periodic note
- obsidian_patch_periodic: Insert/replace content in periodic note relative to a heading, block reference, or frontmatter field
- obsidian_delete_periodic: Delete the current periodic note
Commands & UI Control
- obsidian_get_commands: List all available Obsidian commands from the command palette
- obsidian_execute_command: Execute a specific Obsidian command by its ID
- obsidian_open_file: Open a file in Obsidian UI, optionally in a new tab/pane
Advanced Features
- obsidian_get_recent_periodic_notes: Get most recent periodic notes for specified period type
- obsidian_get_recent_changes: Get recently modified files in the vault
- obsidian_dataview_query: Execute a Dataview DQL query against the vault (requires Dataview plugin)
Example prompts
It's good to first instruct Claude to use Obsidian. Then it will always call the tool.
File & Search Operations
- Get the contents of the last architecture call note and summarize them
- Search for all files where Azure CosmosDb is mentioned and quickly explain to me the context in which it is mentioned
- Summarize the last meeting notes and put them into a new note 'summary meeting.md'. Add an introduction so that I can send it via email
- Find all notes containing project deadlines and create a consolidated timeline
Active Note Operations
- Add this meeting summary to the note I currently have open
- Replace the active note content with the updated version I'm about to provide
- Insert a new "Action Items" section under the "Meeting Notes" heading in my active document
- Append today's accomplishments to whatever note I have open right now
Periodic Notes Management
- Add today's tasks to my daily note
- Get the content of this week's weekly note and summarize the key points
- Create a monthly review section in my monthly periodic note with this quarter's achievements
- Append my standup update to today's daily note
- Show me what's in my quarterly note and help me plan the next quarter
Command Execution & UI Control
- Open my project notes in a new tab so I can reference them
- Execute the 'Toggle Reading View' command to switch the current view
- Show me all available Obsidian commands so I can see what's possible
- Open the file 'Projects/2024/planning.md' in a new pane
- Run the command to create a new note from my meeting template
Path Encoding & Filename Support
The server includes robust path encoding that handles filenames with spaces, special characters, Unicode, and emojis. All file operations work seamlessly with complex filenames.
Supported Filename Types
- Spaces:
Projects/2024 Q1/meeting notes.md - Unicode characters:
Área/configuração/São Paulo.md - Special characters:
Research (2024)/data #1 & analysis + results.md - Emojis:
Projects 🚀/📘 documentation/notes ⭐.md - Mixed types:
Área (Special) & More + [Data] = Value #1 🚀.md
Technical Features
- Idempotent: Prevents double-encoding of already encoded paths
- Unicode normalization: Normalizes to NFC for cross-platform consistency
- RFC 3986 compliant: Preserves safe characters (-_.~) while encoding others
- Directory structure preservation: Maintains "/" separators and trailing "/" slashes
- Backward compatible: No changes to existing simple filename behavior
Example Operations
# All these filename types work with any operation:
obsidian_get_file_contents("Projects/Meeting Notes 📝.md")
obsidian_append_content("Área/configuração.md", "New content")
obsidian_list_files_in_dir("Special (Folder) & More")
obsidian_patch_content("Research #1/data + analysis.md", ...)
obsidian_list_files_in_dir("Reports/2024/")
Template-Aware Heading Insertion
When using obsidian_patch_content (or similar patch operations) to insert content under a heading that doesn't exist, the server automatically creates the heading. By default, it uses template-aware positioning to maintain consistent document structure.
How It Works
-
Auto-create missing headings: When you patch content to a heading that doesn't exist, the heading is created automatically (enabled by default, can be disabled with
create_heading_if_missing: false) -
Template detection: The server looks for a template to determine where the new heading should be inserted:
- First checks the note's frontmatter for a
template:field - Falls back to folder convention:
Daily Notes/*.md→Templates/Daily Notes.md
- First checks the note's frontmatter for a
-
Position-aware insertion: If a template is found, the new heading is inserted in the correct position based on the template's heading order, rather than appended to the end
Example
If your template (Templates/Daily Notes.md) has:
## Todos
## Notes
## Journal
And your daily note only has ## Todos and ## Journal, patching content to Notes will insert it between them—not at the end.
Frontmatter Template Reference
Add a template: field to your note's frontmatter to specify which template defines the heading structure:
---
template: Daily Note.md
---
The server will look for Templates/Daily Note.md (or the full path if provided).
Parameters
| Parameter | Default | Description |
|---|---|---|
create_heading_if_missing |
true |
Create the heading if it doesn't exist |
template_path |
auto-detect | Explicit path to template file |
use_template |
true |
Use template for heading positioning |
Disabling Template Positioning
To always append new headings to the end (original behavior), set use_template: false:
obsidian_patch_content(
filepath="Daily Notes/2024-01-15.md",
operation="append",
target_type="heading",
target="New Section",
content="Content here",
use_template=False # Always append to end
)
Configuration
Obsidian REST API Key
There are two ways to configure the environment with the Obsidian REST API Key.
- Add to server config (preferred)
{
"mcp-obsidian-ek": {
"command": "uvx",
"args": [
"mcp-obsidian-ek"
],
"env": {
"OBSIDIAN_API_KEY": "<your_api_key_here>"
}
}
}
Note: OBSIDIAN_HOST (default: 127.0.0.1) and OBSIDIAN_PORT (default: 27124) are optional.
Sometimes Claude has issues detecting the location of uvx. You can use which uvx to find and paste the full path in the config.
- Create a
.envfile in the working directory with the following required variables:
OBSIDIAN_API_KEY=your_api_key_here
OBSIDIAN_HOST=your_obsidian_host
OBSIDIAN_PORT=your_obsidian_port
Note:
- You can find the API key in the Obsidian plugin config
- Default port is 27124 if not specified
- Default host is 127.0.0.1 if not specified
Quickstart
Install
Obsidian REST API
You need the Obsidian REST API community plugin running: https://github.com/coddingtonbear/obsidian-local-rest-api
Install and enable it in the settings and copy the api key.
Claude Desktop
On MacOS: ~/Library/Application\ Support/Claude/claude_desktop_config.json
On Windows: %APPDATA%/Claude/claude_desktop_config.json
Development (from local repo)
{
"mcpServers": {
"mcp-obsidian-ek": {
"command": "uv",
"args": [
"--directory",
"/path/to/mcp-obsidian",
"run",
"mcp-obsidian-ek"
],
"env": {
"OBSIDIAN_API_KEY": "<your_api_key_here>"
}
}
}
}
Published (from PyPI)
{
"mcpServers": {
"mcp-obsidian-ek": {
"command": "uvx",
"args": [
"mcp-obsidian-ek"
],
"env": {
"OBSIDIAN_API_KEY": "<your_api_key_here>"
}
}
}
}
Development
Building
To prepare the package for distribution:
- Sync dependencies and update lockfile:
uv sync
Debugging
Since MCP servers run over stdio, debugging can be challenging. For the best debugging experience, we strongly recommend using the MCP Inspector.
You can launch the MCP Inspector via npm with this command:
npx @modelcontextprotocol/inspector uv --directory /path/to/mcp-obsidian run mcp-obsidian-ek
Upon launching, the Inspector will display a URL that you can access in your browser to begin debugging.
You can also watch the server logs with this command:
tail -n 20 -f ~/Library/Logs/Claude/mcp-server-mcp-obsidian-ek.log
Project details
Release history Release notifications | RSS feed
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 mcp_obsidian_ek-0.6.4.tar.gz.
File metadata
- Download URL: mcp_obsidian_ek-0.6.4.tar.gz
- Upload date:
- Size: 106.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7c00b3a948014877c22102ba3faa65dbce40698bcdc3618eadbce13c3efc51d
|
|
| MD5 |
761eedeaceb53a26107f081ddda15a19
|
|
| BLAKE2b-256 |
bbdd963babcd6103e17d0c29533df0255a76b0e90fc10f8ed37d622b9d701552
|
Provenance
The following attestation bundles were made for mcp_obsidian_ek-0.6.4.tar.gz:
Publisher:
release.yml on ernestkoe/mcp-obsidian-ek
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_obsidian_ek-0.6.4.tar.gz -
Subject digest:
a7c00b3a948014877c22102ba3faa65dbce40698bcdc3618eadbce13c3efc51d - Sigstore transparency entry: 789726470
- Sigstore integration time:
-
Permalink:
ernestkoe/mcp-obsidian-ek@386a9c63b518cf87f4083aade8f25f959323859f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ernestkoe
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@386a9c63b518cf87f4083aade8f25f959323859f -
Trigger Event:
push
-
Statement type:
File details
Details for the file mcp_obsidian_ek-0.6.4-py3-none-any.whl.
File metadata
- Download URL: mcp_obsidian_ek-0.6.4-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08db0d7657cd869d9eff39f70cb3cdb9c12544d792aaec2e8e0666c541d494bd
|
|
| MD5 |
671b9f22bb15be7d4c1ad6293e6922b3
|
|
| BLAKE2b-256 |
c466e60f73d1944c2b2eed8f1f67f6316e5d32ddd09aba6a145356f81b75c7f3
|
Provenance
The following attestation bundles were made for mcp_obsidian_ek-0.6.4-py3-none-any.whl:
Publisher:
release.yml on ernestkoe/mcp-obsidian-ek
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_obsidian_ek-0.6.4-py3-none-any.whl -
Subject digest:
08db0d7657cd869d9eff39f70cb3cdb9c12544d792aaec2e8e0666c541d494bd - Sigstore transparency entry: 789726471
- Sigstore integration time:
-
Permalink:
ernestkoe/mcp-obsidian-ek@386a9c63b518cf87f4083aade8f25f959323859f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ernestkoe
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@386a9c63b518cf87f4083aade8f25f959323859f -
Trigger Event:
push
-
Statement type: