Agent Skills by ALSEL
Anthropic ClaudeLLM・AI開発⭐ リポ 0品質スコア 70/100

mcp-protocol-server-implementation

公式の@modelcontextprotocol/sdkクライアントと連携するMCP(Model Context Protocol)サーバー実装の要件です。以下の場合に使用してください:(1)MCPサーバーをゼロから実装する、(2)「Expected initialize response」エラーが発生する、(3)MCPクライアントが接続できない、またはタイムアウトする、(4)tools/listは成功するがクライアントがサーバーを認識しない、(5)MCP Streamable HTTPトランスポートを実装する。initializeメソッド、通知処理、SSEレスポンス形式、セッション管理について解説します。

description の原文を見る

Requirements for implementing an MCP (Model Context Protocol) server that works with the official @modelcontextprotocol/sdk client. Use when: (1) implementing an MCP server from scratch, (2) getting "Expected initialize response" errors, (3) MCP client fails to connect or times out, (4) tools/list returns successfully but client doesn't recognize server, (5) implementing MCP Streamable HTTP transport. Covers initialize method, notification handling, SSE response format, and session management.

SKILL.md 本文

MCPプロトコルサーバー実装

問題

カスタムMCPサーバーを実装する場合、公式のMCP SDKクライアント(@modelcontextprotocol/sdk)のStreamableHTTPClientTransportが接続に失敗したり、タイムアウトしたりすることがあります。これはtools/listが正しいJSON-RPC応答を返している場合でも発生します。

コンテキスト / トリガー条件

  • カスタムMCPサーバー(Lambda、Express等)を一から構築している
  • @modelcontextprotocol/sdkからStreamableHTTPClientTransportを使用している
  • クライアントが「Expected initialize response」エラーをスローする
  • 接続中にクライアントがタイムアウトする
  • サーバーがtools/listの有効なJSON-RPCを返すが、クライアントが機能しない
  • tools/listへの直接curlは機能するが、SDKクライアントは失敗する

ソリューション

1. initializeメソッドを処理する(必須)

SDKクライアントは最初のリクエストとしてinitializeを送信します。サーバーは以下のように応答する必要があります。

if (method === "initialize") {
  return {
    jsonrpc: "2.0",
    id,
    result: {
      protocolVersion: "2024-11-05", // Current MCP protocol version
      serverInfo: {
        name: "your-server-name",
        version: "1.0.0",
      },
      capabilities: {
        tools: {}, // Indicates server supports tools
      },
    },
  };
}

2. 通知を処理する(必須)

クライアントはinitialize後にnotifications/initializedを送信します。JSON-RPC 2.0仕様に従い、通知にはidフィールドがなく、サーバーは応答ボディを送信してはいけません。

// Check if message is a notification
function isNotification(message: McpRequest): boolean {
  return message.id === undefined;
}

// In handler:
if (isNotification(mcpRequest)) {
  // Return 202 Accepted with empty body
  return { statusCode: 202, headers, body: "" };
}

3. SSE応答フォーマット(推奨)

クライアントがAccept: text/event-streamを送信する場合、SSE形式で応答します。

function formatAsSSE(response: McpResponse): string {
  return `event: message\ndata: ${JSON.stringify(response)}\n\n`;
}

function clientAcceptsSSE(acceptHeader: string | undefined): boolean {
  return acceptHeader?.includes("text/event-stream") ?? false;
}

// Set Content-Type accordingly
const contentType = useSSE ? "text/event-stream" : "application/json";

4. セッション管理(推奨)

mcp-session-idヘッダーを介してセッションを追跡します。

const incomingSessionId = headers["mcp-session-id"];
const sessionId = incomingSessionId ?? randomUUID();

// Include in response headers
responseHeaders["mcp-session-id"] = sessionId;
responseHeaders["Access-Control-Expose-Headers"] = "mcp-session-id";

5. CORSヘッダー(ブラウザクライアント必須)

const headers = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers":
    "Content-Type,Authorization,mcp-session-id,mcp-protocol-version",
  "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
  "Access-Control-Expose-Headers": "mcp-session-id",
  "Cache-Control": "no-cache",
};

検証

  1. まずcurlでテストします:
# Test initialize
curl -X POST https://your-server/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'

# Should return protocolVersion, serverInfo, capabilities

# Test tools/list
curl -X POST https://your-server/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
  1. 次にMCP SDKクライアントでテストします:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "test", version: "1.0.0" });
const transport = new StreamableHTTPClientTransport(
  new URL("https://your-server/mcp"),
);
await client.connect(transport);
const tools = await client.listTools();

最小限のMCPサーバーハンドラー完全版:

export function handler(event: APIGatewayProxyEvent): APIGatewayProxyResult {
  const headers = { "Content-Type": "application/json" /* CORS headers */ };

  if (event.httpMethod === "OPTIONS") {
    return { statusCode: 200, headers, body: "" };
  }

  const request = JSON.parse(event.body ?? "{}");

  // Handle notifications (no id = notification)
  if (request.id === undefined) {
    return { statusCode: 202, headers, body: "" };
  }

  // Handle methods
  switch (request.method) {
    case "initialize":
      return {
        statusCode: 200,
        headers,
        body: JSON.stringify({
          jsonrpc: "2.0",
          id: request.id,
          result: {
            protocolVersion: "2024-11-05",
            serverInfo: { name: "my-server", version: "1.0.0" },
            capabilities: { tools: {} },
          },
        }),
      };

    case "tools/list":
      return {
        statusCode: 200,
        headers,
        body: JSON.stringify({
          jsonrpc: "2.0",
          id: request.id,
          result: { tools: MY_TOOLS },
        }),
      };

    case "tools/call":
      // Handle tool execution
      break;

    default:
      return {
        statusCode: 200,
        headers,
        body: JSON.stringify({
          jsonrpc: "2.0",
          id: request.id,
          error: {
            code: -32601,
            message: `Method not found: ${request.method}`,
          },
        }),
      };
  }
}

注記

  • プロトコルバージョン: 2026年初頭の時点では2024-11-05を使用します。MCPスペックで更新を確認してください。
  • JSON-RPCエラーコード:
    • -32700: パースエラー
    • -32600: 無効なリクエスト
    • -32601: メソッドが見つかりません
    • -32603: 内部エラー
  • メソッド呼び出し順序: クライアントは常に最初にinitializeを送信し、次にnotifications/initializedを送信してから、tools/listなどの他のメソッドを送信します。
  • タイムアウトの問題: クライアントがタイムアウトする場合は、initializeの応答が正しいことを確認してください。これが最も一般的な原因です。

参考資料

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
cajias
リポジトリ
cajias/claude-skills
ライセンス
MIT
最終更新
2026/5/9

Source: https://github.com/cajias/claude-skills / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: cajias · cajias/claude-skills · ライセンス: MIT