# Obsidian MCP Server

MCP server that gives LLM agents access to your [Obsidian](https://obsidian.md) vault through the official [Obsidian CLI](https://help.obsidian.md/cli). Read, create, search notes, manage tasks, tags, properties, plugins and more — all via the [Model Context Protocol](https://modelcontextprotocol.io).

> **Important:** This server requires the **Obsidian desktop app running** on your machine. The CLI is a bridge to the app's internal API — it does not work without a running Obsidian instance.

## Prerequisites

### 1. Obsidian 1.12+

You need Obsidian version **1.12 or later** (with the latest installer — 1.12.4+).

Download: https://obsidian.md/download

### 2. Enable CLI in Obsidian

1. Open Obsidian
2. Go to **Settings** → **General**
3. Enable **Command line interface**
4. Follow the prompt to register the CLI
5. **Restart your terminal** for PATH changes to take effect

Verify it works:

```bash
obsidian --version
```

> **Windows users:** You also need the `Obsidian.com` terminal redirector file, available to [Catalyst](https://obsidian.md/pricing) members on the Obsidian Discord.

### 3. Python 3.11+ and uv

Install [uv](https://docs.astral.sh/uv/getting-started/installation/) if you don't have it:

```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

## Installation

Clone the repository and install dependencies:

```bash
git clone https://github.com/Storks/obsidian-mcp.git
cd obsidian-mcp
uv sync
```

Verify everything is set up:

```bash
uv run obsidian-mcp
```

The server communicates via stdio, so you won't see any output — it's waiting for MCP messages. Press `Ctrl+C` to stop.

## Connecting to LLM agents

The server uses **stdio** transport. Every MCP client needs to know how to start the process: run `uv` with the project directory and the `obsidian-mcp` command.

Below are configuration examples for popular tools. Replace `/path/to/obsidian-mcp` with the actual path where you cloned the repository.

---

### Claude Code

Add via CLI:

```bash
claude mcp add obsidian-mcp -- uv run --directory /path/to/obsidian-mcp obsidian-mcp
```

Or add manually to `.mcp.json` in your project root (or `~/.claude.json` for global access):

```json
{
  "mcpServers": {
    "obsidian-mcp": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "/path/to/obsidian-mcp", "obsidian-mcp"]
    }
  }
}
```

#### Restricting available tools

The server exposes 54 tools — you may not need all of them. Claude Code lets you allow or deny specific tools via `.claude/settings.json` (project-level) or `~/.claude/settings.json` (global). Tools follow the naming pattern `mcp__obsidian-mcp__<tool_name>`.

**Example: read-only mode** — deny any tool that can modify the vault:

```json
{
  "permissions": {
    "deny": [
      "mcp__obsidian-mcp__obsidian_create",
      "mcp__obsidian-mcp__obsidian_append",
      "mcp__obsidian-mcp__obsidian_prepend",
      "mcp__obsidian-mcp__obsidian_delete",
      "mcp__obsidian-mcp__obsidian_move",
      "mcp__obsidian-mcp__obsidian_rename",
      "mcp__obsidian-mcp__obsidian_property_set",
      "mcp__obsidian-mcp__obsidian_property_remove",
      "mcp__obsidian-mcp__obsidian_task",
      "mcp__obsidian-mcp__obsidian_bookmark",
      "mcp__obsidian-mcp__obsidian_base_create",
      "mcp__obsidian-mcp__obsidian_plugin_enable",
      "mcp__obsidian-mcp__obsidian_plugin_disable",
      "mcp__obsidian-mcp__obsidian_plugin_install",
      "mcp__obsidian-mcp__obsidian_plugin_reload",
      "mcp__obsidian-mcp__obsidian_workspace_save",
      "mcp__obsidian-mcp__obsidian_workspace_load"
    ]
  }
}
```

**Example: allow only specific tools** — useful when you want a minimal set:

```json
{
  "permissions": {
    "allow": [
      "mcp__obsidian-mcp__obsidian_read",
      "mcp__obsidian-mcp__obsidian_search",
      "mcp__obsidian-mcp__obsidian_search_context",
      "mcp__obsidian-mcp__obsidian_files",
      "mcp__obsidian-mcp__obsidian_tags",
      "mcp__obsidian-mcp__obsidian_outline"
    ]
  }
}
```

Any tool not listed in `allow` will require manual confirmation before each use.

---

### OpenCode

Add to `opencode.json` in your project root (or `~/.config/opencode/opencode.json` for global access):

```json
{
  "mcp": {
    "obsidian-mcp": {
      "type": "local",
      "command": ["uv", "run", "--directory", "/path/to/obsidian-mcp", "obsidian-mcp"],
      "enabled": true
    }
  }
}
```

---

### Codex (OpenAI)

Add via CLI:

```bash
codex mcp add obsidian-mcp -- uv run --directory /path/to/obsidian-mcp obsidian-mcp
```

Or add manually to `~/.codex/config.toml`:

```toml
[mcp_servers.obsidian-mcp]
command = "uv"
args = ["run", "--directory", "/path/to/obsidian-mcp", "obsidian-mcp"]
```

---

## Configuration

Environment variables (all optional):

| Variable | Default | Description |
|---|---|---|
| `OBSIDIAN_PATH` | `obsidian` | Path to the Obsidian CLI binary |
| `OBSIDIAN_TIMEOUT` | `30` | Command timeout in seconds |
| `OBSIDIAN_VAULT` | — | Default vault name (if not specified per-call) |

Example with environment variables in `.mcp.json`:

```json
{
  "mcpServers": {
    "obsidian-mcp": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "/path/to/obsidian-mcp", "obsidian-mcp"],
      "env": {
        "OBSIDIAN_VAULT": "My Notes",
        "OBSIDIAN_TIMEOUT": "60"
      }
    }
  }
}
```

## Available tools (54)

Every tool accepts an optional `vault` parameter to target a specific vault.

### Files (12)

| Tool | Description |
|---|---|
| `obsidian_create` | Create or overwrite a file |
| `obsidian_read` | Read file contents |
| `obsidian_append` | Append content to a file |
| `obsidian_prepend` | Prepend content after frontmatter |
| `obsidian_delete` | Delete a file |
| `obsidian_move` | Move or rename a file |
| `obsidian_rename` | Rename a file |
| `obsidian_open` | Open a file in Obsidian |
| `obsidian_file_info` | Show file info |
| `obsidian_files` | List files in the vault |
| `obsidian_folder_info` | Show folder info |
| `obsidian_folders` | List folders in the vault |

### Search (2)

| Tool | Description |
|---|---|
| `obsidian_search` | Search vault for text |
| `obsidian_search_context` | Search with matching line context |

### Daily Notes (5)

| Tool | Description |
|---|---|
| `obsidian_daily` | Open today's daily note |
| `obsidian_daily_path` | Get daily note file path |
| `obsidian_daily_read` | Read daily note contents |
| `obsidian_daily_append` | Append content to daily note |
| `obsidian_daily_prepend` | Prepend content to daily note |

### Tasks (2)

| Tool | Description |
|---|---|
| `obsidian_tasks` | List tasks in the vault |
| `obsidian_task` | Show or update a task |

### Tags (2)

| Tool | Description |
|---|---|
| `obsidian_tags` | List tags in the vault |
| `obsidian_tag` | Get tag info |

### Properties (4)

| Tool | Description |
|---|---|
| `obsidian_properties` | List properties in the vault |
| `obsidian_property_set` | Set a property on a file |
| `obsidian_property_remove` | Remove a property from a file |
| `obsidian_property_read` | Read a property value |

### Links (5)

| Tool | Description |
|---|---|
| `obsidian_backlinks` | List backlinks to a file |
| `obsidian_links` | List outgoing links from a file |
| `obsidian_unresolved` | List unresolved links |
| `obsidian_orphans` | List files with no incoming links |
| `obsidian_deadends` | List files with no outgoing links |

### Outline (1)

| Tool | Description |
|---|---|
| `obsidian_outline` | Show headings for a file |

### Templates (1)

| Tool | Description |
|---|---|
| `obsidian_templates` | List available templates |

### Bookmarks (2)

| Tool | Description |
|---|---|
| `obsidian_bookmarks` | List bookmarks |
| `obsidian_bookmark` | Add a bookmark |

### Vault (1)

| Tool | Description |
|---|---|
| `obsidian_vault` | Show vault info |

### Word Count (1)

| Tool | Description |
|---|---|
| `obsidian_wordcount` | Count words and characters |

### Plugins (7)

| Tool | Description |
|---|---|
| `obsidian_plugins` | List installed plugins |
| `obsidian_plugins_enabled` | List enabled plugins |
| `obsidian_plugin_info` | Get plugin info |
| `obsidian_plugin_enable` | Enable a plugin |
| `obsidian_plugin_disable` | Disable a plugin |
| `obsidian_plugin_install` | Install a community plugin |
| `obsidian_plugin_reload` | Reload a plugin |

### Workspace (4)

| Tool | Description |
|---|---|
| `obsidian_workspace` | Show workspace tree |
| `obsidian_workspaces` | List saved workspaces |
| `obsidian_workspace_save` | Save current layout |
| `obsidian_workspace_load` | Load a saved workspace |

### Bases (3)

| Tool | Description |
|---|---|
| `obsidian_bases` | List .base files in the vault |
| `obsidian_base_create` | Create a new item in a base |
| `obsidian_base_query` | Query a base and return results |

### History (2)

| Tool | Description |
|---|---|
| `obsidian_diff` | Compare file versions |
| `obsidian_history` | List file versions |

## Development

```bash
# Install dev dependencies
uv sync

# Run tests
uv run pytest tests/ -v
```

## License

MIT
