0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MCP (Model Context Protocol) の内部仕様を深掘り:JSON-RPC 2.0とStreamable HTTPを用いたClient-Server通信の実践

0
Posted at

LLM統合における密結合の課題とMCPの登場

LLM(大規模言語モデル)を実務に適用する際、外部データやAPIと連携させる「AIエージェント」の構築が不可欠となっています。しかし、従来のシステム統合には大きな課題が存在していました。それは、各LLMや外部ツールごとに、個別最適化されたAPIインテグレーションコードを記述しなければならないという点です。

この個別開発によるアプローチは、システム全体のメンテナンスコストを増大させ、セキュリティ上の脆弱性を生む要因となっていました。この課題を根本から解決するために登場したのが、「Model Context Protocol (MCP)」です。

MCPは、AIと外部データソース、ツール群を安全かつシームレスに接続するためのオープンな標準プロトコルです。AIを単一の「ツール」として扱うのではなく、標準化された「エコシステム」として再定義するパラダイムシフトをもたらします。

なぜJSON-RPC 2.0とStreamable HTTPなのか

MCPの最大の特徴は、そのトランスポート層に「JSON-RPC 2.0」と「Streamable HTTP(主にServer-Sent Events: SSE)」を採用している点にあります。なぜ独自のプロトコルを新規設計せず、既存の標準規格を採用したのでしょうか。そこには、設計における明確な「why(背景とトレードオフ)」が存在します。

1. JSON-RPC 2.0によるシンプルさと双方向性

JSON-RPC 2.0は、非常に軽量な仕様であり、リクエスト、レスポンス、通知(Notification)の3つの基本パターンのみで構成されています。複雑なgRPCやGraphQLと比較して、JSON-RPC 2.0は「クライアントとサーバーの双方が、相手の内部実装に依存せずにメッセージを解釈できる」という高い柔軟性を持っています。LLMが動的にツールを選択し、パラメータを渡すプロセスにおいて、このシンプルさは開発コストの削減に直結します。

2. Streamable HTTP (SSE) の採用理由

Webブラウザやサーバーレス環境など、あらゆるネットワーク環境で動作させるためには、ファイアウォールを通過しやすい標準的なHTTPポート(80/443)での通信が不可欠です。WebSocketは双方向通信が可能ですが、プロトコルの切り替え(Upgradeヘッダ)が必要であり、企業ネットワークのプロキシや一部のクラウド環境で遮断されることがあります。

これに対し、Server-Sent Events (SSE) を用いた「Streamable HTTP」は、標準的なHTTP上で動作するため、既存のインフラをそのまま活用できます。サーバーからクライアントへの通知はSSEで行い、クライアントからサーバーへの要求は標準的なHTTP POSTで行うという非対称な設計により、高い「堅牢性」と「互換性」を両立させています。

通信シーケンスの解剖:初期化からツール実行まで

ClientとServer間で交わされる実際の通信は、以下の3つのフェーズに分かれます。

1. 初期化フェーズ(initialize)

通信の開始時、クライアントはサーバーに対して initialize リクエストを送信します。クライアント側のバージョンや利用可能な機能(capabilities)を提示し、サーバー側と合意形成を行います。これにより、互換性のミスマッチを未然に防ぎます。

2. ツール一覧の取得(tools/list)

初期化完了後、クライアントはサーバーが提供する機能の一覧を tools/list メソッドで要求します。サーバーは、LLMが理解できる形式(JSON Schema)でツールの説明や引数の定義を返します。このスキーマ情報が、LLMのプロンプト生成に直接利用されます。

3. ツールの実行(tools/call)

LLMが特定のツール実行を決定すると、クライアントは tools/call を実行します。具体的な引数(arguments)がサーバーに渡され、サーバーは処理結果を返却します。この一連の流れがすべて標準化されたフォーマットで行われます。

Node.js SDKによる具体的な実装例

それでは、実際に動作するMCPサーバーの実装コードを見てみましょう。以下は、Node.js用の公式SDK(@modelcontextprotocol/sdk)を使用した、簡単な足し算ツールを提供するサーバーの実装例です。

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

// MCPサーバーの初期化
const server = new Server(
  {
    name: "calculator-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// 提供するツールの一覧を定義
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "add_numbers",
        description: "2つの数値を加算します。",
        inputSchema: {
          type: "object",
          properties: {
            a: { type: "number", description: "最初の数値" },
            b: { type: "number", description: "2つ目の数値" },
          },
          required: ["a", "b"],
        },
      },
    ],
  };
});

// ツール実行時のロジックを定義
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "add_numbers") {
    const { a, b } = request.params.arguments as { a: number; b: number };
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({ result: a + b }),
        },
      ],
    };
  }
  throw new Error("Tool not found");
});

// 標準入出力をトランスポート層としてサーバーを起動
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP Server running on stdio");

このコードでは、StdioServerTransport を使用しています。標準入出力(stdio)をベースにした通信は、コンテナ間や同一ホスト内のローカル実行において、最も「セキュア」で高速な接続手段となります。ポートを開放する必要がないため、外部からの攻撃経路を最小限に抑えられます。

新たな進化:Stateless HTTPへの展望

MCPは現在も急速に進化しています。公式のロードマップ(MCP 2026-07-28 Release Candidateなど)では、従来のSSEをベースにしたステートフルな接続に加え、Stateless HTTP の仕様が提案されています。

なぜ「ステートレス」への拡張が必要なのでしょうか。その理由は、モダンなインフラストラクチャとの親和性にあります。従来のSSEは常時接続を維持するため、サーバーのメモリリソースを消費し続けます。これは、AWS Lambda、Vercel、Cloudflare Workersなどのサーバーレス(FaaS)環境やエッジコンピューティング環境とは相性が良くありません。

Stateless HTTP が導入されることで、以下のビジネス的・技術的メリットが生まれます。

  • スケーラビリティの向上: サーバー側でクライアントの接続状態(セッション)を保持する必要がないため、ロードバランサーによるリクエストの分散が極めて容易になります。
  • サーバーレスフレンドリー: 実行時間制限があるクラウド関数でも、オーバーヘッドなしでMCPサーバーを動かすことが可能になります。
  • 運用コストの削減: コネクションを維持するためのポーリングやキープアライブ処理が不要になり、クラウド利用料金の削減につながります。

この進化は、MCPをローカルの開発ツールや特定のLLMクライアントに閉じたものから、エンタープライズ領域における広大な分散システムのエコシステムへと引き上げる重要な一歩となります。

結論

MCPは、単なる「便利な接続ライブラリ」ではなく、AI時代における「情報と機能の共通インターフェース」です。JSON-RPC 2.0やStreamable HTTP、そして進化し続けるStateless HTTPといったWeb標準の技術をベースに据えることで、安全で拡張性が高く、そして何よりも将来にわたって陳腐化しない堅牢な設計を実現しています。この強固な基盤の上に構築されたエコシステムは、これからのAIエージェント開発において間違いなく中心的な役割を果たすことになるでしょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?