rag について
FieldCure MCP RAG Serverは、ローカル文書をインデックス化し、複数のナレッジベースを対象にキーワード検索とセマンティック検索を組み合わせて提供します。多様な文書形式に対応し、AIによるコンテキスト補完や埋め込みも利用できます。
主な機能
- 01BM25とベクトルのハイブリッド検索
- 02複数のローカルナレッジベースのインデックス化
- 03オフィス文書とPDFからのテキスト抽出
- 04スキャンPDFのOCRと音声の文字起こし
- 05AIによるチャンクのコンテキスト補完
- 06埋め込み待ちチャンクの再試行
活用シーン
- 01複数のナレッジベースからプロジェクト文書を検索
- 02OCRを使ったスキャンPDFのインデックス化
- 03文字起こしを使った音声記録の検索
- 04インデックス作成中の検索継続
MCP 対応
stdioのMCPサーバーとしてナレッジベースの読み取り専用検索を提供し、`kb_id`で対象を指定できます。インデックス作成依頼用の`start_reindex`も公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
FieldCure MCP RAG Server
ローカルのドキュメントコレクションをインデックス化して検索するための、Model Context Protocol (MCP) サーバーです。DOCX、HWPX、PDF(OCR 対応)、Excel、PowerPoint、音声(Whisper による文字起こし、Windows 専用)に対応し、韓国語と英語に最適化されたキーワード検索とセマンティック検索のハイブリッド検索を提供します。
C# と公式の MCP C# SDK で構築されています。
Commands
fieldcure-mcp-rag
├── serve --base-path <path> # Multi-KB MCP search server (stdio)
├── exec --path <kb-path> [--force] [--partial ...] # Headless indexing for a single KB
├── exec-queue --queue-file <path> [--sweep-all] # Process deferred indexing queue
├── prune-orphans --base-path <path> # Delete orphan KB folders
└── smoke-ocr --pdf <scanned.pdf> # Self-test: OCR a scanned PDF (Windows)
- serve — ベースパス以下のすべてのナレッジベースを提供する読み取り専用の MCP サーバーです。
kb_idパラメーターを使い、単一のプロセスで複数の KB を処理します。exec によるインデックス作成中も実行できます(SQLite WAL)。 - exec — ソースフォルダーをスキャンし、ドキュメントをチャンクに分割して、AI でコンテキスト化し、埋め込みを生成して SQLite に保存します。
--partialを指定すると、モデル変更時に下流のステージのみを再実行し、OCR 出力を保持します。 - exec-queue — 延期されたインデックス作成キューを処理する逐次オーケストレーターです。一度に 1 つのエントリーを処理し、GPU の競合を回避します。
--sweep-allは延期されたエントリーも処理します(アプリのシャットダウン時に使用)。 - prune-orphans — 孤立した KB フォルダー(GUID 名で、config.json がないフォルダー)を削除します。保護対象フォルダー(
.、_で始まるもの、-backup-を含むもの)は変更しません。 - smoke-ocr — 診断モードです。スキャン PDF を OCR フォールバックパーサーで読み込み、認識したテキストを標準出力に表示します。結果が空でなければ
0で終了します。DllNotFoundExceptionとBadImageFormatExceptionを明確に区別して表示するため、ネイティブライブラリの欠落やアーキテクチャの不一致をすぐに確認できます。特定のホスト(特に win-arm64 の dnx インストール環境)で OCR ネイティブライブラリのパスが正しく設定されているか確認するのに便利です。
Features
Search
- Reciprocal Rank Fusion(RRF)を使った BM25 とベクトル検索のハイブリッド検索
- 埋め込みプロバイダーが設定されていない場合の BM25 のみのフォールバック
- 韓国語に最適化されたチャンク分割(文境界、小数点の保護、括弧を考慮)
System.Numerics.Vectorによる SIMD 加速コサイン類似度- 部分文字列検索と CJK に適したキーワードマッチングのための FTS5 トライグラムインデックス
Indexing
- SHA256 による変更検出を備えた増分インデックス作成
- バイリンガルキーワードの拡充を伴う AI によるチャンクのコンテキスト化(チャンクのコンテキスト化を参照)
- 埋め込み生成の失敗時にも負荷の高い上流処理を保持する 2 コミットパイプライン(インデックス作成の仕組みを参照)
- DOCX/HWPX から数式を
[math: LaTeX]ブロックとして抽出 - スキャンされたページ向けに OCR フォールバック(Tesseract eng+kor)を備えた PDF 対応
- Whisper.net による音声文字起こし(
.mp3、.wav、.m4a、.ogg、.flac、.webm)— Windows 専用。検出された GPU/RAM/コア数に基づいて、起動時にモデルサイズ(Tiny→Large)が自動選択されます。各文字起こしチャンクには、今後の再インデックス監査用にaudio.model_sizeとaudio.transcribed_atが記録されます。 - 古い PID の自動クリーンアップを備えた、プロセス間インデックス作成ロック
- 削除されたファイルの孤立データのクリーンアップ
Queue Orchestrator
- すべてのインデックス作成リクエストは
start_reindexMCP ツールを経由します。exec を直接起動することはありません。 - スコープの統合ルール:full ⊃ contextualization ⊃ embedding(重複リクエストは重複作成ではなく、より広いスコープに更新されます)
- 再利用防止機能を備えた PID ベースのオーケストレーターロック(
orchestrator.lock) - 論理的な KB 削除(config.json の削除)と
prune-orphansによる物理クリーンアップ - アプリのシャットダウン時にまとめて処理するための、延期されたインデックス作成(
--sweep-all)
Operations
- マルチ KB サーブ:単一プロセスでベースパス以下のすべてのナレッジベースを提供し、KB ごとに遅延読み込み
- SQLite WAL モードにより、インデックス作成中も検索が可能
cancelファイルによる正常なシャットダウン- プロバイダー設定を含む KB ごとの
config.json
統合
- Ollama ネイティブ —
/api/embedによる埋め込み、keep_aliveとnum_ctxに対応した/api/chatによるコンテキスト化。Ollama 0.4.0 以降が必要です。 - OpenAI 互換 —
/v1/embeddingsによる埋め込み、/v1/chat/completionsによるコンテキスト化。OpenAI、Azure OpenAI、Groq、LM Studio、Together AI で動作します。 - Gemini ネイティブ —
task_typeによる非対称検索(RETRIEVAL_DOCUMENT/RETRIEVAL_QUERY)と Matryoshka 次元切り詰め(768 / 1536 / 3072)に対応した/v1beta/models/{model}:embedContentによる埋め込み。gemini-embedding-2、多言語、8k トークン入力に対応しています。 - Anthropic —
/v1/messagesによるコンテキスト化。 - 環境変数による API キー —
OPENAI_API_KEY、ANTHROPIC_API_KEYなど。バッチインデックス作成コマンド(exec、exec-queue)は環境変数のみを使用します。クライアントが対応している場合、対話型 MCP 検索では MCP エリシテーションにフォールバックできます。 - 標準 MCP stdio トランスポート(stdin/stdout 経由の JSON-RPC)
チャンクのコンテキスト化
標準的な RAG のチャンク分割では、コンテキストが失われます。「そのプロトコル」に関する文は、周囲の段落から切り離されると意味が曖昧になります。このサーバーは、統合チャンクコンテキスト化によってこの問題に対処します。チャンクごとに LLM を 1 回呼び出し、コンテキストの付与とバイリンガル(韓国語+英語)のキーワード生成をまとめて行います。
結果は元のチャンクテキストと並べて保存されます。
- 元のテキストは、正確な検索結果の表示のために保持されます
- コンテキスト化されたテキストは、埋め込みと BM25 のインデックス作成に使用されます
- バイリンガルキーワードにより言語をまたいだ検索が可能になり、韓国語のクエリで英語のドキュメントを検索したり、その逆を行ったりできます
これは、config.json で contextualizer を設定すると有効になります。チャンクをそのままインデックス化したい場合は、プロバイダー/モデルを空に設定して無効にできます。
インデックス作成の仕組み
exec コマンドは、ファイルごとに 5 段階のパイプラインを実行します。
- 抽出 — ドキュメントからテキストを抽出します(DOCX、PDF OCR、音声の文字起こしなど)
- チャンク分割 — 約 1000 文字のウィンドウに分割します
- コンテキスト化 — LLM による補強を行います(任意。上記を参照)
- 埋め込み — API 経由でベクトル埋め込みを生成します
- 永続化 — SQLite に保存します
大きなファイルでは、ステージ 1 だけで 20 分以上かかる場合があります。たとえば、596 ページのスキャン済み PDF の OCR や、数時間の音声録音の Whisper による文字起こしです。どの KB でも、最初の音声ファイルの処理時には ggml モデルのダウンロードが 1 回だけ発生します({UserProfile}/.fieldcure/whisper-models/ にキャッシュされます)。後続のステージが失敗したときに、コストのかかる上流処理の結果が失われないよう、パイプラインでは2 コミットモデルを使用します。
Stages 1-3 (Extract → Chunk → Contextualize)
↓
[Commit 1] chunks saved as PendingEmbedding
↓
Stage 4 (Embed)
├─ success → [Commit 2a] promote chunks to Indexed
└─ failure → chunks remain PendingEmbedding (retry next exec)
これが重要な理由:25 分かけて行った OCR の結果は、埋め込み API の呼び出し前にディスクへ永続化されます。ステージ 4 が失敗しても(ネットワークエラー、レート制限、トークン制限、プロセスのクラッシュ、さらには停電の場合も)、チャンクは保持されます。次回の exec ではファイルのハッシュが一致すればスキップされ(OCR を再実行しません)、後続の再試行パスではステージ 4 のみが試行されます。
チャンク単位の障害分離(バイナリ分割)
ファイル内の 1 つのチャンクが埋め込みモデルのトークン制限を超える場合(たとえば、教科書の数式が密集したページなど)、バイナリ分割アルゴリズムによってそのチャンクだけを分離します。
EmbedBatch([0..1249]) → 400 "input[846] too long"
├─ EmbedBatch([0..624]) → OK (promote 625)
└─ EmbedBatch([625..1249]) → 400
├─ EmbedBatch([625..937]) → 400
│ ... (binary search narrows toward chunk 846)
│ └─ EmbedBatch([846..846]) → 400 (mark chunk 846 Failed)
└─ EmbedBatch([938..1249]) → OK (promote 312)
結果:1249 個のチャンクがインデックス化され、チャンク 846 のみが Failed としてマークされます。ファイルのステータスは Degraded となり、完全に欠落するのではなく、部分的に検索可能な状態になります。
後続の再試行パス
各 exec の最後に、以前の実行で PendingEmbedding 状態のまま残ったチャンクに対する再試行パスが実行されます。
- DB から補強済みテキストを読み込みます。OCR やコンテキスト化を再実行する必要はありません
- 埋め込み API のみを呼び出します。通常、数分ではなく数秒で完了します
- チャンクごとに最大 3 回再試行し、上限に達するとチャンクを
Failedとしてマークします - 認証エラー(401/403)が発生すると、プロバイダーを利用不可としてマークし、残りの再試行をスキップします
ファイルの状態
| 状態 | 意味 | ハッシュ一致時のスキップ動作 |
|---|---|---|
Ready | インデックス作成完了 | ハッシュが一致する場合はスキップ |
Degraded | 一部のチャンクで失敗(バイナリ分割で分離済み) | ハッシュが一致する場合はスキップ |
PartiallyDeferred | 埋め込みの再試行待ちのチャンクがあります | メインループではスキップし、延期分の処理で取り込みます |
Failed | 抽出または埋め込みの再試行が失敗 | スキップします。再試行には --force が必要です |
NeedsAction | ユーザーによる対応が必要 | 個別のカウンターでカウントしてスキップします |
スキーマのバージョン管理
各 KB DB には PRAGMA user_version タグが付与されています。exec コマンドは、InitializeSchema() の一環として古いスキーマを自動的に移行します。serve コマンドは DB を読み取り専用で開き、移行を実行することはありません。古いスキーマの KB でも検索クエリの処理を継続でき、新機能用の列は使用されません。
インストール
dotnet tool(推奨)
dotnet tool install -g FieldCure.Mcp.Rag
ソースから
git clone https://github.com/fieldcure/fieldcure-mcp-rag.git
cd fieldcure-mcp-rag
dotnet build
要件
- .NET 8.0 Runtime 以降
- OCR:Windows x64 のみ — スキャンした PDF 用の Tesseract OCR は、初回使用時に遅延ロードされます(Windows のみ)。その他のプラットフォームでは、テキストが埋め込まれた PDF は通常どおり動作します。テキストレイヤーのないスキャンページは、警告なしにスキップされます。
- 埋め込みプロバイダー(Ollama、OpenAI など)— 任意。BM25 検索はプロバイダーなしでも動作します
- Ollama 0.4.0 以降(埋め込みまたはコンテキスト化に Ollama を使用する場合)
クイックスタート
埋め込みの設定なしでフォルダーにインデックスを作成し、検索します(BM25 のみ)。
# 1. Install
dotnet tool install -g FieldCure.Mcp.Rag
# 2. Create a minimal config
$kbPath = "$env:LOCALAPPDATA\FieldCure\Mcp.Rag\demo"
New-Item -ItemType Directory -Force -Path $kbPath
@'
{
"id": "demo",
"name": "Demo KB",
"sourcePaths": ["C:\\my-docs"]
}
'@ | Set-Content "$kbPath\config.json"
# 3. Index
fieldcure-mcp-rag exec --path $kbPath
# 4. Start the search server
fieldcure-mcp-rag serve --base-path "$env:LOCALAPPDATA\FieldCure\Mcp.Rag"
セマンティック検索とコンテキスト化によって検索品質を最大限に高めるには、config.json に embedding ブロックと contextualizer ブロックを追加してください。詳しくは、以下の使い方を参照してください。
使い方
1. ナレッジベースフォルダーを作成する
%LOCALAPPDATA%\FieldCure\Mcp.Rag\{kb-id}\config.json
{
"id": "my-kb-001",
"name": "Project Docs",
"created": "2026-04-03T00:00:00Z",
"sourcePaths": ["C:\\Users\\me\\Documents\\project-docs"],
"contextualizer": {
"provider": "anthropic",
"model": "claude-haiku-4-5-20251001",
"apiKeyPreset": "Claude"
},
"embedding": {
"provider": "openai",
"model": "text-embedding-3-small",
"apiKeyPreset": "OpenAI"
}
}
API キーは環境変数から解決されます。apiKeyPreset: "OpenAI" → OPENAI_API_KEY、"Claude" → ANTHROPIC_API_KEY、"Gemini"(または "Google")→ GEMINI_API_KEY です。
Gemini 埋め込みの例 — 1536 次元の Matryoshka 切り詰めを使った非対称検索です(フルサイズの 3072 次元と同じ MTEB スコアで、ストレージ使用量は 50% です)。
"embedding": {
"provider": "gemini",
"model": "gemini-embedding-2",
"apiKeyPreset": "Gemini",
"dimension": 1536
}
| 次元数 | MTEB | ストレージ | 用途 |
|---|---|---|---|
| 768 | 67.99 | 25% | ストレージ容量に制約がある場合 |
| 1536 | 68.17 | 50% | 推奨されるデフォルト |
| 3072 | 68.17 | 100% | 最高品質(正規化済み) |
serve モードでは、クライアントが対応している場合、search_documents は MCP エリシテーションを通じてプロンプトを表示することもできます。exec および exec-queue では、不足しているキーを環境変数で指定する必要があります。 |
2. ドキュメントにインデックスを作成する
fieldcure-mcp-rag exec --path "C:\Users\me\AppData\Local\FieldCure\Mcp.Rag\my-kb-001"
3. MCP 検索サーバーを起動する
fieldcure-mcp-rag serve --base-path "C:\Users\me\AppData\Local\FieldCure\Mcp.Rag"
1 つのサーブプロセスで、ベースパス配下のすべてのナレッジベースを処理します。ツールには、対象の KB を指定する kb_id パラメーターがあります。
Claude Desktop
claude_desktop_config.json に追加します。
{
"mcpServers": {
"rag": {
"command": "fieldcure-mcp-rag",
"args": ["serve", "--base-path", "C:\\Users\\me\\AppData\\Local\\FieldCure\\Mcp.Rag"],
"env": {
"OPENAI_API_KEY": "sk-...",
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
config.json リファレンス
| フィールド | 説明 |
|---|---|
id | ナレッジベース識別子 |
name | 表示名 |
sourcePaths | インデックス対象のフォルダー一覧(複数指定可能) |
contextualizer.provider | "anthropic"、"openai"、"ollama"、または無効にする場合は空 |
embedding.provider | "openai"、"ollama"、"gemini"、または無効にする場合は空 |
embedding.dimension | 出力次元数。0 = プロバイダーの既定値。Gemini は MRL による切り詰めに対応しています:768 / 1536 / 3072。 |
contextualizer.model | モデル ID、またはコンテキスト化を無効にする場合は空 |
contextualizer.apiKeyPreset | 環境変数に対応します:"OpenAI" → OPENAI_API_KEY、"Claude" → ANTHROPIC_API_KEY |
contextualizer.baseUrl | API ベース URL の上書き(null = プロバイダーの既定値) |
embedding.* | contextualizer と同じ構成 |
embedding.maxChunkChars | 分割前のチャンクあたりの最大文字数(既定値:4000) |
embedding.batchSize | 埋め込み API 呼び出しあたりの最大チャンク数(既定値:プロバイダーテーブルから自動設定) |
embedding.keepAlive | Ollama のみ:VRAM の保持時間(既定値:"5m") |
embedding.numCtx | Ollama のみ:コンテキストウィンドウのトークン数(既定値:8192)。contextualizer のみ。 |
systemPrompt | コンテキスト化用のカスタムシステムプロンプト(null = 組み込みの既定値) |
ツール
list_knowledge_bases を除くすべてのツールでは、対象のナレッジベースを指定するために kb_id パラメーターが必要です。
| ツール | 説明 |
|---|---|
list_knowledge_bases | 利用可能なすべての KB をステータス(ファイル数/チャンク数、インデックス作成状況)とともに一覧表示します |
search_documents | RRF を使用した BM25 とベクトルのハイブリッド検索。search_mode に対応:auto、bm25、vector |
get_document_chunk | ID で指定したチャンクの全内容を取得します |
start_reindex | インデックス作成リクエストをキューに登録します。スコープのマージ、強制/遅延フラグ、オーケストレーターの自動起動 |
cancel_reindex | 保留中(未開始)のキュー項目を削除します |
get_index_info | インデックスのメタデータ、キューの状態(ステータス/位置/遅延/last_error)、コンテキスト化の健全性 |
check_changes | ファイルシステムのドライランスキャン。軽量で、API 呼び出しはありません |
検索モード
search_mode | 動作 |
|---|---|
auto | 埋め込みが利用可能な場合はハイブリッド検索、そうでない場合は BM25。推奨 |
bm25 | キーワードのみ(FTS5)。埋め込み呼び出しなし |
vector | セマンティック検索のみ。埋め込みプロバイダーがない場合はエラーになります |
対応形式
ドキュメント形式は FieldCure.DocumentParsers により提供されます:
- DOCX — Microsoft Word(数式の抽出に対応)
- HWPX — 韓国標準ドキュメント(OWPML、数式の抽出に対応)
- XLSX — Excel スプレッドシート
- PPTX — PowerPoint プレゼンテーション
- PDF —
## Page Nヘッダー付きの PDF テキスト抽出。スキャンされたページでは OCR にフォールバックします(Tesseract、eng+kor) - TXT, MD — プレーンテキスト/Markdown
プロジェクト構成
src/FieldCure.Mcp.Rag/
├── Program.cs # CLI entry (exec | exec-queue | serve | prune-orphans)
├── MultiKbContext.cs # Multi-KB manager (lazy load, Classify, lazy unload)
├── ExecQueueRunner.cs # Deferred queue orchestrator
├── OrphanCleanupRunner.cs # prune-orphans CLI
├── Configuration/
│ ├── RagConfig.cs # config.json model (KeepAlive, NumCtx fields)
│ └── OllamaDefaults.cs # Shared defaults (KeepAlive="5m", NumCtx=8192)
├── Indexing/
│ ├── IndexingEngine.cs # 5-stage pipeline (2-commit model)
│ └── EmbeddingBatchSplitter.cs # Binary-split per-chunk failure isolation
├── Contextualization/
│ ├── IChunkContextualizer.cs
│ ├── OpenAiChunkContextualizer.cs # /v1/chat/completions
│ ├── OllamaChunkContextualizer.cs # /api/chat (keep_alive + num_ctx)
│ ├── AnthropicChunkContextualizer.cs
│ └── NullChunkContextualizer.cs
├── Embedding/
│ ├── IEmbeddingProvider.cs
│ ├── OpenAiCompatibleEmbeddingProvider.cs # /v1/embeddings
│ ├── OllamaEmbeddingProvider.cs # /api/embed (keep_alive)
│ ├── NullEmbeddingProvider.cs
│ └── EmbeddingBatchSizes.cs
├── Storage/
│ └── SqliteVectorStore.cs # SQLite + FTS5 + SIMD cosine similarity
├── Search/
│ ├── HybridSearcher.cs # BM25 + Vector → RRF
│ └── RrfFusion.cs
├── Chunking/
│ ├── TextChunker.cs
│ └── ChunkLimits.cs
└── Tools/
├── ListKnowledgeBasesTool.cs
├── SearchDocumentsTool.cs
├── GetDocumentChunkTool.cs
├── StartReindexTool.cs # Queue entry point + orchestrator spawn
├── CancelReindexTool.cs # Remove pending queue entry
├── GetIndexInfoTool.cs # Includes queue state
└── CheckChangesTool.cs
データストレージ
ナレッジベースのデータは %LOCALAPPDATA%\FieldCure\Mcp.Rag\{kb-id}\ に保存されます:
config.json— ナレッジベースの設定rag.db— SQLite データベース(チャンク、埋め込み、FTS5 インデックス、ファイルハッシュ、インデックス作成ロック)
キューとロックのファイルは %LOCALAPPDATA%\FieldCure\Mcp.Rag\ に保存されます:
.deferred-queue.json— 保留中のインデックス作成リクエストorchestrator.lock— キューオーケストレーターの PID ロック
開発
# Build
dotnet build
# Test
dotnet test
# Pack as dotnet tool
dotnet pack src/FieldCure.Mcp.Rag -c Release
関連項目
AssistStudio エコシステムの一部です。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。