こんにちは。Enjoy IT Life管理人の@nishina555です。
AI エージェントの文脈で注目されている**MCP(Model Context Protocol)**ですが、自分でMCPサーバーを作成できると、AIに任意のツールやリソースを提供できるようになります。
この記事では、TypeScript SDKを使ったMCPサーバーの自作手順をまとめます。
プロジェクトの作成
まずはプロジェクトの初期化と必要なパッケージのインストールを行います。
mkdir example-mcp
cd example-mcp
npm install @modelcontextprotocol/sdk
npm install --save-dev typescript @types/node
npx tsc --init
package.json
{
"name": "example-mcp",
"version": "1.0.0",
"type": "module",
"scripts": {
"build": "tsc"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.9.0"
},
"devDependencies": {
"@types/node": "^22.14.1",
"typescript": "^5.8.3"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "node",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
MCPサーバーの基本構造
MCPサーバーの実装は大きく3つのステップで構成されます。
McpServer(またはServer)インスタンスの作成- サーバーに機能(tool / resource / prompt)を登録
- トランスポートとサーバーを接続して起動
// McpServerインスタンスの作成
const server = new McpServer({
name: "Echo",
version: "1.0.0",
capabilities: {
resources: {},
tools: {},
prompts: {},
},
});
// serverに機能を登録(後述)
// transportとserverの連携
const transport = new StdioServerTransport();
await server.connect(transport);
サーバーの3つの機能
MCPサーバーには以下の3つの機能を登録できます。
- tool — 外部APIを利用した検索や登録のように、何かしらのアクションを実行させる場合に使います
- resource — ドキュメント等のリソースを参照させる場合に使います
- prompt — プロンプトをテンプレート化する場合に使います
MCPサーバーの実装方法
MCPサーバーの実装には2つのスタイルがあります。
register形式(McpServerクラスの利用)
McpServerクラスを使うと、server.tool()、server.resource()、server.prompt()のように直感的にメソッドチェーンで機能を登録できます。
import {
McpServer,
ResourceTemplate,
} from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "Echo",
version: "1.0.0",
capabilities: {
resources: {},
tools: {},
prompts: {},
},
});
server.resource(
"echo",
new ResourceTemplate("echo://{message}", { list: undefined }),
async (uri, { message }) => ({
contents: [
{
uri: uri.href,
text: `Resource echo: ${message}`,
},
],
})
);
server.tool("echo", { message: z.string() }, async ({ message }) => ({
content: [{ type: "text", text: `Tool echo: ${message}` }],
}));
server.prompt("echo", { message: z.string() }, async ({ message }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Please process this message: ${message}`,
},
},
],
}));
const transport = new StdioServerTransport();
await server.connect(transport);
request_handler形式(Serverクラスの利用)
Serverクラスを使う場合は、setRequestHandlerメソッドでリクエストスキーマごとにハンドラを登録します。記述はやや冗長になりますが、より細かいコントロールが可能です。
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{
name: "Hello Resources",
version: "1.0.0",
},
{
capabilities: {
resources: {},
},
}
);
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: [
{
uri: "hello://world",
name: "Hello World Message",
description: "A simple greeting message",
mimeType: "text/plain",
},
],
};
});
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
if (request.params.uri === "hello://world") {
return {
contents: [
{
uri: "hello://world",
text: "Hello, World! This is my first MCP resource.",
},
],
};
}
throw new Error("Resource not found");
});
const transport = new StdioServerTransport();
await server.connect(transport);
McpServerクラスとServerクラスの違い
Serverクラスは低レベルなAPIで、細かいコントロールが可能な分、記述は冗長になります。公式のmodelcontextprotocol/serversリポジトリのコードを見るとServerクラスで実装されているものが多く、またMcpServerクラスはloggingに対応していないなどの制約があります。公式ドキュメントのResources、Prompts、ToolsのページのサンプルコードもいずれもServerクラスによる実装です。
McpServerクラスは細かい制御はできないものの記述が簡潔で、シンプルなMCPサーバーであればこちらで十分です。
ビルド
TypeScriptのコンパイルを実行します。
npx tsc
MCPクライアントに設定
ビルドしたJSファイルをMCPクライアント(Claude Desktop、Cursorなど)の設定に追加します。
{
"mcpServers": {
"example-mcp": {
"command": "node",
"args": ["/path/to/example-mcp/build/register-format/echo.js"]
}
}
}
argsにはビルド後のJSファイルのパスを指定してください。
MCPサーバーのデプロイ方法
作成したMCPサーバーを公開・配布する方法はいくつかあります。
- パターン1: npmで公開 —
npxコマンドで実行してもらう方法です - パターン2: GitHubで公開 — ソースコードをGitHubで公開し、cloneしてもらってDockerビルドやローカルビルドで起動してもらう方法です
- パターン3: ホスティングサービスに登録 — SmitheryなどのMCPサーバーのホスティングサービスに登録する方法です1
サンプルリポジトリ
この記事のサンプルコードは以下のリポジトリで公開しています。
参考
- MCPサーバー自作入門
- Building MCP Servers: Part 1 — Getting Started with Resources
- modelcontextprotocol/typescript-sdk(公式TypeScript SDK)
- For Server Developers - Model Context Protocol(公式クイックスタート)
- Example Servers - Model Context Protocol
- MCPサーバーの機能を全部(Prompt, Resource, Tool)試してみる