mcpField
O
Obsidian Mcp Server

Obsidian Mcp Server

ローカル
github.com/smith-and-webメモリ・ナレッジ192 日前に更新

Obsidian Mcp Server について

Obsidian MCP Serverは、MCP接続を通じてAIアシスタントからノートやナレッジベースの構成を操作できるサーバーです。ノート編集、メタデータ、リンク機能に加え、Postgres、pgvector、Ollamaによるローカル意味検索を任意で利用できます。

主な機能

  1. 01ノートの作成、編集、移動、読み取り
  2. 02タグとYAML frontmatterの管理
  3. 03ノート検索とリンク確認
  4. 04セクションとディレクトリの編集
  5. 05任意で利用できるローカル意味検索

活用シーン

  1. 01AIアシスタントを通じたノート作成と整理
  2. 02テキスト、タグ、バックリンクによるノート検索
  3. 03タグと未解決のwikiリンクの監査
  4. 04ローカル埋め込みによる関連ノート検索

MCP 対応

HTTPとSSE経由でObsidianのナレッジベース操作をMCPツールとして提供し、stdioには直接対応しません。DATABASE_URLを設定すると、任意の意味検索ツールを利用できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"obsidian-mcp-server-smith-and-web": {
"command": "npx",
"args": [
"-y",
"@smith-and-web/obsidian-mcp-server"
],
"env": {
"VAULT_PATH": "<VAULT_PATH>",
"PORT": "<PORT>"
}
}
}
}
起動コマンドnpx -y @smith-and-web/obsidian-mcp-server
設定が必要な環境変数
VAULT_PATH
PORT

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@smith-and-web/obsidian-mcp-server

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Obsidian MCP サーバー

CI npm Docker License Node.js MCP TypeScript Sponsor

Model Context Protocol (MCP) サーバーです。Claude などの AI アシスタントが Obsidian の保管庫とやり取りできるようにします。自然な会話を通じて、ノートへのアクセス、コンテンツの作成、タグの管理、ナレッジベースの検索ができます。

機能

ノート管理
  • CRUD 操作:ノートの作成、読み取り、更新、削除(安全確認付き)
  • 書き込みモード:コンテンツの上書き、追記、先頭への追加
  • 一括読み取り:1 回のリクエストで複数のノートを読み取り
  • ファイル情報:コンテンツを読み取らずにメタデータを取得(大規模な保管庫で効率的)
  • 移動/複製:保管庫の構成を再編成
  • セクション操作:見出しを指定して、特定のセクションを読み取り、追記、置換
フロントマターとタグ
  • フロントマターの解析:YAML フロントマターを構造化 JSON として取得/設定(gray-matter を使用)
  • タグ管理:タグを追加/削除(フロントマターまたはインライン)
  • タグ監査:必須タグがないノートを検出
  • タグ検索:使用回数とともにすべてのタグを一覧表示
検索とリンク
  • 全文検索:コンテキストとともにコンテンツやファイル名を検索
  • バックリンク:特定のノートにリンクしているノートをすべて検索
  • リンク切れ:解決できない Wiki リンクを検出
  • 検索と置換:正規表現に対応した一括テキスト置換
セマンティック検索(任意)
  • 意味による検索:Postgres と pgvector、および Ollama のローカル埋め込みを利用した、見出しを考慮したチャンクに対するベクトル検索と全文検索のハイブリッド検索
  • 類似ノート:ノート全体の埋め込みに基づき、指定したノートに近いノートを検索
  • 増分インデクサー:同じイメージから起動する 2 つ目のプロセスが保管庫をポーリングし、変更されたものだけを再埋め込みします。inotify が機能しない NFS/SMB でも動作します
  • ネットワーク外へデータを送信しません:埋め込みはローカルで計算されます。DATABASE_URL を設定しない限り、この機能は完全に無効です
ディレクトリ操作
  • 作成/削除/名前変更:ディレクトリを完全に管理
  • 内容の一覧表示:保管庫の構成を閲覧
パフォーマンス
  • トークンの最適化:応答をコンパクトにするオプション(応答を 40~60%縮小)
  • 効率的なスキャン:コンテンツを読み取らずにファイル情報を取得
  • SSE トランスポート:ローカルにインストールせずにリモートアクセス

クイックスタート

**クライアントの接続方法:**サーバーは HTTP + SSE のみ で MCP 通信を行います(stdio モードはありません)。サーバーを起動して(npx、Docker、またはソースから)、クライアントから http://HOST:PORT/sse に接続します。stdio サーバーにしか対応していないクライアントは、以下に示すように mcp-remote 経由で接続します。サーバーは PORT で すべてのネットワークインターフェース をリッスンするため、ネットワーク全体から保管庫への読み書きを許可するのでなければ、API_KEY を設定するか(認証を参照)、ループバックに限定してください(例:Docker では -p 127.0.0.1:3001:3000)。

npx(最速)

Node.js 20.19 以降が必要です。サーバーをフォアグラウンドで起動します(既定のポートは 3000 です)。

VAULT_PATH=/path/to/your/vault npx @smith-and-web/obsidian-mcp-server

オプションを指定する場合:

VAULT_PATH=/path/to/vault PORT=3001 COMPACT_RESPONSES=true npx @smith-and-web/obsidian-mcp-server
Docker(本番環境に推奨)

GitHub Container Registry のビルド済みイメージを使用する場合:

docker run -d \
  --name obsidian-mcp \
  -v /path/to/your/vault:/vault:rw \
  -p 127.0.0.1:3001:3000 \
  -e VAULT_PATH=/vault \
  ghcr.io/smith-and-web/obsidian-mcp-server:latest

latest は最新リリースに追従します。本番環境では、バージョンタグ(例::1.6.0)を指定してください。API_KEY を設定して他のマシンからの接続を許可する場合に限り、127.0.0.1: を削除してください。

または Docker Compose を使用する場合:

  1. docker-compose.yml を作成します:

    services:
      obsidian-mcp:
        image: ghcr.io/smith-and-web/obsidian-mcp-server:latest
        container_name: obsidian-mcp
        restart: unless-stopped
        volumes:
          - /path/to/your/vault:/vault:rw
        ports:
          - "127.0.0.1:3001:3000"
        environment:
          - VAULT_PATH=/vault
    
  2. サーバーを起動します

    docker compose up -d
    
  3. 実行中であることを確認します

    curl http://localhost:3001/health
    
ローカル開発
  1. 依存関係をインストールします

    npm install
    
  2. 環境変数を設定します

    export VAULT_PATH=/path/to/your/vault
    export PORT=3000
    
  3. サーバーを起動します

    npm start
    # Or with auto-reload:
    npm run dev
    

AI アシスタントの設定

Claude Desktop

Claude Desktop の設定ファイルに追加します:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json

オプション 1:ローカルサーバー(mcp-remote 経由)

{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:3001/sse"]
    }
  }
}

オプション 2:HTTPS を使用したリモートサーバー

{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://your-domain.com/sse"]
    }
  }
}

サーバーは事前に起動しておく必要があります(クイックスタートを参照)。Claude Desktop は mcp-remote を起動し、stdio とサーバーの SSE エンドポイントをブリッジします。このサーバーは stdio を使用しないため、Claude Desktop から直接起動することはできません。

Cursor

Cursor の MCP 設定(Settings → MCP)に追加します:

{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:3001/sse"]
    }
  }
}
その他の MCP クライアント

Claude Code は SSE サーバーを直接サポートします:

claude mcp add --transport sse obsidian http://localhost:3001/sse
# with an API key:
claude mcp add --transport sse obsidian https://your-host/sse --header "Authorization: Bearer your-secret-key"

その他の MCP 対応クライアントは、mcp-remote を使用して接続できます:

npx mcp-remote http://localhost:3001/sse

または、クライアントが SSE サーバーをネイティブにサポートしている場合は、http://localhost:3001/sse の SSE エンドポイントに直接接続してください。

利用可能なツール

ノート操作
ツール説明
read-noteノートの内容を読み取ります(効率化のため frontmatterOnly をサポート)
read-multiple-notes複数のノートを一括で読み取ります
create-note新しいノートを作成します
edit-noteノートの内容を置き換えます
write-note上書き、追記、または先頭への追加モードで書き込みます
delete-noteノートを削除します(確認が必要)
move-noteノートを移動/名前変更します
duplicate-noteノートを新しい場所にコピーします
get-notes-info内容を読み取らずにファイルのメタデータを取得します
ディレクトリ操作
ツール説明
list-vaultファイルとディレクトリを一覧表示します
create-directory新しいディレクトリを作成します
delete-directoryディレクトリを削除します(再帰オプションあり)
rename-directoryディレクトリを名前変更/移動します
フロントマターとタグ
ツール説明
get-frontmatterYAML フロントマターを JSON として取得します
update-frontmatterフロントマターのフィールドをその場で更新します(変更されていないフィールドのテキストは完全に保持されます。無効な YAML は拒否されます)
add-tagsフロントマターまたは本文内にタグを追加します
remove-tagsノートからタグを削除します
list-tagsすべてのタグと件数を一覧表示します
find-notes-by-tag特定のタグが付いたノートを検索します
search-missing-tagタグが付いていないノートを検索します
audit-tagsフォルダー内で必須タグを監査します
検索とリンク
ツール説明
search-vault文脈付きで全文検索します
get-backlinksあるノートにリンクしているノートを検索します
find-broken-links解決できない wiki リンクを検索します
find-replace検索と置換を一括で行います
セマンティック検索(DATABASE_URL が設定されている場合のみ)
ツール説明
semantic-searchベクトル検索と全文検索を組み合わせた検索です。directory、tags、フロントマターの type と status で絞り込みます。`mode: hybrid
similar-notes重心埋め込みに基づき、あるノートに最も近いノートを検索します
index-statusモデル、件数、インデクサーの最終実行時刻、遅延を表示します
reindex-note1つのノートをすぐに再インデックスします
search-feedback検索の評価と、使用したパスまたは期待するパスを記録します。学習ログが有効な場合のみ利用できます
recommend-notesbest_score または average_vector を使用し、肯定的な例に類似し、否定的な例とは異なるノートを検索します。セマンティック検索が必要です
maintenance-decisionメンテナンスの検出事項について、明示的な承認または却下の判断を記録します。セマンティック検索が必要です

設定については、セマンティック検索を参照してください。

セクション操作
ツール説明
read-section見出しの下にあるコンテンツを読み取ります
append-to-sectionセクションに追記します
replace-sectionセクションの内容を置き換えます
append-to-fileファイルの末尾に追記します
insert-at-markerテキストマーカーの位置に挿入します
list-headingsノート内のすべての見出しを一覧表示します

アーキテクチャ

┌─────────────────┐     HTTPS/SSE      ┌──────────────────┐
│  Claude Desktop │ ◄────────────────► │   MCP Server     │
└─────────────────┘                    │   (Express.js)   │
                                       └────────┬─────────┘
                                                │
                                       ┌────────▼─────────┐
                                       │   VaultManager   │
                                       │   (File System)  │
                                       └────────┬─────────┘
                                                │
                                       ┌────────▼─────────┐
                                       │  Obsidian Vault  │
                                       │   (Markdown)     │
                                       └──────────────────┘

プロジェクト構成

obsidian-mcp-server/
├── src/
│   ├── index.ts              # Express server entry point
│   ├── vault/
│   │   ├── VaultManager.ts   # Core vault operations
│   │   └── frontmatter.ts    # YAML parsing utilities
│   ├── tools/
│   │   ├── definitions.ts    # MCP tool schemas
│   │   ├── handlers.ts       # Tool execution logic
│   │   └── index.ts          # Tool exports
│   ├── server/
│   │   ├── mcp.ts            # MCP protocol handlers
│   │   └── middleware.ts     # Express middleware
│   ├── index/                # Optional semantic search
│   │   ├── config.ts         # DATABASE_URL / OLLAMA_URL / EMBED_MODEL
│   │   ├── exclusions.ts     # What the indexer never reads
│   │   ├── chunker.ts        # Heading-aware chunking
│   │   ├── embedder.ts       # Ollama client (+ a fake for tests)
│   │   ├── ranking.ts        # Fusion, weights, per-note cap and env validation
│   │   ├── store.ts          # pgvector schema, upserts, hybrid search
│   │   ├── scanner.ts        # Vault walk and change detection
│   │   └── SearchService.ts  # What the MCP tools call
│   ├── maintain/             # Report configuration, decisions, renderer and worker
│   ├── maintain.ts           # Report-only maintenance CLI
│   ├── learn/                # Learn log, redaction, configuration and reports
│   ├── learn-report.ts       # Read-only learn-report CLI
│   ├── eval/                 # Golden validation, metrics and fixed ranking grid
│   ├── eval.ts               # Read-only brain-eval CLI entry point
│   ├── indexer.ts            # Indexer entry point (second container)
│   └── types/
│       └── index.ts          # TypeScript type definitions
├── sql/001_schema.sql        # Index schema (dimension substituted at start)
├── tests/                    # Vitest unit tests
├── Dockerfile
├── docker-compose.yml
├── package.json
└── README.md

環境変数

変数デフォルト説明
PORT3000サーバーのポート
VAULT_PATH/vaultObsidian ボルトへのパス
COMPACT_RESPONSESfalse応答キーを短縮して、応答サイズを40~60%削減します
API_KEY(none)認証用の API キーです。設定すると、Bearer トークンが必要になります(定数時間で比較されます)
REQUIRE_TAILSCALE_LOGIN(none)オプションです。Tailscale-User-Login ヘッダー(tailscale serve によって設定されます)がこのログイン名と一致することを要求します。サーバーに tailscale serve 経由でループバック上からのみアクセスできる場合に限り、信頼できます
SSE_KEEPALIVE_SECONDS30GET /sse ストリームで : ping SSE コメントを送信する間隔(秒)です。0 にすると無効になります。約5分間バイトを受信しなかったストリームを切断し、initialize を再送せずに再接続するクライアントがあります。その場合、セッションのクライアント名が失われます
MCP_INSTRUCTIONS_FILE(none)オプションです。MCP の initialize 結果に含める instructions として、ボルトの内容と使用するタイミングをクライアントに送るテキスト/Markdown ファイルのパスです。ほとんどのクライアントはモデルのコンテキストに追加します。ファイルが存在しない場合、起動エラーになります。短くしてください(クライアントによっては約2 KBで切り詰められます)
MCP_INSTRUCTIONS(none)同じ内容をインラインで指定します。MCP_INSTRUCTIONS_FILE が設定されている場合は無視されます
DATABASE_URL(none)Postgres + pgvector の接続文字列です。セマンティック検索を有効にします。未設定の場合、この機能は無効です
OLLAMA_URLhttp://localhost:11434埋め込み生成に使用する Ollama サーバー
EMBED_MODELnomic-embed-textOllama の埋め込みモデルです。次元数はモデルから検出されます
LEARN_LOGfalseオプションの学習ログを有効にします。設定が無効な場合、ログ記録は無効になります
LEARN_REDACT_PATTERNS_FILEunsetログ記録が有効な場合に必要な、読み取り可能な正規表現ファイル
LEARN_RETENTION_DAYS30クエリテキスト、埋め込み、フィードバックメモを消去するまでの日数です。整数1~3650
INDEX_COLLECTIONdefault共有データベース内の、このボルトのコレクション名
MAINTAIN_REPORT_DIRdry 実行でない場合は必須メンテナンスレポート用の、既存の書き込み可能なディレクトリ
MAINTAIN_REPORT_VAULT_DIRemptyボルトからの相対パスで指定するレポートディレクトリです。記録されるレポートパスに使用されます
MAINTAIN_TZUTCレポートのタイムスタンプと ISO 週に使用する IANA タイムゾーン
MAINTAIN_LINK_COSINE0.85リンク欠落のコサイン類似度しきい値です。0より大きく1未満
MAINTAIN_DUP_COSINE0.92近似重複のコサイン類似度しきい値です。0より大きく1未満
MAINTAIN_DUP_TITLE_SIM0.6近似重複タイトルの類似度です。0より大きく1未満
MAINTAIN_HUB_DAYS14古いハブを判定する、リンク先ノートの更新間隔です。整数1~365
MAINTAIN_SUMMARY_DROP0.05要約と本文のコサイン類似度の低下しきい値です。0より大きく1未満
MAINTAIN_MAX_PER_CLASS10実行ごとにクラスごとに新たに検出する項目の最大数です。整数1~100
SEARCH_FUSIONrrf融合方式です。rrf(重み付き逆順位)または dbsf(分布ベースのスコア融合)
SEARCH_RRF_K60RRF の順位定数です。整数1~1000。DBSF では検証されますが使用されません
SEARCH_W_VECTOR1ベクトル検索の重みです。有効な数値で、0~10
SEARCH_W_TEXT1全文検索の重みです。有効な数値で、0~10。両方の重みを0にはできません
SEARCH_PER_NOTE_CAP0ノートあたりのチャンク数の上限です。整数0~8。0は上限なしを意味します
INDEX_INTERVAL_SECONDS60インデクサーのみ:ボルトをスキャンする間隔(秒)
INDEX_VERBOSEfalseインデクサーのみ:インデックス作成または削除されたすべてのファイルをログに記録します
EMBED_BATCH_SIZE16Ollama リクエストあたりのテキスト数
EMBED_PROVIDERollamaollama、または fake(テストやスモーク実行用の決定論的なハッシュ埋め込み。実際の検索には使用しません)
EMBED_DIM(auto)fake プロバイダーの埋め込み次元数(デフォルトは64)。Ollama ではモデルから検出されるため無視されます

学習ログ

オプションの計測レイヤーにはセマンティック検索が必要で、デフォルトでは無効です。3 つの検索ツール(semantic-search、similar-notes、search-vault)、成功した読み取り(read-note、read-multiple-notes、read-section)、明示的なフィードバック、およびクライアント名を含むセッションの開始/終了を記録します。セッションは従来の SSE ストリーム(GET /sse + /message)と、1.10.1 以降の POST /sse クライアントです。initialize は Mcp-Session-Id ヘッダーを返し、後続のリクエストでその値を返送すると、そのセッションに記録されます。ヘッダーを付けて DELETE /sse を送信するとセッションが終了します。ヘッダーなしの POST /sse リクエストは、クライアント名 post、セッションなしで記録されます。検索のランキングは変わりません。検索でこれらのログが読み取られることはありません。

LEARN_LOG=true と、読み取り可能な UTF-8 ファイルを指定した LEARN_REDACT_PATTERNS_FILE を設定します。空行とコメントは無視され、その他の各行は空白を削除したうえで、大文字と小文字を区別しない JavaScript の正規表現ソースとしてコンパイルされます。ファイルの例を以下に示します。

# comment
\bexample-term\b

組み込みの 8 つのパターンでも、秘密鍵ヘッダー、アクセスキー形式、JWT、ホスト型 Git トークン、シークレットの代入、ベアラー認証情報、URL のトークンパラメーター、64 文字の 16 進文字列を検出します。機密性の高いクエリ(類似ノートのパスを含む)とその埋め込み表現は、保存前に消去されます。機密性の高い文字列パラメーターは [redacted] に置き換えられます。機密性の高いフィードバックのメモは消去され、機密性の高いフィードバックのパスは破棄され、機密性の高い読み取りパスは記録されません。サイト固有のパターンは外部ファイルに記述します。設定が無効な場合、検索ではなくログ記録が無効になり、起動時にその旨が報告されます。

記録された検索は、追加で requestId を返します。この値を読み取りの省略可能な requestId 引数に渡し、その後 requestId、rating(positive、negative、neutral)、usedPaths を指定して search-feedback を呼び出します。expectedPaths と短い note は省略可能です。source のデフォルト値は agent です。user は、人間による明示的なフィードバックの場合にのみ使用します。不明な ID を指定すると、{ recorded: false, reason: 'unknown requestId' } が返されます。不明な ID を指定した読み取りは、関連付けなしで記録されます。

検索、読み取り、セッションの書き込みはすべてファイア・アンド・フォーゲットで実行されます。ツールの応答が遅れることはなく、失敗は learn-log: とともにログに記録されます。フィードバックは完了を待ちます。インデクサーのループは --once を除き、1 日に最大 1 回、データ保持処理を適用します。LEARN_RETENTION_DAYS(デフォルトは 30 日)の経過後、クエリテキスト、クエリの埋め込み表現、フィードバックのメモが消去されます。パス、順位、タイムスタンプ、確認済みパラメーター、クライアント名、フィードバックのパスは保持されます。ログ記録が無効な場合でも、sql/002_learning.sql は 4 つの学習テーブルを作成します。次元をリセットすると、埋め込み列が再作成されます。クエリの保持期間を適用する必要がある場合は、学習テーブルのデータをデータベースダンプに含めず、生のデータベースファイルをバックアップから除外してください。

既存のデータベースに対して、読み取り専用レポートを実行します。

node dist/learn-report.js --days 30 --out /existing-directory/learn-report.json

--days のデフォルトは 30 で、指定範囲は 1~365 です。出力ディレクトリはあらかじめ存在している必要があります。読み取り専用接続を使用し、ランキングとログ記録の環境設定を無視して、クエリテキストを含まない件数と割合を出力します。標準出力にはレポートの順序でドット区切りのキーが表示され、その後に VOLUME GATE: pass|fail が表示されます。 レポートには、選択したコレクションと期間のデータが表示されます。セッションには、クライアント別の件数と、終了したセッションの所要時間の中央値(分)が含まれます。検索には、ツール別の件数と、秘匿化された共有率が含まれます。リンクされたセマンティック読み取りでは、読み取り経路における最小ランクを使用します。usedAt1、usedAt3、usedAt8はリンクされた読み取りの割合であり、missRateは結果に含まれなかった割合です。linkedSearchRateは、リンクされた読み取りを伴うセマンティック検索の割合で、linkedSemanticPerDayはその1日あたりの件数です。再検索率とフォールバック率は、セッションに関連付けられたセマンティック検索の後、120秒以内に別のセマンティック検索またはテキスト検索が行われた割合です。フィードバックカバレッジは、フィードバックがあるセマンティック検索の割合です。ソース別件数と否定率には、すべてのフィードバックが含まれます。分母がゼロの場合の割合と、値がない場合の中央値はnullです。数値は小数点以下4桁に丸められます。ボリュームゲートは、リンクされたセマンティック検索が1日あたり30件(丸め後)に達すると通過します。エージェントからのフィードバックは準拠状況を測定し、ユーザーによる修正は独立したラベルを提供します。

セマンティック検索

デフォルトでは無効です。DATABASE_URLを設定すると、サーバー(ツールが4つ追加されます)とインデクサー(インデックスを最新の状態に保つ別プロセス)の両方で有効になります。すべてローカルで動作します。Postgres(pgvector拡張機能を使用)と、埋め込み生成用のOllamaを使用します。

仕組み
  • Vaultが常に信頼できる唯一の情報源です。 インデックスは派生データであり、削除して再構築できます(--reindex)。
  • チャンク分割では見出しを考慮します。 ノートはH1~H3で分割されます。約800トークンを超えるセクションは、オーバーラップを設けてさらに分割されます。各チャンクには階層を示すパンくずリスト(Title › H2 › H3)が付きます。チャンク0はタイトルとフロントマターのsummaryで構成されるため、どのノートが質問に答えるかを判断するうえで、1行の要約が最も強い手がかりになります。
  • 検索にはハイブリッド方式を使用します。 HNSWインデックスによるコサイン類似度とPostgresの全文検索を並行して実行し、設定可能な加重逆順位融合(デフォルト)または分布ベースのスコア融合(DBSF)で統合します。そのため、言い換え表現と正確な識別子(ホスト名、チケット番号)のどちらにも対応できます。
  • 変更検出は監視ではなくポーリング方式です。 inotifyはNFSやSMBを介して伝播しないためです。インデクサーは各間隔で全ファイルの情報を取得し、mtimeまたはサイズが変わったファイルだけをハッシュ化し、内容が変わったファイルだけを再度埋め込みます。
  • 除外は、読み取り前にパスによって適用されます。 .obsidian/、.trash/、.git/、Synologyの#recycle/、@eaDir/、@tmp/、AppleDoubleの._*、ドットファイル、.md以外のファイル、.noindexファイルを含むディレクトリ、およびフロントマターにindex: falseが指定されたノートが対象です。
  • リンクはObsidianと同じ方法で解決されます。 [[Areas/note]]はパスで解決されます。[[note]]は、Vault内に同じベース名のノートが1つだけある場合に解決されます。2つある場合は未解決のまま記録され、ターゲットはNULLになります。重複する2つのうち1つを削除すると、次回のインデックス作成時にもう1つが再解決されます。
  • モデルはスキーマ上の事実として記録されます。 初回実行時に埋め込みモデルと次元数がデータベースに記録されます。異なるモデルでは、--reindexを実行するまでインデックス作成が拒否されます。
検索品質の評価(brain-eval)

npm run build でビルドし、インデックスと同じデータベース、コレクション、埋め込み設定で実行します。

node dist/eval.js --golden /private/golden.json --grid --out /private/runs/grid.json
# Or evaluate one configuration alongside the baseline:
node dist/eval.js --golden /private/golden.json --config '{"wText":1.5,"perNoteCap":2}' --out /private/runs/candidate.json
# npm run eval -- <the same arguments> also works.

出力ディレクトリはあらかじめ作成しておく必要があります。CLI はデータベースを読み取り専用で開き、スキーマの変更、再インデックス、インデックスへの書き込みは行いません。埋め込みモデルと次元数は保存されたメタデータと一致している必要があり、想定されるすべてのノートがコレクションに存在している必要があります。各クエリは一度だけ埋め込まれ、そのベクトルはすべての設定で再利用されます。固定グリッドには40個の設定が含まれ、v1.8.0 のベースライン rrf-k60-v1-t1-cap0 から始まります。CLI は環境から読み込んだ SEARCH_* のランキング設定を無視します。--config は、指定したフィールドのみをベースラインにマージします。無効なランキング環境設定があると、サーバーの起動に失敗します。

ゴールデンファイルは非公開の評価データであり、キーは次のものに限定されます。

{
  "version": 1,
  "created": "2026-01-01",
  "notes": "Synthetic example only",
  "queries": [
    {
      "id": "example-1",
      "category": "exact-id",
      "query": "synthetic search phrase",
      "expected": ["Example.md"]
    }
  ]
}

クエリ ID は一意でなければなりません。クエリ文字列は空であってはならず、期待値リストは空ではなく、一意の .md パスで構成されている必要があります。カテゴリは exact-id、paraphrase、decision-why、multi-hop、recent の順に報告されます。不明なキーは拒否されます。ゴールデンセットと評価レポートは、公開コードリポジトリの外に保管してください。

メトリクスでは、8個のチャンクをリクエストした後、結果の順序に沿って一意のノートパスを使用します。

  • mrr:最初の期待ノートの逆順位の平均値。該当しない場合は0です。
  • recall5:5位以内のヒット率で、上位5件のノートのいずれかに期待ノートが含まれているかを示します。
  • ndcg8:8件のノートに対する二値関連性の正規化割引累積利得です。
  • distinctNotes:返された一意のノート数の平均値です。メトリクスはカテゴリ別にも集計され、JSON レポートでは小数点以下4桁に丸められます。

候補は MRR を少なくとも0.0300改善し、すべてのカテゴリのヒット率を維持し、ベースラインでヒットが5位以内だったすべてのクエリのヒットを維持する必要があります。比較ではメトリクスを1万分の1の整数に丸めます。合格した候補は、MRR、ヒット率、NDCG の順に高いものが上位になります。同点の場合は、変更したランキングフィールドが少ないものを優先し、それも同じ場合は ID の辞書順で小さいものを優先します。合格した候補がない場合は、changed: false としてベースラインが選ばれます。JSON には、ゴールデンファイルの SHA-256、クエリごとのノートリスト、ゲートの理由、採用された環境変数が含まれます。標準出力には、ランキングテーブル、カテゴリ別比較、最後に WINNER 行が表示されます。

終了コード:レポートが正常に完了した場合(ランキングに変更がない場合を含む)は 0、入力の問題(引数、ゴールデンファイルの検証、モデルの不一致、想定パスの欠落)の場合は 2、その他の実行時エラー(データベース、埋め込みサービス、出力への書き込み)の場合は 1 です。

検索には pgvector 0.8.0 以降が必要です。各トランザクションでは厳密順序の反復 HNSW スキャンを使用し、フィルター付き検索では hnsw.ef_search を100に引き上げます。デフォルトの RRF スコアは v1.8.0 と一致し、完全な同点の場合はチャンク位置、続いて ID の順になります。DBSF スコアの範囲は0から、2つの検索経路の重みの合計までです。

インデックスが認識するフロントマター
---
title: ubuntubox — NFS mount gate     # else first H1, else file name
type: area                            # filterable: semantic-search { type }
status: active                        # filterable: semantic-search { status }
tags: [infra, nas]                    # filterable: semantic-search { tags }
summary: One line that answers "what is this note about".
index: true                           # false = never indexed
---

無効なフロントマターは隠されず、報告されます。 --- ブロックが有効な YAML ではないノート(よくある原因は、summary: Finished it: all done のように : を含む値が引用符で囲まれていないことです。summary: "Finished it: all done" のように引用符で囲んでください)は、本文をインデックス化しますが、メタデータは含めません。このようなノートをインデックス化すると、インデクサーは WARN invalid frontmatter in <path>: <YAML error> をログに出力し、その後の起動時にも毎回出力します。各パスの行には invalid_frontmatter=<count> が含まれ、index-status は invalidFrontmatter: { count, notes: [{ path, error }] }(先頭から20件)を返します。reindex-note は warning を返します。ノートを修正すると、次のパスでフラグが解除されます。

セットアップ
  1. データベース:pgvector を備えた任意の Postgres 16 以降を使用します。スキーマは初回起動時に sql/001_schema.sql から作成されるため、手動で実行する必要はありません。HNSW インデックスの構築には共有メモリが必要です。Postgres コンテナーに shm_size: 1g を指定してください。
  2. 埋め込み:ollama pull nomic-embed-text(768 次元、8k コンテキスト)または bge-m3(1024 次元)を実行します。
  3. サーバー:サーバーの環境変数に DATABASE_URL、OLLAMA_URL、EMBED_MODEL(任意で INDEX_COLLECTION も)を追加します。/health エンドポイントで semanticSearch: enabled が報告されます。
  4. インデクサー:同じイメージを command: ["node", "dist/indexer.js"] で再度実行し、同じ環境変数を設定して、ボルトを読み取り専用でマウントします。node dist/indexer.js --once --verbose を実行すると、1 回だけ処理して終了します。ファイルの処理に失敗した場合は、0 以外の終了コードを返します。
services:
  obsidian-mcp:
    image: ghcr.io/smith-and-web/obsidian-mcp-server:latest
    environment:
      VAULT_PATH: /vault
      API_KEY: ${API_KEY}
      DATABASE_URL: postgres://brain:${DB_PASSWORD}@brain-db:5432/brain
      OLLAMA_URL: http://ollama:11434
      EMBED_MODEL: nomic-embed-text
      INDEX_COLLECTION: secondbrain
    volumes:
      - /path/to/vault:/vault:rw
    ports: ["127.0.0.1:3001:3000"]

  obsidian-indexer:
    image: ghcr.io/smith-and-web/obsidian-mcp-server:latest
    command: ["node", "dist/indexer.js"]
    environment:
      VAULT_PATH: /vault
      DATABASE_URL: postgres://brain:${DB_PASSWORD}@brain-db:5432/brain
      OLLAMA_URL: http://ollama:11434
      EMBED_MODEL: nomic-embed-text
      INDEX_COLLECTION: secondbrain
      INDEX_INTERVAL_SECONDS: "60"
    volumes:
      - /path/to/vault:/vault:ro

  brain-db:
    image: pgvector/pgvector:0.8.2-pg16
    shm_size: 1g
    environment:
      POSTGRES_DB: brain
      POSTGRES_USER: brain
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./brain-db:/var/lib/postgresql/data

  ollama:
    image: ollama/ollama:latest
    volumes:
      - ./ollama:/root/.ollama
インデクサー CLI
コマンド説明
node dist/indexer.js継続して実行し、INDEX_INTERVAL_SECONDS ごとに 1 回処理します。SIGTERM で正常に停止します
node dist/indexer.js --once1 回だけ処理します。ファイルの処理でエラーがあった場合は終了コード 1 を返します
node dist/indexer.js --reindexこのコレクションを削除して再構築します(EMBED_MODEL の変更後に必要です)
npx -p @smith-and-web/obsidian-mcp-server obsidian-mcp-indexernpm パッケージから同じインデクサーを実行します(--once、--reindex、--verbose も指定できます)
--verbose / INDEX_VERBOSE=trueインデックス作成または削除したすべてのファイルをログに記録します
セキュリティに関する注意事項
  • インデクサーに必要なのはボルトへの読み取りアクセスのみです。:ro でマウントしてください。
  • チャンクテキストは Postgres に平文で保存されます。データベースはボルトと同様に扱ってください。同じネットワーク境界とバックアップポリシーを適用し、ボルトの他の部分と同じアクセスキーを共有すべきではない情報はインデックスに含めないでください(index: false または .noindex ディレクトリを使用してください)。
  • 埋め込みが Ollama ホストの外に出ることはありません。この機能では外部 API は一切使用しません。

API エンドポイント

エンドポイントメソッド説明
/healthGETヘルスチェック
/sseGETMCP 用 SSE エンドポイント
/ssePOSTMCP プロトコルの直接呼び出し
/messagePOSTSSE トランスポートメッセージ

認証

サーバーでは、オプションの API キー認証をサポートしています。API_KEY が設定されている場合、すべての /sse および /message エンドポイントで認証が必要です。/health エンドポイントは引き続き公開されます。

認証の有効化

API_KEY 環境変数を設定します。

# Docker
docker run -d \
  --name obsidian-mcp \
  -v /path/to/vault:/vault:rw \
  -p 3001:3000 \
  -e VAULT_PATH=/vault \
  -e API_KEY=your-secret-key \
  ghcr.io/smith-and-web/obsidian-mcp-server:latest

# npx
API_KEY=your-secret-key VAULT_PATH=/path/to/vault npx @smith-and-web/obsidian-mcp-server
認証方式

クライアントはAuthorization ヘッダーにキーを含めて送信します。

Authorization: Bearer your-secret-key

?api_key= クエリパラメーターは1.6.0 で削除されました(アクセスログやクライアント履歴に残るためです)。これを使用していたクライアントは、ヘッダーに切り替える必要があります。たとえば mcp-remote では --header "Authorization: Bearer your-secret-key" を指定します。

Tailscale ログイン(オプションの第 2 要素)

ループバックで tailscale serve の背後に配置する場合は、[email protected] を設定します。その場合、リクエストには、tailnet ユーザー用に serve が追加する Tailscale-User-Login ヘッダーも必要です。それ以外はすべて 403 になります。ポートに他の方法でアクセスできる場合は、この設定に頼らないでください。直接接続するクライアントがヘッダーを偽装できるためです。

API キーを使ったクライアント設定

Claude Desktop / Cursor(mcp-remote 経由):

{
  "mcpServers": {
    "obsidian": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://your-domain.com/sse",
        "--header", "Authorization: Bearer your-secret-key"
      ]
    }
  }
}

Claude Code:

claude mcp add --transport sse obsidian https://your-domain.com/sse --header "Authorization: Bearer your-secret-key"
セキュリティに関する考慮事項
  • 強力なキーを生成する:32 文字以上のランダムな文字列を使用してください
  • HTTPS 必須:サーバーをリモートに公開する場合は、キーの傍受を防ぐため、必ず HTTPS を使用してください
  • ファイルアクセス:サーバーはマウントされた保管庫に対する完全な読み書きアクセス権を持ちますが、すべてのパスは保管庫内に制限されます(../../etc/passwd のように保管庫の外に出るパスは拒否されます。1.4.1 で修正済みです)
  • バインドアドレス:サーバーはすべてのインターフェースで待ち受けます。Docker では、リモートアクセスが意図されている場合を除き、ループバックに公開してください(127.0.0.1:3001:3000)
  • CORS:現在、すべてのオリジンを許可しています。必要に応じて本番環境では制限してください
  • ログ内のキー:キーは Authorization ヘッダーでのみ送信してください。URL はアクセスログに記録されるため、以前の ?api_key= クエリパラメーターは削除されました
  • ネットワークセキュリティ:機密性の高い保管庫では、VPN やファイアウォールルールなどの追加の保護層を検討してください

NGINX Proxy Manager を使ったデプロイ

SSL を使用してリモートアクセスする場合:

  1. Proxy Host を追加します:

    • ドメイン:obsidian.yourdomain.com
    • 転送先ホスト名:obsidian-mcp(コンテナ名)
    • 転送先ポート:3000
    • WebSocket は不要です(SSE は通常の HTTP です)。重要なのは、以下の Advanced ブロックです
  2. SSL タブ:Let's Encrypt 証明書をリクエストします

  3. Advanced タブ(SSE 用):

    proxy_buffering off;
    proxy_cache off;
    proxy_set_header Connection '';
    proxy_http_version 1.1;
    chunked_transfer_encoding off;
    

Tailscale によるプライベートアクセス

クライアントが Tailscale のテイルネット上にある場合、パブリックリバースプロキシを完全に省略できます。コンテナはループバック上で動作させ、tailscale serve を使ってテイルネット専用の HTTPS 証明書で公開してください:

docker run -d --name obsidian-mcp -v /path/to/vault:/vault:rw -p 127.0.0.1:3001:3000 \
  -e API_KEY=your-secret-key -e [email protected] \
  ghcr.io/smith-and-web/obsidian-mcp-server:latest
sudo tailscale serve --bg --https=443 http://127.0.0.1:3001

クライアントは Authorization: Bearer ヘッダーを付けて https://<machine>.<tailnet>.ts.net/sse を使用します。このサーバーでは、Tailscale Funnel を絶対に有効にしないでください。REQUIRE_TAILSCALE_LOGIN が何を保護し、何を保護しないかについては、Tailscale ログインを参照してください。

トラブルシューティング

コンテナの問題
# View logs
docker-compose logs -f obsidian-mcp

# Restart
docker-compose restart

# Rebuild
docker-compose up -d --build
保管庫へのアクセス
# Check host mount
ls -la /path/to/your/vault

# Check container access
docker exec obsidian-mcp ls -la /vault
接続と認証のエラー
  • 401 Unauthorized:Authorization: Bearer <key> ヘッダーがないか、正しくありません(?api_key= クエリパラメーターは受け付けられなくなりました)。
  • 403 Forbidden:REQUIRE_TAILSCALE_LOGIN が設定されており、リクエストがそのユーザーとして tailscale serve 経由で届いていません。
  • Path escapes vault:リクエストされたパスが VAULT_PATH の外に解決されます。保管庫からの相対パスを使用してください。
  • 検索結果にノートの summary、タグ、または種類のフィルターが反映されない場合:index-status で invalidFrontmatter を確認するか、インデクサーのログで WARN invalid frontmatter を確認してください。ノートの YAML が無効なため、メタデータなしでインデックス化されています。
  • リバースプロキシ経由で SSE 接続が切断される場合:プロキシのバッファリングを無効にし(上記の NGINX ブロックを参照)、証明書を確認して、ファイアウォールでポートが許可されていることを確認してください。
  • Claude Desktop は起動するもののツールが表示されない場合:サーバーはすでに起動している必要があり、設定では mcp-remote を使用する必要があります(サーバーには stdio モードがありません)。

開発

クイックスタート
# Clone and install
git clone https://github.com/smith-and-web/obsidian-mcp-server.git
cd obsidian-mcp-server
make install

# Run with example vault
make dev

# Test connection
make test-connection
使用可能なコマンド

使用可能なコマンドをすべて確認するには、make help を実行してください:

Development:
  make install         Install dependencies
  make dev             Run server with hot-reload
  make start           Run server in production mode
  make test-connection Test server connectivity

Docker:
  make docker-build    Build Docker image
  make docker-up       Start Docker container
  make docker-down     Stop Docker container
  make docker-logs     View container logs
  make docker-restart  Restart container
  make docker-shell    Open shell in container
Bruno による API テスト

このリポジトリには、主要なツールをテストするための Bruno コレクションが含まれています(4 つのセマンティック検索ツールには DATABASE_URL と、実行中のインデックスが必要です)。

  1. Bruno(無料のオープンソース API クライアント)をインストールします
  2. ./bruno/obsidian-mcp からコレクションを開きます
  3. local または remote 環境を選択します
  4. リクエストを実行して各ツールをテストします

コレクションはカテゴリ別に整理されています:

  • health/ - サーバーの状態とツール一覧
  • notes/ - ノートの CRUD 操作
  • directories/ - ディレクトリ操作
  • frontmatter/ - フロントマター操作
  • tags/ - タグ管理
  • search/ - 検索と検索・置換
  • links/ - バックリンクとリンク切れ
  • sections/ - セクション単位の操作
サンプル保管庫

開発とテスト用に、./examples/test-vault/ にサンプル保管庫が含まれています。すべての機能をテストできるよう、タグ、リンク、セクションを含むサンプルノートが用意されています。

コントリビューション

ガイドラインについては、CONTRIBUTING.md を参照してください。

ライセンス

MIT ライセンスです。詳細はLICENSEを参照してください。

関連プロジェクト

メンテナンスワーカー

サーバーと同じイメージから node dist/maintain.js(または npm run maintain)を実行し、DATABASE_URL、INDEX_COLLECTION、VAULT_PATH、MAINTAIN_REPORT_DIR を設定してください。ホストのスケジューラーを使って週次で実行してください。--dry は、実行を記録したりレポートを書き込んだりせずに、候補数と健全性指標を出力します。インデックスはすでに存在している必要があります。

7 つの決定論的なチェックで、リンク切れ、リンクされていない言及、一意に修正可能な未解決リンク、欠落している index または aliases の frontmatter、古くなった要約、類似度の高い重複、古くなったプロジェクトまたはエリアのハブを検出します。type が journal または inbox のノートは、リンク先の候補から除外されます。Journal/ 配下のノートには、どちらの方向にもリンク候補を提案しません。リンクされていない言及として数えるのは、ノートの本文(frontmatter、最初の H1、コード、wikilink、Markdown リンクを除く)に含まれ、ハイフンを単語の一部として扱ったうえで、大文字と小文字を区別しない完全一致の単語だけです。確認のため、ワーカーは VAULT_PATH から元のノートを読み込みます。類似度の高い重複ペアのうち、すでに相互にリンクしているペアと、両方が plan ノートであるペアは除外されます。インデクサーは、コンテンツの変更時に要約と本文のコサイン類似度の履歴を記録し、メンテナンス処理では古いノートのベースラインを補完します。検索ランキングは変更されず、メンテナンス処理が学習テーブルを読み取ることもありません。

ISO 週ごとに、設定した出力ディレクトリに Brain maintenance YYYY-Www.md が作成されます。レポートは index: false、安定した検出項目 ID、承認/却下のチェックボックス、傾向、承認数を含むドラフトノートです。検索やリンクグラフには含まれません。再実行時は最初にチェックボックスを解析し、その週のレポートのみをアトミックに置き換えます。移動されたレポートも、maintenance_report frontmatter によって引き続き検出されます。

各検出項目のチェックボックスを 1 つ選択するか、finding: "f17"、decision: "accept" または "reject"、任意の理由を指定して maintenance-decision を呼び出すよう、アシスタントに明示的に依頼してください。チェックボックスの選択が矛盾している場合、決定は記録されません。チェックボックスによって以前の決定が上書きされることはありませんが、明示的なツール呼び出しでは変更できます。却下された検出項目が再提案されることはありません。修正済みの検出項目は、承認数に加算されずに解決済みとなります。クラスごとに新しい検出項目の数が制限され、レポートに記載される未解決の検出項目は最大 50 件です。

この段階ではレポートのみが生成されます。承認を記録しても決定が保存されるだけで、ノートは変更されません。承認された検出項目は自分で適用してください。類似度の高い重複の統合とハブのレビューは、今後もレポートのみを生成します。ワーカーが既存のノートを編集することはありません。Vault への書き込みは、ワーカー自身のレポートのみです。

recommend-notes は、1~10 個の positive パス、最大 10 個の negative パス、任意の整数 k(1~50)、type、directory を受け取ります。例として指定したノートは除外されます。best_score は最も近い positive と negative を比較し、average_vector は positive の平均を使用します。negative が存在する場合は、negative の平均から離れる方向に調整されます。どちらのツールにも学習ログは必要ありません。機密性の高い決定理由は、有効なリダクションパターンまたは組み込みのパターンに基づき、null として保存されます。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。