Content
# MCP server for Obsidian (Go)
Go implementation of the MCP server to interact with Obsidian via the [Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) community plugin.
This is a port of the original [Python implementation](https://github.com/MarkusPfundstein/mcp-obsidian) by [Markus Pfundstein](https://github.com/MarkusPfundstein), built with the official [modelcontextprotocol/go-sdk](https://github.com/modelcontextprotocol/go-sdk).
> **Drop-in replacement:** All 13 tools expose the same names and parameters as the Python version. Existing Claude Desktop configs only need the `command` path updated to point at the Go binary — no other changes required.
## Why a Go port?
- **Easy distribution** — compile once, ship a single self-contained binary with no runtime dependencies. No Python, no `uv`, no virtual environments.
- **Optimised execution** — lower memory footprint and faster startup compared to the Python process.
- **Cross-platform** — `go build` produces native binaries for macOS, Linux, and Windows from the same source.
## Tools
| Tool | Description |
|------|-------------|
| `obsidian_list_files_in_vault` | Lists all files and directories in the root of your vault |
| `obsidian_list_files_in_dir` | Lists all files and directories in a specific vault directory |
| `obsidian_get_file_contents` | Returns the content of a single file |
| `obsidian_batch_get_file_contents` | Returns the contents of multiple files, concatenated |
| `obsidian_append_content` | Appends Markdown content to a new or existing file |
| `obsidian_put_content` | Creates or replaces a file with the given content |
| `obsidian_patch_content` | Inserts content relative to a heading, block reference, or frontmatter field |
| `obsidian_delete_file` | Deletes a file or directory from the vault |
| `obsidian_simple_search` | Full-text search across all vault files |
| `obsidian_complex_search` | JsonLogic query search (supports `glob` and `regexp` operators) |
| `obsidian_get_periodic_note` | Gets the current periodic note (daily/weekly/monthly/quarterly/yearly) |
| `obsidian_get_recent_periodic_notes` | Gets the most recent periodic notes for a given period type |
| `obsidian_get_recent_changes` | Gets recently modified vault files |
## Prerequisites
- Go 1.23 or later
- [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin installed and enabled in Obsidian
## Configuration
The server is configured via environment variables. You can set them directly or use a `.env` file in the working directory.
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `OBSIDIAN_API_KEY` | **Yes** | — | API key from the Obsidian plugin settings |
| `OBSIDIAN_HOST` | No | `127.0.0.1` | Hostname where Obsidian is running |
| `OBSIDIAN_PORT` | No | `27124` | Port of the Obsidian REST API plugin |
| `OBSIDIAN_PROTOCOL` | No | `https` | Protocol (`http` or `https`) |
Example `.env` file:
```env
OBSIDIAN_API_KEY=your_api_key_here
OBSIDIAN_HOST=127.0.0.1
OBSIDIAN_PORT=27124
```
You can find the API key in Obsidian → Settings → Local REST API.
## Quickstart
### Build
```sh
cd mcp-obsidian-go
go build -o mcp-obsidian ./cmd/mcp-obsidian
```
On Windows:
```sh
go build -o mcp-obsidian.exe ./cmd/mcp-obsidian
```
### Run
```sh
OBSIDIAN_API_KEY=your_key_here ./mcp-obsidian
```
## MCP Client Configuration
### Claude Desktop
Config file locations:
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
#### Using a pre-built binary
```json
{
"mcpServers": {
"mcp-obsidian-go": {
"command": "/path/to/mcp-obsidian",
"env": {
"OBSIDIAN_API_KEY": "<your_api_key_here>"
}
}
}
}
```
#### Using `go run` directly from source
```json
{
"mcpServers": {
"mcp-obsidian-go": {
"command": "go",
"args": [
"run",
"/path/to/mcp-obsidian-go/cmd/mcp-obsidian"
],
"env": {
"OBSIDIAN_API_KEY": "<your_api_key_here>",
"OBSIDIAN_HOST": "127.0.0.1",
"OBSIDIAN_PORT": "27124"
}
}
}
}
```
## Project Structure
```
mcp-obsidian-go/
├── cmd/
│ └── mcp-obsidian/
│ └── main.go # Entry point: wires config → client → MCP server
├── internal/
│ ├── config/
│ │ └── config.go # Loads and validates environment variables
│ ├── obsidian/
│ │ └── client.go # HTTP client for the Obsidian Local REST API
│ └── tools/
│ ├── vault.go # 8 vault file tools
│ ├── search.go # 2 search tools
│ ├── periodic.go # 3 periodic note / recent changes tools
│ └── register.go # Registers all tool groups with the MCP server
├── go.mod
└── go.sum
```
## Documentation
Detailed docs are in the [`docs/`](docs/) folder:
| Document | Description |
|----------|-------------|
| [docs/architecture.md](docs/architecture.md) | Data flow, package layout, and key design decisions |
| [docs/tools-reference.md](docs/tools-reference.md) | Full parameter reference and examples for all 13 tools |
| [docs/configuration.md](docs/configuration.md) | All environment variables, `.env` usage, and troubleshooting |
| [docs/clients.md](docs/clients.md) | Config snippets for Claude Desktop, Cursor, VS Code, and others |
| [docs/contributing.md](docs/contributing.md) | How to add new tools and contribution guidelines |
## Notes
- The Obsidian Local REST API uses a self-signed TLS certificate on localhost; TLS verification is intentionally disabled for the local connection.
- `obsidian_batch_get_file_contents` has no dedicated API endpoint — files are fetched sequentially and concatenated client-side.
- `obsidian_get_recent_changes` uses a Dataview DQL query under the hood; the Dataview plugin must be installed in Obsidian.
## Credits
This project is a Go port of [mcp-obsidian](https://github.com/MarkusPfundstein/mcp-obsidian) by [Markus Pfundstein](https://github.com/MarkusPfundstein). All credit for the original idea, tool design, and Python implementation goes to him.