Skip to main content
Glama
JeddowesF

Obsidian-MCP-For-Cursor

by JeddowesF
README.md
# Obsidian-MCP-For-Cursor

MCP server for [Obsidian](https://obsidian.md) vaults, optimised for **Cursor agents** — safe note editing, lean tool surface, direct filesystem access.

Forked from [@istrejo/obsidian-mcp](https://github.com/istrejo/obsidian-mcp) (MIT) with Cursor-specific enhancements.

## Features

- **10 agent-focused tools** — no unused `move_note`, `search_by_tags`, or `get_graph`
- **Safe writes** — `patch` and `replace_section` modes so agents cannot accidentally truncate notes with partial `replace`
- **Token-AND search** — multi-word vault search requires all terms to appear in a note
- **Optimistic concurrency** — `contentHash` on read, optional `expectedHash` on write

## Tools (v1)

| Tool | Purpose |
|------|---------|
| `read_note` | Read note body + frontmatter; returns `contentHash` |
| `update_note` | Safe edits: `patch`, `replace_section`, `append`, `prepend`, `replace` |
| `create_note` | Create a new note |
| `delete_note` | Delete a note |
| `list_notes` | List notes in the vault |
| `list_recent` | Recently modified notes |
| `search_content` | Full-text search (token-AND for multi-word queries) |
| `manage_frontmatter` | Get/set YAML frontmatter |
| `manage_folders` | Create/list vault folders |
| `get_backlinks` | Notes linking to a given note |

## Requirements

- Node.js >= 20
- An Obsidian vault path via `OBSIDIAN_VAULT_PATH`

## Setup

```bash
git clone https://github.com/JeddowesF/Obsidian-MCP-For-Cursor.git
cd Obsidian-MCP-For-Cursor
npm install
npm run build
npm test
```

## Cursor configuration

Copy the relevant section from [`examples/cursor-mcp.json`](examples/cursor-mcp.json) into `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "obsidian": {
      "command": "node",
      "args": ["/absolute/path/to/Obsidian-MCP-For-Cursor/dist/index.js"],
      "env": {
        "OBSIDIAN_VAULT_PATH": "/absolute/path/to/your/vault",
        "PATH": "/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
      }
    }
  }
}
```

Reload the Cursor window after saving.

## Safe write workflow

1. **Read** the note — note the `contentHash` in the response.
2. **Edit** using the safest mode:
   - `patch` — find/replace a unique substring (`old_string` / `new_string`)
   - `replace_section` — replace content under a heading (`heading` + `content`)
   - `append` / `prepend` — add content without touching existing body
   - `replace` — full body overwrite only; blocked if new body < 50% of existing unless `force: true`
3. Pass `expectedHash` from step 1 to detect concurrent edits.

### Example: patch a line

```json
{
  "path": "Projects/my-project",
  "mode": "patch",
  "old_string": "status: draft",
  "new_string": "status: done"
}
```

### Example: replace a section

```json
{
  "path": "Projects/my-project",
  "mode": "replace_section",
  "heading": "Next steps",
  "content": "- Ship v1\n- Write docs"
}
```

## Environment variables

| Variable | Required | Description |
|----------|----------|-------------|
| `OBSIDIAN_VAULT_PATH` | Yes | Absolute path to your Obsidian vault |
| `OBSIDIAN_READ_ONLY` | No | Set to `true` to disable writes |
| `OBSIDIAN_MAX_FILE_SIZE` | No | Max file size in bytes (default 10 MB) |
| `OBSIDIAN_LOG_LEVEL` | No | `debug`, `info`, `warn`, `error` (default `info`) |

## Development

```bash
npm run dev      # run server directly (stdio)
npm test         # vitest with coverage
npm run lint     # eslint
npm run typecheck
npm run build
```

## License

MIT — see [LICENSE](LICENSE). Upstream attribution: [@istrejo/obsidian-mcp](https://github.com/istrejo/obsidian-mcp).