LangChain(LLMアプリ構築用のPythonフレームワーク)を使ってエージェント機能を実装しているQAエンジニアや、CI/CDパイプラインにエージェントのテストを組み込みたい方に向けた内容です。
2025年8月にプレリリースされたlangchain==1.4.0a2には、langchain.mcpという新モジュールが追加されました。MCP(Model Context Protocol、AIモデルが外部ツールやデータソースに接続するための共通規格)サーバーを、そのままLangChainのツールとしてcreate_agentに渡せるアダプタです。
このアダプタ自体はまだアルファ版ですが、外部ツール接続を含むエージェントをどうテストするかは、導入前に整理しておく価値があります。この記事では実際にインストールして動かす手順と、CI上での検証方針を整理します。
前提条件
手を動かす前に、以下を確認してください。
- Python 3.10以上の環境(LangChain 1.x系の動作要件に準拠)
- pipもしくはpoetry・uvなどのパッケージ管理ツール
- 接続先のMCPサーバー(テスト用にローカルのstdio起動スクリプトでも可)
- Anthropic APIキーなど、create_agentに渡すモデルのクレデンシャル
アルファ版のため、本番のCIパイプラインにそのまま組み込む前に、専用のテスト用ジョブやブランチで先に検証することをおすすめします。バージョン番号にa2(alpha 2の意味)が付いている通り、APIが今後変わる可能性があるためです。
インストール
pip install "langchain[mcp]==1.4.0a2"この1行でlangchain.mcpが使えるようになります。内部的にはFastMCP(MCPクライアント実装を提供するライブラリ)のfastmcp.Clientをそのまま利用しており、LangChain側で機能を薄いラッパーに再実装していない点が特徴です。つまりFastMCPのドキュメントに書かれているオプションが、ほぼそのまま使えます。
最小構成で接続する
まずは動作確認として、最小のコードでMCPサーバーに接続します。
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter
async with MCPAdapter("https://example.com/mcp") as adapter:
agent = create_agent("anthropic:claude-sonnet-5", await adapter.get_tools())
result = await agent.ainvoke({"messages": [{"role": "user", "content": "..."}]})MCPAdapterにはURL・ローカルスクリプトパス(stdio経由で起動)・インプロセスのFastMCPサーバー・複数サーバーを列挙する設定・自分で構築したfastmcp.Clientのいずれも渡せます。トランスポート(通信方式)は自動判別されるため、プロトコルごとに接続コードを書き分ける必要がありません。
ここで押さえておきたいのは、get_tools()が返すツールはasync withのブロックを抜けたあとも呼び出し可能という点です。async withはツール探索(discovery)のスコープであり、ツール自体の生存期間を制御しているわけではありません。テストコードを書く際にこの違いを誤解すると、接続クローズ後にツールが使えなくなると思い込んでリトライ処理を過剰に書いてしまうことがあります。
認証・キャッシュ・タイムアウトを設定してテスト用クライアントを作る
CIで安定してテストを回すには、タイムアウトや認証を明示的に設定したクライアントを使うのが安全です。
from fastmcp.client import Client
from langchain.mcp import MCPAdapter
client = Client(
"https://example.com/mcp",
auth="oauth", # またはbearerトークン文字列、任意のhttpx auth
cache=True, # レスポンスキャッシュをオプトインで有効化
timeout=30,
)
async with MCPAdapter(client) as adapter:
tools = await adapter.get_tools()authにはOAuthフローを回す"oauth"、bearer認証用のトークン文字列、または任意のhttpx.Authインスタンスが渡せます。CI環境ではOAuthのブラウザ認証は使えないため、テスト用にはbearerトークンをシークレット変数として注入する構成が現実的です。
cacheはデフォルトで無効です。cache=Trueにすると、サーバー側が返すttlMs(キャッシュ有効期限)やcacheScopeのヒントを尊重したインメモリキャッシュが有効になります。CIでテストのたびに同じツール一覧を取得するなら、キャッシュを有効にして通信回数を減らすと実行時間の短縮につながります。ただしキャッシュはクライアントごと・インメモリなので、テスト間でクライアントを使い回す設計にしないと効果は出ません。
動作確認の方法
最小構成が動いたら、以下の観点でCIパイプラインに落とし込むテストを組み立てます。
- 接続の疎通確認: MCPサーバーへの接続が確立し、get_tools()が空でないツールリストを返すかを確認するスモークテスト
- ツールのスキーマ検証: 返されたツールの入力パラメータ・型が、期待するスキーマと一致しているかの検証(サーバー側の仕様変更を早期検知する目的)
- タイムアウト境界のテスト: timeoutを意図的に短く設定し、遅延時に例外がハンドリングされるかの確認
- モックサーバーでの再現テスト: 本番のMCPサーバーに依存せず、インプロセスのFastMCPサーバーをテスト用に立てて、CIをネットワーク非依存にする構成
特に最後の「インプロセスのFastMCPサーバーを使う」構成は、CIの安定性という観点で重要です。外部のMCPサーバーに毎回接続するテストは、ネットワークの不安定さやレート制限によってフレーキーテスト(不安定で結果が揺れるテスト)になりがちです。テスト用のFastMCPサーバーをコード内で立てて MCPAdapter に渡せば、外部要因を排除した決定的なテストが組めます。
品質メトリクスの観点では、エージェントのツール呼び出しが「正しいツールを選んだか」「引数が正しいか」を計測する仕組みも合わせて検討する価値があります。LangChainのエコシステムには評価用のLangSmithという別サービスもありますが、まずはユニットテストレベルでget_tools()の戻り値をアサーションで検証するところから始めるのが手堅い進め方です。
ハマりやすいポイント
async withブロックのスコープを誤解する点は特に注意が必要です。ブロックを抜けた後もツールオブジェクト自体は呼び出せますが、内部でクライアントの接続が既に閉じられている場合、実際にツールを実行しようとした瞬間に接続エラーが出ることがあります。
テストコードでは「ツール取得」と「ツール実行」を同じasync withスコープ内で完結させるか、接続の生存期間を明示的に管理する設計にするか、どちらかの方針を早めに決めておくとデバッグが楽になります。CIログにエラーが出た際、これがネットワーク起因なのかスコープ管理起因なのかを切り分けられるよう、接続確立と実行の間に十分なログを仕込んでおくとよいでしょう。
まとめ
langchain.mcpはまだアルファ版ですが、MCPサーバーをLangChainのツールとして扱う入り口が一本化された点は、テスト設計をシンプルにする材料になります。
- インストールはpip install "langchain[mcp]==1.4.0a2"の1行で完結する
- CIでの安定運用にはfastmcp.Clientでタイムアウト・認証・キャッシュを明示設定する
- 外部依存を減らすには、インプロセスのFastMCPサーバーをテスト用に立てる構成を検討する
- async withのスコープはツール探索用であり、ツールの生存期間とは別という点を押さえる
まずは最小構成のコードをローカルで動かし、get_tools()の戻り値をアサーションで検証するテストを1本書いてみるところから始めてみてください。アルファ版のAPIは今後変わる可能性があるため、CIに組み込む際はバージョン固定と、リリースノートの定期確認もあわせて行うと安心です。