Cloudflare Dashboardに表示された「Onboard your agent to Cloudflare」からCodex向けのセットアップを行い、実際にCloudflare Workers用の小さなアプリを実装しました。
作ったのは、DOIまたはDOI URLを入力するとCrossrefから論文メタデータを取得し、タイトル・著者・掲載誌・発行年・引用候補を表示するアプリです。
この記事では、連携すると何が変わるのか、どこまで自動化できたのか、実装時に気づいた点をまとめます。
CodexとCloudflareを接続すると何が変わるのか
今回のセットアップでは、Cloudflareの公式Agent Setup Promptを使い、Cloudflare関連のSkillsとMCP ServerをCodexへ追加しました。
- Cloudflare公式ドキュメントを、実装対象に合わせて参照できる
- Cloudflareアカウント内のWorkers・Zones・Observabilityなどを確認できる
- Wrangler設定やWorkers APIを、現在の仕様に合わせて生成・検証できる
- OAuthで許可した範囲に限り、Cloudflareリソースを操作できる
重要なのは、Codexが無条件にCloudflare全体を操作できるわけではないことです。実際にできる操作はOAuth scopeに依存します。今回は読み取り専用で接続したため、アカウント確認はできましたが、本番デプロイは行っていません。
公式セットアップ手順:
実装したもの
構成はシンプルです。
Browser
│ DOIを入力
▼
Cloudflare Worker
├─ DOI形式を検証
├─ Cache APIを確認
└─ Crossref REST APIから論文情報を取得
1つのWorkerがWeb画面とAPIの両方を返します。
-
GET /: DOI入力画面 -
GET /api/health: 動作確認 -
GET /api/lookup?doi=...: 論文メタデータ取得
Wrangler設定
新規プロジェクトなので、Cloudflareが推奨するwrangler.jsoncを使いました。
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "doi-metadata-worker-demo",
"main": "src/index.ts",
"compatibility_date": "2026-09-07",
"compatibility_flags": ["nodejs_compat"],
"observability": {
"enabled": true,
"logs": {
"enabled": true,
"head_sampling_rate": 1
},
"traces": {
"enabled": true,
"head_sampling_rate": 0.05
}
}
}
Workers LogsとTracesは別々に有効化しています。ログは検索しやすいようにJSON形式で出力します。
console.log(JSON.stringify({
message: "incoming request",
method: request.method,
path: url.pathname,
}));
DOIの正規化と検証
利用者はDOI文字列だけでなく、https://doi.org/...形式でも入力できます。外部APIへ送る前に正規化と形式確認を行います。
function normalizeDoi(raw: string): string | null {
const normalized = raw
.trim()
.replace(/^doi:\s*/i, "")
.replace(/^https?:\/\/(?:dx\.)?doi\.org\//i, "")
.trim();
if (normalized.length === 0 || normalized.length > 300) return null;
if (!/^10\.\d{4,9}\/\S+$/i.test(normalized)) return null;
return normalized;
}
不正な入力はCrossrefへ送らず、HTTP 400と日本語のエラーメッセージを返します。
Crossref取得結果をキャッシュする
Crossref REST APIは登録不要で利用できますが、同じ問い合わせを繰り返さないようキャッシュを入れました。
const encodedDoi = encodeURIComponent(doi);
const cacheKey = new Request(
`https://doi-cache.internal/works/${encodedDoi}`,
);
const cached = await caches.default.match(cacheKey);
if (cached) {
const headers = new Headers(cached.headers);
headers.set("X-Cache", "HIT");
return new Response(cached.body, {
status: cached.status,
headers,
});
}
取得成功時は1時間キャッシュします。レスポンス後のキャッシュ書き込みは、処理が途中で破棄されないようctx.waitUntil()へ渡しています。
const response = Response.json(metadata, {
headers: {
"Cache-Control": "public, max-age=3600",
"X-Cache": "MISS",
},
});
ctx.waitUntil(caches.default.put(cacheKey, response.clone()));
return response;
Crossref REST API:
検証結果
以下を実行しました。
pnpm types
pnpm check
pnpm deploy:dry-run
pnpm dev
結果は次のとおりです。
| 確認項目 | 結果 |
|---|---|
| WranglerによるWorkers型生成 | 成功 |
| TypeScript strict mode | 成功 |
| deploy dry-run | 成功 |
/api/health |
HTTP 200 |
| 不正なDOI | HTTP 400 |
| DOI初回取得 | HTTP 200 / X-Cache: MISS
|
| 同じDOIの2回目 | HTTP 200 / X-Cache: HIT
|
テストには10.1038/s41586-021-03819-2を使用し、タイトル、著者、Nature、2021年、journal-articleを取得できました。
dry-runのパッケージサイズは12.38 KiB、gzip後は4.61 KiBでした。
実装時の注意点
OAuth scopeと実装可能範囲は別
Codexがコードを作れることと、Cloudflareへデプロイできることは別です。読み取り専用OAuthでは、ローカル実装と検証はできますが、Workerの新規作成や更新はできません。
compatibility_dateはUTC基準に注意
JSTでは日付が変わっていても、Wrangler側ではまだ前日として扱われ、当日の日付が「未来」と判定される場合がありました。新規Workerでは現在の日付を基本にしつつ、実際にインストールしたWranglerが受け付ける最新日を確認するのが安全です。
メタデータは登録内容に依存する
Crossrefが返す内容は、出版社などから登録されたメタデータに依存します。すべてのDOIで著者名や掲載誌が完全に揃うとは限りません。また、Crossref以外の登録機関が管理するDOIは取得できない場合があります。
まとめ
Cloudflare連携によって、Codexは単にコードを書く用途だけでなく、次のような一連の作業を支援できました。
- 公式ドキュメントと現在の設定仕様を確認する
- WorkerとWeb UIを実装する
- Wranglerから型を生成する
- ローカルWorkers環境で実際にAPIを検証する
- キャッシュ、ログ、Tracesを含む設定を確認する
- OAuth権限の範囲を確認し、本番変更を止める
今回は読み取り専用のためローカル実装までですが、書き込み権限を明示的に追加すれば、同じ流れでWorkersへのデプロイや、その後のログ確認までつなげられます。
Cloudflare Workers公式ドキュメント:
※ 本記事のコードと動作結果は、Codexを使用して生成した後、Wranglerの型チェック・dry-run・ローカル実行・HTTP応答・ブラウザ表示まで確認しています。