mcpField
C
cloudflare-workers

cloudflare-workers

github.com/tenequmクラウド・DevOps4082 回インストール1 週間前に更新
リポジトリ

cloudflare-workers について

Cloudflare Workers 上でアプリケーションを構築・デプロイする開発者向けスキルです。バインディング、フレームワーク連携、テスト、リモート MCP サーバーのホスティングを扱います。

主な機能

  1. 01API とフルスタックアプリの構築
  2. 02ストレージ・コンピュートのバインディング
  3. 03スケジュール処理とキューの実行
  4. 04Web フレームワークとの連携
  5. 05ローカル開発とテスト
  6. 06リモート MCP サーバーのデプロイ

活用シーン

  1. 01REST または GraphQL バックエンドの構築
  2. 02エッジでの認証とルーティング
  3. 03バックグラウンド処理と Webhook の処理
  4. 04MCP サーバーのホスティング

MCP 対応

Cloudflare Workers 上でリモート MCP サーバーをホストする方法を説明します。MCP クライアントに公開するツールやリソースの仕様は記載されていません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tenequm/skills --skill cloudflare-workers

インストール後、Claude Code で/cloudflare-workersを入力して読み込まれたか確認します。

詳細

Cloudflare Workers

概要

Cloudflare Workers は、Cloudflare のグローバルネットワーク上で JavaScript、TypeScript、Python、Rust のコードを実行するサーバーレス実行環境です。Workers はミリ秒単位で実行され、自動的にスケールし、バインディングを通じて Cloudflare のストレージ製品やコンピューティング製品と連携します。

主なメリット:

  • コールドスタートなし - Workers はコンテナではなく V8 アイソレートで実行されます
  • グローバルなデプロイ - コードは世界中の 300 以上の都市で実行されます
  • 豊富なエコシステム - D1、KV、R2、Durable Objects、Queues、Containers、Workflows などへのバインディングを利用できます
  • フルスタックに対応 - 1 つのプロジェクトで API の構築と静的アセットの配信が可能です
  • 標準規格に準拠 - Web API(fetch、crypto、streams、WebSockets)を使用します

このスキルを使用する場面

次の用途には Cloudflare Workers を使用します。

  • API とバックエンド - RESTful API、GraphQL、tRPC、WebSocket サーバー
  • フルスタックアプリケーション - 静的アセットを含む React、Next.js、Remix、Astro、Vue、Svelte
  • エッジミドルウェア - 認証、レート制限、A/B テスト、ルーティング
  • バックグラウンド処理 - スケジュール済みジョブ(cron)、キューコンシューマー、Webhook
  • データ変換 - ETL パイプライン、リアルタイムデータ処理
  • AI アプリケーション - Workers AI を使用した RAG システム、チャットボット、画像生成
  • 永続的なワークフロー - 自動再試行機能を備えた複数ステップの長時間実行タスク(Workflows)
  • コンテナワークロード - Workers とともに Docker コンテナを実行(Containers)
  • MCP サーバー - リモート Model Context Protocol サーバーをホスト
  • プロキシとゲートウェイ - API ゲートウェイ、コンテンツ変換、プロトコル変換

クイックスタートのワークフロー

1. Wrangler CLI をインストールする
npm install -g wrangler

# Login to Cloudflare
wrangler login
2. 新しい Worker を作成する
# Using C3 (create-cloudflare) - recommended
npm create cloudflare@latest my-worker

# Or create manually
wrangler init my-worker
cd my-worker
3. Worker を記述する

基本的な HTTP API(TypeScript):

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/api/hello") {
      return Response.json({ message: "Hello from Workers!" });
    }

    return new Response("Not found", { status: 404 });
  },
};

環境変数と KV を使用する場合:

interface Env {
  MY_VAR: string;
  MY_KV: KVNamespace;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Access environment variable
    const greeting = env.MY_VAR;

    // Read from KV
    const value = await env.MY_KV.get("my-key");

    return Response.json({ greeting, value });
  },
};
4. ローカルで開発する
# Start local development server with hot reload
wrangler dev

# Access at http://localhost:8787
5. 本番環境にデプロイする
# Deploy to workers.dev subdomain
wrangler deploy

# Deploy to custom domain (configure in wrangler.toml)
wrangler deploy

コアコンセプト

Workers ランタイム

Workers は V8 JavaScript エンジンと Web 標準 API を使用します。

  • 実行モデル:アイソレート(コンテナではありません)— コールドスタートがありません
  • CPU 時間制限:リクエストごとに 10ms(Free)、30s(Paid)
  • メモリ制限:アイソレートごとに 128 MB
  • 言語:JavaScript、TypeScript、Python、Rust
  • API:fetch、crypto、streams、WebSockets、WebAssembly

サポートされる API:

  • Fetch API(HTTP リクエスト)
  • URL API(URL の解析)
  • Web Crypto(暗号化、ハッシュ化)
  • Streams API(データストリーミング)
  • WebSockets(リアルタイム通信)
  • Cache API(エッジキャッシュ)
  • HTML Rewriter(HTML の変換)
ハンドラー

Workers はハンドラーを通じてイベントに応答します。

Fetch ハンドラー(HTTP リクエスト):

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext) {
    return new Response("Hello!");
  },
};

Scheduled ハンドラー(cron ジョブ):

export default {
  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) {
    // Runs on schedule defined in wrangler.toml
    await env.MY_KV.put("last-run", new Date().toISOString());
  },
};

Queue ハンドラー(メッセージ処理):

export default {
  async queue(batch: MessageBatch<any>, env: Env, ctx: ExecutionContext) {
    for (const message of batch.messages) {
      await processMessage(message.body);
      message.ack();
    }
  },
};
バインディング

バインディングは Worker を Cloudflare のリソースに接続します。wrangler.toml で設定します。

KV(キーと値のストレージ):

[[kv_namespaces]]
binding = "MY_KV"
id = "your-kv-namespace-id"
// Usage
await env.MY_KV.put("key", "value");
const value = await env.MY_KV.get("key");

D1(SQL データベース):

[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "your-database-id"
// Usage
const result = await env.DB.prepare(
  "SELECT * FROM users WHERE id = ?"
).bind(userId).all();

R2(オブジェクトストレージ):

[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"
// Usage
await env.MY_BUCKET.put("file.txt", "contents");
const object = await env.MY_BUCKET.get("file.txt");
const text = await object?.text();

環境変数(シークレット以外のみ):

[vars]
GREETING = "hello"
ENVIRONMENT = "development"

シークレット(機密データ — wrangler.toml には絶対に記述しないでください):

# Set via CLI; the value is encrypted server-side and never written to disk locally
wrangler secret put MY_API_KEY
コンテキスト(ctx)

ctx パラメーターを使用すると、リクエストのライフサイクルを制御できます。

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext) {
    // Run tasks after response is sent
    ctx.waitUntil(
      env.MY_KV.put("request-count", String(Date.now()))
    );

    // Pass through to origin on exception
    ctx.passThroughOnException();

    return new Response("OK");
  },
};
トップレベルでの環境アクセス

2025 年 3 月以降は、ハンドラーに渡す代わりに、モジュールレベルで env をインポートできます。

import { env } from "cloudflare:workers";

// Access bindings outside of handlers
const apiClient = new ApiClient({ apiKey: env.API_KEY });

export default {
  async fetch(request: Request): Promise<Response> {
    // env is also available here without the parameter
    const data = await env.MY_KV.get("config");
    return Response.json({ data });
  },
};

これにより、関数シグネチャを介して env をプロパティドリリングする必要がなくなり、モジュールレベルでの初期化が可能になります。

迅速な開発パターン

Wrangler の設定

必須の wrangler.toml:

name = "my-worker"
main = "src/index.ts"
compatibility_date = "2025-09-01"

# Custom domain
routes = [
  { pattern = "api.example.com/*", zone_name = "example.com" }
]

# Or workers.dev subdomain
workers_dev = true

# Environment variables
[vars]
ENVIRONMENT = "production"

# Bindings
[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-id"

[[d1_databases]]
binding = "DB"
database_name = "production-db"
database_id = "your-db-id"

[[r2_buckets]]
binding = "ASSETS"
bucket_name = "my-assets"

# Cron triggers
[triggers]
crons = ["0 0 * * *"]  # Daily at midnight
環境管理

ステージング環境と本番環境には環境を使用します。

[env.staging]
vars = { ENVIRONMENT = "staging" }

[env.staging.d1_databases]
binding = "DB"
database_name = "staging-db"
database_id = "staging-db-id"

[env.production]
vars = { ENVIRONMENT = "production" }

[env.production.d1_databases]
binding = "DB"
database_name = "production-db"
database_id = "production-db-id"
# Deploy to staging
wrangler deploy --env staging

# Deploy to production
wrangler deploy --env production
よく使われるパターン

エラー処理付き JSON API:

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    try {
      const url = new URL(request.url);

      if (url.pathname === "/api/users" && request.method === "GET") {
        const users = await env.DB.prepare("SELECT * FROM users").all();
        return Response.json(users.results);
      }

      if (url.pathname === "/api/users" && request.method === "POST") {
        const body = await request.json();
        await env.DB.prepare(
          "INSERT INTO users (name, email) VALUES (?, ?)"
        ).bind(body.name, body.email).run();
        return Response.json({ success: true }, { status: 201 });
      }

      return Response.json({ error: "Not found" }, { status: 404 });
    } catch (error) {
      return Response.json(
        { error: error.message },
        { status: 500 }
      );
    }
  },
};

認証ミドルウェア:

async function authenticate(request: Request, env: Env): Promise<string | null> {
  const authHeader = request.headers.get("Authorization");
  if (!authHeader?.startsWith("Bearer ")) {
    return null;
  }

  const token = authHeader.substring(7);
  const userId = await env.SESSIONS.get(token);
  return userId;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const userId = await authenticate(request, env);

    if (!userId) {
      return Response.json({ error: "Unauthorized" }, { status: 401 });
    }

    // Proceed with authenticated request
    return Response.json({ userId });
  },
};

CORS ヘッダー:

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type, Authorization",
};

export default {
  async fetch(request: Request): Promise<Response> {
    if (request.method === "OPTIONS") {
      return new Response(null, { headers: corsHeaders });
    }

    const response = await handleRequest(request);

    // Add CORS headers to response
    Object.entries(corsHeaders).forEach(([key, value]) => {
      response.headers.set(key, value);
    });

    return response;
  },
};
静的アセット(フルスタックアプリ)

Worker のコードとともに静的ファイルを配信します。

[assets]
directory = "./public"
binding = "ASSETS"
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);

    // API routes
    if (url.pathname.startsWith("/api/")) {
      return handleAPI(request, env);
    }

    // Serve static assets via the ASSETS binding
    return env.ASSETS.fetch(request);
  },
};
テスト

Vitest を使用する場合:

import { env, createExecutionContext } from "cloudflare:test";
import { describe, it, expect } from "vitest";
import worker from "./index";

describe("Worker", () => {
  it("responds with JSON", async () => {
    const request = new Request("http://example.com/api/hello");
    const ctx = createExecutionContext();
    const response = await worker.fetch(request, env, ctx);

    expect(response.status).toBe(200);
    expect(await response.json()).toEqual({ message: "Hello!" });
  });
});

フレームワークとの統合

Workers は、アダプターを使って主要なフレームワークをサポートしています。

  • Next.js - App Router と Pages Router を完全にサポート
  • Remix / React Router - Cloudflare ネイティブのアダプター
  • Astro - Workers 上でのサーバーサイドレンダリング
  • SvelteKit - Cloudflare アダプターを利用可能
  • Hono - Workers 向けに構築された軽量なウェブフレームワーク
  • tRPC - Workers を完全にサポートする型安全な API

Hono の使用例:

import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => c.text("Hello!"));
app.get("/api/users/:id", async (c) => {
  const id = c.req.param("id");
  const user = await c.env.DB.prepare(
    "SELECT * FROM users WHERE id = ?"
  ).bind(id).first();
  return c.json(user);
});

export default app;

高度なトピック

高度な機能の詳細については、リファレンスファイルをご覧ください。

  • バインディング完全ガイド:references/bindings-complete-guide.md - すべてのバインディングの種類(D1、KV、R2、Durable Objects、Queues、Workers AI、Vectorize、Workflows、Containers、Secrets Store、Pipelines、AutoRAG)
  • デプロイと CI/CD:references/wrangler-and-deployment.md - Wrangler v4 への移行、コマンド、GitHub Actions、GitLab CI/CD、段階的なロールアウト、リモートバインディング
  • 開発のベストプラクティス:references/development-patterns.md - テスト、デバッグ、エラー処理、パフォーマンス、トップレベルでの env アクセスパターン
  • 高度な機能:references/advanced-features.md - Containers、Workflows、MCP サーバー、Workers for Platforms、WebSockets、Node.js 互換性、ストリーミング
  • 可観測性:references/observability.md - ログ(tail、Logpush、Workers Logs)、メトリクス、トレース、デバッグ

リソース

公式ドキュメント:

テンプレートとクイックスタート:

コミュニティ:

コメント