NestJS MCP サーバーモジュール

**モデル コンテキスト プロトコル (MCP)**を使用して、NestJS アプリケーションから AI 用のツール、リソース、プロンプトを簡単に公開できる NestJS モジュールです。
@rekog/mcp-nestを使用すると、NestJS で使い慣れた方法でツール、リソース、プロンプトを定義し、依存性注入の機能をフルに活用して、既存のコードベースを利用して複雑なエンタープライズ対応の MCP サーバーを構築できます。
特徴
Related MCP server: SSE MCP Server
インストール
npm install @rekog/mcp-nest @modelcontextprotocol/sdk zod
クイックスタート
1. モジュールのインポート
// app.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from '@rekog/mcp-nest';
import { GreetingTool } from './greeting.tool';
@Module({
imports: [
McpModule.forRoot({
name: 'my-mcp-server',
version: '1.0.0',
}),
],
providers: [GreetingTool],
})
export class AppModule {}
2. ツールとリソースを定義する
// greeting.tool.ts
import type { Request } from 'express';
import { Injectable } from '@nestjs/common';
import { Tool, Resource, Context } from '@rekog/mcp-nest';
import { z } from 'zod';
import { Progress } from '@modelcontextprotocol/sdk/types';
@Injectable()
export class GreetingTool {
constructor() {}
@Tool({
name: 'hello-world',
description:
'Returns a greeting and simulates a long operation with progress updates',
parameters: z.object({
name: z.string().default('World'),
}),
})
async sayHello({ name }, context: Context, request: Request) {
const userAgent = request.get('user-agent') || 'Unknown';
const greeting = `Hello, ${name}! Your user agent is: ${userAgent}`;
const totalSteps = 5;
for (let i = 0; i < totalSteps; i++) {
await new Promise((resolve) => setTimeout(resolve, 100));
// Send a progress update.
await context.reportProgress({
progress: (i + 1) * 20,
total: 100,
} as Progress);
}
return {
content: [{ type: 'text', text: greeting }],
};
}
@Resource({
uri: 'mcp://hello-world/{userName}',
name: 'Hello World',
description: 'A simple greeting resource',
mimeType: 'text/plain',
})
// Different from the SDK, we put the parameters and URI in the same object.
async getCurrentSchema({ uri, userName }) {
return {
content: [
{
uri,
text: `User is ${userName}`,
mimeType: 'text/plain',
},
],
};
}
}
完了です!
TIP
上記の例は、MCPツール内でHTTPRequestヘッダーにアクセスする方法を示しています。これは、ユーザーの識別、クライアント固有のロジックの追加など、様々なユースケースに役立ちます。その他の例については、認証テストをご覧ください。
STDIO のクイックスタート
主な違いは、モジュールをインポートするときにtransportオプションを指定する必要があることです。
McpModule.forRoot({
name: 'playground-stdio-server',
version: '0.0.1',
transport: McpTransportType.STDIO,
});
残りは通常通り、ツール、リソース、プロンプトを定義できます。STDIOトランスポートを使用したスタンドアロンのNestJSアプリケーションの例を以下に示します。
async function bootstrap() {
const app = await NestFactory.createApplicationContext(AppModule, {
logger: false,
});
return app.close();
}
void bootstrap();
次に、MCP サーバーを MCP Stdio クライアントと共に使用するか (例を参照)、プロジェクトをビルドした後に次の MCP クライアント構成で使用することができます。
{
"mcpServers": {
"greeting": {
"command": "node",
"args": [
"<path to dist js file>",
]
}
}
}
APIエンドポイント
HTTP + SSE トランスポートは 2 つのエンドポイントを公開します。
ストリーミング可能な HTTP トランスポートは、次のエンドポイントを公開します。
POST /mcp : すべてのMCP操作(ツール実行、リソースアクセスなど)のメインエンドポイント。ステートフルモードでは、セッションの作成と維持を行います。
GET /mcp : リアルタイム更新と進捗状況通知のための Server-Sent Events (SSE) ストリームを確立します。ステートフルモードでのみ利用可能です。
DELETE /mcp : MCPセッションを終了します。ステートフルモードでのみ使用できます。
ヒント
グローバル プレフィックス付きのモジュールを使用することもできますが、次のようにしてそれらのエンドポイントを除外することをお勧めします。
app.setGlobalPrefix('/api', { exclude: ['sse', 'messages', 'mcp'] });
認証
標準の NestJS Guards を使用して MCP エンドポイントを保護できます。
1. ガードを作成する
CanActivateインターフェースを実装します。ガードはリクエストの検証(JWTやAPIキーのチェックなど)を処理し、必要に応じてユーザー情報をリクエストオブジェクトに添付する必要があります。
特別なことは何もありません。詳細については、NestJS のドキュメントを確認してください。
2. ガードをつける
McpModule.forRoot設定にガードを渡してください。ガードは/sseと/messages両方のエンドポイントに適用されます。
// app.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from '@rekog/mcp-nest';
import { GreetingTool } from './greeting.tool';
import { AuthGuard } from './auth.guard';
@Module({
imports: [
McpModule.forRoot({
name: 'my-mcp-server',
version: '1.0.0',
guards: [AuthGuard], // Apply the guard here
}),
],
providers: [GreetingTool, AuthGuard], // Ensure the Guard is also provided
})
export class AppModule {}
以上です!残りはNestJS Guardsと同じです。
遊び場
playgroundディレクトリには、MCPと@rekog/mcp-nest機能を簡単にテストするためのサンプルが含まれています。詳細はplayground/README.mdを参照してください。
構成
McpModule.forRoot()メソッドは、サーバーの設定に使用するMcpOptionsオブジェクトを受け取ります。使用可能なオプションは以下のとおりです。
オプション | 説明 | デフォルト |
name
| 必須。MCP サーバーの名前。 | - |
version
| 必須。MCP サーバーのバージョン。 | - |
capabilities
| オプションのMCPサーバー機能をアドバタイズします。 @modelcontextprotocol/sdk を参照してください。 | undefined
|
instructions
| サーバーと対話する方法に関するクライアントへのオプションの指示。 | undefined
|
transport
| 有効にするトランスポート タイプを指定します。 | [McpTransportType.SSE, McpTransportType.STREAMABLE_HTTP, McpTransportType.STDIO]
|
sseEndpoint
| SSE 接続のエンドポイント パス ( SSE
トランスポートで使用)。 | 'sse'
|
messagesEndpoint
| メッセージを送信するためのエンドポイント パス ( SSE
トランスポートで使用されます)。 | 'messages'
|
mcpEndpoint
| MCP 操作の基本エンドポイント パス ( STREAMABLE_HTTP
トランスポートで使用されます)。 | 'mcp'
|
globalApiPrefix
| すべてのMCPエンドポイントのグローバルプレフィックス。既存のアプリケーションに統合する場合に便利です。 | ''
|
guards
| 認証/承認のために MCP エンドポイントに適用する NestJS ガード配列。 | []
|
decorators
| 生成された MCP コントローラーに適用する NestJS クラス デコレーターの配列。 | []
|
sse
| SSE
トランスポートに固有の構成。 | { pingEnabled: true, pingIntervalMs: 30000 }
|
sse.pingEnabled
| 接続を維持するために定期的な SSE ping メッセージを有効にするかどうか。 | true
|
sse.pingIntervalMs
| SSE ping メッセージを送信する間隔 (ミリ秒単位)。 | 30000
|
streamableHttp
| STREAMABLE_HTTP
トランスポートに固有の構成。 | { enableJsonResponse: true, sessionIdGenerator: undefined, statelessMode: true }
|
streamableHttp.enableJsonResponse
| true
の場合、 /mcp
エンドポイントは非ストリーミング リクエスト ( listTools
など) に対して JSON 応答を返すことができます。 | true
|
streamableHttp.sessionIdGenerator
| statelessMode
モードで実行しているときに一意のセッション ID を生成する関数。statelessMode が false
場合に必須です。 | undefined
|
streamableHttp.statelessMode
| true
の場合、 STREAMABLE_HTTP
トランスポートはステートレス(セッションなし)で動作します。 false
の場合、ステートフルで動作し、 sessionIdGenerator
が必要になります。 | true
|