ライブラリに戻る
MCP

MCPチュートリアル:2026-07-28仕様でゼロから本番サーバーへ

最終更新:2026年8月22日

主要ポイント

  • MCP SDK月間ダウンロード数9700万超、しかしOAuth使用サーバーはわずか8.5% — プロトコルの普及がセキュリティ態勢を上回っており、本チュートリアルの本番ハードニング手順はB2Bデプロイメントにおいて必須です。
  • MCP SDK v2はパッケージサイズを83%削減し、速度を25%向上 — 2026-07-28仕様はTypeScript、Python、Go、C#向けに再設計されたSDKと共にリリースされ、それぞれに移行ガイドが付属しています。
  • 2026-07-28仕様はセッションと初期化ハンドシェイクを削除 — 各リクエストは自己完続型となり、共有状態なしでプレーンなラウンドロビンロードバランサー背後の任意のサーバーインスタンスに到達します。
  • 8月22日MCPロードマップは5つの優先領域を定義 — エージェントアイデンティティ、HTTPトランスポート統一、エージェント的メッセージングプリミティブ、改善されたツールプリミティブ、SDK開発者体験 — それぞれが本チュートリアルの本番パスで扱われます。
  • 82%のMCPサーバーがパストラバーサルに対して脆弱Practical DevSecOpsによる) — ここでのサンドボックス化と入力検証の手順がデモとデプロイメントの違いです。

Model Context Protocolは2026年に月間SDKダウンロード数9700万を超え、TypeScriptとPython SDKはそれぞれ10億以上の総ダウンロード数に達しました。2026-07-28仕様はローンチ以来最大の改訂をリリースしました:ステートレスプロトコルコア、ファーストクラス拡張、デプロイメントサーフェスを簡素化する3つの非推奨化。3週間後の8月22日、MCPメンテナーが新ロードマップを公開し、次の仕様サイクルに向けた5つの優先領域を定義しました — エージェントアイデンティティ、HTTPトランスポート統一、エージェント的メッセージングプリミティブ、改善されたツールプリミティブ、SDK開発者体験。

本チュートリアルは本番パスをカバーします:ステートレスで水平スケーラブル、アイデンティティ対応、ロードマップのエンタープライズ優先事項に対応したMCPサーバーの構築。公式クイックスタートはClaude Desktopに接続された天気サーバーを案内します。本記事はそのクイックスタートが終わる場所から始まります — 動作するデモと、本番のB2Bエージェントシステム背後に配置するサーバーの間の手順です。

ステップ1 — SDK v2によるプロジェクトセットアップ

2026-07-28仕様は再設計されたSDKと共にリリースされました。TypeScript SDK v2は新しいクライアント・サーバー分割によりパッケージサイズを約83%削減し、パフォーマンスを25%向上させました。Python SDK 2.0+Go SDKC# SDK v2.0はすべて公開日に2026-07-28プロトコルバージョンをサポートし、破壊的変更に向けた詳細な移行ノートがあります。

本チュートリアルではPython 3.10+とuvを使用します:

uv init mcp-server
cd mcp-server
uv venv
source .venv/bin/activate
uv add "mcp[cli]"

mcp[cli]エクストラはサーバーの実行と検査のためのCLIツールを提供します。SDKはPythonの型ヒントとdocstringを使用してツール定義を自動生成します — 関数を定義し、デコレートすると、プロトコルメタデータがシグネチャから派生します。

ステップ2 — 最初のツールを定義する

MCPサーバーは3つの能力タイプを公開します:tools(モデルが呼び出す関数)、resources(モデルが読むデータ)、prompts(テンプレート化されたワークフロー)。B2Bサーバーの場合、toolsが主要サーフェスです — エージェントがカタログを検索し、見積もりを生成し、在庫を予約する方法です。

from mcp.server import MCPServer

mcp = MCPServer("catalog-server")

@mcp.tool()
async def search_catalog(query: str, supplier_id: str | None = None) -> str:
    """Search the supplier catalog by keyword, optionally filtered by supplier.

    Args:
        query: Search keyword (SKU, product name, or category)
        supplier_id: Optional supplier filter (e.g., "s-12")
    """
    results = await catalog.search(query=query, supplier_id=supplier_id)
    return format_results(results)

@mcp.tool()
async def get_pricing(sku: str, quantity: int) -> str:
    """Get tiered pricing for a SKU at a given quantity.

    Args:
        sku: Supplier product identifier
        quantity: Order quantity (determines pricing tier)
    """
    price = await pricing_engine.get(sku=sku, quantity=quantity)
    return f"SKU {sku}: ${price.unit_price:.2f} (tier: {price.tier_name})"

各ツールのdocstringがモデルのツールリストに表示される説明になります。型ヒントが入力スキーマになります。これがMCP Module Code Standardのパターンです:各ツールには型付きスキーマ、明確なdocstring、単一責任があります。

STDIOログの落とし穴: STDIOベースのサーバーでは、stdoutに決して書き込まないでください — JSON-RPCメッセージストリームを破損します。stderrに書き込む標準のloggingモジュールを使用してください:

import logging
logger = logging.getLogger(__name__)
logger.info("Catalog search: query=%s", query)  # stderr, safe

ステップ3 — トランスポート:STDIO vs Streamable HTTP

2026-07-28仕様はリモートMCPサーバーを「他のHTTPワークロードと同様」にします(仕様チェンジログ)。ロードマップの第2優先領域 — HTTPネイティブトランスポート統一 — はこれをstdio上でStreamable HTTPを話すローカルサーバーに拡張し、1つのトランスポートモデルに統一します。

ローカル開発とデスクトップクライアントでは、STDIOがデフォルトです:

if __name__ == "__main__":
    mcp.run(transport="stdio")

本番B2Bデプロイメント — エージェントがデスクトップアプリではなくクラウドワークロードとして実行される場合 — ではStreamable HTTPが本番トランスポートです。サーバーはロードバランサー背後で実行し、Mcp-MethodMcp-Nameヘッダーを持つHTTP POSTリクエストを受け付け、HTTP上でJSON-RPCで応答します:

if __name__ == "__main__":
    mcp.run(transport="http", host="0.0.0.0", port=8080)

ヘッダーベースのルーティング機能は、ゲートウェイ、レートリミッター、WAFがMcp-MethodMcp-Nameヘッダーで直接ルーティングと計量ができることを意味します — ルーティング決定にJSONボディの解析は不要です。これがステートレスプロトコルが設計されたデプロイメント形態です:ラウンドロビンロードバランサー背後のステートレスサーバーインスタンスのプール、共有セッション層なし。

ステップ4 — ステートフルワークフローのための明示的ハンドル

ステートレスは状態が消えることを意味しません。2026-07-28仕様は隠れたセッション状態を明示的ハンドルパターンで置き換えます:ツールがハンドル(order_idquote_idbasket_id)を鋳造し、モデルがそれを後続呼び出しで通常の引数として渡します。これはMCP 2026-07-28:B2Bエージェントデプロイメントにおけるステートレスプロトコルの意味で詳しく扱われています。

5つのツール呼び出しにまたがる見積もりワークフロー — リクエスト作成、カタログ検索、見積もり生成、在庫予約、価格ティア適用 — では、ハンドルが各呼び出しを通じてスレッド化されます:

@mcp.tool()
async def create_request(buyer_id: str, line_items: list[dict]) -> str:
    """Create an RFQ request and return a request_id handle."""
    request = await rfq_engine.create(buyer_id, line_items)
    return f"request_id={request.id}"

@mcp.tool()
async def generate_quote(request_id: str, supplier_ids: list[str]) -> str:
    """Generate a quote from specified suppliers. Returns quote_id."""
    quote = await rfq_engine.quote(request_id, supplier_ids)
    return f"quote_id={quote.id}"

各呼び出しが必要なハンドルを運びます。呼び出し間で何も覚えているサーバーはありません。ロードバランサーが呼び出し3とは異なるインスタンスに呼び出し4をルーティングしても、まだ機能します — ハンドルはリクエスト内にあります。監査チームが1週間後にこのワークフローを再構築する必要がある場合、リクエスト引数のハンドルが完全なストーリーを伝えます。

ステップ5 — エージェントアイデンティティ:エンタープライズのギャップ

ロードマップの第3優先領域 — エージェントアイデンティティとエンタープライズ対応セキュリティ — はB2Bデプロイメントにとって最も重要です。ロードマップは明確です:MCP認証は今日「ブラウザでアクセスを承認する人」を中心に構築されていますが、「より多くの呼び出し元が独自のアイデンティティを持つクラウドワークロードとして実行されるエージェントであり、不在のユーザーの代わりに行動するか、サブエージェントに狭い権限を委譲しています。」

ロードマップが定義する前進パス:

  1. DPoP (RFC 9449)Demonstrating Proof of PossessionはOAuthトークンをクライアントが保持するキーにバインドします。盗まれたトークンだけでは別のプロセスからリクエストを再生できません。DPoPはエージェントに何を許可するかを決定しません;意図された保持者の外部でクレデンシャルを再利用することを困難にします。
  2. Workload Identity FederationIETF WIMSEワーキンググループはマルチシステム環境でのワークロードアイデンティティのアーキテクチャを開発しています。エージェントはワークロードなので、ワークロードのアイデンティティを取得します:SPIFFE IDで命名、短期クレデンシャルで認証、共有APIキーではありません。
  3. Enterprise-Managed Authorization (EMA)EMA拡張はアクセス決定を組織のアイデンティティプロバイダーに移動します。MCPクライアントはユーザーアイデンティティアサーションをIdentity Assertion JWT Authorization Grant (ID-JAG)と交換し、そのグラントをサーバー固有のアクセストークンと交換します。これは中央割り当てと取り消しをサポートします。

本チュートリアルの本番サーバー向けの最小ベースライン:

  • 共有APIキーなし。 各エージェントは短期間のオーディエンスバインドトークンを取得します。
  • DPoP付きOAuth。 Practical DevSecOps MCP Security Statistics 2026レポートはわずか8.5%のMCPサーバーがOAuthを使用していることを発見しました — 残りの91.5%はAPIキーまたは認証なしに依存しています。
  • 各信頼境界でのトークン交換。 CoSAIトークン交換標準(8月18日公開)はエージェント的ワークフローの基礎的制御としてトークン交換を確立します。各register_tools()エントリポイントは永続的クレデンシャルではなくタスクスコープトークンを受け入れるべきです。

本番前にこれらの標準を検証する12のコントロールについてはMCP Security Hardening Checklistを、モジュールレベルの防御態勢についてはMCP Module Code Standardを参照してください。

ステップ6 — プログレッシブツールディスカバリー:100ツール問題の解決

ロードマップの第4優先領域 — 改善されたプリミティブ — は具体的な本番問題に対処します:「100のツールを持つサーバーに接続することは、ユーザーがまだ1つの質問もしていない時にモデルがその全サーフェスに対して支払うことを意味し、ツール選択はリストが成長するにつれて悪化する傾向があります。」

ロードマップの答えはプログレッシブディスカバリーです:サーバーは小さなエントリポイントを提供し、会話が絞り込まれるにつれてカタログのより多くを明らかにします。接続時に100のツールスキーマをモデルのコンテキストウィンドウにダンプする代わりに、サーバーは少数のトップレベルツールを公開し、エージェントが何をしているかに基づいてサーフェスを動的に拡張します。

2026-07-28仕様はすでにビルディングブロックを提供しています:

  • server/discover RPC — クライアントはセッションハンドシェイクなしで、他のことをする前にサーバーの能力を学習できます。
  • ttlMscacheScope付きtools/list — リストレスポンスはキャッシュヒントを運び、クライアントはツールカタログをキャッシュし各接続での再取得を回避します。
  • 各リクエストの_meta — プロトコルバージョン、クライアント情報、能力はネゴシエートされたセッションではなくリクエストごとに移動します。

50以上のツールを持つサーバーの場合、プログレッシブディスカバリーパターンは次のようになります:

@mcp.tool()
async def discover_tools(category: str) -> str:
    """Discover available tools in a category. Start here for a guided tour.

    Args:
        category: Tool category — 'catalog', 'pricing', 'inventory', 'orders'
    """
    available = tool_registry.by_category(category)
    return format_tool_list(available)

エージェントは最初にdiscover_tools("catalog")を呼び出し、5-8のフォーカスされたツールセットを取得し、ワークフローが要求する場合にのみ他のカテゴリに拡張します。これによりコンテキストウィンドウをリーンに保ち、ツール選択を正確にします — MCP Module Code Standardの単一責任ツール設計の背後にある同じ原則です。

ステップ7 — デプロイメント:ステートレス、水平、ロードバランサー背後

2026-07-28仕様が設計されたデプロイメント形態:

                    ┌──────────────────┐
                    │  Load Balancer   │
                    │  (round-robin)   │
                    └────────┬─────────┘
                             │
              ┌──────────────┼──────────────┐
              │              │              │
     ┌────────┴────┐ ┌───────┴────┐ ┌───────┴────┐
     │ MCP Server  │ │ MCP Server  │ │ MCP Server  │
     │  Instance 1 │ │  Instance 2 │ │  Instance 3 │
     │ (stateless) │ │ (stateless) │ │ (stateless) │
     └─────────────┘ └─────────────┘ └─────────────┘
              │              │              │
              └──────────────┼──────────────┘
                             │
                    ┌────────┴─────────┐
                    │  Upstream Systems │
                    │  (NetSuite, etc.)  │
                    └──────────────────┘

共有セッションストアなし。スティッキーセッションロードバランサーなし。セッションリプレイインフラストラクチャなし。各リクエストは必要なもの — プロトコルバージョン、クライアント情報、能力、ハンドル — をリクエストボディとヘッダーに運び、サーバー側状態にはありません。

本番ハードニング向け:

  • 各サーバーインスタンスをサンドボックス化。 MCP Project Sandboxing Baseline(8月16日公開)は生成されたプロセスのOSレベルサンドボックス化を要求します。Landlock (Linux)、Seatbelt (macOS)、またはWindows ACLを使用してファイルシステムとネットワークアクセスを制限します。82%のパストラバーサル脆弱性率(Practical DevSecOpsによる)は入力検証だけでは不十分な証拠です。
  • 各ツールをレートリミット。 MCP Module Code Standardはツールごとのレートリミットを要求します。MCP Ruby SDK DoS脆弱性(8月16日開示)はリソース枯渇攻撃が現実の攻撃サーフェスであることを確認します。
  • MCPロギングチャネルではなくOpenTelemetryにログ。 2026-07-28仕様はstderrとOpenTelemetryを優先してロギング機能を非推奨化しました。MCPサーバーログはカスタムトランスポートなしで既存のオブザーバビリティパイプライン(Datadog、CloudWatch、Honeycomb)に統合されます。
  • WAFとレートリミット用にヘッダーベースルーティングを使用。 Mcp-MethodMcp-Nameヘッダーにより、ゲートウェイはJSONボディを解析せずにルーティングと認証ができます。

ロードマップの先:5つの優先領域

8月22日ロードマップは次の仕様サイクルの方向性を定義します。本チュートリアルは本番対応部分をカバーし、ロードマップは次に来るものを示します:

優先領域 ステータス チュートリアルカバレッジ
エージェントアイデンティティとエンタープライズセキュリティ 進行中 (DPoP, WIMSE, EMA) ステップ5 — ベースライン確立;完全な実装は仕様確定待ち
HTTPネイティブトランスポート統一 リリース済み(リモート)、進行中(ローカル) ステップ3 — リモートHTTPが本番;ローカルStreamable HTTP over stdioがロードマップ目標
エージェント的メッセージングプリミティブ 拡張リリース中 (Tasks, サブスクリプション) カバレッジ外 — サーバー開始イベント (webhooks, channels) が次のフロンティア
改善されたプリミティブ (プログレッシブディスカバリー) デザイン段階 ステップ6 — パターンはdiscover_toolsで今日実装可能;仕様レベルサポートが到来
改善されたSDK開発者体験 リリース済み (SDK v2, 適合テスト) ステップ1 — SDK v2が現在の本番ベースライン

ロードマップは方向性であり、互換性の約束ではありません。7月28日仕様はすでにステートレスHTTPコアとTasks拡張を提供しました。プッシュイベント、統一ディスカバリー、委任、クロスSDK適合にはまだ実装作業が必要です。B2Bデプロイメントでは、エージェントアイデンティティ優先事項が注目すべきものです — MCPセキュリティ記事ガバナンスチェックリストが指摘してきた正確なギャップ(APIキーと長期間トークン)に対処します。

チュートリアルの本番パスは5ステップ本番チェックリストをカバーします:

MCPサーバー:ゼロから本番へ SDKセットアップからステートレスデプロイまでの5ステップ — エンタープライズパス 1 プロジェクトセットアップ & SDK v2 83%小型化、25%高速化 uv init + mcp[cli] — Python 3.10+, TypeScript, Go, C# SDKsはすべて2026-07-28をサポート 出典:blog.modelcontextprotocol.io/posts/2026-07-28 2 ツール & トランスポート定義 型付きスキーマ、docstring、STDIOまたはStreamable HTTP @mcp.tool() with type hints — ゲートウェイルーティング用Mcp-Method/Mcp-Nameヘッダー 出典:modelcontextprotocol.io/specification/2026-07-28 3 ステートフルワークフローの明示的ハンドル request_id → quote_id → hold_id — ステートレスプロトコル、ステートフルワークフロー セッションハンドシェイクなし — 各リクエストが自己完続、監査可能、キャッシュ可能 出典:SEP-2575, SEP-2567 (ステートレスMCP) 4 エージェントアイデンティティ & エンタープライズセキュリティ DPoP (RFC 9449), Workload Identity Federation, EMA拡張 OAuth使用わずか8.5% — 82%がパストラバーサル脆弱性 — サンドボックス必須 出典:Practical DevSecOps MCP Security Statistics 2026 5 本番デプロイメント ラウンドロビンLB背後のステートレスプール — OpenTelemetry、サンドボックス化、レートリミット スティッキーセッションなし、共有状態層なし — 任意のインスタンスが任意のリクエストを処理 出典:MCP Project Sandboxing Baseline (8月16日), CoSAI token-exchange (8月18日) ロードマップの先 — 5つの優先領域 (2026年8月22日) エージェントアイデンティティ DPoP, WIMSE, EMA HTTPトランスポート Streamable HTTP統一 メッセージングプリミティブ Tasks, webhooks, channels プログレッシブディスカバリー 100ツール問題を解決 SDK体験 適合テスト 方向性であり互換性の約束ではない — 基盤は7月28日リリース、拡張とアイデンティティ作業は進行中 出典:blog.modelcontextprotocol.io/posts/mcp-roadmap (2026年8月22日) SDKセットアップからステートレス本番までの5ステップ — ideabosque.com/library

関連読書

ビルドビネット

NetSuiteを実行する中堅ディストリビューターが、CRMを離れることなくサプライヤーカタログを検索し、見積もりを生成し、在庫レベルを確認できるAIアシスタントを営業チームに提供したいと考えました。最初の試みはすべてのエージェントインスタンス間で共有される単一のAPIキーを使用しました — OAuthをスキップする91.5%のMCPサーバー。サプライヤーの価格表更新がログファイル内でキーを露出し、チームは15のサービスでクレデンシャルをローテーションするのに2日を費やしました。

再構築は本チュートリアルの本番パスに従いました:型付きツールスキーマ付きSDK v2、ラウンドロビンロードバランサー背後のStreamable HTTPトランスポート、15分有効期限のDPoPバインドOAuthトークン、5ステップ見積もりワークフローの明示的ハンドル、各サーバーインスタンスのOSレベルサンドボックス化。エージェントはコード標準に従うMCPモジュールを通じてNetSuiteに接続し、プログレッシブディスカバリーは最初に8つのカタログツールを公開し、ワークフローが要求する場合にのみ価格と在庫に拡張します。6つのサーバーインスタンスがロードバランサー背後でステートレスに実行します。共有セッションストアなし。スティッキーセッションなし。各リクエストがそのハンドル、トークン、プロトコルバージョンを運びます。

スコープ定義ビルドをリクエスト

1週間のディスカバリー。システムインベントリ、ワークフローマップ、固定スコープを取得 — 当社とビルドするかどうかにかかわらず。

あなたのシステムのためにこれを構築したいですか?

ここの各ドキュメントは実際の本番作業から来ています。ターゲットシステムとワークフローがあれば、1週間でスコープを定義できます。

スコープ付き構築を依頼

1週間のディスカバリ。システムインベントリ、ワークフローマップ、固定スコープを提供します — 私たちと構築するかどうかにかかわらず。