Semantic Notes Vault MCP

repository·main·Indexed 19 days ago

https://github.com/aaronsb/obsidian-mcp-plugin

An Obsidian plugin that turns your vault into an MCP-compatible server, allowing AI assistants like Claude Desktop and Claude Code to read, write, search, and traverse notes as a connected knowledge graph. It features a Search Facade for operator-based and natural language queries, a Presentation Facade to reduce token usage via structured Markdown, and supports standard HTTP transport with Bearer token authentication.

Tokens
41.4K
Snippets
95
Records
176
Agent score
65%

What's inside obsidian-mcp-plugin

  1. Understand Obsidian Bases support in the MCP plugin

    main

    The plugin implements support for Obsidian's Bases feature (available in Obsidian v1.9.0+), which allows AI agents to interact with database-like views of notes.

    Key Capabilities:

    • List bases: Retrieve all .base files in the vault.
    • Read base: Parse YAML configuration from .base files.
    • Create base: Generate new .base files using the correct YAML format.
    • Query base: Execute queries against note data (note: filter evaluation is currently under development).
    • Export: Export base data to CSV, JSON, or Markdown formats.
    • View support: Define Table and Card views.

    Important Technical Details:

    • Format: Uses YAML for .base files (not JSON).
    • Property Prefixes: Queries must use specific prefixes to distinguish property types: note.*, file.*, and formula.*.
    • Syntax: Filter expressions use a JavaScript-like syntax rather than SQL.
  2. Understand the Graph Tool core concepts

    main

    The graph tool treats your Obsidian vault as a knowledge graph to enable AI navigation and analysis of connections. The model consists of:

    • Nodes: Individual notes.
    • Edges: Connections between notes, including both explicit links and tag connections.
    • Paths: Routes through the graph that connect different concepts.
  3. Understand tool visibility and permissions

    main

    All operations in the MCP server are subject to a tree-based tool visibility gating system (defined in ADR-101). This allows users to granularly enable or disable specific actions via the settings UI.

    Each operation is mapped to an OperationType for runtime enforcement via SecureObsidianAPI:

    Operation GroupActionsOperationType
    dailyread, pathREAD
    dailyappend, prependUPDATE
    taskslist, getREAD
    taskstoggle, set_status, addUPDATE / CREATE
    templateslist, readREAD
    templatesinsertCREATE
    propertieslist, getREAD
    propertiesset, removeUPDATE
  4. Understand the Security Architecture of the Obsidian MCP Plugin

    main

    The plugin employs a multi-layered security architecture designed to prevent path traversal attacks and enforce operation-level permissions. The core of this system is the VaultSecurityManager, which orchestrates validation through several layers before an operation is executed.

    Security Layers

    1. Input Validation: Rejects dangerous patterns.
    2. Path Type Validation: Rejects absolute paths.
    3. Framework Normalization: Utilizes Obsidian's internal normalizePath.
    4. Path Resolution: Resolves paths to their absolute form.
    5. Path Normalization: Removes any remaining ../ sequences.
    6. Boundary Validation: Ensures the resolved path remains within the vault boundaries.
    7. Real Path Verification: (Optional) Prevents symlink attacks.

    Core Components

    • VaultSecurityManager: The central authority that validates operations by checking permissions, normalizing paths, and logging the event.
    • SecureObsidianAPI: A wrapper around the standard ObsidianAPI that intercepts calls (like getFile, createFile, deleteFile) to run them through the VaultSecurityManager first.
    • OperationPermissions: Defines what actions are allowed (e.g., READ, CREATE, UPDATE, DELETE, MOVE/RENAME, EXECUTE).
    // Core Security Architecture
    class VaultSecurityManager {
      private validator: PathValidator;
      private permissions: OperationPermissions;
      private auditLog: SecurityAuditLog;
      
      async validateOperation(operation: VaultOperation): Promise<ValidatedOperation> {
        // 1. Check operation permission
        // 2. Validate and normalize path
        // 3. Check path-based permissions
        // 4. Log operation
        return validatedOperation;
      }
    }
    
    // Integration Point
    class SecureObsidianAPI extends ObsidianAPI {
      private security: VaultSecurityManager;
      
      async getFile(path: string): Promise<ObsidianFileResponse> {
        const validated = await this.security.validateOperation({
          type: OperationType.READ,
          path: path
        });
        return super.getFile(validated.path);
      }
    }
  5. What are Obsidian Bases and how do they work?

    main

    Obsidian Bases is a core Obsidian feature (v1.9.0+) that transforms collections of notes into databases using .base files.

    Key characteristics:

    • Data Source: It reads properties directly from your existing Markdown note frontmatter.
    • Scope: By default, Bases query your entire vault; you must use filters to narrow the scope.
    • Format: Configuration is stored in .base files using YAML syntax.
    • Mental Model: Instead of a separate plugin, think of a Base as a configuration file that defines how to filter, calculate, and display your existing notes.
  6. How the Search Facade architecture works

    main

    The plugin uses a Search Facade to provide a single, unified search interface to AI clients. Instead of exposing multiple search tools, the facade automatically routes queries to the most appropriate internal engine based on the query syntax:

    1. Operator-based search: Triggered when the query contains explicit operators like file:, tag:, path:, content:, OR, AND, or /regex/. This method is optimized for speed and precision.
    2. AdvancedSearchService: Triggered for natural language queries (queries without explicit operators). This engine uses tokenization and TF-IDF-like scoring to provide relevance ranking and snippet extraction.

    This architecture allows the AI to use a single tool while benefiting from both precise operator filtering and semantic relevance ranking.

  7. Authentication and Connection Standards

    main

    The plugin has moved away from non-standard connection methods to follow standard MCP HTTP patterns:

    • Authentication: Always use the Authorization: Bearer <key> header. Do not use the deprecated URL-embedded credential format (e.g., obsidian:key@localhost).
    • Transport: The plugin operates exclusively in pooled mode (MCPServerPool), which supports multiple concurrent connections. This replaces the previous enableConcurrentSessions toggle.
    • Deprecated Options: The mcp-remote bridge and Windows-specific mcp-remote workarounds are no longer supported as primary connection options because modern clients support HTTP transport natively.
  8. Choose a graph traversal strategy

    main

    When using advanced-traverse, you can select a strategy to control how the AI explores the graph:

    • Breadth-First: Explores all nodes at the current depth before moving deeper. Use this for comprehensive coverage and finding all related content.
    • Best-First: Prioritizes nodes with the highest relevance scores. Use this for focused research on specific topics.
    • Beam Search: Keeps only the top N candidates (defined by beamWidth) at each level. Use this for large vaults to balance coverage and performance.
  9. How the MCP server handles SSE routes and debug info

    main

    To prevent route shadowing that causes SSE reconnection loops, the MCP server uses a specific routing structure:

    • Protocol Endpoint: The main MCP transport endpoint is registered using app.all('/mcp', ...) to ensure a single handler manages both POST (for messages) and GET (for the SSE stream).
    • Debug Endpoint: The debug information endpoint has been moved to GET /mcp-info.

    Previously, a debug endpoint at GET /mcp would intercept the SSE stream establishment, causing clients to retry indefinitely. Using /mcp-info ensures the streaming channel opens correctly while keeping debug information accessible.

  10. Risk Mitigation during Migration

    main

    To manage the risks associated with architectural redesign, the following mitigation patterns are used:

    • Feature Flags: Used to enable a gradual rollout of new architectural components.
    • Fallback Mechanism: Allows reverting to the current implementation if issues arise.
    • Performance Monitoring: Tracks metrics continuously during the migration process.
    • User Feedback: Utilizes beta testing with BRAT users to validate changes.
  11. Understanding CPU-bound semantic operations and worker threads

    main

    The plugin offloads heavy CPU-bound semantic operations to a worker thread pool to prevent blocking the Obsidian main thread (the event loop). This prevents MCP client timeouts and heartbeat failures during intensive tasks.

    Key Behaviors:

    • Scope: Only CPU-bound semantic work (like fuzzy matching in edit.window) is offloaded. I/O-bound vault operations that are already fast remain on the main thread.
    • Timeout: A 30s worker task timeout is enforced as a safety mechanism to prevent unbounded work.
    • Memory Efficiency: For large files, the worker uses a memory-efficient two-row Levenshtein distance algorithm rather than a full matrix.
    • Overhead: Note that offloading involves serialization overhead and a context round-trip (shipping file contents to the worker), which may slightly increase latency for very small files, but it protects the overall stability of the MCP connection.
  12. Configure Network Exposure Modes

    main

    The MCP HTTP server's network exposure is controlled by three primary axes: protocol (HTTP/HTTPS), bind address (which interface the server listens on), and certificate provenance (self-signed vs. user-supplied).

    To secure your vault, you should aim for a 🟢 OK state. The most common safe configurations are:

    • HTTP on Loopback: Traffic never leaves the local machine.
    • HTTPS on Loopback: Encrypted and local-only.
    • HTTPS with User Certificate on a LAN/Public interface: The intended setup for remote access.

    Avoid the 🔴 JAIL state: This occurs when using HTTP on any interface other than loopback (e.g., 0.0.0.0 or a custom LAN IP). In this state, your API key and vault contents are transmitted in cleartext across the network.