必要なものは3つです。2026年10月4日時点のLangGraphとMCP連携は、①MCPサーバー、②ツール呼び出し対応モデル、③MCPツールをLangChainツールへ変換するアダプターを用意し、list_tools()で読み込んだツールをエージェントへ渡せば実装できます。
新規実装はlangchain.mcp.MCPAdapterを選びます。独立パッケージlangchain-mcp-adaptersは2026年9月17日にアーカイブされました。既存コードは環境を固定し、新規コードはlangchain[mcp]>=1.4.0へ移行します。
- ローカル接続:Pythonスクリプトを
Pathで渡し、stdioで起動する - リモート接続:MCPエンドポイントのURLを渡し、Streamable HTTPで接続する
- LangGraph側:標準的な会話ループは
create_agent、独自の分岐が必要ならStateGraphとToolNodeを使う
手順1:現行パッケージを入れ、接続方式を決める

2026年10月4日時点のLangChain公式MCPドキュメントは、MCP機能をlangchain.mcpへ移し、MCPAdapterを案内しています。現時点ではベータ版なので、検証したバージョンを固定して使います。
LangGraphからMCPツールを呼ぶ流れ
- 利用者の依頼
- LangGraphのエージェント
- MCPAdapter
- MCPサーバーのツール
- ToolMessage

当日確認できる版はLangChain 1.4.3、LangGraph 1.2.12です。分離した仮想環境で次を実行します。
動作環境:Python 3.11、LangChain 1.4.3、LangGraph 1.2.12を想定した構成例
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install "langchain[mcp]==1.4.3" "langgraph==1.2.12" langchain-openai
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
| 選ぶ対象 | 現行の書き方 | 向いている接続 | 注意点 |
|---|---|---|---|
| 単一のリモートサーバー | MCPAdapter("https://.../mcp") |
Streamable HTTP | 認証情報をソースへ直書きしない |
| 単一のローカルサーバー | MCPAdapter(Path("server.py")) |
stdio | 文字列ではなくPathを渡す |
| 複数サーバー | MCPAdapter({"mcpServers": {...}}) |
stdioとHTTPの混在 | サーバー名がツール名の接頭辞になる |
| 旧システムの保守 | MultiServerMCPClient |
旧adapter対応範囲 | 保守終了済み。新規採用しない |
stdioとStreamable HTTPは用途で分ける
同じマシンのスクリプトにはstdio、リモートのMCPサーバーにはStreamable HTTPを使います。現行MCPAdapterはURLならHTTP、Pathならstdioと推定するため、旧設定のtransport指定は基本形では不要です。
SSEは後方互換のため残っていますが、公式移行ガイドでは非推奨の接続方式として整理されています。新しいリモート実装をSSEから始める理由はありません。MCP自体の接続方式やサーバー側の構造から確認したい場合は、MCPサーバーとは|仕組み・接続手順・作り方・一覧も先に読むと迷いにくくなります。
LangGraph MCP連携の3手順
- 1 接続先を決める:URL・Path・mcpServers
- 2 ツールを発見する:list_tools
- 3 グラフへ渡す:create_agent・ToolNode

手順2:MCPツールを読み込み、エージェントから呼ぶ

最短経路は、公開されているLangChainドキュメントMCPサーバーへ接続する例です。MCPAdapterがサーバーのツール一覧を取得し、create_agentへ渡します。モデルは利用者の依頼と各ツールの説明を見て、必要なツールを選びます。
動作環境:Python 3.11、langchain[mcp]==1.4.3、langchain-openai、環境変数OPENAI_API_KEYとLANGCHAIN_MODEL_ID。後者には利用中のプロバイダーで有効なツール呼び出し対応モデルIDを設定してください。
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import asyncio
import os
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter
async def main() -> None:
if not os.getenv("OPENAI_API_KEY"):
raise RuntimeError("OPENAI_API_KEYを環境変数に設定してください")
model_id = os.environ["LANGCHAIN_MODEL_ID"]
async with MCPAdapter("https://docs.langchain.com/mcp") as adapter:
tools = await adapter.list_tools()
agent = create_agent(model_id, tools=tools)
result = await agent.ainvoke(
{
"messages": [
{
"role": "user",
"content": "LangGraphで短期メモリを追加する公式手順を探して",
}
]
}
)
print(result["messages"][-1].content)
if __name__ == "__main__":
asyncio.run(main())
ポイントは次の3点です。
list_tools()は、MCPサーバーが公開しているツールをLangChainのツールへ変換して返します。ainvoke()へ渡すのは通常のメッセージです。MCP固有のJSON-RPCをアプリ側で組み立てる必要はありません。- ツール呼び出し対応モデルが必要です。モデルIDは利用中のプロバイダーで有効なものへ置き換えてください。
接続をいつ閉じるか
公式ガイドでは、async withを抜けた後も取得済みツールを呼べます。既定では呼び出しごとに接続します。同じ接続を再利用するなら、上の例のようにainvoke()もコンテキスト内で行います。
ツール発見から回答まで
- list_tools
- tool call
- MCPサーバーが実行
- ToolMessage
- 最終回答

手順3:StateGraphへToolNodeを組み込む

独自の承認分岐、業務状態、専用ノード、終了条件が必要ならStateGraphを直接組みます。MCPツールはToolNodeへそのまま渡せます。
動作環境:手順1と同じ。MCPエンドポイントは環境変数MCP_SERVER_URL、モデルIDはLANGCHAIN_MODEL_IDから取得
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import asyncio
import os
from langchain.chat_models import init_chat_model
from langchain.mcp import MCPAdapter
from langgraph.graph import MessagesState, START, StateGraph
from langgraph.prebuilt import ToolNode, tools_condition
async def build_graph():
endpoint = os.environ["MCP_SERVER_URL"]
model_id = os.environ["LANGCHAIN_MODEL_ID"]
async with MCPAdapter(endpoint) as adapter:
tools = await adapter.list_tools()
model = init_chat_model(model_id).bind_tools(tools)
async def call_model(state: MessagesState):
response = await model.ainvoke(state["messages"])
return {"messages": [response]}
builder = StateGraph(MessagesState)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", tools_condition)
builder.add_edge("tools", "agent")
return builder.compile()
async def main() -> None:
graph = await build_graph()
result = await graph.ainvoke(
{"messages": [{"role": "user", "content": "利用可能なツールを使って依頼を処理して"}]}
)
print(result["messages"][-1].content)
if __name__ == "__main__":
asyncio.run(main())
tools_conditionは、モデルの最後のメッセージにツール呼び出しがあればtoolsノードへ、なければ終了へ進めます。ToolNodeがMCPツールを実行し、その結果がmessagesへ追加され、再びagentへ戻ります。StateGraphの状態、ノード、エッジを先に整理したい場合は、LangGraph完全ガイド|StateGraph実装とv1.2新機能を参照してください。
旧langchain-mcp-adaptersコードはこう読み替える

2026年9月以前の解説で多いのが、MultiServerMCPClientを使う実装です。既存プロジェクトの調査用に旧コードを示しますが、新しいプロジェクトへコピーする例ではありません。
対象環境:読解用の別仮想環境にPython 3.11、langchain-mcp-adapters==0.3.2、langchain==1.4.3、langgraph==1.2.12、langchain-openaiを固定します。必要な環境変数はOPENAI_API_KEY、LANGCHAIN_MODEL_ID、MCP_BEARER_TOKENです。MCP Python SDK 2系とは混在させません。
# 既存コードの読解用です。新規実装ではMCPAdapterを使用してください。
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import asyncio
import os
from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
async def main() -> None:
token = os.environ["MCP_BEARER_TOKEN"]
model_id = os.environ["LANGCHAIN_MODEL_ID"]
client = MultiServerMCPClient(
{
"internal": {
"transport": "http",
"url": "https://example.com/mcp",
"headers": {"Authorization": f"Bearer {token}"},
}
},
tool_name_prefix=True,
handle_tool_errors=True,
)
tools = await client.get_tools()
agent = create_agent(model_id, tools=tools)
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "利用可能なツールで状態を確認して"}]}
)
print(result["messages"][-1].content)
if __name__ == "__main__":
asyncio.run(main())
| 旧langchain-mcp-adapters | 現行langchain.mcp | 移行時の確認点 |
|---|---|---|
pip install langchain-mcp-adapters |
pip install "langchain[mcp]" |
同じ環境へ両方を残さない |
MultiServerMCPClient |
MCPAdapter |
非同期コンテキスト管理へ変更 |
get_tools() |
list_tools() |
メソッド名を置換 |
| サーバー辞書を直接渡す | {"mcpServers": {...}} |
標準MCPConfig形状に変更 |
transportを明示 |
URL/Path/設定から推定 | ローカルスクリプトはPath |
tool_name_prefix=True |
複数サーバーでは自動接頭辞 | プロンプトや監視のツール名も更新 |
Callbacks |
FastMCP Clientのhandler | ログ・進捗処理を書き替える |
tool_interceptors |
LangChain middleware | 認可・監査処理を移す |
複数サーバーはmcpServersの下に名前付きで並べます。ツール名はサーバー名で区別されます。ローカル側の作り方は、FastMCPでMCPサーバーを自作するPythonガイドで確認できます。
旧APIから現行APIへの移行
- langchain-mcp-adapters → langchain[mcp]
- MultiServerMCPClient → MCPAdapter
- get_tools → list_tools
- transportを指定 → URL・Pathから推定

本番へ進む前に認証・権限・エラー境界を固める

トークンはFastMCP Clientへ渡す
現行APIの認証は、接続設定へトークン文字列を埋め込むのではなく、FastMCPのClientへ渡します。環境変数やシークレットマネージャーから読み込み、ログへ値を出さないでください。
動作環境:langchain[mcp]>=1.4.0、FastMCPクライアント、Bearer認証対応MCPサーバー
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
import os
from fastmcp.client import Client
from langchain.mcp import MCPAdapter
async def load_authenticated_tools():
endpoint = os.environ["MCP_SERVER_URL"]
token = os.environ["MCP_BEARER_TOKEN"]
client = Client(endpoint, auth=token)
async with MCPAdapter(client) as adapter:
return await adapter.list_tools()
auth="oauth"も利用できますが、資格情報の保存、利用者とのひも付け、コールバック処理はアプリケーション側の責任です。
ツール実行エラーと接続障害を分ける
isError=TrueはToolMessage(status="error")としてモデルへ戻るため、引数を直して再試行できます。接続、セッション、変換の障害は例外です。監視でも両者を分けます。
destructiveHintだけで自動許可しない
readOnlyHintやdestructiveHintは承認分岐に使えます。ただし、MCP公式のツール注釈解説が示すとおり、注釈は強制制御ではなく、信頼できないサーバーの値を鵜呑みにはできません。
- 接続可能なMCPサーバーを許可リストで制限する
- 削除、送信、決済、公開などの操作は実行前に人の承認を挟む
- ツールへ渡す引数をスキーマだけでなく業務ルールでも検証する
- 秘密情報へアクセスするツールと外部送信ツールを同じ無制限エージェントへ集めない
- ツール名、サーバー名、実行結果、エラー種別を監査ログへ残す
失敗と承認を切り分ける
- isError → ToolMessage → 引数を見直す
- 接続・セッション → 例外 → 再接続を判断
- 破壊的・外部副作用 → 人の承認 → 許可後に実行

実装で詰まりやすい5つの原因
旧パッケージを新規環境へ入れてしまう
❌ 検索上位の古い例を見て、langchain-mcp-adaptersから新規開発を始める。
⭕ langchain[mcp]を入れ、MCPAdapterとlist_tools()を使う。旧パッケージは既存環境の調査時だけ参照する。
ローカルスクリプトを文字列で渡す
❌ MCPAdapter("weather_server.py")のように、ローカルパスを単なる文字列で渡す。
⭕ MCPAdapter(Path("weather_server.py"))とする。現行APIでは文字列ターゲットはHTTPまたはHTTPSのURLである必要があります。
新APIでget_toolsを呼ぶ
❌ await adapter.get_tools()と書き、属性エラーになる。
⭕ 現行MCPAdapterではawait adapter.list_tools()を使う。旧コードの機械置換ではimportと設定形状も同時に直します。
asyncの境界を曖昧にする
❌ 通常関数からawaitを呼ぶ、またはNotebook上の既存イベントループ内でasyncio.run()を重ねる。
⭕ スクリプトはasync def main()とasyncio.run(main())を使い、Notebookではセルからawait main()を呼びます。
ツール注釈を権限制御だと思い込む
❌ readOnlyHint=Trueなら無条件で安全だと判断する。
⭕ 信頼できるサーバーかを別途検証し、許可リスト、引数検証、ネットワーク制御、人の承認で強制します。注釈はUIや承認判断の補助情報に限定します。
疎通確認はモデルを呼ぶ前に行う
問題が起きたら、まずツール一覧の名前と説明を確認し、読み取り専用ツールを一つだけ呼び、最後にLangGraphへ組み込みます。
確認順序:
- MCPサーバーのエンドポイントへ到達できる
list_tools()が空でなく、想定したツール名を返す- ツールの入力スキーマが意図どおりである
- 読み取り専用の呼び出しが成功する
- LangGraphがtool callからToolMessageへ戻る
- 接続障害とサーバー実行エラーを別々に記録できる
複数サーバーを同時に使う場合は、各サーバーを単独で確認した後に統合します。リモート接続のサーバー側実装まで追うなら、MCP Streamable HTTP完全実装ガイドも参照してください。
よくある質問
Q1. LangGraphとMCPは何が違いますか?
LangGraphは状態、ノード、分岐、永続化を管理するエージェント実行基盤です。MCPはツールやコンテキストをクライアントへ提供するためのプロトコルです。LangGraphが処理の流れを決め、MCPが外部ツールとの共通接続面を提供します。
Q2. langchain-mcp-adaptersはもう使えませんか?
既存の固定環境で直ちに動かなくなるという意味ではありません。ただし公式リポジトリは2026年9月17日にアーカイブされ、継続的な修正とサポートはlangchain.mcpへ移りました。新規実装では選ばず、既存コードも移行計画を作ってください。
Q3. MultiServerMCPClientは何に置き換わりましたか?
MCPAdapterに置き換わりました。複数サーバーは{"mcpServers": {...}}形式の設定を渡し、list_tools()でツールを取得します。
Q4. stdioとStreamable HTTPはどちらを選びますか?
同一マシンのローカルスクリプトならstdio、ネットワーク越しのサーバーならStreamable HTTPが基本です。旧HTTP/SSEは後方互換用で、新規リモート実装の第一候補ではありません。
Q5. MCPサーバーが複数あるとツール名は衝突しませんか?
現行の複数サーバー設定では、ツール名がサーバー名で名前空間化されます。移行時は、旧ツール名を前提にしたシステムプロンプト、テスト、監視ルールも更新してください。
Q6. MCPツールのセッションは維持されますか?
現行の既定パターンでは、ツール呼び出しごとに接続して処理後に解放します。一つの実行中に接続を再利用したい場合は、エージェント実行をMCPAdapterのコンテキスト内に置きます。サーバー側の状態を暗黙のセッションだけに依存させない設計も重要です。
Q7. ツールがisErrorを返すとグラフ全体が停止しますか?
現行APIでは、サーバーが返す実行エラーは通常ToolMessage(status="error")としてモデルへ届きます。モデルが入力を修正できる余地があります。一方、接続や変換の障害は例外になるため、アプリケーション側で捕捉し、再試行条件と上限を決めます。
Q8. 認証ヘッダーをMCPAdapterへ直接書けばよいですか?
現行の推奨はFastMCP Clientへ認証を設定し、そのクライアントをMCPAdapterへ渡す方法です。秘密値は環境変数やシークレットマネージャーから取得し、コード、設定ファイル、ログへ残さないでください。
Q9. create_agentとStateGraphのどちらを使うべきですか?
標準的な「モデルがツールを選び、結果を受けて回答する」ループならcreate_agentが簡潔です。承認、独自状態、複数の業務ノード、特殊な終了条件を組み込みたいならStateGraphとToolNodeを選びます。
運営元 Uravation よりAIエージェントを構想から本番運用まで進める順番と、体制・KPIの決め方をまとめた資料を無料で公開しています。 AIエージェント導入ロードマップを受け取る(無料)
参考・出典
- Model Context Protocol (MCP) — LangChain公式。現行MCPAdapter、インストール、接続方式(参照日: 2026年10月4日)
- Migrate from langchain-mcp-adapters — LangChain公式。旧APIから現行APIへの対応表(参照日: 2026年10月4日)
- Connections — LangChain公式。接続ライフサイクル、複数サーバー、キャッシュ(参照日: 2026年10月4日)
- MCP in LangChain: Stateless Protocol, Elicitation, and More! — LangChain公式、2026年9月3日公開(参照日: 2026年10月4日)
- LangChain MCP Adapters — 旧公式リポジトリ。2026年9月17日アーカイブ(参照日: 2026年10月4日)
- The 2026-07-28 Specification — Model Context Protocol公式、2026年7月28日公開(参照日: 2026年10月4日)
- Tool Annotations as Risk Vocabulary — Model Context Protocol公式、2026年3月16日公開(参照日: 2026年10月4日)
- langchain 1.4.3 release — LangChain公式、2026年9月28日公開(参照日: 2026年10月4日)
- langgraph 1.2.12 release — LangGraph公式、2026年9月21日公開(参照日: 2026年10月4日)
- MCP Python SDK 2.3.0 release — Model Context Protocol公式、2026年10月2日公開(参照日: 2026年10月4日)
結論と次の一歩
LangGraphからMCPツールを呼ぶ実装は、MCPAdapterで接続し、list_tools()でツールを読み込み、create_agentまたはToolNodeへ渡す3手順です。2026年10月4日時点では、langchain-mcp-adaptersを新規採用するのではなく、LangChain本体のlangchain.mcpを使うのが公式の移行先です。
- 公開ドキュメントMCPサーバーで、現行
MCPAdapterのツール一覧取得を確認する - 対象のMCPサーバーを一つだけ接続し、読み取り専用ツールで疎通を確認する
- 削除・送信・公開などの副作用があるツールへ承認ゲートを追加してから業務フローへ組み込む
この記事を読んで導入イメージが固まってきた方へ
UravationではAIエージェント導入の研修・コンサルを行っています。
