faq-rag
FAQ RAG MCP Server
Glean Solutions Engineering の技術演習用に意図的に小さく作られた検索拡張生成(RAG)アプリケーションです。提供された FAQ Markdown ファイルをインデックス化し、コサイン類似度で関連するパッセージを取得し、LLM を通じて根拠に基づく回答を生成し、その結果を1つのローカル MCP ツール ask_faq として公開します。
このプロジェクトは完全にクロスプラットフォームです。すべてのセットアップおよび実行コマンドは uv を使用し、Windows、macOS、Linux で同一です。これを Claude Code を使う Windows ユーザーに渡す場合? START_HERE_WINDOWS.md から始めてください。リポジトリには、Claude Code が自動的に読み取る CLAUDE.md セットアップランブックと、faq-rag サーバー用のポータブルなプロジェクトスコープの .mcp.json 定義が含まれています。
30秒の説明
プロセス起動時に、Python は FAQ ファイルを読み取り、それらをおよそ200文字のチャンクに分割し、埋め込みを生成して正規化し、インデックスをメモリにキャッシュします。各質問について、質問を埋め込み、コサイン類似度でチャンクをランク付けし、最良の4つのテキストチャンクを設定済みの LLM に送信し、完成した回答とソースファイル名だけを返します。
flowchart LR
A[FAQ Markdown files] --> B[~200-character chunks]
B --> C[Document embeddings cached in RAM]
Q[Question] --> D[Query embedding]
C --> E[Cosine similarity]
D --> E
E --> F[Top 4 text chunks]
F --> G[Grounded LLM generation]
G --> H[answer + sources]
H --> I[MCP client]埋め込みはパッセージの特定にのみ使用されます。LLM が受け取るのは元の質問と取得されたテキストであり、生の埋め込みベクトルではありません。
Related MCP server: faq-rag
正確な MCP 契約
ツール: ask_faq
入力:
{
"question": "How do I reset my password?",
"top_k": 4
}出力—追加のキーはありません:
{
"answer": "Use the reset link on the login page [faq_auth.md].",
"sources": ["faq_auth.md", "faq_sso.md"]
}top_k は1から10までの整数を受け付け、デフォルトは4です。
提供された HTTP オプションではなく、なぜ MCP なのか?
RAG の中核はどちらのラッパーでも同一です。MCP を選んだ理由は、AI クライアントがツールスキーマを発見し、いつ呼び出すかを判断し、ローカルの Python プロセスを起動し、カスタム HTTP クライアント、ポート、URL、ヘルスエンドポイントを必要とせずに構造化された結果を受け取れるからです。MCP は相互運用性を向上させますが、それ自体が検索品質を向上させるわけではありません。
この実装は、課題で要求されている stdio トランスポートを使用します。MCP クライアントは mcp_server.py をローカルの子プロセスとして起動し、プロセスの標準入力と標準出力を通じて MCP メッセージを交換します。サーバーは stdout に通常のログを書き込みません。そのチャネルはプロトコルトラフィック用に予約されているためです。
セットアップ(Windows、macOS、Linux のいずれの OS でも)
要件:
Git
uv— 互換性のある Python を自動的にダウンロードするため、別途 Python のインストールは不要です。Windows:winget install -e --id astral-sh.uv; macOS:brew install uv。利用可能な API クレジットを持つ OpenAI API キー
Claude Code や Cursor などの MCP クライアント
コマンドは PowerShell、zsh、bash で同一です:
git clone https://github.com/cq2wgwtzb5-lgtm/glean-faq-rag-mcp.git
cd glean-faq-rag-mcp
uv sync.env.example をコピーして .env.local を作成し、エディタでそこに API キーを追加してください:
OPENAI_API_KEY=your_key_here.env.local は Git によって無視されます。コミットしたり共有したりしないでください。
決定論的テストを実行します(API 呼び出しなし):
uv run pytest -qMCP を追加する前に、直接エンドツーエンドのスモークテストを実行します:
uv run rag_core.pyClaude Code は、このフォルダ内でセッションを開始すると、チェックイン済みの .mcp.json を自動的に検出します。承認、確認、呼び出しの手順は docs/WINDOWS_MCP_SETUP.md に従ってください(手順はすべての OS に適用されます)。Windows ユーザーは、同じ uv コマンドをラップする setup_windows.ps1 を代わりに実行することもできます。
マシン上の任意のチャットスレッドから使用する
プロジェクトスコープの .mcp.json は、このフォルダ内で開始されたセッションでのみ読み込まれます。ask_faq をマシン上のすべての Claude Code セッションで利用できるようにするには、クローンの絶対パスを使用してサーバーをユーザースコープで一度登録します(すべての OS で同じコマンド):
claude mcp add --scope user faq-rag -- uv run --directory "<absolute path to this repo>" mcp_server.pyリポジトリ内のセッションは引き続きプロジェクトスコープのエントリを使用し、その他のすべてのセッションはユーザースコープのエントリを使用します。削除するには claude mcp remove --scope user faq-rag を実行します。
評価
ユニットテストは決定論的なフェイク埋め込みを使用し、モデル呼び出しを行いません:
uv run pytest -qライブ評価器は、実際のモデル API に対して5つの代表的な質問を実行し、期待されるソース、必須の事実、および回答を控える動作をチェックします:
uv run evaluate.py --output eval-results.jsoneval-results.json は、モデルの出力やアカウント設定が異なるため、意図的に無視されます。面接中にレポートをキャプチャするか、画面共有してください。
重要な設計判断
インメモリ NumPy インデックス
提供されたコーパスから生成されるチャンクはわずかです。ベクターデータベースを導入すると、この結果を改善することなく、デプロイとレビューの複雑さが増すだけです。正規化された NumPy ベクトルにより、コサイン類似度は単純な行列ベクトル積になります。
境界を考慮したチャンク分割
ターゲットは要件どおりおよそ200文字のままです。実装は段落、行、文、単語の境界を優先するため、正確な文字数に合わせるためだけにテキストが任意の場所で切られることはありません。
起動時の1回の埋め込みパス
ドキュメントの埋め込みはプロセス起動時に一度だけ生成され、RAM にキャッシュされます。各質問には新しいクエリ埋め込みが作成されます。キャッシュは共有コーパスデータ—会話やユーザーセッションのメモリではありません。プロセスが終了するとキャッシュは消え、次回起動時に再構築されます。
根拠に基づく生成と引用
生成プロンプトは、モデルを取得済みの FAQ コンテキストに制限し、正確なファイル名の引用を要求し、FAQ が質問に答えられない場合にその旨を述べるよう指示します。レスポンスの sources リストは取得順を保持し、取得されたチャンクからのファイル名のみを含みます。
明示的な失敗時の動作
このアプリケーションは、OPENAI_API_KEY がない場合は即座に失敗し、空白の質問や無効な top_k を拒否し、モデルのタイムアウトを30秒に設定し、SDK のリトライを2回許可します。エラーは、でっち上げた FAQ の回答ではなく、MCP エラーのままになります。
既知の制限と本番環境への発展
この演習では、永続インデックス、増分取り込み、アクセス制御、ハイブリッド語彙検索、再ランキング、鮮度・権威シグナル、監査ログ、ユーザーごとのパーソナライゼーションを意図的に省いています。
エンタープライズシステムでは、許可されていないテキストがモデルコンテキストに入ることがないよう、取得の前に権限を強制する必要があります。検索品質も、コサイン類似度だけではなく、語彙、意味、鮮度、権威、グラフの各シグナルを使用することになるでしょう。これらは本番環境の中心的な関心事ですが、3つのローカルファイルのために実装すると、軽量なソリューションを求める演習の意図に反することになります。
リポジトリガイド
rag_core.py— 取り込み、チャンク分割、埋め込み、取得、生成mcp_server.py— stdio 上の1つのask_faqMCP ツールfaqs/— 提供された FAQ コーパスtests/— 決定論的なユニットテストと設定テストevals/cases.json— 5つのライブ評価ケースevaluate.py— ライブ評価ランナーpyproject.toml/uv.lock— 固定されたクロスプラットフォーム環境(uv sync)setup_windows.ps1— 同じuv手順をラップする Windows 用便利ラッパーCLAUDE.md— Claude Code 向けの自動セットアップおよび学習手順.mcp.json— ポータブルなプロジェクトスコープの Claude Code MCP 設定START_HERE_WINDOWS.md— Windows ユーザー向けの1プロンプトでの引き継ぎdocs/WINDOWS_MCP_SETUP.md— Claude Code 接続手順docs/TALK_TRACK.md— 面接用プレゼンテーションと想定質問docs/REQUIREMENTS_TRACEABILITY.md— 課題からコードへの対応関係のエビデンスマップdocs/VALIDATION.md— 合格したチェックと残っているライブテストの境界
セキュリティ
API キーをコミットしないでください。MCP サーバーを有効にする前にレビューしてください。ローカルの stdio サーバーは、クライアントを起動したユーザーの権限で実行されます。このサーバーは、設定された FAQ ディレクトリのみを読み取り、設定された OpenAI モデルのみを呼び出します。
面接準備
docs/TALK_TRACK.md を使用してください。そこには、アーキテクチャ、各選択の理由、MCP が HTTP とどう異なるか、そしてこの小さな演習が Glean のエンタープライズ検索および根拠に基づく回答の問題にどう対応するかが説明されています。
This server cannot be deployed
Maintenance
Related MCP Connectors
Query any docs site via MCP. Submit a URL, ask questions, get cited answers.
Ask any GitHub repository a question. Get source-backed answers.
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Docs Q&A: search 169 data and AI guides, fetch any page as markdown. Read-only, keyless.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables semantic search and question-answering over FAQ documents using RAG (Retrieval-Augmented Generation) with OpenAI embeddings and in-memory vector similarity.-
- FlicenseNot gradedqualityDmaintenanceEnables answering natural-language questions from FAQ documents using vector search and LLM generation via an MCP tool.-
- FlicenseNot gradedqualityCmaintenanceEnables MCP hosts like Cursor or Claude to query an enterprise knowledge base via stdio, providing RAG-based answers with cited sources.-
- FlicenseNot gradedqualityAmaintenanceEnables MCP clients to query a compiled Markdown knowledge base through a single ask tool, returning cited answers grounded in wiki articles over stdio or streamable HTTP.-