TypeScriptによるMCPサーバー実装の基本構成とTool追加の具体手順
Model Context Protocol(MCP)は、LLM(大規模言語モデル)アプリケーションと外部データソースやツールを安全に接続するための標準プロトコルです。
この記事では、TypeScriptと公式の@modelcontextprotocol/sdkを用いて、独自のMCPサーバーを構築する基本構成と、実務で使えるToolを追加する手順を解説します。
この記事で分かること
- TypeScriptによるMCPサーバーのプロジェクト基本構成
-
@modelcontextprotocol/sdkを使用したStdio接続サーバーの最小実装 - 入力スキーマを定義して独自のToolを追加・処理する実装手順
- 実装時の注意点と動作確認用チェックリスト
前提条件
- Node.js (v18以上推奨)
- TypeScriptの基本知識
- npm または pnpm などのパッケージマネージャ
※MCPの仕様やSDKは更新される可能性があるため、実装時には最新の公式ドキュメントおよびリポジトリを確認してください。
プロジェクトのセットアップ
まず、プロジェクトディレクトリを作成し、必要なパッケージをインストールします。
mkdir mcp-ts-server-demo
cd mcp-ts-server-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
npx tsc --init
tsconfig.jsonの主要設定を調整します。
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
基本実装:MCPサーバーの構築
標準入出力(Stdio)を介して通信するMCPサーバーの基本コードを作成します。
プロジェクト構成
mcp-ts-server-demo/
├── src/
│ └── index.ts
├── package.json
└── tsconfig.json
src/index.ts の実装例
以下のコードは、サーバーの初期化、Toolの登録、並びにStdioトランスポートによる起動処理を行います。
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
// 1. サーバーインスタンスの生成
const server = new Server(
{
name: "custom-ts-mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// 2. 利用可能なToolの一覧を定義
const FETCH_USER_TOOL = {
name: "fetch_user_info",
description: "指定されたユーザーIDに対応するユーザー情報を取得します(独自実装例)。",
inputSchema: {
type: "object",
properties: {
userId: {
type: "string",
description: "取得対象のユーザーID",
},
},
required: ["userId"],
},
};
// Zodによる入力値検証用スキーマ
const FetchUserInfoSchema = z.object({
userId: z.string(),
});
// 3. Tool一覧要求(tools/list)のハンドラー設定
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [FETCH_USER_TOOL],
};
});
// 4. Tool実行要求(tools/call)のハンドラー設定
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "fetch_user_info") {
// 入力引数の検証
const parsed = FetchUserInfoSchema.safeParse(args);
if (!parsed.success) {
throw new Error(`無効な引数です: ${parsed.error.message}`);
}
const { userId } = parsed.data;
// 実際の業務ロジックの呼び出し(ここではダミーデータを返却)
const userInfo = {
id: userId,
name: `User-${userId}`,
role: "Developer",
};
return {
content: [
{
type: "text",
text: JSON.stringify(userInfo, null, 2),
},
],
};
}
throw new Error(`未定義のToolが呼び出答されました: ${name}`);
});
// 5. トランスポートの設定と起動
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
// 標準エラー出力ログを出力(stdoutは通信に使用するためログ出力には使用しない)
console.error("MCP TypeScript Server is running on stdio");
}
main().catch((error) => {
console.error("Fatal error running server:", error);
process.exit(1);
});
クライアント設定例(Claude Desktopの場合)
作成したMCPサーバーをローカルのClaude Desktop環境などで読み込ませる場合の設定例です。
※環境に合わせてビルドパスやnodeコマンドのパスを書き換えてください。
claude_desktop_config.json への記述例:
{
"mcpServers": {
"my-ts-server": {
"command": "node",
"args": [
"/絶対パス/mcp-ts-server-demo/node_modules/tsx/dist/cli.mjs",
"/絶対パス/mcp-ts-server-demo/src/index.ts"
]
}
}
}
実装時・運用時の注意点
-
標準出力(
console.log)の使用禁止- Stdioトランスポートでは、
process.stdoutがJSON-RPCメッセージの伝送に使用されます。console.logを呼び出すと通信データが壊れ、クライアント側でパースエラーが発生します。デバッグログを出力する場合は必ずconsole.errorを使用してください。
- Stdioトランスポートでは、
-
機密情報の取り扱い
- APIキーやアクセストークンなどの認証情報は、ソースコードにハードコーディングせず、環境変数(
process.env)から読み込む構造にしてください。
- APIキーやアクセストークンなどの認証情報は、ソースコードにハードコーディングせず、環境変数(
-
エラーハンドリング
- Tool内部で発生した例外は適切にキャッチし、LLM側で原因が理解しやすいエラーメッセージまたはエラー構造体をレスポンスとして返却してください。
導入・実装チェックリスト
実装およびデプロイ前に確認すべきチェックリストです。
-
console.logを使わず、ログ出力にconsole.errorを使用しているか - ツール入力値のバリデーション(Zod等)を行っているか
- 存在しないTool名が渡された際のフォールバック処理が存在するか
- APIキー等の機密情報を環境変数から読み込む構成になっているか
-
tsconfig.jsonのモジュール解釈設定(NodeNext等)が適切か
まとめ
TypeScriptでMCPサーバーを実装する際は、@modelcontextprotocol/sdk を利用することで、標準仕様に基づいたToolの公開が容易に行えます。標準入出力を破壊しないログ出力管理や、Zod等による入出力の型チェックを徹底し、安全で保守性の高いMCPサーバーを構築しましょう。