第5週前半では、MCP(Model Context Protocol)が「AIと外部をつなぐ仕組み」であることを学びました。
本記事では、ローカルLLM(Ollama)を使い、MCPの仕組みを理解するための簡易構成を実装します。
これは、AIが判断し、仲介層を通じて外部ツールを呼び出し、その結果を受け取る流れをコードで再現しています。
まずは疑似的なMCPで構造を理解し、その後に本物のMCPへ発展させることを目的とします。
AIエージェントとは
AIエージェントは、判断して動くだけでなく、外部ツールやデータと接続して初めて実用性が高まります。
第5週・実践編では、MCPクライアントの役割を簡易的に再現した仲介層(call_mcp)を用意し、外部ツールを直接呼び出すことで疑似的なMCP接続を実装します。
具体的には、次のような流れをコードで再現します。
AI(判断)
↓
MCPの役割を持つ仲介層(call_mcp)
↓
外部ツール(関数)
↓
結果をAIに戻すこの構造は、実際のMCPである以下の構成の簡易版になっています。
AI → MCPクライアント → MCPサーバー → 外部ツール
学習ロードマップ(拡張版)
| 週 | 内容 |
|---|---|
| 第1週 | チャット + JSON出力 |
| 第2週 | ツール呼び出し |
| 第3週 | ループ型エージェント |
| 第4週 | マルチエージェント |
| 第5週 | MCPで外部とつなぐ |
| 第5週・実装編 | 疑似MCPで外部とつなぐ・実装編 |
| 第5週・上級編 | MCPサーバーの利用・上級編 |
作業環境について
本記事は、第1週の内容を前提として進めています。
そのため、以下の環境がすでに整っている状態を想定しています。
- ローカルLLM実行環境:Ollama
- 使用モデル:qwen3
- Python仮想環境(venv)
- ollama Pythonライブラリのインストール済み
作業環境の準備ができていない場合
第1週の記事で、環境構築からJSON出力までを解説しています。
未実施の場合は、先に第1週から進めることをおすすめします。
AIエージェント入門|ローカルLLMで学ぶチャットとJSON出力【第1週】
第5週・実装編のゴール
- 外部ツール呼び出しの流れを理解する
- MCPの役割をコードで体験する
- 第2週の「tools」との違いを理解する
疑似的MCPの実装
外部ツールを作る
ここでは「外部ツール」を別関数として定義します。
# mcp_tools.py
def get_weather(city: str) -> str:
return f"{city}の天気は晴れです"MCPの役割を持つ仲介層を作る
# mcp_client.py
from mcp_tools import get_weather
def call_mcp(tool_name, args):
if tool_name == "get_weather":
return get_weather(args["city"])
return "unknown tool"完成コード(疑似的なMCP接続を使うエージェント本体)
MCP-Implementation.py
from ollama import chat
from mcp_client import call_mcp
TOOLS = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "天気を取得",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
}
]
messages = [
{"role": "system", "content": "あなたはアシスタントです"},
{"role": "user", "content": "東京の天気を教えて"}
]
response = chat(
model="qwen3",
messages=messages,
tools=TOOLS
)
message = response["message"]
tool_calls = message.get("tool_calls", [])
if tool_calls:
for tool in tool_calls:
name = tool["function"]["name"]
args = tool["function"]["arguments"]
result = call_mcp(name, args)
messages.append(message)
messages.append({
"role": "tool",
"content": result
})
final = chat(
model="qwen3",
messages=messages
)
print(final["message"]["content"])
else:
print(message.get("content"))MCP-Implementation.pyの実行
Git Bashで、保存したフォルダに移動してから実行します。
./.venv/Scripts/python.exe MCP-Implementation.py正常に動けば、AIからの返答がターミナルに表示されます。
東京の天気は晴れています。気温も穏やかなので、外に出かけやすい日ですね!MCP-Implementation.pyの処理フロー
AI(LLM)が外部のデータやツールと接続するための「呼び出し口(関数)」をインポートする。
from mcp_client import call_mcpツールの定義(準備)
TOOLS 変数の中で、AIが使える「ツール」を定義しています。
ここでは get_weather という名前で、city(都市名)を引数に取る関数であることをAIに教えています。
1回目のAI呼び出し(判断)
response = chat(
model="qwen3",
messages=messages,
tools=TOOLS
)ここでAIにメッセージを送ります。
AIはユーザーの「東京の天気を教えて」という要望を理解し、「get_weather(city='東京') を呼び出せ」という指示(tool_calls)を返します。
ツールの実行と会話履歴の蓄積
AIが指定した引数(tool_calls)を使って、実際に疑似的MCPを動かします。( call_mcp)
結果を messages という会話履歴に蓄積します。
if tool_calls:
for tool in tool_calls:
# AIが指定した引数を使って、実際に外部サーバー(MCP)を叩く
result = call_mcp(name, args)
# AIの「命令」と、ツールが出した「実行結果」の両方を履歴に追加
messages.append(message) # AIの命令
messages.append({
"role": "tool",
"content": result # 「東京は晴れです」などのデータ
})2回目のAI呼び出し(要約・回答)
final = chat(
model="qwen3",
messages=messages
)蓄積された会話履歴をAIに渡し実行結果を自然言語で生成します。
第5週・実装編のまとめ
この週では、疑似的なMCP接続を使って外部ツールを利用する方法を学びました。
今回のポイントは、AIと外部ツールの役割分担です。
MCPは外部接続の標準
MCPは、AIと外部ツールやデータをつなぐための共通ルールです。
どのツールでも同じ方法で接続できます。
AIは判断だけする
AI(ローカルLLM)は、「何をするか」「どのツールを使うか」を決めるだけで、実際の処理は行いません。
MCPが仲介する
MCPは、AIの指示を受けて、外部ツールへつなぐ役割を担当します。
外部ツールが実行する
実際に処理を行うのは、以下の様な外部ツールです。
- API
- データベース
- Web検索
ここまでで、ローカルLLMとMCPの基本構造を「疑似MCP」を使って理解できました。
しかし実際のAIエージェントでは、今回のような簡易的な仲介層ではなく、
本物のMCPサーバーを通じて外部ツールと接続する構成が使われます。
次の記事では、DuckDuckGo検索に対応したMCPサーバーを実際に利用し、
AIエージェントがリアルなWeb検索を行う仕組みを構築していきます。
- 疑似MCP → 本物MCPへ
- ローカル関数 → 実際の外部ツールへ
とステップアップすることで、より実用的なAIエージェントの姿が見えてきます。
AIエージェント入門|本物のMCPサーバーに接続する【第5週・上級編】
