palace-mcp
# palace-mcp
MCP server that exposes an Obsidian vault to AI assistants via the [Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin.
Built with [FastMCP](https://github.com/jlowin/fastmcp). Agents can list, read, write, search, and delete notes — and read whichever note is currently open in Obsidian.
## Prerequisites
- **Obsidian** with the [Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin installed and running
- **Python 3.12+**
- **[uv](https://docs.astral.sh/uv/)** (recommended) or pip
Copy your API key from the plugin settings in Obsidian before continuing.
## Installation
```bash
git clone <repo-url> palace-mcp
cd palace-mcp
uv sync
```
## Configuration
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `OBSIDIAN_API_KEY` | yes | — | Bearer token from the Local REST API plugin |
| `OBSIDIAN_HOST` | no | `127.0.0.1` | Host where Obsidian's REST API listens |
| `OBSIDIAN_PORT` | no | `27123` | Port for the REST API |
| `OBSIDIAN_PROTOCOL` | no | `http` | `http` or `https` |
| `PALACE_APPEND_DENY` | no | `/Context/,/System/,Index.md` | Comma-separated paths where `append_note` is blocked |
When using HTTPS with the plugin's self-signed certificate, certificate verification is skipped automatically.
## Running
Start the server over stdio (the default transport for MCP clients):
```bash
export OBSIDIAN_API_KEY="your-api-key"
uv run python server.py
```
Or via FastMCP:
```bash
uv run fastmcp run server.py
```
## Cursor setup
Add to your MCP config (e.g. `~/.cursor/mcp.json`):
```json
{
"mcpServers": {
"obsidian-palace": {
"command": "uv",
"args": ["run", "python", "server.py"],
"cwd": "/path/to/palace-mcp",
"env": {
"OBSIDIAN_API_KEY": "your-api-key-here"
}
}
}
}
```
Restart Cursor or reload MCP servers after saving.
## Tools
| Tool | Description |
|------|-------------|
| `list_notes` | List files and folders. Pass a subdirectory path, or leave empty for the vault root. |
| `read_note` | Read a note's full contents by vault-relative path (e.g. `People/Alice.md`). |
| `write_note` | Create a new note or overwrite an existing one. |
| `append_note` | Append text to the end of a note. Creates the note if it doesn't exist. |
| `search_notes` | Full-text search; returns matching filenames ranked by relevance. |
| `active_note` | Return the contents of the note currently open in Obsidian. |
| `delete_note` | Permanently delete a note. Irreversible — use with care. |
## Append protection
Some vault paths are treated as **overwrite-only**. Appending to them can silently stack duplicate content inside a single note, which is hard to detect later.
By default, `append_note` is refused for paths matching:
- `/Context/` (any note under a `Context` folder)
- `/System/` (any note under a `System` folder)
- `Index.md` (any file named `Index.md`)
Use `write_note` to replace these notes instead. Override the deny list with the `PALACE_APPEND_DENY` environment variable.
## License
MIT
TDQS
Scored across 7 tools
Each tool maps to a distinct file operation: listing, reading, writing, appending, searching, accessing the active note, and deleting. There is no meaningful overlap between tool purposes.
Most tools follow a clear verb_note pattern: read_note, write_note, append_note, delete_note, and search_notes. The deviations are minor: list_notes uses plural and active_note is adjective_noun, but the overall convention is still predictable.
Seven tools is a well-scoped set for an Obsidian vault server. Each tool covers a necessary note operation without unnecessary bloat.
The core note lifecycle is covered: list, read, write, append, search, and delete. Missing operations like rename, move, or folder management are minor gaps that agents can usually work around by writing to a new path.