Upgrade to Pro — share decks privately, control downloads, hide ads and more …

自作MCPサーバ入門

 自作MCPサーバ入門

機械学習の社会実装勉強会第47回 (https://machine-learning-workshop.connpass.com/event/356041/presentation/) の発表資料です。

More Decks by 西岡 賢一郎 (Kenichiro Nishioka)

Other Decks in Technology

Transcript

  1. 📋 アジェンダ 1 MCP とは何か 2 Function Calling との違い 3

    MCP の基本アーキテクチャ 4 通信方式の選択 5 MCP サーバ構築方法 6 基本実装例 7 高度な機能実装 8 セキュリティ考慮事項 9 テスト方法 10 構築時の注意点 11 デモ 12 まとめ・今後の展望
  2. 🤔 そもそも MCP とはなにか MCP の概要 Model Context Protocol: LLM

    と外部データソースを連携するプロトコル JSON-RPC 2.0 ベースの通信フレームワーク Anthropic の Claude でサポート開始、 2025 年 3 月に OpenAI も公式採用 解決する課題 LLM が外部システムにアクセスできない リアルタイムデータの取得が困難 企業データとの統合が複雑 MCP の利点 標準化されたインターフェース セキュアなデータアクセス 拡張性の高いアーキテクチャ 最新情報 : MCP は Anthropic が 2024 年に発表したオープンスタンダードで、 OpenAI と Microsoft が 2025 年 3 月に公式サポートを表明 しました。業界標準として注目されています。
  3. 📝 Function Calling との違い 項目 FUNCTION CALLING MCP スコープ 単発の関数実行

    永続的な接続・セッション 状態管理 ステートレス ステートフル(コンテキスト保持) 接続方式 API 呼び出し毎に接続 持続的な接続( Stdio/SSE ) データソース 静的な関数定義 動的なリソース・ツール提供 ユースケース 計算、単純な API 呼び出し 企業システム統合、リアルタイムデータ 要約 : Function Calling は「関数の実行」 、 MCP は「システム同士の継続的な連携」
  4. 🏗️ MCP の基本アーキテクチャ 3 つの主要コンポーネント アーキテクチャのポイント MCP は JSON-RPC 2.0

    をベースとした通信プロトコルです。ホストがクライアントを通じて サーバーと通信し、 LLM に必要な外部コンテキストやツールを提供します。この構成により、 モデルは安全に外部データにアクセスし、リアルタイム情報を取得できます。 1. Hosts ( ホスト ) LLM アプリケーション ( Claude Desktop 等) 接続を開始する側 3. Servers ( サー バー ) コンテキスト提供者 ツール / リソースを公開 2. Clients ( クライ アント ) ホスト内でプロトコルを管 理 仲介役として機能
  5. 🛠️ 自作 MCP サーバ入門 開発環境の準備 必要なパッケージ プロジェクト構成 mcp-server/ ├── main.py

    ├── requirements.txt ├── config/ │ └── server_config.yaml └── tests/ └── test_server.py プロジェクト構成のポイント main.py: MCP サーバーのエントリポイント requirements.txt: 依存パッケージの管理 config/: サーバー設定の外部化 tests/: ユニットテスト・統合テスト 開発環境構築のポイント MCP サーバー開発は Python 3.10 以上を推奨しています。 仮想環境( venv )での開発でパッケージの競合を避け、 uv を使うことでパッケージイ ンストールが高速化できます。 1 つの MCP サーバーで複数のツールを提供できるため、機能ごとにモジュール化すると保守性が向上します。 bash Copy # 推奨: uv での環境構築 uv pip install "mcp[cli]" # 代替: pip での環境構築 pip install mcp
  6. 💻 基本実装例 必要なコード量はたったこれだけ! 🚀 実装のポイント デコレータの魅力 @mcp.tool() デコレータは関数の定義をそ のまま活かしながら、 自動的に関数のシグネ

    チャから引数の型と説明文を生成します。 ド キュメンテーション文字列は自動的にツールの 説明として使用されます。 Claude との相性 Claude Desktop と連携すると、 MCP サーバ ーが自動検出され、 簡単にツールとしてアク セス可能になります。 main.py Copy from mcp.server.fastmcp import FastMCP # サーバー作成 mcp = FastMCP(" 企業データ連携") # ツール定義(関数にデコレータを付けるだけ) @mcp.tool() def get_inventory(sku: str) -> int: """ 在庫数を取得""" return 1500 # リソース定義(データ提供も簡単) @mcp.resource("customer/{id}") def get_customer(id: str) -> str: """ 顧客情報を取得""" return f" 顧客ID: {id}" # サーバー起動(1 行で完了) if __name__ == "__main__": mcp.run() 最短 5 行で MCP サーバーが完成 → デコレータで既存関数をツール化 → 型ヒントから自動でスキーマ生成 → 設定不要で Claude Desktop に接続可能 → 機械学習の社会実装勉強会
  7. 🔧 高度な機能実装 認証機能 OAuth 2.1 認証で企業システムとの安全な連携。スコープ 制限で最小権限の原則を実現。 複数データの一括処理 API 呼び出し回数を削減、

    LLM との通信を最適化。リスト 型引数で複数処理を実装。 スキーマ検証 Pydantic による自動入力検証で型安全性を確保。バリデー ションエラーを自動処理。 auth_setup.py from mcp.server.fastmcp import FastMCP mcp = FastMCP(" セキュアサーバー") # 認証設定(OAuth 2.1 対応) mcp = FastMCP( "MyApp", auth_server_provider=MyOAuthProvider(), auth=AuthSettings( issuer_url="https://myapp.com", required_scopes=["read", "write"] ) ) bulk_operations.py @mcp.tool() def bulk_inventory_check(sku_list: list[str]) -> list[dict]: """ 複数商品の在庫を一括確認""" return [ {"sku": sku, "stock": get_stock(sku)} for sku in sku_list ] schema_validation.py from pydantic import BaseModel class OrderRequest(BaseModel): product_id: str quantity: int @mcp.tool() def create_order(order: OrderRequest) - > dict: """ 注文作成(自動バリデーション付き)""" return { "order_id": "12345", "status": "created" }
  8. 🔒 セキュリティ考慮事項 (1/2) 1. 認証・認可の方法 認証方式( HTTP-based transport 向け) 認可設計

    2. プロトコルレベルの保護 HTTPS 必須 全 HTTP 通信で TLS 暗号化強制。中間者攻撃を防止し、データ 転送の安全性を確保します。 トークン検証 全リクエストでアクセストークンの有効性、発行者、有効期 限、スコープを厳密に検証します。 リダイレクト URI 検証 登録済み URI との厳密な一致を確認し、オープンリダイレクト 脆弱性からユーザーを保護します。 重要な注意点 プロトコル仕様に完全準拠していない MCP 実装は、セキュリ ティ脆弱性を招く可能性があります。常に最新の仕様に従っ てください。 OAuth 2.1: HTTP transport 使用時は MUST 要件、 PKCE 強制適 用 • Bearer Token: 簡単実装、短期利用に適している • 環境変数 : Stdio transport 推奨(認証仕様対象外) • 動的クライアント登録 : RFC7591 サポート推奨 • 最小権限の原則 : 必要最小限のアクセス許可のみ • 明示的ユーザー同意 : ツール実行前の必須確認 • スコープベース制御 : OAuth スコープによる機能制限 •
  9. 🔒 セキュリティ考慮事項 (2/2) 3. 攻撃対策 4. 監査・運用 セキュリティはプロセスです。定期的な監査とアップデートを通じて継続 的に強化していくことが重要です。 重要なセキュリティリスク

    リスク 説明 対策 トークン漏洩 OAuth トークンが盗まれると複数サービスに影響 トークンスコープ制限、定期ローテーション ツール悪用 LLM が騙されて危険なツールを実行 明示的同意、 Human-in-the-loop データ漏洩 機密データが意図せず外部に送信 DLP 統合、出力フィルタリング プロンプトインジェクション 悪意のある指示でシステム制御奪取 入力サニタイゼーション、権限分離 実装の優先順位 優先度 対策 理由 高 OAuth 2.1 、 HTTPS 公式仕様要件 高 明示的同意、入力検証 基本的攻撃対策 中 レート制限、監査ログ 運用安定性 低 高度な脅威検知 段階的導入 入力検証 : スキーマ検証、 SQL インジェクション対策 • レート制限 : ツール呼び出し頻度制限、 DoS 攻撃対策 • リソース制限 : CPU 、メモリ使用量の監視と制限 • サンドボックス化 : ツール実行環境の分離 • 包括的ログ記録 : 全操作、認証試行の履歴記録 • 分散トレーシング : OpenTelemetry 等での追跡可能性 • 異常検知 : 不正な操作パターンの検出 •
  10. 🧪 テスト方法 1. MCP Inspector ツール # インタラクティブなデバッグツール npx @modelcontextprotocol/inspector

    python main.py 特徴 : 視覚的なインターフェース リアルタイムでツール実行確認 エラーの詳細表示 2. ユニットテスト import pytest from mcp.testing import MCPTestClient @pytest.fixture def test_client(): return MCPTestClient(mcp_server) def test_inventory_check(test_client): response = test_client.call("get_inventory", {"sku": "IT assert response["stock"] >= 0 3. 統合テスト def test_end_to_end_workflow(): client = MCPClient("http://localhost:8080") result = client.call_tool("get_inventory", {"sku": "TEST assert result["status"] == "success" エンドツーエンドテストでは、実際の API リクエストを行い、レスポンス の整合性を検証します。モック化せず本物のサーバーに対してテストを実 行するため、環境の事前準備が重要です。 テスト戦略まとめ テスト種類 ツール 目的 視覚的検査 MCP Inspector 手動デバッグ・動作確認 ユニットテスト pytest 個別機能の検証 統合テスト カスタムスクリプト エンドツーエンド検証 負荷テスト Locust, Apache Bench パフォーマンス測定 セキュリティテスト 手動 / 自動リクエスト 認証・権限確認 テスト自動化のヒント CI/CD パイプラインに組み込むことで、コード変更によるエラーを早期発見できます。 GitHub Actions やテスト結果を自動で Slack に通知する仕組み を作ると効率的です。
  11. ⚠️ 構築時の注意点 1. パフォーマンス考慮事項 接続プーリング from mcp import ConnectionPool class

    OptimizedMCPServer: def __init__(self): self.db_pool = ConnectionPool( factory=create_db_connecti on, max_size=50, timeout=30 ) キャッシュ戦略 from functools import lru_cache import redis class HybridCache: def __init__(self): self.local_cache = {} self.redis_client = redis.Redi s() self.cache_ttl = 300 # 5 分 ヒント : 高頻度アクセスデータはメモリキャッシュ、大 量データは分散キャッシュを使い分けましょう 2. エラーハンドリング from enum import Enum class MCPErrorCode(Enum): INVALID_REQUEST = -32600 METHOD_NOT_FOUND = -32601 INVALID_PARAMS = -32602 INTERNAL_ERROR = -32603 @mcp_server.exception_handler(ValueErr or) async def handle_validation_error( error: ValueError ): エラー処理のベストプラクティス JSON-RPC 2.0 仕様に準拠したエラーコード 詳細なエラーメッセージをクライアントに提供 システム内部エラーはログに記録し、一般化した情 報のみを返す 3. 設定管理 from pydantic import BaseSettings class MCPSettings(BaseSettings): secret_key: str jwt_algorithm: str = "HS256" max_connections: int = 100 database_url: str class Config: env_file = ".env" 設定ファイルの階層化 config/default.yaml: デフォルト設定 config/development.yaml: 開発環境 config/staging.yaml: テスト環境 config/production.yaml: 本番環境 .env: シークレット( Git 管理外)
  12. デモ n8n の MCP ノードを活用したサーバ構築を紹介します 環境セットアップ Docker を使った n8n 環境の構築と初期設定を行います。ユ

    ーザー登録後、管理画面にアクセスして基本設定を確認しま す。 ワークフロー作成 MCP エンドポイントを公開するためのワークフローを作成し ます。 Bearer Token による認証設定や SSE 接続の設定を組 み込みます。 ツール実装 Function ノードを使って MCP ツールを実装します。 JavaScript で各ツールのロジックを記述し、入出力スキーマ を定義します。 疎通確認 MCP Inspector を使って作成した MCP サーバーに接続し、ツ ールの呼び出しテストを行います。 Claude Desktop との連 携も確認します。 n8n の MCP ノードの特徴 コード不要のビジュアル開発 OAuth 認証自動サポート 他ノードとの連携容易 高い拡張性と柔軟性
  13. 📝 まとめ・今後の展望 今回学んだこと MCP は LLM と外部システムを繋ぐ標準プロトコル Anthropic によるオープンスタンダードで JSON-RPC

    2.0 ベース。 OpenAI も 2025 年 3 月に公式採用したことで業界標準となりつつある。 Python の FastMCP で簡単に実装可能 最短 5 行で MCP サーバーが完成し、デコレータで既存関数をツール化。 型ヒントから自動でスキーマ生成され、設定不要で Claude Desktop に 接続可能。 セキュリティとパフォーマンスが重要 HTTP 通信の場合、 OAuth 2.1 認証は必須要件。 入力検証、レート制 限、接続プーリング、キャッシュ戦略で安全性と効率を確保。 今後の展望 企業システム統合 ERP 、 CRM 、 SCM など社内シ ステムとの連携で AI による業 務効率化 リアルタイム分析 BI ダッシュボードとの統合に よるデータ駆動型の意思決定 支援 マルチテナント対応 SaaS プラットフォームでの活 用と複数組織へのサービス提 供 セキュリティ強化 より高度な認証・認可と監査 機能の実装 次のステップ ご清聴ありがとうございました 自分の業務に合わせた MCP サーバー構築 業務フローを分析し、 AI アシスタントとの連携ポイントを特定 1 既存システムとの統合検討 API 設計とセキュリティモデルの確立 2 セキュリティ・パフォーマンス最適化 段階的な機能拡張と継続的な改善 3