概要
昨今MCPが流行っていますが、仕様理解が中々難しい印象です
当該記事では、MCP Server, Clientを実装したい開発者 (私含め)が
簡単なサンプルをベースにMCP Client, Server, LLMの連携イメージ全体像を掴む事を目指しました
Model Context Protocol (MCP) とは
概要
MCPは、2024年にAntropic社により標準化 されたAI <-> 外部データソース連携の為の標準規格
です
MCP以前は、LLMとのツール統合は全てカスタムメイドであり
共通IFという意味で、AI用の「USBポート」を自称しています
用語はAntropic公式documentが理解しやすいです
トレンド
昨今話題のものですと、以下の様なものかと見受けられます
- Playwright MCP: LLM経由でのブラウザ自動操作
- AWS MCP: LLM経由でのAWSリソース分析
これらはMCP Serverです
Cursor, ClineなどがMCP Clientに該当します
利点 (例)
- Modelが持っていない知識をリアルタイムに反映
- knowledge cutoff対策
- (検索シナリオ等で) コンテキストの節約
- [As-is] promptに検索対象全件含めるとLLMに与えるコンテキストを浪費していた
- [to-Be] MCP Server側が指定するschemaに合わせ検索条件を指定、promptに渡す情報を事前にフィルタしコンテキストを節約
機能
MCP Serverは、本来5種類の機能を包括しますが
一般にMCPとして利用されるものはToolsと考えて差し支えないのが現状かと見受けられます
当該記事では以降MCP Toolsを中心に解説をしています

IF仕様
MCP Clientから参照するMCP ServerのIF仕様は公式にて予め大方決まっています
下記(1)にてセッションを確立した後、(2)-(7)ではJSONRPCにて通信を行います
MCP Clientは当該仕様に合わせルーティングを行います
# | endpoint | プロトコル | 機能 |
---|---|---|---|
1 | /session (/mcp) | HTTP | MCP Client - Server間のセッション確立 |
2 | /resources/list | JSONRPC | resource一覧取得 |
3 | /resources/read | JSONRPC | resource詳細取得 |
4 | /prompts/list | JSONRPC | prompt一覧取得 |
5 | /prompts/get | JSONRPC | prompt詳細取得 |
6 | /tools/list | JSONRPC | tool一覧取得 |
7 | /tools/call | JSONRPC | tool実行 |
*注記 = (1)に関してのみ、パスの命名はAntropic仕様に明記されておらずブレがあります
作成したもの
理解も兼ねて
- SUUMO (賃貸サイト)情報のスクレイピングMCP Server.tool
- 及び簡単なMCP Clientを作成しました
構成

例えば、以下の様な、賃貸検索結果画面のURLを指定するとスクレイピングにより賃貸候補リストを取得します
// prompt例
https://suumo.jp/jj/chintai/ichiran/FR301FC001/
?ar=030&bs=040&ra=013&rn=0220&ek=022007660&cb=0.0&ct=9999999&mb=0
&mt=9999999&et=9999999&cn=9999999&shkr1=03&shkr2=03&shkr3=03
&shkr4=03&sngz=&po1=25&pc=30 から家賃の安い先頭5件を列挙してください
成果物
↓ CLIベースにて動作するMCP Clientから、作成したMCP Server.toolを呼び出します
シーケンス
-
[User -> MCP Client]
「Suumo賃貸検索サイトのURLを含めた指示」をMCP Clientに送信する -
[MCP Client <-> LLM (1)]
(1)の指示をLLMに転送し、LLMから「MCP Server.tool利用指示」が返却される -
[MCP Client <-> MCP Server.tool]
(2)の指示をMCP Serverに転送
MCP Server.tool内にて、実際に対象のWeb Siteに対しスクレイピングを行い、賃貸情報を取得し返却する -
[MCP Client <-> LLM (2)]
(3)を過去のコンテキストとマージし、再度LLMに送信し、ユーザの欲しい回答を得る -
[MCP Client -> User]
(4)をユーザに返却し、回答とする
注記
スクレイピングは常識の範囲内でお願い致します
Prototype (実装)
L mcp-client (mcp公式ライブラリにてopenaiと接続する簡潔なmcp client)
L mcp-server (fastapi-mcpにて、mcp toolをホスティング)

- [start session]
- [init]:
/tools/list
利用可能なMCP toolsを取得 - [interaction]: LLMからの返答に
tool_calls
が含まれる場合、/tools/call
にてMCP Server.toolを利用
MCP Client
modelcontextprotocolライブラリをベースにMCP Clientを作成しています
尚、以下参考とさせていただいております
MCP Server
FastAPI MCPは非常に便利です
FastAPIにおける、app
(server)をFastApiMCP
でwrapするだけで、MCP Server化します
LLM
LLM側は、OpenAI Chat Competitions APIにて、modelはgpt-4o
を利用しています
その他、スクレイピング等の内容は、Github Repositoryをご参照ください
(スクレイピングを検証する際は、個人の責任で、常識の範囲内でお願いいたします)
Prototype (動作)
以下5段階にて、連携を行います
上記Github Repositoryを動作させる際は、README.mdを参照しつつ、以下を実行してください
// server
$ cd mcp-server && rye run python src/main.py
// client
$ cd mcp-client && rye run python src/main.py
1. User -> MCP Client
MCP Clientに対して、ユーザが指示を入力する
# | sequence | interaction |
---|---|---|
1 | ![]() |
![]() |
2. MCP Client <-> LLM (1)
- ユーザ入力と
/tools/list
にて取得したMCP toolsリストをLLM側に渡します - LLM側の回答に
tool_calls
が含まれる場合、MCP Clientは指示内容をMCP toolsにルーティングします- 尚、指示内容は(3)の通り、
/tools/list
レスポンス内schema定義に沿ってLLM側がjson形式にて指定 -
function.name
= tool指定 -
function.arguments
= 指示を記載
- 尚、指示内容は(3)の通り、
# | sequence | interaction |
---|---|---|
2 | ![]() |
available_tools にMCP toolsリストを含める![]() |
3 | ![]() |
response![]() |
3. MCP Client <-> MCP Server.tool
- (3)の指示を用いてMCP toolに対し
/tools/call
します - MCP tool側の回答内、
content
に結果が含まれます
# | sequence | interaction |
---|---|---|
4 | ![]() |
![]() |
5 | ![]() |
response![]() |
4. MCP Client <-> LLM (2)
- (5)の
content
内容を整形し、元のcontextと合わせて再度LLM側に渡します - MCP tool結果を踏まえたLLM最終結果が返されます
- 今回は
finish_reason='stop'
。content
に回答があり、tool_calls=None
です
- 今回は
# | sequence | interaction |
---|---|---|
6 | ![]() |
request context![]() 元のcontext +tool回答結果 = messages ![]() |
7 | ![]() |
response。content に回答あり![]() |
5. MCP Client -> User
(7)から最終結果を取り出し、ユーザに返却します
# | sequence | interaction |
---|---|---|
8 | ![]() |
![]() |
総括
非常に進化が早い分野ですので、現時点のご参考までに。といった形です
今回は簡易的な解説でしたが、今後は、JSONRPC周りなど、より詳細な記事を書けたらと思います
以上