Model Context Protocol入門：AIをリアルワールドに接続する | 第3章：MCPの実装を始める

## はじめに

これまでの第1章と第2章では、**Model Context Protocol（MCP）**の概要とその動作仕組みを解説しました。MCPがAIを外部データやツールと接続する標準化されたプロトコルであり、クライアント-サーバーアーキテクチャを通じてリソースやツールを提供する方法を学びました。今回は、理論から一歩進んで、**MCPを実際に実装する方法**を具体的に見ていきます。

この第3章では、シンプルなMCPサーバーを構築し、Claude Desktopや他のアプリケーションに統合する手順をステップごとに説明します。コード例を交えながら、初心者でも試せる内容を目指します。開発環境を準備して、MCPの実装に挑戦してみましょう！

## 準備：開発環境のセットアップ

MCPサーバーを構築する前に、以下の環境を準備します：

- **必須ツール**：
  - Python 3.8以降（またはTypeScript/Node.js、今回はPythonを使用）。
  - `mcp`ライブラリ（Anthropic提供の仮定ライブラリ、またはJSON-RPC 2.0対応ライブラリ）。
  - Claude Desktop（MCP対応アプリケーション）またはMCPをサポートするIDE（例：Zed）。
- **推奨**：
  - Git（コード管理用）。
  - テキストエディタ（VS Codeなど）。
  - ローカル環境にサンプルデータ（例：テスト用ファイルやデータベース）。

### ライブラリのインストール

Pythonを使ったMCPサーバーを構築するため、以下のコマンドで必要なパッケージをインストールします：

```bash
pip install mcp jsonrpcserver
```

※ 注：`mcp`は仮定のライブラリ名です。実際には、Anthropicの公式ドキュメント（modelcontextprotocol.io）を参照し、最新のSDKをインストールしてください。

## ステップ1：シンプルなMCPサーバーの構築

まずは、ディレクトリ内のファイルリストをリソースとして提供する簡単なMCPサーバーを作成します。このサーバーは、AIがローカルファイルの情報を取得できるようにします。

以下のコードは、Pythonを使ったMCPサーバーの例です：

```python
from mcp import MCPServer
import os
import json

class FileListServer(MCPServer):
    def __init__(self, host, port):
        super().__init__(host, port)
        self.register_resource("list_files", self.list_files)
        self.register_resource("read_file", self.read_file)

    def list_files(self, params):
        directory = params.get("directory", ".")
        try:
            files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
            return {"status": "success", "files": files}
        except Exception as e:
            return {"status": "error", "message": str(e)}

    def read_file(self, params):
        filepath = params.get("filepath")
        try:
            with open(filepath, "r", encoding="utf-8") as f:
                content = f.read()
            return {"status": "success", "content": content}
        except Exception as e:
            return {"status": "error", "message": str(e)}

if __name__ == "__main__":
    server = FileListServer(host="localhost", port=8080)
    print("MCPサーバーを起動中: http://localhost:8080")
    server.start()
```

### コードの説明
- **MCPServerクラス**：JSON-RPC 2.0通信を処理するベースクラス。
- **list_files**：指定ディレクトリのファイルリストを返すリソース。
- **read_file**：指定ファイルの内容を読み込むリソース。
- **register_resource**：リソースを登録し、AIがアクセス可能に。
- **start()**：サーバーを起動。

このサーバーは、ディレクトリ内のファイル一覧やファイル内容をAIに提供します。たとえば、Claudeがコード補完時にプロジェクトファイルの内容を参照できます。

## ステップ2：MCPサーバーのテスト

サーバーを起動したら、動作を確認します。以下の手順でテストします：

1. **サーバー起動**：
   ```bash
   python server.py
   ```
   コンソールに「MCPサーバーを起動中: http://localhost:8080」と表示されれば成功です。

2. **JSON-RPCリクエストの送信**：
   テスト用に`curl`やPythonスクリプトを使ってリクエストを送信します。以下はPythonでの例：

   ```python
   import json
   import requests

   url = "http://localhost:8080"
   payload = {
       "jsonrpc": "2.0",
       "method": "list_files",
       "params": {"directory": "."},
       "id": 1
   }

   response = requests.post(url, json=payload)
   print(json.dumps(response.json(), indent=2, ensure_ascii=False))
   ```

   期待されるレスポンス：
   ```json
   {
     "jsonrpc": "2.0",
     "result": {
       "status": "success",
       "files": ["server.py", "test.txt"]
     },
     "id": 1
   }
   ```

3. **エラーハンドリングの確認**：
   存在しないディレクトリやファイルを指定して、エラーメッセージが正しく返るか確認します。

## ステップ3：Claude Desktopとの統合

次に、このサーバーをClaude Desktopに接続します。以下の手順に従います：

1. **設定ファイルの編集**：
   Claude Desktopの設定ファイル（例：`claude_desktop_config.json`）を開きます。以下のようにサーバー情報を追加：

   ```json
   {
     "mcp_servers": [
       {
         "name": "LocalFileServer",
         "url": "http://localhost:8080",
         "auth": "none"
       }
     ]
   }
   ```

2. **Claudeでのテスト**：
   Claude Desktopを起動し、以下のようなプロンプトを入力：
   ```
   ディレクトリ内のファイルリストを取得してください。
   ```
   Claudeがサーバーに接続し、ファイルリストを返します。たとえば：
   ```
   現在のディレクトリには以下のファイルがあります：
   - server.py
   - test.txt
   ```

3. **セキュリティ設定**：
   本番環境では、`auth`にOAuth 2.1トークンを設定し、アクセスを制限します。テスト環境では`"none"`で十分です。

## ステップ4：実用的なツールとの統合

シンプルなファイルサーバーを構築できたので、次は実用的なツールと統合してみましょう。例として、**GitHub API**をMCPサーバーに統合する方法を示します。

### GitHub APIサーバーの例

以下のコードは、GitHubリポジトリのコミット履歴を取得するMCPサーバーです：

```python
from mcp import MCPServer
import requests

class GitHubServer(MCPServer):
    def __init__(self, host, port, github_token):
        super().__init__(host, port)
        self.github_token = github_token
        self.register_resource("get_commits", self.get_commits)

    def get_commits(self, params):
        repo = params.get("repo")
        try:
            headers = {"Authorization": f"Bearer {self.github_token}"}
            url = f"https://api.github.com/repos/{repo}/commits"
            response = requests.get(url, headers=headers)
            response.raise_for_status()
            commits = response.json()
            return {
                "status": "success",
                "commits": [{"sha": c["sha"], "message": c["commit"]["message"]} for c in commits[:5]]
            }
        except Exception as e:
            return {"status": "error", "message": str(e)}

if __name__ == "__main__":
    # GitHub Personal Access Tokenを環境変数から取得
    import os
    token = os.getenv("GITHUB_TOKEN")
    server = GitHubServer(host="localhost", port=8081, github_token=token)
    print("GitHub MCPサーバーを起動中: http://localhost:8081")
    server.start()
```

### セットアップ手順
1. **GitHubトークンの取得**：
   - GitHubでPersonal Access Tokenを生成（`repo`スコープを有効化）。
   - 環境変数`GITHUB_TOKEN`に設定：
     ```bash
     export GITHUB_TOKEN=your_token_here
     ```

2. **サーバー起動**：
   ```bash
   python github_server.py
   ```

3. **Claudeでテスト**：
   Claude Desktopにサーバーを追加（ポート8081を指定）。プロンプト例：
   ```
   リポジトリ「octocat/Hello-World」の最新コミットを取得してください。
   ```
   レスポンス例：
   ```
   以下のコミットが見つかりました：
   - SHA: abc123, メッセージ: "Initial commit"
   - SHA: def456, メッセージ: "Add README"
   ```

## 実装のコツと注意点

MCPサーバーを構築する際のベストプラクティスをいくつか紹介します：

- **エラーハンドリング**：ユーザーにわかりやすいエラーメッセージを返す。  
- **パフォーマンス**：リソースの取得をキャッシュして、遅延を最小限に。  
- **セキュリティ**：本番環境ではHTTPSとOAuthを必須に。ローカルテスト以外で`"auth": "none"`は避ける。  
- **既存サーバーの活用**：PostgreSQLやSlack用のオープンソースMCPサーバーを利用すると、ゼロから構築する手間が省ける。  
- **ログ記録**：リクエストとレスポンスをログに記録し、デバッグを容易に。

## まとめと次へのステップ

この第3章では、MCPサーバーの構築からClaude Desktopへの統合、そしてGitHub APIとの実用的な接続までをハンズオンで学びました。MCPの実装は、シンプルなリソース提供から始めて、複雑なツール統合へと拡張できる柔軟なプロセスです。

次の第4章では、「MCPの実践的な応用」をテーマに、ソフトウェア開発、ビジネスワークフロー、研究など、さまざまな分野でのMCPの活用例を紹介します。実世界でのMCPの可能性に興味がある方は、ぜひお楽しみに！

---

役に立ったと思ったら、「いいね」や「ストック」をしていただけると嬉しいです！次の章でまたお会いしましょう！