サイコロのイラスト

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 で実装した SDK
  • zod: バリデーションライブラリ。ツールのインターフェイスを定義するために使用する
npm install agents @modelcontextprotocol/sdk zod

MCP ツールを実装する

MCP サーバーが提供するツールを実装します。ここではサイコロをランダムに振った値を返す dice_roll ツールを実装します。サイコロの面を指定するための sides 引数を受け取ります。

MCPAgent クラスを継承した MyMcp クラスを作成し、init メソッド内でツールを定義します。src/MyMcp.ts ファイルを作成し、以下のコードを追加します。

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 関数を使用してリクエストを受け取ります。

index.ts
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 という名前を指定する必要があります。

wrangler.jsonc
{
  "migrations": [
		{
			"new_sqlite_classes": [
				"MyMCP"
			],
			"tag": "v1"
		}
	],
	"durable_objects": {
		"bindings": [
			{
				"class_name": "MyMCP",
				"name": "MCP_OBJECT"
			}
		]
	},
}

ローカルで実行する

以下のコマンドでローカルでサーバーを実行します。

npm run dev

Warning

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.jsoncMCP_OBJECT を指定する
  • McpAgent.serve() メソッドを使用すると MCP サーバーを Streamable HTTP で起動できる
  • McpAgent.serveSSE() メソッドを使用すると MCP サーバーを SSE で起動できる
  • MCP Inspector を使用すると MCP サーバーのデバッグができる

参考

記事の理解度チェック

以下の問題に答えて、記事の理解を深めましょう。

MCPAgent クラスを継承したクラスで MCP サーバーのツールの定義を行うメソッドはどれですか?

  • constructor

    もう一度考えてみましょう

  • start

    もう一度考えてみましょう

  • run

    もう一度考えてみましょう

  • init

    正解!