Back to list
Cloudflare Workers に VibeKanban 活用して x402 MCP サーバーを開発・デプロイする
Developing and Deploying an x402 MCP Server to Cloudflare Workers using VibeKanban!
Translated: 2026/3/21 7:00:25
Japanese Translation
はじめまして!Cloudflare Workers について初めて深く学びましたので、その学習成果とデプロイプロセスを記事にしてみました。本稿では、実装に伴った試行錯誤と、Cloudflare Workers への MCP サーバーデプロイ方法について解説します。
Cloudflare Workers は、Cloudflare 提供のサーバーレスコンピューティングプラットフォームです。バンドルサイズなどの制約はあるものの、フロントエンドアプリのような感で TypeScript/JavaScript アプリが簡単にデプロイできる点が魅力です。また、KV や D1 などの主要な Cloudflare サービスとシームレスに統合されています。
Hono は、TypeScript/JavaScript で主に開発される、軽量で高速でモダンなウェブアプリおよび API フレームワークです。その軽量かつ高速な特徴により、Cloudflare Workers と極めて互換性が高いです。
Vibe Kanban は、Claude Code や Codex などの AI コーディングエージェントをカンバン形式(タスク可視化)で管理し、自動化された開発フローを実現するためのツールです。
今回の実装では、以下の開発ワークフローを実践しました:
1. 製品ビジョンとコンセプトの策定
2. cc-sdd で要件定義書・設計書・タスクリストの作成
3. VibeKanban(GitHub Issues として)にタスクの登録
4. git worktree を用いた作業ディレクトリの準備
5. タスクの並列実行
6. 自己レビューと PR の作成
コードレビューには CodeRabbit を使用し、cc-sdd で生成されたタスクを VibeKanban タスクに変換するためのプロンプトは以下の通りです。
"@(cc-sdd) で生成されたタスクリストを参照し、作業計画を vibe_kanban のタスクとして登録してください。各タスクには以下の内容を含めてください:
- 設計詳細については @design.md を参照してください。
- そのタスクの具体的な作業内容。
- 他のタスクとの依存関係や、並行作業が可能なかどうか。
- 並列実行が可能な場合、タイトルに + を追加してください。
"
これらのタスクを降順に登録でき、それを直接 GitHub Issue に変換できるのが最大の特徴です。
x402 は、米国有数の仮想通貨取引所の Coinbase によって発表されたステーブルコイン決済の標準プロトコルです。真にその名前通り、HTTP ステータスコード 402 "Payment Required" を採用しており、HTTP プロトコルのコンプライアンスにより注目されています。Cloudflare は x402 フォンドーションの共同設立者となっており、AI エージェントとの互換性から、さまざまなブロックチェーンテックスタックにおいて多大な関心を集めています。
本稿では、Cloudflare Workers 上に x402 バックエンドサーバーと MCP サーバーを開発・デプロイし、チャットインターフェース(GPT App)を通じて気象情報を取得する際に同時にステーブルコイン決済が処理されるサンプルアプリを構築しました。
【実装できること】
- GPT App から get_weather ツールを呼び出して気象情報を取得する
- x402 決済検証を通過したリクエストのみが /weather にアクセスできる
- x402server と mcpserver を Cloudflare Workers 上で別々にデプロイする
- E2E テストで mcpserver -> x402FetchClient -> x402server の統合動作を検証する
このプロジェクトのソースコードは、以下の GitHub リポジトリで公開されています。
vibeKanban-gitworktree-sample
【VibeKanban と GitWorktree を組み合わせたサンプルアプリ概要】
x402 バックエンドサーバーと MCP サーバーを用い、GPT App 内のチャットインターフェースから気象予報情報を取得すると同時にステーブルコイン決済が行われるサンプルアプリです。
【このプロジェクトでできること】
- GPT App から get_weather ツールを呼び出して天気情報を取得する
- x402 による支払い検証を通過したリクエストのみ /weather にアクセスできる
- Cloudflare Workers 上で x402server と mcpserver を分離してデプロイする
- E2E テストで mcpserver -> x402FetchClient -> x402server の結合動作を検証する
【構成】
【リポジトリ構成】
| パス | 役割 | 主な技術 |
| :--- | :--- | :--- |
| pkgs/x402server | 天気 API と x402 決済検証を提供するバックエンド | Hono, x402, Cloudflare Workers, TypeScript |
| pkgs/mcpserver | GPT App から呼び出される MCP サーバー(x402server を決済付きで呼び出す) | Hono, MCP, MCP SDK, x402 fetch, Cloudflare Workers, TypeScript |
| pkgs/*/__tests__ | 単体・結合テスト群 | Vitest |
| ルート (package.json) | monorepo の共通スクリプト・ワークスペース管理 | pnpm, workspace |
【リクエストの流れ】
1. GPT App から MCP ツール get_weather を実行
2. mcpserver が x402-fetch-client を用いて /weather を呼び出す
3. x402server が paymentMiddleware で支払いを検証
4. 検証後に天気データを返却
【機能一覧】
| 機能 | 概要 | 提供パッケージ | 補足 |
| :--- | :--- | :--- | :--- |
| ヘルスチェック API | サービス稼働確認(/, /health) | x402server, mcpserver | 監視・疎通確認に利用 |
| 天気情報取得 API | 都市名を指定して気象情報を取得 | mcpserver | |
Original Content
Introduction Hello everyone! I recently properly studied Cloudflare Workers for the first time, so I'm writing this article to share my findings! This post will cover what I tried during implementation and how to deploy an MCP server to Cloudflare Workers! cloudflare.com Cloudflare Workers is a serverless computing platform provided by Cloudflare. While there are some constraints like bundle size, its charm lies in the ease of deploying TypeScript/JavaScript apps with a frontend-like feel! It also integrates seamlessly with other major Cloudflare services like KV and D1. hono.dev Hono is a lightweight, fast, and modern web framework for developing web applications and APIs, primarily in TypeScript/JavaScript. Being fast and lightweight, it is extremely compatible with Cloudflare Workers! Vibe Kanban is a tool that manages AI coding agents (like Claude Code or Codex) in a Kanban format (task visualization) to realize automated development flows! I practiced the following development workflow for this implementation: 0. Formulate product vision and concept. 1. Create requirements, design documents, and task lists with cc-sdd. 2. Register tasks in VibeKanban (register as GitHub Issues). 3. Prepare working directories with git worktree. 4. Parallel execution of tasks. 5. Self-review deliverables and create PRs. I used CodeRabbit for code reviews! I used a prompt like this to convert tasks generated by cc-sdd into VibeKanban tasks: Review the task list generated by @(cc-sdd) and register the work plan as Tasks in vibe_kanban. Each task should include: - Refer to @design.md for design details. - Specific work content for this task. - Dependencies on other tasks or if parallel work is possible. - If it can be executed in parallel, add a + to the title. Register tasks in descending order. The best part is being able to turn them directly into GitHub Issues! x402.org x402 is a standard protocol for stablecoin payments announced by Coinbase, a prominent cryptocurrency exchange in the US. True to its name, it adopts the HTTP status code 402 Payment Required and has gained significant attention for its compliance with the HTTP protocol. Cloudflare has not only co-founded the x402 Foundation but, given its compatibility with AI agents, it's a technology that has garnered immense interest within various blockchain tech stacks. I developed and deployed an x402 backend server and an MCP server on Cloudflare Workers. I created a sample app where stablecoin payments are processed simultaneously when weather information is retrieved through a chat interface within a GPT App! What it can do: Call the get_weather tool from a GPT App to retrieve weather information. Access /weather only for requests that have passed x402 payment verification. Deploy x402server and mcpserver separately on Cloudflare Workers. Verify the integrated operation of mcpserver -> x402FetchClient -> x402server via E2E tests. The source code for this project is available in the following GitHub repository: / vibekanban-gitworktree-sample vibekanban-gitworktree-sample VibeKanbanとGitWorktreeを掛け合わせたサンプルアプリ 概要 x402バックエンドサーバーとMCPサーバーを使ってGPT App内のチャットインターフェースから天気予報の情報を取得すると同時にステーブルコイン支払いが行われるサンプルアプリ。 このプロジェクトでできること GPT App から get_weather ツールを呼び出して天気情報を取得 x402 による支払い検証を通過したリクエストのみ /weather にアクセス Cloudflare Workers 上で x402server と mcpserver を分離デプロイ E2E テストで mcpserver -> x402FetchClient -> x402server の結合動作を検証 構成 リポジトリ構成 パス 役割 主な技術 pkgs/x402server 天気 API と x402 決済検証を提供するバックエンド Hono / x402 / Cloudflare Workers / TypeScript pkgs/mcpserver GPT App から呼び出される MCP サーバー。x402server を決済付きで呼び出す Hono MCP / MCP SDK / x402 fetch / Cloudflare Workers / TypeScript pkgs/*/__tests__ 単体・結合テスト群 Vitest ルート (package.json) monorepo の共通スクリプト・ワークスペース管理 pnpm workspace リクエストの流れ GPT App から MCP ツール get_weather を実行 mcpserver が x402-fetch-client で /weather を呼び出し x402server が paymentMiddleware で支払いを検証 検証後に天気データを返却 機能一覧 機能 概要 提供パッケージ 補足 ヘルスチェック API サービス稼働確認 (/, /health) x402server, mcpserver 監視・疎通確認に利用 天気情報取得 API 都市名を受けて天気を返却 (/weather) x402server 都市未登録時は 404 x402 課金付きアクセス制御 /weather を課金保護し未決済時は 402 を返却 x402server 価格・ネットワークは環境変数で設定 MCP ツール公開 get_weather ツールを外部クライアントへ公開 mcpserver 入力検証・エラー整形を実施 x402 決済付き fetch クライアント 支払い情報付きで x402server を呼び出す mcpserver Service Binding … View on GitHub Path Role Key Technologies pkgs/x402server Backend providing Weather API and x402 payment verification. Hono / x402 / Cloudflare Workers / TypeScript pkgs/mcpserver MCP server called by GPT App. Calls x402server with payment. Hono MCP / MCP SDK / x402 fetch / Cloudflare Workers / TypeScript Root (package.json) Common scripts and workspace management for the monorepo. pnpm workspace Feature Overview Provided Package Notes Health Check API Service availability check (/, /health). x402server, mcpserver Used for monitoring and connectivity checks. Weather Info API Returns weather based on city name (/weather). x402server Returns 404 if city is not registered. x402 Paid Access Control Protects /weather and returns 402 if unpaid. x402server Price and network configured via env vars. MCP Tool Exposure Exposes get_weather tool to external clients. mcpserver Performs input validation and error formatting. x402 Payment-enabled Fetch Client Calls x402server with payment information. mcpserver Supports both Service Binding and URLs. E2E Integration Test Verifies flow from MCP to backend. mcpserver tests Confirms 402/404/Success cases. Let's pick up and introduce some important implementation parts. First, the x402 server! You need to set environment variables in wrangler.jsonc. Since there's no highly sensitive information here, I'm not using the Secret feature for these. { "$schema": "node_modules/wrangler/config-schema.json", "name": "x402server", "main": "src/index.ts", "compatibility_date": "2026-02-23", "compatibility_flags": ["nodejs_compat"], "vars": { "SERVER_WALLET_ADDRESS": "0x51908F598A5e0d8F1A3bAbFa6DF76F9704daD072", "FACILITATOR_URL": "https://x402.org/facilitator", "X402_PRICE_USD": "$0.01", "X402_NETWORK": "eip155:84532" } } The x402 server is built on Hono. The main code is in src/app.ts. x402 middleware is applied only to specific routes. import { paymentMiddleware } from "@x402/hono"; import { Hono } from "hono"; import { createRoutes } from "./route"; import { createResourceServer, resolvePaymentOptions } from "./utils/config"; import type { CreateAppOptions, ErrorResponse, WeatherService } from "./utils/types"; import { createMockWeatherService } from "./weather/service"; const toErrorResponse = (statusCode: number, message: string): ErrorResponse => ({ statusCode, message, }); export const createApp = ( weatherService: WeatherService = createMockWeatherService(), options: CreateAppOptions = {}, ): Hono => { const app = new Hono(); const enablePayment = options.enablePayment ?? true; if (enablePayment) { const paymentOptions = resolvePaymentOptions(options.payment); const resourceServer = createResourceServer(paymentOptions); const routes = createRoutes(paymentOptions); const protectedRouteKeys = new Set(Object.keys(routes)); let resourceServerInitialization: Promise | null = null; app.use(async (c, next) => { const routeKey = `${c.req.method.toUpperCase()} ${c.req.path}`; if (!protectedRouteKeys.has(routeKey)) return next(); if (!resourceServerInitialization) { resourceServerInitialization = resourceServer.initialize().catch((error) => { resourceServerInitialization = null; throw error; }); } await resourceServerInitialization; return next(); }); app.use(paymentMiddleware(routes, resourceServer, undefined, undefined, false)); } app.get("/", (c) => c.json({ status: "ok" }, 200)); app.get("/health", (c) => c.json({ status: "ok" }, 200)); app.get("/weather", async (c) => { const city = c.req.query("city")?.trim(); if (!city) return c.json(toErrorResponse(400, "city query parameter is required"), 400); try { const weather = await weatherService.getWeatherByCity(city); if (!weather) return c.json(toErrorResponse(404, "city not found"), 404); return c.json(weather, 200); } catch { return c.json(toErrorResponse(503, "weather service unavailable"), 503); } }); return app; }; Regarding the weather retrieval logic: for verification purposes, I've implemented it to return hardcoded demo data instead of hitting an external API. In a production setting, this would be where you call an external service. import { WeatherData, WeatherService } from "../utils/types"; const MOCK_WEATHER_DATA: ReadonlyArray = [ { city: "Tokyo", condition: "Sunny", temperatureC: 28, humidity: 60 }, { city: "Osaka", condition: "Cloudy", temperatureC: 26, humidity: 65 }, { city: "New York", condition: "Rainy", temperatureC: 22, humidity: 72 }, ]; const normalizeCity = (city: string): string => { const trimmed = city.trim().replace(/^['\"]+|['\"]+$/g, ""); const withoutCountry = trimmed.split(",")[0]?.trim() ?? trimmed; return withoutCountry.toLowerCase(); }; export const createMockWeatherService = (): WeatherService => { return { async getWeatherByCity(city: string): Promise { const normalized = normalizeCity(city); return MOCK_WEATHER_DATA.find((item) => normalizeCity(item.city) === normalized) ?? null; }, }; }; x402-specific settings are consolidated in src/utils/config.ts. Implementing an x402 server requires configuring a facilitator and a resource server. Briefly, a facilitator acts as a bridge between the API you want to apply x402 to and the blockchain, handling signature verification and transaction submission for payments. Facilitators are recommended to save development effort. The MCP server is also based on Hono. import { StreamableHTTPTransport } from "@hono/mcp"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { Hono } from "hono"; import { cors } from "hono/cors"; // ... (imports) export const createApp = (options: CreateAppOptions = {}): Hono => { const app = new Hono(); const mcpServer = new McpServer({ name: "x402-weather-payment-mcpserver", version: "1.0.0" }); // ... (logic to handle MCP via Streamable HTTP transport) return app; }; The x402 client setup is implemented in x402-fetch-client.ts. // ... (X402FetchClient implementation using wrapFetch from @x402/fetch) And the tool for retrieving weather information: // ... (get_weather tool registration using McpServer.registerTool) The Point I Got Stuck On I learned this for the first time: when calling one Worker from another, you cannot simply specify the URL; you must use Bindings. You need to register this in your wrangler.jsonc. { "services": [ { "binding": "X402SERVER", "service": "x402server" } ] } Now that the code is explained, let's look at the deployment! Install dependencies: pnpm i Deploy: pnpm x402server run deploy Condition: x402server must already be deployed! Register the private key for the x402 client and the x402server endpoint using Secrets. pnpm mcpserver run secret CLIENT_PRIVATE_KEY --name mcpserver pnpm mcpserver run secret X402_SERVER_URL --name mcpserver Deploy: pnpm mcpserver run deploy Register https://mcpserver..workers.dev/mcp as the GPT App URL to enable x402 payments from chat! Register the MCP server endpoint in your GPT App. Add the app from the + button and ask for the weather. If the weather is returned and USDC payment is processed, you're set! Check the block explorer to confirm the stablecoin payment! That's it for now! While you can achieve similar results using AWS Lambda or AgentCore, Cloudflare Workers is highly recommended for quick and easy experimentation. The sample code for x402 is abundant and fits perfectly! Thank you for reading until the end! (Included original Japanese references) Official Site - Vibekanban GitHub - Vibekanban