Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
O

obsidian-local-rest-api

> 编程语言
Open source

A secure REST API and Model Context Protocol (MCP) server for your vault.

2.7K stars0 likes2 views
WebsiteGitHub

About

A secure REST API and Model Context Protocol (MCP) server for your vault.

Local REST API with MCP

Give your scripts, browser extensions, and AI agents a direct line into your Obsidian vault via a secure, authenticated REST API.

  • Interactive API docs: https://coddingtonbear.github.io/obsidian-local-rest-api/

  • Obsidian Community page: https://community.obsidian.md/plugins/obsidian-local-rest-api/

  • What you can do

  • Quick start

    • REST API
    • MCP clients
      • Claude Code
      • Claude Desktop
      • Cursor
      • Other clients
  • API overview

    • Browser clients and response headers
  • Patching notes

    • Raw-content mode
  • Targeting specific sections

  • Searching

  • MCP (Model Context Protocol)

    • Protocol revisions
    • Connecting a client
    • Available tools
    • Binary files and attachments
    • Available resources
  • API Extensions

    • Typed extension API
    • Known extensions
  • Contributing

  • Credits

What you can do

Access your vault through the REST API or the built-in MCP server — both interfaces expose the same core capabilities, so scripts, browser extensions, and AI agents all speak the same language.

  • Read, create, update, or delete notes — full CRUD on any file in your vault, including binary files
  • Surgically patch specific sections — target a heading, block reference, or frontmatter key and append, prepend, replace, delete, or move just that section without touching the rest of the file
  • Search your vault — simple full-text search or structured JsonLogic queries against note metadata (frontmatter, tags, path, content)
  • Access the active file — read or write whatever note is currently open in Obsidian
  • List and execute commands — trigger any Obsidian command as if you'd used the command palette
  • Query tags — list all tags across your vault with usage counts
  • Open files in Obsidian — tell Obsidian to open a specific note in its UI
  • Extend the API — other plugins can register their own routes via the API extension interface

All requests are served over HTTPS with a locally generated certificate and gated behind API key authentication.

Quick start

After installing and enabling the plugin, open Settings → Local REST API to find your API key and certificate.

REST API

…

To avoid certificate warnings, you can download the plugin's certificate authority from https://127.0.0.1:27124/obsidian-local-rest-api.crt and trust it in your OS or browser, or point your HTTP client at it directly (for example curl --cacert obsidian-local-rest-api.crt ...). The plugin generates its own certificate authority on first run and serves a server certificate signed by it, so the download is a CA certificate rather than the server certificate itself. That CA is name-constrained: it can only vouch for 127.0.0.1, localhost, your configured binding host, and the hostnames you list under Subject alternative names, so trusting it does not let it (or anyone who obtains its key) impersonate other sites.

MCP clients

The MCP server runs at https://127.0.0.1:27124/mcp/ and requires that you provide your bearer token for authentication via an Authorization header (i.e. Authorization: Bearer <your-api-key>). Because the plugin uses a locally generated certificate authority, you may need to either trust that certificate in your OS/client, or use the plain HTTP endpoint at http://127.0.0.1:27123/mcp/ (enable it under Settings → Local REST API → Enable HTTP server).

Claude Code

Claude Code has native HTTP MCP support. The quickest way to add the server is via the CLI:

bash
claude mcp add --transport http obsidian https://127.0.0.1:27124/mcp/ \
  --header "Authorization: Bearer <your-api-key>"

Or add it manually to .mcp.json in your project root (project-scoped) or configure it user-wide via claude mcp add --scope user:

json
{
  "mcpServers": {
    "obsidian": {
      "type": "http",
      "url": "https://127.0.0.1:27124/mcp/",
      "headers": {
        "Authorization": "Bearer <your-api-key>"
      }
    }
  }
}

Claude Desktop

Claude Desktop does not natively support remote HTTP MCP servers, but you can bridge it with mcp-remote (requires Node.js). Add the following to claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
json
{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": [
        "mcp-remote@latest",
        "https://127.0.0.1:27124/mcp/",
        "--header",
        "Authorization: Bearer <your-api-key>"
      ]
    }
  }
}

Restart Claude Desktop after saving the file.

Cursor

Cursor supports the Streamable HTTP MCP transport. Add the following to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project-specific):

json
{
  "mcpServers": {
    "obsidian": {
      "url": "https://127.0.0.1:27124/mcp/",
      "headers": {
        "Authorization": "Bearer <your-api-key>"
      }
    }
  }
}

Other clients

Any MCP client that supports the Streamable HTTP transport can connect to https://127.0.0.1:27124/mcp/ with an Authorization: Bearer <your-api-key> header. Consult your client's documentation for the exact configuration format.

API overview

Endpoint Methods Description
/vault/{path} GET PUT PATCH POST DELETE Read, write, or delete any file in your vault
/active/ GET PUT PATCH POST DELETE Operate on the currently open file
/search/simple/ POST Full-text search across all notes
/search/ POST Structured search via JsonLogic
/commands/ GET List available Obsidian commands
/commands/{commandId}/ POST Execute a command
/tags/ GET List all tags with usage counts
/open/{path} POST Open a file in the Obsidian UI
/ GET Server status and authentication check
/mcp/ GET POST MCP (Model Context Protocol) server — connect AI agents directly to your vault

For full request/response details, see the interactive docs.

Browser clients and response headers

Several endpoints answer in a response header rather than in the body: Content-Location tells you where a write actually landed, Markdown-Patch-Warnings reports what a PATCH had to work around, Deprecation warns that a format is sunsetting, and Mcp-Session-Id carries the session for a sessionful MCP connection.

Browsers hide response headers from JavaScript unless the server opts them in, so the API sends Access-Control-Expose-Headers: * and all of them are readable with response.headers.get(...). Safari honours the wildcard from 15.4 onward; older browsers see only the CORS-safelisted headers. Requests made with credentials: "include" are not supported — the API authenticates with a bearer token and sends Access-Control-Allow-Origin: *, which browsers reject for credentialed requests.

Patching notes

The PATCH method is one of the most useful features of this API. It lets you make targeted edits without rewriting entire files.

Send a JSON instruction: an operation (replace, prepend, append, or delete) applied to a scope (content, marker, markerAndContent, or parent) of a target — a heading (addressed as an array of heading texts from the top level down), a block reference, or a frontmatter key. The payload rides in content (a string), value (JSON, for frontmatter values), or destination (a heading move):

bash
# Replace the value of a frontmatter field
curl -k -X PATCH \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{"targetType":"frontmatter","target":"status","operation":"replace","value":"done"}' \
  https://127.0.0.1:27124/vault/path/to/note.md

Heading levels inside a content string are relative to the target (a leading # becomes a direct child). Advisory warnings (e.g. a heading rebased past level 6) come back as percent-encoded JSON in the Markdown-Patch-Warnings response header — decode with decodeURIComponent before parsing. Pass ifMatch (the version from a document map) for optimistic concurrency.

Note: Whitespace is library-owned — your content is reduced to trimmed, canonical form (leading and trailing blank lines are meaningless), and the API itself supplies the blank line wherever inserted content faces body text, so an append or prepend always lands as its own block and never merges into an existing paragraph. Heading lines, existing blank lines, and each document's spacing style are preserved as-is. See the interactive docs for worked examples.

To continue an existing block instead of starting a new one — say, extending a list — add within to a heading instruction: an index selecting one of the section's top-level body blocks (0-based in document order, negative counting from the end, so -1 is the last block). A within edit splices literally, so you own the joint:

bash
# Add an item to the last list under "Log" (the leading \n continues the block)
curl -k -X PATCH \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  --data '{"targetType":"heading","target":["Log"],"within":-1,"operation":"append","content":"\n- new item"}' \
  https://127.0.0.1:27124/vault/path/to/note.md

With markerAndContent scope, prepend/append instead insert a new block beside the indexed one. Indices are positional, so read the document map first and pair the edit with ifMatch.

Raw-content mode

If your client templates markdown into the request body (Shortcuts, Tasker, curl from a template), JSON-escaping that content into an instruction is fragile. Raw-content mode moves the instruction's fields out of the body — target in the URL (or in Target-Type/Target headers with an explicit Markdown-Patch-Version: 2), operation and options in headers — and the body is the raw payload, no JSON escaping required:

bash
# Append a templated line under a heading — no JSON escaping anywhere
curl -k -X PATCH \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Operation: append" \
  -H "Content-Type: text/markdown" \
  --data "- $TEMPLATED_CONTENT" \
  https://127.0.0.1:27124/vault/notes/daily.md/heading/Log

A text/* body is the content carrier, an application/json body the value carrier, and no body at all carries nothing (a delete, or a move via a Destination header). Target-Scope, Within (the instruction's within index as a plain integer, e.g. -1), Create-Target-If-Missing, Reject-If-Content-Preexists, and If-Match headers round out the instruction. See the interactive docs for the header encodings and the full details.

Already using the older header-driven PATCH format? It spread the instruction across request headers instead of a JSON body, and is deprecated and will be removed in 6.0. It still works — send Markdown-Patch-Version: 1 to opt back into it (the

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

TypeScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言