AI 개발

Cloudflare cf CLI는 AI Agent가 JSON으로 명령을 검색하고 확인한 뒤 API를 어떻게 부르나 (2026)

약 15분

Agent는 2900개가 넘는 명령을 외우지 않는다. 한 문장으로 검색하고, 그 명령이 보낼 API 필드를 읽은 다음 실행한다. 결과는 표준 출력의 들여쓴 JSON이다. 진행과 오류는 표준 오류로 간다. 모델은 인자만 채운다. Cloudflare API를 부르는 것은 cf다.

읽기 전 요약

대상 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 사용의 약 4분의 1, 출시 전 주는 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이 없으면 실패인가?

항상 그렇지는 않다. 데이터를 반환하지 않는 변경은 표준 출력이 비어 있다. 실패는 0이 아닌 종료 코드이고 오류는 표준 오류에 있다. 중단된 삭제는 표준 오류가 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가 데모 결과에만 있는지 먼저 확인한다. 세 곳이 맞으면 운영 자원을 바꾼다.

이어서 읽기

변경 기록: 처음 게시