Skip to main content
Glama
jhgaylor

Express MCP Handler

by jhgaylor

express-mcp-ハンドラー

モデル コンテキスト プロトコル (MCP)を Express アプリケーションに統合し、LLM とツール間のシームレスな通信を可能にするミドルウェア。

npmバージョン npmダウンロード ライセンス: MIT Node.js バージョン タイプスクリプト CI コードコフ

モデルコンテキストプロトコル (MCP) とは何ですか?

モデルコンテキストプロトコル(MCP)は、大規模言語モデル(LLM)を外部データソースやツールと統合するためのオープンプロトコルです。これにより、AIアシスタントは標準化されたインターフェースを介してリアルタイムデータにアクセスし、操作を実行し、さまざまなサービスと対話できるようになります。

Related MCP server: Memory Cache Server

特徴

  • ステートフル ハンドラー: 1 回限りのリクエストを処理したり、セッション ID と Server-Sent Events (SSE) を使用して長期間有効なセッションを維持したりできます。

  • ステートレス ハンドラー: 単純な 1 回限りのやり取りのために、各リクエストを完全に分離して処理します。

  • SSE ハンドラー: 専用の GET および POST エンドポイントを使用して、Server-Sent Events (SSE) 経由の Model Context Protocol (MCP) を処理します。

  • タイプセーフ API : 信頼性の高い統合のために TypeScript を使用して構築されています。

  • 柔軟な構成: カスタマイズ可能なエラー処理、セッション管理、ライフサイクル フック。

  • Express 統合: ミドルウェア パターンを使用して Express ルートに直接プラグインします。

インストール

npm 経由でインストール:

npm install express-mcp-handler

または糸:

yarn add express-mcp-handler

またはpnpm:

pnpm add express-mcp-handler

仲間への依存

このパッケージには次のピア依存関係が必要です。

  • express >= 4.0.0

  • @modelcontextprotocol/sdk >= 1.10.2

  • zod >= 3.0.0

まだインストールしていない場合はインストールしてください。

npm install express @modelcontextprotocol/sdk zod

クイックスタート

始めるための基本的な例を次に示します。

import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { statelessHandler } from 'express-mcp-handler';

const app = express();
app.use(express.json());

// Create a factory function that returns a new McpServer instance for each request
const serverFactory = () => new McpServer({
  name: 'my-mcp-server',
  version: '1.0.0',
});

// Mount the stateless handler
app.post('/mcp', statelessHandler(serverFactory));

app.listen(3000, () => {
  console.log('Express MCP server running on port 3000');
});

使用法

Express-mcp-handler は、さまざまなユースケースに合わせて 3 つのハンドラー タイプを提供します。

ステートフルモード

statefulHandlerを使用して、クライアントとサーバーの間で再利用可能なセッションを確立します。これは、複数のやり取りにわたってコンテキストを維持するのに最適です。

import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { statefulHandler } from 'express-mcp-handler';
import { randomUUID } from 'node:crypto';

const app = express();
app.use(express.json());

// Create an MCP server instance
const server = new McpServer({
  name: 'my-server',
  version: '1.0.0',
});

// Configure handler options
const handlerOptions = {
  sessionIdGenerator: randomUUID, // Function to generate unique session IDs
  onSessionInitialized: (sessionId: string) => {
    console.log(`Session initialized: ${sessionId}`);
    // You could store session metadata or initialize resources here
  },
  onSessionClosed: (sessionId: string) => {
    console.log(`Session closed: ${sessionId}`);
    // Perform cleanup logic here
  },
  onError: (error: Error, sessionId?: string) => {
    console.error(`Error in session ${sessionId}:`, error);
    // Handle errors for monitoring or logging
  }
};

// Mount the handlers for different HTTP methods
app.post('/mcp', statefulHandler(server, handlerOptions));
app.get('/mcp', statefulHandler(server, handlerOptions));
app.delete('/mcp', statefulHandler(server, handlerOptions));

app.listen(3000, () => {
  console.log('Express MCP server running on port 3000');
});

ステートフル ハンドラー:

  • 最初のリクエストで新しいセッションを初期化します( mcp-session-idヘッダーなし)

  • クライアントが後続のリクエストに含める必要があるmcp-session-idヘッダーを返します。

  • サーバーからクライアントにメッセージをプッシュするための Server-Sent Events (SSE) を管理します

  • セッションを閉じると自動的にクリーンアップされます

ステートレスモード

セッション管理のない 1 回限りのリクエスト処理にはstatelessHandler使用します。これは、サーバーレス環境や単純なリクエストに最適です。

import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { statelessHandler } from 'express-mcp-handler';

const app = express();
app.use(express.json());

// Function that creates a fresh McpServer for each request
const serverFactory = () => new McpServer({
  name: 'stateless-mcp-server',
  version: '1.0.0',
});

// Configure with custom error handling
const options = {
  onError: (error: Error) => {
    console.error('MCP error:', error);
    // Add custom error reporting logic here
  }
};

app.post('/mcp', statelessHandler(serverFactory, options));

app.listen(3000, () => {
  console.log('Express Stateless MCP server running on port 3000');
});

各ステートレス リクエスト:

  • 新しいトランスポートとサーバーのインスタンスを作成します

  • セッション追跡なしで完全な分離を保証

  • シンプルな環境やサーバーレス環境に適しています

SSEモード

sseHandlersを使用して、Server-Sent Events (SSE) 経由の Model Context Protocol (MCP) を処理します。これは、リアルタイムのストリーミング応答に最適です。

import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { sseHandlers } from 'express-mcp-handler';

const app = express();
app.use(express.json());

// Provide a factory function that returns a fresh McpServer for each SSE connection
const serverFactory = () => new McpServer({
  name: 'sse-mcp-server',
  version: '1.0.0',
});

// Configure SSE handlers
const handlers = sseHandlers(serverFactory, {
  onError: (error: Error, sessionId?: string) => {
    console.error(`[SSE][${sessionId || 'unknown'}]`, error);
  },
  onClose: (sessionId: string) => {
    console.log(`[SSE] transport closed: ${sessionId}`);
    // Clean up any session resources
  },
});

// Mount the SSE endpoints
app.get('/sse', handlers.getHandler);
app.post('/messages', handlers.postHandler);

app.listen(3002, () => {
  console.log('Express MCP SSE server running on port 3002');
});

SSE ハンドラーは以下を提供します。

  • GET /sse : SSEストリームを確立し、 mcp-session-idヘッダーを返します。

  • POST /messages : mcp-session-idクエリパラメータを使用して、SSEトランスポート経由でMCPメッセージを送信します。

APIリファレンス

ステートフルハンドラー

function statefulHandler(
  server: McpServer,
  options: {
    sessionIdGenerator: () => string;
    onSessionInitialized?: (sessionId: string) => void;
    onSessionClosed?: (sessionId: string) => void;
    onError?: (error: Error, sessionId?: string) => void;
    onInvalidSession?: (req: express.Request) => void;
  }
): express.RequestHandler;

パラメータ

タイプ

説明

server

McpServer

プロトコルロジックを処理するMcpServerのインスタンス

options.sessionIdGenerator

() => string

一意のセッションIDを返す関数

options.onSessionInitialized

(sessionId: string) => void

*(オプション)*新しいセッションIDで呼び出されるコールバック

options.onSessionClosed

(sessionId: string) => void

*(オプション)*セッションが閉じられたときに呼び出されるコールバック

options.onError

(error: Error, sessionId?: string) => void

*(オプション)*エラー時に呼び出されるコールバック

options.onInvalidSession

(req: express.Request) => void

*(オプション)*無効なセッションにアクセスしたときに呼び出されるコールバック

ステートレスハンドラー

function statelessHandler(
  serverFactory: () => McpServer,
  options?: {
    sessionIdGenerator?: () => string;
    onClose?: (req: express.Request, res: express.Response) => void;
    onError?: (error: Error) => void;
  }
): express.RequestHandler;

パラメータ

タイプ

説明

serverFactory

() => McpServer

リクエストごとに新しいサーバーインスタンスを返す関数

options.sessionIdGenerator

() => string

*(オプション)*トランスポートセッションID生成をオーバーライドする

options.onClose

(req: express.Request, res: express.Response) => void

*(オプション)*リクエスト/レスポンスサイクルが終了したときに呼び出されるコールバック

options.onError

(error: Error) => void

*(オプション)*処理中にエラーが発生したときに呼び出されるコールバック

sseハンドラ

function sseHandlers(
  serverFactory: ServerFactory,
  options: SSEHandlerOptions
): {
  getHandler: express.RequestHandler;
  postHandler: express.RequestHandler;
};

パラメータ

タイプ

説明

serverFactory

ServerFactory

SSE接続ごとに新しいMcpServerを返すファクトリー関数

options.onError

(error: Error, sessionId?: string) => void

*(オプション)*エラー時に呼び出されるコールバック。 errorとオプションのsessionIdを受け取ります。

options.onClose

(sessionId: string) => void

(オプション) SSEセッションが閉じられたときに呼び出されるコールバックは、 sessionIdを受け取ります。

エラー処理

すべてのハンドラー タイプは、オプションを通じてカスタム エラー処理をサポートします。

// Example of custom error handling for stateful handler
const handlerOptions = {
  // ... other options
  onError: (error: Error, sessionId?: string) => {
    console.error(`Error in session ${sessionId}:`, error);
    // Send error to monitoring service
    Sentry.captureException(error, {
      extra: { sessionId }
    });
  }
};

TypeScript サポート

このパッケージはTypeScriptで記述されており、すべてのエクスポートの型定義を提供します。TypeScriptを使用すると、完全なIntelliSenseと型チェックを利用できます。

import { statefulHandler, StatefulHandlerOptions } from 'express-mcp-handler';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

// Type-safe options
const options: StatefulHandlerOptions = {
  sessionIdGenerator: () => Date.now().toString(),
  onError: (error, sessionId) => {
    // TypeScript knows the types of these parameters
    console.error(`Error in session ${sessionId}:`, error);
  }
};

const server = new McpServer({
  name: 'typed-server',
  version: '1.0.0',
});

// Type-safe handler
app.post('/mcp', statefulHandler(server, options));

発達

このプロジェクトに貢献するには:

git clone https://github.com/jhgaylor/express-mcp-handler.git
cd express-mcp-handler
npm install
npm run build
npm test

テスト範囲

このプロジェクトはしっかりとしたテスト範囲をカバーしており、それを維持することを約束しています。

すべての変更は、テストには Jest、カバレッジ レポートには Codecov を使用して、CI/CD パイプラインを通じて検証されます。

継続的インテグレーション

このプロジェクトでは、継続的インテグレーションのためにGitHub Actionsを使用しています。メインブランチへのプッシュとプルリクエストごとに、以下の処理が行われます。

  1. リントチェックを実行する

  2. プロジェクトを構築する

  3. カバレッジ付きテストを実行する

  4. カバレッジレポートをCodecovにアップロードする

現在の CI ステータスは、この README の上部にあるバッジ、または GitHub リポジトリの[アクション] タブで確認できます。

ライセンス

MITライセンス

npmへの公開

まだ npm にログインしていない場合はログインしてください。

npm login

パッケージを npm に公開します (prepublishOnly ビルドが実行されます)。

npm publish

新しいバージョンをバンプ、タグ付け、プッシュするには:

npm version patch    # or minor, major
git push origin main --tags

ハンドラーの種類の概要

ハンドラ

シナリオ

セッション

ストリーミング

ステートレスハンドラー

1回限りまたはサーバーレスのワークロード

いいえ

いいえ

ステートフルハンドラー

マルチターンインタラクション

はい

はい

sseハンドラ

リアルタイムSSEストリーミング

はい

はい

トラブルシューティング

mcp-session-id
クライアントが最初のリクエストで返されたmcp-session-idヘッダーを含んでいることを確認します。

トランスポート接続が予定より早く終了しました
ネットワーク接続を確認し、クライアントが SSE イベントを適切に処理していることを確認します。

変更履歴

このプロジェクトに対するすべての注目すべき変更はCHANGELOG.mdに記録されています。

-
security - not tested
F
license - not found
-
quality - not tested

Resources

Looking for Admin?

Admins can modify the Dockerfile, update the server description, and track usage metrics. If you are the server author, to access the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jhgaylor/express-mcp-handler'

If you have feedback or need assistance with the MCP directory API, please join our Discord server