
Cloudflare で MCP サーバーを構築する
Model Context Protocol (MCP) の 2025-03-26 の仕様では新たに Streamable HTTP が追加され、リモート MCP サーバーへの注目が集まっています。この記事では `agents` フレームワークを使用して Cloudflare 上に MCP サーバーを構築する方法を紹介します。
音声による概要
この音声概要は AI によって生成されており、誤りを含む可能性があります。
Model Context Protocol (MCP) の 2025-03-26 の仕様では新たに Streamable HTTP が追加され、リモート MCP サーバーへの注目が集まっています。従来の MCP サーバーは stdio を使用してローカルで実行されることが一般的であったため、デスクトップアプリケーションや CLI ツールのみで利用されるなど、利用シーンが限られていました。
Streamable HTTP を使用することで、リモートの MCP サーバーを Web アプリケーションから利用されることが期待されます。Claude の Web 版ではリモート MCP サーバー経由で MCP サーバーにアクセスできるようになったことが発表されています。
この記事では Cloudflare 上に MCP サーバーを構築する方法を紹介します。完成したコードは以下のリポジトリで確認できます。
Cloudflare プロジェクトを作成する
まずは以下のコマンドを実行して Cloudflare プロジェクトを作成します。
npm create cloudflare@latest my-mcp-server
対話形式でプロジェクトの設定を行います。SSE での応答を行うために Worker + Durable Objects
を選択します。
╭ Create an application with Cloudflare Step 1 of 3
│
├ In which directory do you want to create your application?
│ dir ./my-mcp-server
│
├ What would you like to start with?
│ category Hello World example
│
├ Which template would you like to use?
│ type Worker + Durable Objects
│
├ Which language do you want to use?
│ lang TypeScript
│
├ Copying template files
│ files copied to project directory
│
├ Updating name in `package.json`
│ updated `package.json`
│
┴ Installing dependencies
続いて以下のパッケージをインストールします。
agents
: Cloudflare 上で AI エージェントを構築するためのフレームワーク@modelcontextprotocol/sdk
: MCP の仕様を TypeScript で実装した SDKzod
: バリデーションライブラリ。ツールのインターフェイスを定義するために使用する
npm install agents @modelcontextprotocol/sdk zod
MCP ツールを実装する
MCP サーバーが提供するツールを実装します。ここではサイコロをランダムに振った値を返す dice_roll
ツールを実装します。サイコロの面を指定するための sides
引数を受け取ります。
MCPAgent
クラスを継承した MyMcp
クラスを作成し、init
メソッド内でツールを定義します。src/MyMcp.ts
ファイルを作成し、以下のコードを追加します。
import { McpAgent } from 'agents/mcp';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
export class MyMCP extends McpAgent {
server = new McpServer({
name: 'MyMCP Server',
version: '0.1.0',
});
async init() {
this.server.tool(
// ツールの名前
'dice_roll',
// ツールの説明
'サイコロを降った結果を返します',
// ツールの引数のスキーマ
{ sides: z.number().min(1).max(100).default(6).describe('サイコロの面の数') },
// ツールの実行関数
async ({ sides }) => {
// サイコロを振る
const result = Math.floor(Math.random() * sides) + 1;
// 結果を返す
return {
content: [{ type: 'text', text: result.toString() }],
};
}
);
}
}
エントリーポイントである src/index.ts
ファイルを編集します。Cloudflare Workers では fetch
関数を使用してリクエストを受け取ります。
import { MyMCP } from './MyMcp.js';
// Durable Objects のエクスポート
export { MyMCP };
export default {
fetch(request: Request, env: Env, ctx: ExecutionContext) {
const url = new URL(request.url);
// /sse エンドポイントの場合は SSE で応答する
if (url.pathname === '/sse' || url.pathname === '/sse/message') {
// @ts-ignore
return MyMCP.serveSSE('/sse').fetch(request, env, ctx);
}
// /mcp エンドポイントの場合は Streamable HTTP で応答する
if (url.pathname === '/mcp') {
// @ts-ignore
return MyMCP.serve('/mcp').fetch(request, env, ctx);
}
return new Response('Not found', { status: 404 });
},
};
MyMCP
クラスの serve()
メソッドを使用すると MCP サーバーを Streamable HTTP で起動できます。後方互換性のために SSE での応答もサポートする必要があります。/sse
エンドポイントでは SSE での応答を行い、/mcp
エンドポイントでは Streamable HTTP での応答を行います。
最後に Durable Objects を使用するために wrangler.jsonc
を編集します。McpAgent
クラスを使用する場合には、MCP_OBJECT
という名前を指定する必要があります。
{
"migrations": [
{
"new_sqlite_classes": [
"MyMCP"
],
"tag": "v1"
}
],
"durable_objects": {
"bindings": [
{
"class_name": "MyMCP",
"name": "MCP_OBJECT"
}
]
},
}
ローカルで実行する
以下のコマンドでローカルでサーバーを実行します。
npm run dev
Uncaught Error: No such module "node:async_hooks".
というエラーが発生する場合は wrangler.jsonc
に "compatibility_flags": ["nodejs_compat"],
を追加してください。
正しく MCP サーバーを構築できているか確認するために MCP Inspector を使用しましょう。これは GUI ベースで MCP サーバーのデバッグを行うためのツールです。
npx @modelcontextprotocol/inspector
http://127.0.0.1:6274 にアクセスして MCP Inspector を開きます。「Transport Type」で「Streamable HTTP」を選択し、URL 欄に http://localhost:8787/mcp
を入力して「Connect」ボタンをクリックします。
「List Tools」ボタンをクリックすると、実装した dice_roll
ツールが表示されます。「Run Tool」ボタンをクリックすると、ツールを実行できます。結果が表示されていることを確認してください。
同様に /sse
エンドポイントでも動作することを確認します。「Transport Type」を「SSE」に変更し、URL 欄に http://localhost:8787/sse
を入力して「Connect」ボタンをクリックします。
デプロイする
ローカルで動作することが確認できたら、Cloudflare にデプロイしましょう。以下のコマンドを実行します。
npm run deploy
ブラウザが起動し Cloudflare へのログインが求められます。ログインが完了するとターミナル上でデプロイが実行されます。
npm run deploy
> [email protected] deploy
> wrangler deploy
⛅️ wrangler 4.14.4
-------------------
Attempting to login via OAuth...
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth...
Successfully logged in.
Total Upload: 477.30 KiB / gzip: 89.85 KiB
Worker Startup Time: 23 ms
Your Worker has access to the following bindings:
- Durable Objects:
- MCP_OBJECT: MyMCP
Uploaded my-mcp-server (2.04 sec)
Deployed my-mcp-server triggers (0.91 sec)
https://my-mcp-server.azukiazusa.workers.dev
デプロイが完了すると、URL が表示されます。MCP Inspector を使用して、デプロイした MCP サーバーに接続してみましょう。
Workers AI LLM Playground を使用して LLM とリモート MCP サーバーの連携を試すことができます。「MCP Server」の URL 欄に https://${your-subdomain}.workers.dev/sse
を入力します(Streamable HTTP はまだサポートされていません)。
「100 面のサイコロを振ってください」といったプロンプトを入力すると、dice_roll
ツールが実行され、結果が表示されます。
まとめ
agents
パッケージを使用すると Cloudflare 上で簡単に MCP サーバーを構築できるMcpAgent
クラスを継承したクラスを作成し、init
メソッド内でツールを定義する- Durable Objects を使用する場合は
wrangler.jsonc
にMCP_OBJECT
を指定する McpAgent.serve()
メソッドを使用すると MCP サーバーを Streamable HTTP で起動できるMcpAgent.serveSSE()
メソッドを使用すると MCP サーバーを SSE で起動できる- MCP Inspector を使用すると MCP サーバーのデバッグができる