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

最小 MCP サーバー

約 14 分

この回のゴール

1. 使うライブラリ

pip install mcp   # 公式 Python SDK

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

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

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

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("demo-server")

@mcp.tool()
def calculator(expression: str) -> str:
    """数式を評価して結果を返す電卓ツール。

    Args:
        expression: Python で評価可能な数式。例: '2 * (3 + 4)'
    """
    import re
    if not re.match(r"^[\d\s\+\-\*\/\(\)\.\%]+$", expression):
        return f"Error: 不正な式 {expression!r}"
    try:
        return str(eval(expression, {"__builtins__": {}}, {}))
    except Exception as e:
        return f"Error: {e}"


@mcp.tool()
def echo(message: str) -> str:
    """受け取ったメッセージをそのまま返すデバッグ用ツール。"""
    return f"echo: {message}"


if __name__ == "__main__":
    mcp.run()  # stdio transport で起動

ポイント

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

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

@mcp.resource("handbook://chapter/{chapter_num}")
def read_chapter(chapter_num: int) -> str:
    """指定章のハンドブック本文を返す。"""
    return HANDBOOK_CHAPTERS[chapter_num]


@mcp.prompt()
def review_prompt(code: str) -> str:
    """コードレビュー用のプロンプトテンプレート。"""
    return f"以下のコードをレビューしてください:\n\n```\n{code}\n```"

4. サーバーの起動方法

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

python server.py
# → stdio 経由で待機開始

方法 B: mcp CLI

mcp dev server.py  # 開発モード、ブラウザ UI で inspector

方法 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 章の calculator や search_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 が自動検索する」を実現します。

参考文献

A
本家 Claude Academy で手を動かす
この回に対応する Anthropic 公式のレッスンです。ここは「なぜそう動くか」、向こうは「どう書くか」。サインインなしで読めます。
📝 理解度クイズ (3 問) 💡 ログインすると進捗が保存されます

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

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

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