MCP(Model Context Protocol)はAIアプリケーションと外部のツール・データをつなぐ方法を決めた通信規格で、RAG(Retrieval-Augmented Generation)は外部の文書を検索して回答の文脈に差し込む実装手法です。片方がもう片方を置き換える関係ではなく、扱う層が違います。この記事では両者の処理の中身を分解したうえで、「読ませたいだけならRAG、操作させたいならMCP」という使い分けの条件を示し、RAGの検索をMCPサーバーのツールとして公開する併用構成を、仕様2026-07-28版と公式Python SDK 2.3.0で動かしたコードで解説します。
まとめ:MCPとRAGのレイヤー差と使い分け
RAGは2020年の論文で提案された「検索してから生成する」手法で、文書の分割・埋め込み・ベクトル検索・プロンプトへの注入という処理を自分で組みます。MCPは2024年11月にAnthropicが公開したオープンな規格で、JSON-RPC 2.0のメッセージでAIアプリケーションと外部ツールの接続方法を定めています。RAGは「LLMに何を読ませるか」を解き、MCPは「LLMと道具をどうつなぐか」を決めます。
判断は次の3行に集約できます。
- 社内文書を探して答えるだけなら、RAG単独で設計を完結させる。MCPサーバーの自作は過剰投資になる
- チケット起票やデータベース更新のような書き込み、稼働中システムの「今の値」の参照が要件に入るなら外部システムへの接続が必要になり、その接続を複数のAIアプリで共通化するならMCPを選ぶ
- 両方が要る、または同じ検索基盤を複数のAIアプリから使いたいなら、RAGの検索をMCPツールとして公開する併用構成にする
2026年の実装で押さえる変化は2つです。MCPの現行仕様は2026-07-28版で、接続ごとのセッションと初期化ハンドシェイクが廃止されステートレスになりました。公式Python SDKも2.x系でFastMCPがMCPServerへ改称されており、1.x向けの記事のコードはそのままでは動きません。
MCPとRAGの位置づけ──接続プロトコルと検索手法というレイヤー差
使い分けを誤る原因の多くは、両者を同じ層の選択肢として並べることにあります。まず処理の実体を分け、どの層の話かを固定します。
RAGの処理フロー──分割・埋め込み・検索・注入の4工程
RAGの出発点は、Facebook AI Research・ユニバーシティ・カレッジ・ロンドン・ニューヨーク大学の研究者が2020年5月22日にarXivへ投稿し、同年のNeurIPSで発表された論文「Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks」です。ここではベクトル検索を使う代表的な構成を説明します。文書を見出しや意味のまとまりに沿ったチャンクに分割し、埋め込みモデルで各チャンクをベクトルに変換してpgvector・Qdrantなどのベクトルデータベースへ格納します。問い合わせ時は質問を同じモデルでベクトル化し、類似度の高い上位k件を取り出してプロンプトに差し込み、LLMに回答を生成させます。実務のRAGはLLMの重みを更新せずに入力へ根拠を足す構成が一般的ですが、原論文自体は検索器の質問エンコーダと生成モデルをまとめてファインチューニングする手法として提案されており、重みの更新と排他の関係ではありません。仕組みと企業での導入例はRAGの仕組みと導入例の解説で詳しく扱っており、埋め込みモデルの選び方は日本語埋め込みモデルの選定基準にまとめています。
MCPの構成要素──ホスト・クライアント・サーバーと3種類のサーバー機能
MCPはホスト(Claude DesktopやIDEなどのAIアプリケーション)、クライアント(ホストの中でサーバー1つとの接続を受け持つ部品)、サーバー(ツールやデータを提供する側)の3者で構成されます。サーバーが出せる機能は3種類で、仕様は誰が呼び出しを決めるかで区別しています。
| サーバー機能 | 呼び出しを決める主体 | 例 |
|---|---|---|
| ツール(tools) | モデル(model-controlled) | API呼び出し、ファイル書き込み |
| リソース(resources) | アプリケーション(application-controlled) | ファイルの中身、git履歴 |
| プロンプト(prompts) | ユーザー(user-controlled) | スラッシュコマンド |
この区別は、RAGの検索をMCPに載せるときに「LLMが検索を呼ぶ」のか「アプリが文書を添える」のかという設計判断に直結します(後述)。2025年にはOpenAIとGoogle DeepMindも対応を表明し、2025年12月9日にはLinux Foundation傘下に設立されたAgentic AI Foundationへ、創設プロジェクトの1つとして寄贈されました。プロトコル全体の仕組みはMCPの仕組みと3層アーキテクチャの解説に譲ります。
比較表──目的・データの流れ・構築物・標準化の有無
実装者が判断に使う軸で並べます。見るべきは「何を作ることになるか」と「データがどちらへ流れるか」の2行です。
| 比較軸 | RAG | MCP |
|---|---|---|
| 分類 | 実装手法(設計パターン) | 通信プロトコル(公開仕様) |
| 初出 | 2020年の論文 | 2024年11月にAnthropicが公開 |
| 主目的 | 外部知識の検索と注入 | 外部ツール・データ接続の標準化 |
| データの流れ | 読み取り中心 | 読み書き双方向 |
| 主な構築物 | チャンク・埋め込み・ベクトルDB | MCPサーバー・ツール定義 |
| 品質の決め手 | チャンク設計・検索精度 | ツール説明文・スキーマ |
| 標準仕様 | なし | あり(現行は2026-07-28版) |
RAGには標準仕様がなく、品質は作り込みで決まります。MCPは「つなぎ方」が仕様で固定されているぶん、品質を左右するのは接続先のツール定義です。この非対称が次の工数・運用の違いにつながります。
実装・運用で見る違い──構築工数・精度と鮮度・統制の論点
概念の違いが分かっても、見積もりと運用設計は別の話です。現場で比較が必要になる3つの断面で並べます。
構築工数──前処理パイプラインが本体のRAGと接続設定で始まるMCP
RAGの見積もりでは、LLMの呼び出しに加えて、文書の前処理・検索基盤・評価の工数を分けて確認します。前処理にはPDFやWikiからのテキスト抽出、表や画像の扱い、チャンクの粒度決め、文書更新時のインデックス再構築が含まれます。デモの実装とは別に、検索精度の評価と改善にかかる期間も見積もる必要があります。MCPは、GitHub・Slack・Notionのような公開済みサーバーにつなぐだけなら設定ファイルへの記述で済みます。Notion MCPサーバーの接続手順のように、既製サーバーの利用は接続情報の登録がほぼすべてです。自作する場合も公式SDKがあり、ツール数本のサーバーなら後述のとおり数十行で書けます。初期工数はMCP接続が軽く、RAGは検索品質への投資が要る、という前提で見積もりを始めます。
精度と鮮度──検索と生成で決まるRAGの精度と取得元で決まる鮮度
RAGの回答品質は検索と生成の両方で決まります。必要な根拠を取得できなければ品質は落ち、チャンクの切り方、埋め込みモデル、取り出す件数k、検索結果を並べ直すリランキングの有無が、取得する根拠の質を左右します。根拠を取得できても生成モデルが誤読することはあるので、評価は検索と生成を分けて行います。検索したチャンクを出典として示せるため、「どの文書のどこに基づく回答か」を求められる要件には向いています。MCPの応答の質は、ツールの説明文と引数のスキーマに依存します。説明が曖昧なツールは、LLMが誤った引数で呼びます。鮮度はRAGかMCPかではなく、取得元と更新・キャッシュの設計で決まります。夜間バッチで再インデックスするRAGなら日中の文書変更は反映されず、MCPサーバーでも接続先のAPIをその場で呼ぶ実装なら在庫数やチケットの状態のような現在値を返せますが、索引やキャッシュを参照する実装なら古い値を返します。
保守・統制──再インデックス運用のRAGと認可・監査が軸になるMCP
RAGの保守は、文書更新時の再インデックスと、検索の的中率を測り続ける評価が中心です。古い文書に基づく回答に加え、利用者に閲覧権限のない文書が検索結果や回答に混入するリスクもあります。検索時に文書単位のアクセス制御を適用する設計が必要です。MCPの保守は権限と統制が主戦場です。ツールは書き込みや削除も実行できるため、誰の権限でどのツールを呼べるか、危険な操作の前に人の承認を挟むか、呼び出し履歴をどう残すかを決めないと本番に出せません。仕様もツールについて「呼び出しを拒否できる人間を介在させるべき(SHOULD)」と明記しています。認可はOAuth 2.1をもとにした仕組みが2025-03-26版で入り、2025-06-18版でMCPサーバーをOAuthのリソースサーバーとして扱う形に整理されました。読み取り専用のRAGでは起きない「AIが業務システムを操作する」ことへの統制コストが、MCP導入の見積もりに乗る固有の項目です。
使い分けの判断──RAGで足りる条件とMCPが必要になる条件
要件を「読ませたいだけか」「操作させたいか」「道具を使い回すか」の3つの問いに落とすと、選択はほぼ決まります。
RAGを選ぶ条件──大量文書の参照と出典付き回答が要件の中心
規程・マニュアル・過去のナレッジのような大量の文書を対象に、AIに求めるのが「探して答える」ことだけなら、RAGを選びます。回答に出典を付ける必要がある場合や、データがAPIを持たないファイル群で存在する場合も同じです。典型は社内ヘルプデスクの文書回答で、ここにツール接続の仕組みを足しても回答精度は上がりません。操作要件がなく、検索基盤を複数のAIアプリで共有する予定もない文書Q&Aは、RAGだけで設計を完結させてください。浮いた工数は、精度を実際に左右するチャンク設計と検索評価に回します。
MCPを選ぶ条件──書き込み・現在値の参照・複数アプリでの共有
次の要件では外部システムへの接続を検討します。単一アプリならAPIの直接呼び出しでも実装でき、複数の対応ホストで接続を共通化したい場合にMCPを選びます。1つ目は書き込みで、チケット起票・カレンダー登録・データベース更新は検索手法であるRAGには実行できません。2つ目は参照先が文書ではなく稼働中のシステムで、APIから現在値を取る必要がある場合です。3つ目は同じ道具を複数のAIアプリケーションから使い回したい場合で、ここがプロトコルとしてのMCPの本領です。アプリごとに接続を実装するとアプリ数×ツール数だけ実装が増えますが、MCPサーバーとして公開すれば、対応するプロトコル版・トランスポート・認証方式・機能が一致する複数のホストから再利用できます。
見送るべきパターン──文書Q&AへのMCP自作と検索なしの全文注入
失敗には型があります。
- 文書Q&AしかないのにMCPサーバーの自作から入る:接続の標準化は道具が増えるときに効く投資で、道具が1つもない段階では認可・監査の統制コストだけが先に立ちます。利用するAIアプリが1つなら、検索処理をアプリに直接組み込むほうが部品も障害点も少なく済みます。
- MCPのリソースで文書を検索なしに丸ごと渡す:数百ページの規程集を毎回コンテキストに入れる構成では、使用モデルの入力上限・料金・キャッシュの有無を確認し、許容する応答時間内に収まるかを測定します。文書量が増えれば絞り込む検索が要り、それはRAGの領分です。
- RAGの精度問題をMCP導入で直そうとする:検索が外れる原因はチャンク設計や埋め込みにあり、接続層を替えても改善しません。
仕様2026-07-28版で変わった前提──ステートレス化とSDK 2系の改称
2025年以前の解説記事を読んで実装すると、ここで最初につまずきます。MCPの現行仕様(Current)は2026-07-28版で、直前の2025-11-25版から後方互換のない変更が入りました。
セッションと初期化ハンドシェイクの廃止──RAGサーバーの水平分散への影響
2026-07-28版の変更履歴は、Streamable HTTPのプロトコルレベルのセッションとMcp-Session-Idヘッダーの廃止、initialize/notifications/initializedのハンドシェイク廃止を筆頭に挙げています。各リクエストがプロトコル版とクライアントの機能を_metaに載せて届き、サーバーは代わりにserver/discoverで対応版と機能を公開します。RAGの検索サーバーから見ると、接続ごとの状態を持たないので、ロードバランサーの後ろに複数台並べてもセッションを同じ台へ振り分ける設定が要りません。会話をまたいで状態を持ちたい場合は、サーバーが発行したハンドルをツールの引数として明示的に受け渡す形になります。ほかに、tools/listのツールを決まった順序で返すこと(LLMのプロンプトキャッシュの効きを上げるため)が推奨され、一覧系の結果には鮮度の目安となるttlMsとcacheScopeが必須になりました。Sampling・Roots・Loggingの3機能は非推奨です。
Python SDK 2系の変更──FastMCPはMCPServerへ改称
公式Python SDK(PyPIのmcp)は2026年10月2日に2.3.0が出ており、2.x系では1.x系のfrom mcp.server.fastmcp import FastMCPが使えません。2.3.0の環境でこのimportを実行するとModuleNotFoundErrorになり、エラーメッセージ自体がfrom mcp.server.mcpserver import MCPServerへの書き換えを案内します。1.x向けのコードを動かし続けるならmcp<2に固定する、新規に書くならMCPServerを使う、のどちらかです。同じSDKは2025-11-25版以前の初期化ハンドシェイクにも対応しており、クライアントをmode="legacy"にすると旧サーバー向けに2025-11-25版で接続します。
RAG検索をMCPツールとして公開する実装──Python SDK 2.3.0での最小構成
併用の基本形は、構築済みのRAG検索を「質問を受けて関連チャンクを出典付きで返す」1つのツールとしてMCPサーバーに載せる構成です。ツールはモデルが呼び出しを決める機能なので、エージェントは必要と判断したときだけ検索を呼び、返った根拠を読んでから次の行動を決めます。毎回機械的に検索を挟む従来のRAGと違い、雑談には検索を走らせないといった判断もLLMに任せられます。以下のコードはPython 3.12・mcp==2.3.0で2026年10月9日に動作を確認しました。
サーバー側──search_knowledgeツールの定義
検索部分は動作確認用に文字2-gramの類似度で代用しています。本番ではembedを埋め込みモデルの呼び出しに、INDEXの走査をベクトルデータベースへの問い合わせに置き換えます。
# rag_server.py:RAGの検索部分をMCPツールとして公開する最小構成
import math
from collections import Counter
from mcp.server.mcpserver import MCPServer
from mcp.server.mcpserver.exceptions import ToolError
# 本番ではベクトルDBに入っているチャンク。ここでは3件で代用
CHUNKS = [
{"id": "rule-012", "source": "就業規則.pdf p.12", "text": "在宅勤務の申請は前日17時までに上長へ申請する。"},
{"id": "rule-031", "source": "就業規則.pdf p.31", "text": "経費精算は利用月の翌月5営業日以内に申請する。"},
{"id": "faq-007", "source": "社内FAQ.md", "text": "VPNに接続できない場合は端末を再起動してから情報システム部へ連絡する。"},
]
def embed(text: str) -> Counter:
# 埋め込みモデルの代わりに文字2-gramの出現数を使う(動作確認用)
return Counter(text[i:i + 2] for i in range(len(text) - 1))
def cosine(a: Counter, b: Counter) -> float:
dot = sum(a[k] * b[k] for k in a)
norm = math.sqrt(sum(v * v for v in a.values())) * math.sqrt(sum(v * v for v in b.values()))
return dot / norm if norm else 0.0
INDEX = [(c, embed(c["text"])) for c in CHUNKS]
mcp = MCPServer("knowledge-search")
@mcp.tool()
def search_knowledge(query: str, top_k: int = 2) -> list[dict]:
"""社内規程とFAQから、質問に関連する文書の断片を出典付きで返す。
規程・手続き・社内ルールに関する質問に答える前に呼び出すこと。"""
if not query.strip():
raise ToolError("query が空です。質問文を指定してください")
if not 1 <= top_k <= len(INDEX):
raise ToolError(f"top_k は1以上{len(INDEX)}以下で指定してください")
q = embed(query)
ranked = sorted(INDEX, key=lambda pair: cosine(q, pair[1]), reverse=True)
# 類似度0の断片は根拠にならないので返さない(本番の閾値は評価データで決める)
return [
{"source": c["source"], "text": c["text"], "score": round(cosine(q, v), 3)}
for c, v in ranked[:top_k]
if cosine(q, v) > 0
]
if __name__ == "__main__":
mcp.run() # 既定はstdio。ホストがこのプロセスを起動して接続する
空の質問や範囲外のtop_kはToolErrorで返します。SDKはToolErrorのメッセージをis_error=Trueの結果としてモデルに渡しますが、ValueErrorなど他の例外は「Error executing tool search_knowledge」とだけ返し、理由を伝えません。2026年10月9日の実行では、top_k=-1の呼び出しに「top_k は1以上3以下で指定してください」というメッセージがそのまま返りました。類似度0の断片は根拠にならないので除外しており、無関係な質問(例:「zzzz」)には空のリストを返します。
関数のdocstringがそのままツールのdescriptionになり、型ヒントから引数のinputSchema(queryは必須の文字列、top_kは既定値2の整数)が生成されます。LLMはこの説明文を読んで呼ぶかどうかを決めるので、「何についての質問のときに呼ぶか」を明記すると、ツール選択の判断材料になります。必ず検索させる要件では、説明文だけに頼らず、ホスト側で検索を実行する制御も設けます。
クライアント側──stdio接続と検索結果の確認
ホストが行うことを手元で再現するスクリプトです。Python 3.12の仮想環境でpython -m pip install "mcp==2.3.0"を実行し、2つのファイルを同じディレクトリに保存してからpython check_client.pyを実行します。サーバーは子プロセスとして起動され、標準入出力で接続します。sys.executableを使うのは、サーバーをクライアントと同じ仮想環境のPythonで起動するためです。
# check_client.py:ホスト役としてサーバーを起動し、ツール一覧と検索結果を確かめる
import asyncio
import sys
from mcp import Client, StdioServerParameters
async def main():
params = StdioServerParameters(command=sys.executable, args=["rag_server.py"])
async with Client(params) as client:
print("protocol:", client.protocol_version)
tools = await client.list_tools()
for t in tools.tools:
print("tool:", t.name, "| input:", list(t.input_schema["properties"]))
result = await client.call_tool("search_knowledge", {"query": "経費精算の申請期限は?", "top_k": 1})
print(result.structured_content)
asyncio.run(main())
実行結果は次のとおりです。この例で確認できるのは、2026-07-28版での接続、ツール一覧の取得、固定した質問による検索呼び出しです。LLMによるツール選択と回答生成は検証範囲に含みません。
protocol: 2026-07-28
tool: search_knowledge | input: ['query', 'top_k']
{'result': [{'source': '就業規則.pdf p.31', 'text': '経費精算は利用月の翌月5営業日以内に申請する。', 'score': 0.27}]}
戻り値の型にlist[dict]を書いたので、結果はstructured_contentにresultキーで入ります。出典(source)を必ず返すようにしておくと、回答に根拠を添えるRAGの利点をMCP経由でも失いません。ツールの権限設計や認可まで含めた接続実装の工程はAIエージェントにMCPで外部ツールを接続する実装手順で扱っています。
ツールとリソースの選択──LLM主導とアプリ主導の使い分け
RAGをMCPに載せる方法は、ツールとして出すか、リソースとして出すかの2通りです。ツールにすると検索するかどうかと検索語をLLMが決めます。リソースは仕様上アプリケーション主導の機能で、どの文書をいつ文脈に添えるかはホスト側が決めます。質問の種類が多く、検索の要否や検索語の組み立てをLLMに任せたいならツール、開いているファイルや選択中の案件の資料を常に添えたいならリソースが合います。迷う場合はツールで始めてください。リソースで大量の文書を渡すと、前章の「検索なしの全文注入」と同じ失敗になります。
エージェント設計と受託開発での要件整理──RAGとMCPの役割分担
併用構成が特に効くのはAIエージェントの構築です。最後に、エージェントの中での役割分担と、案件で構成を決める手順をまとめます。
エージェントループでの分担──観測にRAG・行動にMCP
エージェントは観測・推論・行動のサイクルを繰り返して目標に近づきます。判断材料となる知識の取り込み(観測)を支えるのがRAG、外部への働きかけ(行動)を支えるのがMCPです。「問い合わせ内容を調べて対応チケットを起票する」エージェントなら、過去の類似対応をRAGの検索ツールで引き、その結果を根拠にチケット管理システムをMCPのツールで操作する、という1周に両者が並びます。検索をいつ・何回呼ぶかをエージェント自身に決めさせる設計はエージェンティックRAGの仕組みと採用判断、サイクルの終了条件まで含めた制御はエージェントループの制御設計の解説で扱っています。
受託開発での設計手順──参照・操作要件の仕分けと構成選定
案件で構成を決めるときは、次の順で要件を棚卸しします。
- AIにさせたいことを「読む」「書く・操作する」「両方」に仕分ける。読むだけならRAG単独、書くだけなら既製MCPサーバーの接続から、両方なら検索のMCPツール化を含む併用構成を起点にする
- 読む対象の量と鮮度を確認する。大量の静的文書ならベクトル検索、少量ならコンテキストへの直接投入、稼働システムの現在値ならMCP経由のAPI参照に割り当てる
- 統制要件を固める。誰が何を操作でき、履歴をどう残すかを決め、書き込み系ツールの実行前に挟む承認まで設計して本番仕様とする
規程の検索応答と予約登録の操作を1つの窓口にまとめるような案件は、AIチャットボット開発の支援で要件の仕分けから構成設計・実装まで通して組み立てられます。RAGかMCPかを決めてから相談するより、この仕分けの段階から入るほうが手戻りが少なく済みます。
MCPとRAGの違い・使い分けでよくある質問
MCPとRAGの違いを一言で説明すると何ですか?
RAGは「外部の文書を検索して回答に注入する実装手法」、MCPは「AIと外部ツールの接続方法を標準化した通信規格」です。RAGはLLMに何を読ませるかを、MCPはLLMと道具をどうつなぐかを扱います。層が違うため優劣の比較は成り立たず、要件がどちらの層の問題かで選びます。
MCPが普及するとRAGは不要になりますか?
なりません。MCPは接続を標準化するだけで、大量の文書から関連箇所を絞り込む検索の問題は解いていません。文書量がコンテキストウィンドウに収まらない場合は、検索などで入力を絞り込みます。検索方式にはBM25などのキーワード検索、ベクトル検索、両者を組み合わせるハイブリッド検索があります。併用する場合は、この記事の実装例のように、RAGの検索をMCPサーバーのツールとして公開し、プロトコル経由で呼び出せます。
社内文書をAIに読ませたいだけの場合はどちらを選ぶべきですか?
RAGです。探させる・根拠付きで答えさせるという要件は、文書の分割・検索・プロンプトへの注入というRAGの守備範囲に収まります。操作や書き込みの要件がなく、使うAIアプリも1つなら、MCPサーバーを自作する必要はありません。工数はチャンク設計と検索精度の評価に集中させてください。
RAGをMCPサーバーにするとき、ツールとリソースのどちらで公開すべきですか?
多くの場合はツールです。MCPの仕様ではツールはモデルが呼び出しを決める機能、リソースはアプリケーションが文脈への添付を決める機能と区別されています。検索するかどうかと検索語をLLMに任せたいならツール、特定のファイルや資料を常に添えたいならリソースが合います。リソースで大量の文書を渡すと検索なしの全文注入になり、トークン費用が膨らみます。
FastMCPのサンプルコードが動かないのはなぜですか?
公式Python SDKの2.x系で、FastMCPがMCPServerへ改称されたためです。mcp 2.3.0ではfrom mcp.server.fastmcp import FastMCPがModuleNotFoundErrorになります。from mcp.server.mcpserver import MCPServerに書き換えるか、1.x系のコードを動かし続けるならmcp<2を指定してインストールしてください。