# Obsidian REST API

> Call the Obsidian Local REST API directly (over HTTP) for vault operations that the mcp__obsidian__* tools do NOT expose. Use when needing to move/rename a note, overwrite a whole file atomically (PUT), act on the currently-open "active" file, run an Obsidian command, open a note in the UI, list all tags, or do date-specific periodic-note CRUD. Prefer the mcp__obsidian__* tools for plain read/append/patch/delete/search; fall back to this skill only when the required method is missing from MCP.

- Skill: `tommass/obsidian-rest-api` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tommass/obsidian-rest-api`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tommass/obsidian-rest-api/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: TomMaSS (https://skillmd.com/u/tommass)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tommass/obsidian-rest-api

---


# Obsidian Local REST API (fallback for missing MCP methods)

## Overview

The connected `obsidian` MCP server exposes only a subset of the Obsidian **Local REST API** (plugin `obsidian-local-rest-api`, v4.1.x). This skill provides the full API surface plus an authenticated wrapper, so a missing MCP method is called over HTTP instead of being worked around with hacks (e.g. delete+recreate to rename).

## When to use

1. First choice is always the `mcp__obsidian__*` tools — read, append, patch, delete, simple/complex search, periodic-note read. Do not use this skill for those.
2. Fall back here only when the needed operation has **no MCP tool**. The REST-only operations are:
   - **Move / rename** a note (`MOVE /vault/{filename}`) — preserves history, updates internal links.
   - **Overwrite a whole file atomically** (`PUT /vault/{filename}`) — instead of MCP delete+recreate.
   - **Active-file** operations (`/active/` GET/PUT/POST/PATCH/DELETE) — the note open in the UI.
   - **Run an Obsidian command** (`GET /commands/`, `POST /commands/{id}/`).
   - **Open/focus a note in the UI** (`POST /open/{filename}`).
   - **List all tags with counts** (`GET /tags/`).
   - **Date-specific / mutating periodic notes** (`/periodic/{period}/...` PUT/POST/PATCH/DELETE).

## How to call

Use the wrapper `scripts/olrapi.sh` — it resolves host/port/API-key from the obsidian MCP server config (`~/.claude.json`) or `OBSIDIAN_*` env vars, and handles the self-signed TLS cert. Never hardcode the key.

```bash
S=~/.claude/skills/obsidian-rest-api/scripts/olrapi.sh

# rename/move a note (the most common reason to reach for this skill)
"$S" MOVE "/vault/Path/To/Old Name.md" -H 'Destination: Path/To/New Name.md'

# move into a folder, keeping the filename (trailing slash on Destination)
"$S" MOVE "/vault/Inbox/todo.md" -H 'Destination: Archive/'

# atomically overwrite a whole note
"$S" PUT "/vault/Path/Note.md" -H 'Content-Type: text/markdown' --data-binary @/tmp/new_body.md

# read a note as structured JSON (frontmatter + tags + stat)
"$S" GET "/vault/Path/Note.md" -H 'Accept: application/vnd.olrapi.note+json'

# list all tags, run a command, open a note
"$S" GET /tags/
"$S" GET /commands/
"$S" POST "/commands/editor:toggle-bold/"
"$S" POST "/open/Path/Note.md?newLeaf=true"
```

The wrapper appends `<<HTTP nnn>>` after the body so the status code is visible. Success codes: `200`/`204`. Check `409` on MOVE (destination exists — add `-H 'Allow-Overwrite: true'` to force).

### Path & encoding rules
- `{filename}` is vault-relative (no leading slash on the vault path itself). Spaces are fine in the shell-quoted argument.
- MOVE `Destination` rejects absolute (`/…`) paths and anything escaping the vault; percent-encode non-ASCII (`r%C3%A9sum%C3%A9.md`).
- Targeting a sub-part of a note (heading/block/frontmatter) uses `Target-Type` + `Target` headers on GET/PATCH/POST — see the reference.

## Full reference

`references/api_reference.md` — every path, method, header enum (Operation, Target-Type, Target-Scope, period), the MOVE contract, search (JsonLogic/Dataview), and the complete MCP↔REST coverage map. Load it when composing a non-trivial call or when unsure whether an operation exists.

Regenerate against the live instance if the plugin was updated: `scripts/olrapi.sh GET /openapi.yaml` (and `GET /` shows the version + any `apiExtensions`).

