voracleでObsidianを検索し、LLM会話を取り込む
Rust製MCP / CLIのvoracleを実装。開発業務へのLLM導入に使うObsidian検索、差分embedding cache、会話取り込みをまとめます。
実装した検索ツール
Obsidianのノートを意味で検索する voracle を実装しました。Rust製のMCP / CLIで、embeddingとrerankingをローカル実行します。開発メモを検索し、LLMの会話も取り込めるツールです。
- MCP サーバー: stdio JSON-RPC 2.0、公開ツールは
searchとreadの2つ - CLI コマンド:
-ingest(インデックス構築)、-list/-rg(セマンティック検索)、-distil(外部 LLM 会話取り込み) - 複数 vault root:
--rootフラグまたはVORACLE_PATH環境変数(コロン区切り)で指定 - embedding キャッシュ:
.embeddings.jsonlによる差分 ingest。変更のないノートはキャッシュから復元 - モデル配置:
~/.local/share/voracle/models/に ONNX モデルを配置
# インデックス構築(初回は全チャンク embedding、2回目以降は差分のみ)
voracle -ingest
# セマンティック検索
voracle -list "kubernetes networking"
# MCP サーバー起動
voracle --server
# 外部 LLM 会話の取り込み(クリップボードから)
voracle -distil c
背景
前身のvalut-oracleは、ONNX Runtimeのpplx-embed-v1-0.6bとColBERTのmxbai-edge-colbertを使っていました。MCPはstdio JSON-RPC 2.0です。
pathfinder と shelpa(現filesystem) と並ぶRust製MCPで、vault検索を担当します。
記事、設計メモ、ドメインファイルが増え、曖昧な記憶から該当chunkを探したくなりました。LLM会話を取り出すdistilも、同じツールへ統合しました。
複数 vault root 対応
vault_path: PathBuf を roots: Vec<PathBuf> に変えました。--root で複数指定し、VaultResolver が再帰的に走査します。
voracle --root /path/to/vault1 --root /path/to/vault2 --server
VORACLE_PATH はコロン区切りです。優先順位は --root > VORACLE_PATH > エラーです。
export VORACLE_PATH=/Volumes/VALUT/obsidian/docs:/Volumes/VALUT/obsidian/articles
embedding キャッシュ
500ノート規模では全chunkのembeddingが重いため、.embeddings.jsonl に差分cacheを持たせました。
vaultごとのJSONLで、1行が1ノートです。note_id、content_hash(DefaultHasher)、mtime_secs、chunkごとのvectorを保存します。ドットで始め、Obsidian UIには表示しません。
mtimeが同じならcacheを使います。異なる場合は内容hashを比べ、hashも変わったノートだけ再計算します。touchやコピーで時刻だけ変わった場合も再利用できます。

-f は全re-embedです。IngestResult の cached_hits で復元件数を返します。
distil コマンドの統合
agent-gatewayの distil shellを統合しました。Claude CLI、Codex CLI、Gemini CLIの会話を取り込む機能です。以前の POST /v1/obsidian/ingest handlerは削除済みでした。
入力は第2引数、stdin、どちらもなければ pbpaste です。aliasは c / claude → claude-opus-4-6、x / codex → codex-5.3、g / gemini → gemini-3.1-pro です。
voracle -distil c # クリップボードから
voracle -distil claude "text" # インライン
cat file.md | voracle -distil x # stdin
第1rootの _notes/llm-completions/{model_dir}/{correlation_id}.md へ書きます。frontmatterにdate、status: raw、correlation_id、modelを保存し、indexがあれば関連ノートを検索して related に入れます。
MCP ツール整理
MCP ingest の除去
MCPは当初 search、read、ingest でした。ingestはCLIで事前に行うため、handle_tool_call のdispatchからは既に外れていましたが、定義だけ残っていました。
tools.rs の ingest と server.rs の tool_definitions() のentryを削除し、公開ツールを search と read に絞りました。
検索結果に read_tool_call を付け、LLMから呼べるようにしました。約1000文字ごとのpageでcontext消費を抑えます。
CLIの使い方です。
usage: voracle [--root <path>]... <command> [args]
options:
--root <path> vault root directory (repeatable)
falls back to VORACLE_PATH (colon-separated)
index:
-ingest [-f] build index (required before search)
search (loads .index.bin):
-list <query> [-k N] semantic file list, default top 3
-rg <query> [-k N] grep-like semantic search with context
-read <note_id> print note content to stdout
tools:
-embed <text> print embedding vector (TSV)
-rerank <query> <file>... rerank files by ColBERT MaxSim score
-status show index status
-distil <model> [content] ingest LLM conversation into vault
model: c(laude), x(codex), g(emini)
reads from: arg, stdin, or clipboard
server:
--server stdio MCP server (JSON-RPC 2.0)
-list と -rg は .index.bin を読みます。前者はpathとscore、後者はchunkと前後contextを表示します。-read は全文をstdoutへ出すCLI専用機能で、MCPの read とは別です。-embed と -rerank はdebugや他ツール連携向けです。
voracle への改名
長い valut-oracle を voracle に短縮し、package、binary、環境変数も変えました。
Cargo.toml: パッケージ名をvoracleに変更src/cli/mod.rs: 環境変数をVALUT_ORACLE_PATH→VORACLE_PATHに変更、全 usage メッセージを更新src/config.rs: モデルディレクトリを~/.local/share/voracle/models/に変更src/main.rs: トレーシングフィルタをvoracle=infoに変更src/mcp/server.rs:ServerInfo.nameをvoracleに変更- ドキュメント全体(README.md、docs/ 内 5 ファイル)を新名称に統一
モデルは ~/.local/share/voracle/models/ に置き、XDG_DATA_HOME があれば従います。pathfinderの約32MBは include_bytes! で埋め込めますが、700MBのため外部配置にしました。リポジトリ履歴からは git filter-repo で除去済みです。
