A
AIエージェントの仕組み
ch7-s3 · Minimal MCP Server

最小 MCP サーバー

約 14 分

この回のゴール

1. 使うライブラリ

npx @modelcontextprotocol/inspector python server.py

公式 SDK のクラス: - FastMCP — サーバーの簡易定義(推奨) - mcp.client.stdio.stdio_client — stdio 経由でサーバーに繋ぐクライアント - mcp.ClientSession — クライアントの会話管理

2. 最小 MCP サーバーの全コード

server.py にこれだけ書けばサーバー 1 つが完成します:

from collections import deque
def bfs(start, goal, neighbors):
    q = deque([(start, [start])])
    visited = {start}
    while q:
        s, path = q.popleft()
        if s == goal:
            return path
        for ns in neighbors(s):
            if ns not in visited:
                visited.add(ns)
                q.append((ns, path + [ns]))

ポイント

これで Claude API で書いていた TOOL_DEFINITION = {...}不要 になります。

3. リソースとプロンプトも登録できる

from mcp.client.stdio import stdio_client, StdioServerParameters
from mcp import ClientSession

async def main():
    params = StdioServerParameters(command="python", args=["server.py"])
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            result = await session.call_tool("calculator", {"expression": "2+3"})
            print(result.content[0].text)  # "5"

4. サーバーの起動方法

方法 A: 直接コマンドライン

import logging
logging.basicConfig(level=logging.DEBUG)

方法 B: mcp CLI

# stdio で手動操作(テスト用)
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}' | python server.py

方法 C: Claude Desktop から自動起動

次回 (s4) で扱う。claude_desktop_config.json にパスを書くと Claude が subprocess として自動起動する。

5. 動作確認の 2 通り

(a) mcp-inspector (CLI/GUI)

npx @modelcontextprotocol/inspector python server.py

ブラウザで ツール一覧を確認・実行 できる公式 GUI。開発時の定番。

(b) 自作クライアント

Python のクライアント SDK でサーバーに繋ぎ、JSON-RPC 往復を可視化 できます:

from mcp.client.stdio import stdio_client, StdioServerParameters
from mcp import ClientSession

async def main():
    params = StdioServerParameters(command="python", args=["server.py"])
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            result = await session.call_tool("calculator", {"expression": "2+3"})
            print(result.content[0].text)  # "5"

6. 第 6 章のツールを MCP 化する

第 6 章の calculatorsearch_handbook を MCP サーバーに移植すれば、同じロジック が:

一度書けば、あらゆる所で使える。これが MCP の威力。

7. デバッグのコツ

ログ確認

import logging
logging.basicConfig(level=logging.DEBUG)

手動テスト

# stdio で手動操作(テスト用)
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}' | python server.py

よくあるハマリポイント

症状 原因 対策
サーバー起動しない 依存関係不足 pip install mcp
ツールが見えない @mcp.tool() 忘れ デコレータ必須
引数エラー 型ヒント不足 明示的な型を付ける
Claude Desktop で読まれない 設定ミス config.json のパス確認

まとめ

この回の限界(次への動機)

サーバーは動いた。次は Claude Desktop に登録して、Claude の純正 UI からこのツールを呼ばせる。 👉 次回「Claude Desktop と繋ぐ」で、本シリーズの集大成として「第 5 章 RAG を MCP 化して Claude が自動検索する」を実現します。

参考文献

📝 理解度クイズ (3 問) 💡 ログインすると進捗が保存されます

💬 このサブステップの Q&A

まだ質問はありません。最初の質問を投稿してみましょう。

質問の投稿にはログインが必要です。