概要
昨今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周りなど、より詳細な記事を書けたらと思います
以上
















