AI 開発

Cloudflare の cf CLI は、AI Agent が JSON でコマンドを検索し、確認してから API を呼ぶためにどう使うか(2026)

約 15 分

Agent は 2900 を超えるコマンドを覚えなくてよい。一文で検索し、そのコマンドが送る API 欄を読み、それから実行する。結果は標準出力のインデント付き JSON。経過とエラーは標準エラー。モデルは引数を埋めるだけ。cf が Cloudflare の API を呼ぶ。

読む前の早見

対象 2026-10-13 時点の公開事実 Agent の使い方
cf 9 月 28 日公開ベータ。API 全体。文書は 2900 超のコマンド。npm で入れる 既定が JSON。--json は要らない
cf cli search ローカル検索。ログイン不要。文全体を引用符で囲む。最大 5 件、良いものが先 command と summary だけ取る。まだ実行しない
cf schema 生成コマンドが送る HTTP。メソッド、パス、パラメータ、本体欄 必須を先に埋める。deploy などは --help
実行結果 9 月 29 日文書:JSON は常にインデント。非対話の削除が --force なしなら、標準エラーに Aborted. と出て終了コードは 0 のままありうる 先に stdout の JSON、それから終了コード

公開記事は「人には整形、Agent には圧縮」と書いた。9 月 29 日の文書は、標準出力が端末かどうかにかかわらず JSON はインデントされると書く。10 月 8 日の 1.0.0-beta.5 公開確認も圧縮出力を見ていない。パーサは文書に従う。orders.example.test は架空。

Agent は三つの JSON で Cloudflare を操作する。コマンドを暗記しない

Cloudflare は 9 月 28 日に cf を公開した。公開記事は、3 月の Agent が Wrangler 利用の約四分の一、公開前の週は 48% だったと書く。Wrangler は手作業で約 280 コマンドであり、API 全体を覆えない。新しい CLI は OpenAPI から生成される。9 月 29 日の文書は 2900 を超えるコマンドと書く。導入は npm install --global cf。cf auth login は人がブラウザで承認する。無人実行は環境変数 CLOUDFLARE_API_TOKEN で、保存済みログインより優先する。トークンはリポジトリに置かない。例は sk_demo_not_real。

  • 検索:cf cli search "create D1 database"。引用符は残す。ローカルで動き、アカウントに触れない。
  • 確認:cf schema d1 create が送る HTTP 欄を出す。実変更の前に --dry-run。試行に資格情報は要らない。
  • 実行:標準出力は JSON 結果だけ。選ばれた zone、エラー、Aborted. は標準エラー。

これはページをクリックする Agent ではない。プラグインディレクトリの mcp.json は Agent Plugins 1.0.0 のディレクトリ契約。MCP の tools/call は Coding Agent が MCP を呼ぶ方法。本篇は cf が Agent に渡す JSON だけを書く。

9 月 29 日文書の先頭二件は次の形である。欄は command と summary だけ:

[
  {
    "command": "cf d1 create",
    "summary": "Create D1 Database"
  },
  {
    "command": "cf d1 update",
    "summary": "Update D1 Database"
  }
]

引用符がないと、最初の語のあとは未知コマンドになる。ルートとグループの --help は先に検索を勧める。個々のコマンドの --help はプレーンテキストで、この配列ではない。コマンドが無いとき CLI は近い名前を出す。それも検索結果ではない。

送るリクエストを先に読み、戻った一ページをあとで読む

cf schema は生成された API コマンドだけ。cf deploy は --help。文書の鍵は operationId、httpMethod、path、pathParams、queryParams、hasRequestBody、requestBodyFields。パラメータは account_id のような API 名。本体欄はオプション名と説明。一覧が欠けているときは --body で全文を渡す。下は同じ鍵の例示で、ホスト名は架空。本番の採取ではない:

{
  "operationId": "dns-records-create",
  "httpMethod": "POST",
  "path": "/zones/{zone_id}/dns_records",
  "pathParams": [
    { "name": "zone_id", "type": "string", "required": true }
  ],
  "queryParams": [],
  "hasRequestBody": true,
  "requestBodyFields": [
    { "name": "type", "type": "string", "required": true, "description": "Record type" },
    { "name": "name", "type": "string", "required": true, "description": "Record name" },
    { "name": "content", "type": "string", "required": true, "description": "Record content" }
  ]
}

必須欄は実行前に門を通す。門をプロンプトだけに置けない理由は AI が JSON Schema を要する理由。一覧コマンドの標準出力は一ページの JSON 配列。ページングはコマンドごとに違う。データを返さない変更は標準出力が空。R2 オブジェクトやモデル画像はオブジェクトではなく、そのまま標準出力へ出る。架空の DNS 一ページ:

[
  {
    "id": "rec_demo_1042",
    "type": "TXT",
    "name": "orders.example.test",
    "content": "demo-pass"
  }
]

欄名はコマンドに従う。まず配列であることを確認し、そのコマンドの schema から id か name を取る。すべてのページに success の封筒があるとは思わない。

標準出力、標準エラー、終了コードを一つの成功にまとめない

Agent は三つの信号を一つに潰しやすい:

見えるもの 意味
標準出力のインデント付き JSON それが結果。文書は端末でもそうでなくてもインデントすると書く。公開記事の「Agent には圧縮」を現在の解析契約にしない。
選ばれた zone、エラー、Aborted. 標準エラー。非対話で --force のない破壊的コマンドは Aborted. だけを出し、終了コードは 0 のままありうる。
cf workers delete --force 一部のコマンドで --force は API パラメータでもある。他の Worker がまだ参照する Worker を消しうる。許す前に schema を見る。
wrangler.jsonc だけのリポジトリ cloudflare.config.ts が無いあいだ、cf dev、cf build、cf deploy を Agent に走らせない。先に cf migrate --dry-run。

Wrangler 設定が既にあるプロジェクトは Wrangler を続ける。他の Cloudflare 作業は cf。この文は AGENTS.md か CLAUDE.md に置く。--local は一部の KV、D1、R2 だけ。cf d1 query にローカル相当はなく、静かに本番 API を叩かずエラーを返す。

本番リソースを変える前の六ステップ

トークンをプロンプトに貼るところから始めない:

  1. 人が cf auth login を終える。無人のときだけ CLOUDFLARE_API_TOKEN。トークンをコマンド JSON に入れない。
  2. 引用符つきで検索する。文全体が一つの引数。最大五件の command を読む。
  3. cf schema を走らせる。required を見る。一覧が欠けていれば --body と API 文書に切り替える。
  4. 先に --dry-run。リクエスト JSON を出し、送信せず、資格情報も要らない。パスが zone_demo_1042 のようなデモ値かを確認する。
  5. 標準出力だけを解析する。空なら、その変更はデータを返していない。破壊的コマンドは標準エラーの Aborted. を見る。
  6. Wrangler プロジェクトは先に移す。cloudflare.config.ts が無いあいだ deploy しない。生成ファイルの TODO(@cloudflare) が残るとビルドは失敗する。

公開ベータのあと、Wrangler はさらに 18 か月保守される。二つは併存できる。同じプロジェクトで Agent に cf deploy で古い設定を覆わせない。

書き込みを許す前に三つの JSON を広げる

失敗の多くは、引用符のない検索、schema と結果の不一致、終了コード 0 を削除完了と読むことである。

  • 検索配列と schema を 整形 し、Schema 検証 で requestBodyFields の required: true が揃っているか見る。
  • JSONPath 抽出 で $[0].command、$.httpMethod、$.path を抜く。
  • --dry-run のリクエストと戻った一ページを JSON Diff する。プロンプトの前に欠けた欄を埋める。
  • 標準エラーに Aborted. があれば、削除は起きていない。
  • zone、トークン、アカウント ID を公開の整形サイトに貼らない。JSONSort はブラウザのローカルで動く。

三つが揃えば、Agent はコマンドを推測しているのではなく API を呼んでいる。インデント自体は誤りではない。

よくある誤り

  • 公開記事を見て圧縮 JSON を待つ。現行文書は常にインデントと書く。10 月 8 日の beta.5 確認も、Agent 検出で短くなった出力を見ていない。
  • 検索に引用符を付けない。二語目は未知コマンドになる。検索結果と「近いコマンド名」は同じ JSON ではない。
  • 終了コード 0 を削除成功と読む。非対話で --force が無いと、中止だけのことがある。標準エラーも見る。
  • wrangler.jsonc だけのリポジトリで cf deploy を走らせる。新しい設定ができ、古い設定が使われなくなることがある。先に移行を dry-run する。
  • API トークンをプロンプトやコミットする JSON に書く。無人は環境変数。例に本物の token を使わない。
  • cf を、自分でブラウザをクリックする Agent と書く。ログインは人が承認する。その後の API 呼び出しは CLI の JSON であり、ページ操作ではない。

FAQ

Agent は今も毎コマンドに --json を付けるか?

付けない。cf の結果は既定で標準出力の JSON である。--json が要ったり表が出たりするのは Wrangler。9 月 29 日文書ではこの JSON はインデントされる。圧縮形式を待たない。

cf cli search はアカウントを使うか?

使わない。検索はローカルで、資格情報は要らない。最大五つのオブジェクトを返し、それぞれ command と summary を持つ。リソースを変えるのはその後のコマンド。

JSON が無いのは失敗か?

いつもではない。データを返さない変更は標準出力が空。失敗は非ゼロの終了コードで、エラーは標準エラー。中止された削除は標準エラーが Aborted. で、終了コードは 0 のままありうる。

Wrangler プロジェクトを今日 cf に切り替えなければならないか?

deploy まで同じ日に切り替えなくてよい。wrangler.jsonc か wrangler.toml があるあいだ、開発、ビルド、デプロイは Wrangler に残す。cloudflare.config.ts への移行は cf migrate で、先に --dry-run。公開ベータのあと Wrangler は 18 か月保守される。

requestBodyFields が欠けていたらどうするか?

文書は、一部コマンドの requestBodyFields が不完全または空だと書く。そのときは --body で全文を渡し、API 文書と照合する。空の一覧を、本体が無い API と読まない。

結論

cf は AI Agent が JSON で Cloudflare API を呼ぶ道である。検索がコマンド名を返し、schema が送る欄を返し、標準出力が一ページの結果を返す。インデント付き JSON を解析し、標準エラーと終了コードは分ける。

cf d1 create が検索配列から来たか、zone_id が schema から来たか、orders.example.test がデモ結果にだけ出るかを先に確認する。三箇所が揃ってから本番を変える。

あわせて読む

更新記録: 初出