obsidian-local-rest-api

repository·main·Indexed 25 days ago

https://github.com/coddingtonbear/obsidian-local-rest-api

A secure, authenticated REST API and Model Context Protocol (MCP) server for Obsidian version 5.0.3. It enables scripts, browser extensions, and AI agents (such as Claude and Cursor) to read, write, search, and execute commands within a vault. Features include surgical patching of notes via headings or block references, JsonLogic and fuzzy search, and a built-in MCP server providing tools for vault management and application control.

Tokens
17.1K
Snippets
27
Records
97
Agent score
82%

What's inside obsidian-local-rest-api

  1. Interact with Obsidian via REST API or MCP

    main

    The Obsidian Local REST API with MCP plugin provides two primary programmatic interfaces:

    1. REST API: Standard HTTP endpoints for reading/writing notes and searching vault contents. This is intended for use with scripts, custom applications, or any standard HTTP client.
    2. MCP server: Exposes vault capabilities as structured tools for AI assistants (such as Claude or Cursor). Connection details can be found via the POST /mcp/ endpoint.
  2. Migrate PATCH requests from 1.x to 2.x

    main

    In plugin version 5.0+, the default PATCH format changed from header-based instructions to a single JSON body.

    1.x Format (Deprecated): Uses headers like Operation, Target-Type, and Target with a text/markdown body. 2.x Format (Default): Uses a JSON body with application/json content-type.

    Key Field Mappings:

    • Operation: append $\rightarrow$ "operation": "append" (also supports "delete")
    • Target-Type: heading $\rightarrow$ "targetType": "heading"
    • Target: A::B $\rightarrow$ "target": ["A", "B"] (an array, no delimiter needed)
    • Target-Scope: content $\rightarrow$ "scope": "content" (also supports "parent" for moves)
    • Body (text/markdown) $\rightarrow$ "content": "..."
    • Body (application/json) $\rightarrow$ "value": <json>
    • Create-Target-If-Missing: true $\rightarrow$ "createTargetIfMissing": true
    • Reject-If-Content-Preexists: true $\rightarrow$ "rejectIfContentPreexists": true

    Important Changes:

    • Heading Targets: Must be arrays (e.g., ["Heading 1", "Subheading 1:1"]).
    • Renaming Headings: Use "scope": "marker" with "content": "New Name". Do not include # characters in the content; they will be treated as literal text.
    • Frontmatter: Values must be sent as typed JSON in the "value" field (e.g., a list, dict, number, or string).
    # After (2.x) Default
    curl -k -X PATCH \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      --data '{"targetType": "heading", "target": ["Heading 1", "Subheading 1:1"], "operation": "append", "content": "Hello"}' \
      "https://127.0.0.1:27124/vault/note.md"
  3. Connect to the built-in MCP server

    main

    The plugin includes a built-in Model Context Protocol (MCP) server that allows AI agents to interact directly with your vault.

    Connection Details:

    • Endpoint: https://127.0.0.1:27124/mcp/ (or http://127.0.0.1:27123/mcp/ if HTTP is enabled in settings).
    • Transport: Streamable HTTP.
    • Authentication: Bearer token (find your API key in Settings → Local REST API).

    Security Note: Clients must trust the plugin's self-signed certificate. You can download it from https://127.0.0.1:27124/obsidian-local-rest-api.crt or configure your client to skip TLS verification for 127.0.0.1.

    Authorization: Bearer <your-api-key>
  4. Connect Claude Code via MCP

    main

    Claude Code has native HTTP MCP support. You can add the Obsidian MCP server via the CLI or by manually editing your .mcp.json file. The server is located at https://127.0.0.1:27124/mcp/ and requires your bearer token in the Authorization header.

    # Via CLI
    claude mcp add --transport http obsidian https://127.0.0.1:27124/mcp/ \
      --header "Authorization: Bearer <your-api-key>"
  5. Handle duplicate headings or block IDs

    main

    If a document contains duplicate sibling headings or duplicate block reference IDs, only the first occurrence is addressable via plain text or ID.

    To target subsequent occurrences, you must use a non-printable marker suffix appended by the server. To find the correct address:

    1. Fetch the document map using the header Accept: application/vnd.olapi.document-map+json.
    2. Copy the specific occurrence's key verbatim from the response. Do not attempt to manually reconstruct or type the marker suffix.
  6. Connect to the MCP server via Streamable HTTP

    main

    To use the Model Context Protocol (MCP) server provided by this plugin, use an MCP-compatible client (such as Claude Code, Cursor, or an MCP SDK client) that supports the Streamable HTTP transport.

    Connection Steps:

    1. Authentication: Pass your API key as a Bearer token in the authorization header.
    2. Initialization: Send an initialize request via POST /mcp/ to start a session.
    3. Session Management: The server will return a session ID in the Mcp-Session-Id response header. You must include this header in all subsequent requests.
    4. Protocol Versioning: After initialization, include the MCP-Protocol-Version header on all requests. This must be set to the protocol version negotiated during the initialize exchange (e.g., 2025-06-18). Requests with an unrecognized version will return a 400 Bad Request error.
  7. Migrate targeted GET, PUT, and POST requests

    main

    Header-based targeting (using Target-Type and Target headers) is deprecated for GET, PUT, and POST requests. You must now use URL-path targeting.

    New URL Pattern: https://127.0.0.1:27124/vault/{path}/{targetType}/{target_segments}

    • Headings: Each nested level is its own path segment. Use percent-encoding for non-ASCII characters or literal / (e.g., TODO%2FDONE).
    • Blocks: .../block/{block_id}
    • Frontmatter: .../frontmatter/{fieldName}

    Note: Sending both URL-path targeting and targeting headers in a single request will result in a 422 ConflictingTargetSpecification error.

    # After (2.x) for GET
    curl -k -H "Authorization: Bearer $API_KEY" \
      "https://127.0.0.1:27124/vault/note.md/heading/Heading%201/Subheading%201:1"
  8. Use Raw-content mode for low-effort PATCH migration

    main

    If you cannot easily JSON-escape your markdown content (e.g., using shell scripts or Tasker), use Raw-content mode. This maintains the 1.x posture of a raw payload in the body but moves the target into the URL path.

    Implementation:

    1. Remove Target-Type, Target, and Target-Delimiter headers.
    2. Append the target to the URL path: .../vault/{path}/{targetType}/{target_segments}.
    3. For headings, each level is a separate path segment, percent-encoded.

    Supported Headers in Raw-mode: Operation, Target-Scope, Create-Target-If-Missing, and Reject-If-Content-Preexists still work. Target-Delimiter and Trim-Target-Whitespace are rejected.

    Body Types:

    • text/* body $\rightarrow$ maps to content field.
    • application/json body $\rightarrow$ maps to value field.
    • No body $\rightarrow$ used for delete or moves via Destination header.
    # Raw-content mode example
    curl -k -X PATCH \
      -H "Authorization: Bearer $API_KEY" \
      -H "Operation: append" \
      -H "Content-Type: text/markdown" \
      --data "- $TEMPLATED_CONTENT" \
      "https://127.0.0.1:27124/vault/note.md/heading/Heading%201/Subheading%201:1"
  9. Quick start with the REST API

    main

    After installing and enabling the plugin, find your API key and certificate in Settings → Local REST API. All requests are served over HTTPS (default port 27124) and require an Authorization: Bearer <your-api-key> header. To avoid certificate warnings, you can download and trust the certificate from https://127.0.0.1:27124/obsidian-local-rest-api.crt or point your client to it.

    # Check the server is running (no auth required)
    curl -k https://127.0.0.1:27124/
    
    # List files at the root of your vault
    curl -k -H "Authorization: Bearer <your-api-key>" \
      https://127.0.0.1:27124/vault/
    
    # Read a note
    curl -k -H "Authorization: Bearer <your-api-key>" \
      https://127.0.0.1:27124/vault/path/to/note.md
  10. Inspect file metadata for search schema

    main
    To understand the exact structure of the file objects used during searches (the 'NoteJson' schema), you can inspect the metadata of a specific file. Use a GET request to the /vault/{filePath} route and set the Accept header to application/vnd.olrapi.note+json. This is useful for determining which keys and values are available for querying in your JsonLogic statements.
  11. Connect Claude Desktop via MCP

    main

    Claude Desktop requires a bridge using mcp-remote (requires Node.js) because it does not natively support remote HTTP MCP servers. Add the configuration to your claude_desktop_config.json file.

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