CloudFlare Agent First Interface — agent-first CLI for CloudFlare management in the AgentCulture org.
Project description
cultureflare
⚠️
cfafiwas renamed tocultureflare. v0.2.2 was the final release under thecfafiPyPI distribution name; installcultureflarefor ongoing updates. ThecfafiCLI command stays as an alias, and a thincfafi/__init__.pyshim ships in the wheel so existingimport cfaficonsumers keep working without changes.
Agent-first CLI for managing CloudFlare state in the AgentCulture OSS
org. Action-oriented (commands describe operator intent, not REST
endpoints), idempotent, dry-run by default, agent-readable markdown +
--json output on every verb.
Install
uv tool install cultureflare
You get both cultureflare and cfafi on the PATH; they're aliases
for the same entry point.
If you previously ran
uv tool install cfafi:cfafi0.2.2 is the final release under that name. Switch touv tool install cultureflareto keep getting updates. Both CLI commands keep working after the swap.
cultureflare --version
cfafi --version # same version, same code (the back-compat alias)
Quick start
# Export credentials securely (see docs/SETUP.md)
export CLOUDFLARE_API_TOKEN=...
export CLOUDFLARE_ACCOUNT_ID=...
# Inspect
cultureflare whoami
cultureflare zones list
cultureflare learn # full self-teaching prompt
cultureflare explain dns create # per-verb docs
# Mutate — dry-run by default; --apply to commit
cultureflare dns create culture.dev TXT _cfafi-test "hello"
cultureflare dns create culture.dev TXT _cfafi-test "hello" --apply
# Higher-level orchestration
cultureflare remote-login setup --hostname irc.culture.dev --allow you@example.com --apply
cfafi <verb> works identically as a backward-compat alias.
Scope (current)
| Resource | Read | Write | Notes |
|---|---|---|---|
| Zones | ✓ zones list |
— | All zones in the token's account |
| DNS records | ✓ via dns create lookup |
✓ dns create (with --apply) |
Idempotent; conflict-aware |
| Cloudflare Access (Zero Trust) | ✓ remote-login show |
✓ remote-login setup / teardown (with --apply) |
Per-hostname Tunnel + Access app + allow-policy + optional service token |
| Token verify | ✓ whoami |
— | Status only (no scope inspection — CF doesn't expose) |
| Workers scripts / routes | bash skills only | — | Python port pending |
| Pages projects / deployments | bash skills only | bash cf-pages-project-create.sh / cf-pages-deployments-purge.sh |
Python port pending |
| API tokens | — | — | Operator-driven by design (out of scope) |
| Zero Trust org onboarding | — | — | Dashboard only for now |
Commands (v0.2.2)
| Command | Description |
|---|---|
cultureflare whoami |
Verify the configured API token is alive |
cultureflare zones list |
List zones in the token's account |
cultureflare dns create ZONE TYPE NAME CONTENT |
Create a DNS record (dry-run; --apply to commit) |
cultureflare remote-login setup --hostname H --allow EMAIL |
Provision the full Tunnel + DNS + Access stack for H (dry-run; --apply to commit) |
cultureflare remote-login show --hostname H |
Inspect what's currently provisioned for H |
cultureflare remote-login teardown --hostname H |
Reverse setup (dry-run; --apply to commit) |
cultureflare learn |
Self-teaching prompt for agents |
cultureflare explain <path> |
Markdown docs for any noun/verb path |
Every command supports --json for raw envelope output suitable for
jq pipelines and downstream agents. Run cultureflare learn for the
full rundown.
--json output
Every command emits the canonical CloudFlare envelope shape
({success, errors, messages, result}) under --json. Examples
(IDs and tokens elided as …):
$ cultureflare whoami --json
{"success":true,"errors":[],"messages":[{"code":10000,"message":"This API Token is valid and active"}],"result":{"id":"…","status":"active","not_before":null,"expires_on":null}}
$ cultureflare zones list --json
{"success":true,"errors":[],"messages":[],"result":[{"id":"…","name":"culture.dev","status":"active","plan":{"name":"Free Website"}}],"result_info":{"page":1,"total_pages":1,"count":1,"total_count":1}}
$ cultureflare dns create culture.dev TXT _cfafi-test "hello" --json
{"success":true,"errors":[],"messages":["dry-run: no changes applied"],"result":{"dry_run":true,"zone_id":"…","would_post":{"type":"TXT","name":"_cfafi-test","content":"hello","ttl":1,"proxied":false,"comment":"Managed by cultureflare in agentculture/cultureflare"}}}
$ cultureflare remote-login show --hostname irc.culture.dev --json
{"success":true,"errors":[],"messages":[],"result":{"hostname":"irc.culture.dev","team_domain":"agentculture.cloudflareaccess.com","tunnel":null,"dns":null,"access_app":null,"policy":null,"service_token":null}}
Errors emit on stderr with the same envelope plus code,
message, and remediation fields.
Credentials
Two environment variables, no .env walking by the installed CLI:
export CLOUDFLARE_API_TOKEN=...
export CLOUDFLARE_ACCOUNT_ID=...
Two-token pattern is recommended:
- Read-only token — for
whoami,zones list,dns create(lookup),remote-login show. Account Settings + Zone Read. - Operator token — adds Tunnel Edit, Access Apps & Policies Edit,
Access Organizations Read, Access Service Tokens Edit (when using
--with-service-token), Zone DNS Edit. Required for any verb that takes--apply.
Full token-scope tables, the secure-loading pattern, and dashboard
walkthrough live in docs/SETUP.md. Scope correctness
is not preflight-validated (CF's /user/tokens/verify doesn't
expose granted scopes); a missing scope surfaces as a 403 mid-run with
remediation pointing back at the docs.
Dry-run vs --apply
Every mutating verb is dry-run by default. Without --apply,
the command:
- Validates inputs (e.g.
--allow user@example.comis required forremote-login setup). - Runs read-side preflight (
whoami, zone resolution). - Prints the plan (or the body it would
POST) and exits cleanly. - Performs no
POST/PUT/DELETEagainst CloudFlare.
Pass --apply to commit. The same command otherwise — same args, same
output shape, plus the resource IDs that got created.
teardown is also dry-run by default; the destructive path requires
--apply.
Hybrid Python CLI / bash skills
The Python CLI is the preferred surface for verbs that have been
ported. Bash counterparts under .claude/skills/cultureflare/scripts/ (read)
and .claude/skills/cultureflare-write/scripts/ (write) remain supported for
verbs not yet migrated:
- Python today:
whoami,zones list,dns create,remote-login {setup,show,teardown},learn,explain. - Bash only today:
cf-pages*.sh,cf-workers*.sh,cf-redirect-create.sh. See each skill'sSKILL.mdfor the full inventory.
Migration tracker:
docs/superpowers/specs/2026-04-24-cfafi-v0.1.0-python-cli-design.md
§ "Subsequent PRs".
Limitations
- No broad CloudFlare coverage — only the resources in the scope table above. Anything else needs the bash skills or a direct CF API call.
- No destructive verbs beyond
remote-login teardown. There's no genericdns delete,zone delete, etc. yet. - No auto-discovery beyond listed verbs (no fuzzy zone/account
matching, no "find me the zone for this hostname" outside of
remote-login). - No API-token minting (
POST /user/tokens) — operator-driven by design; cultureflare never creates tokens for you. - No Zero Trust org onboarding via API in v0.2; if the account
doesn't have ZT enabled,
remote-login setuperrors with a dashboard link. remote-loginorchestration assumes one hostname per Access app and a single allow-policy. Richer Access policy shapes (require / exclude / IdP selection) are a future PR.
Roadmap
The two design docs that drive current and near-term work:
- Python CLI v0.1 design — initial ports, command surface conventions.
remote-loginaction design — orchestration model, idempotency, one-shot-secret handling.
Out-of-scope-for-now items are listed in each spec's "Out of scope" /
"Future" section. The rename agentculture/cfafi →
agentculture/cultureflare is now done; the Python module dir is cultureflare/ with a
cfafi/ shim package for back-compat — the dual-distribution shim and CLI alias
mean both names work simultaneously.
Tests
bash tests/shellcheck.sh # static analysis across all shell scripts
bash tests/markdownlint.sh # lint every markdown file against .markdownlint-cli2.yaml
bats tests/bats/ # bash skill unit tests (mocked curl, real jq, no live token required)
uv run pytest -v # Python CLI unit tests (~140 tests)
All four run in CI on every PR (see .github/workflows/tests.yml).
Required tools on the developer machine: bash, curl, jq,
shellcheck, bats, markdownlint-cli2, uv.
Development
See CLAUDE.md for repo conventions and
docs/SETUP.md for the token scope requirements +
Trusted Publisher setup.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cultureflare-0.5.0.tar.gz.
File metadata
- Download URL: cultureflare-0.5.0.tar.gz
- Upload date:
- Size: 273.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0455b041ca25f1b8ed75bb9a734681ebd3f7547beb0c55b8bfc01bc1e8ca7717
|
|
| MD5 |
88c76372244b38e2508696615dab87c4
|
|
| BLAKE2b-256 |
e0bbab32252f6031fd7f83be59e5ba162fea0bcbca3e7dc6f59e42806382f06f
|
File details
Details for the file cultureflare-0.5.0-py3-none-any.whl.
File metadata
- Download URL: cultureflare-0.5.0-py3-none-any.whl
- Upload date:
- Size: 50.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5900f9a27e303c2998c4b0d84cd08ea17e75414597cf216e3ad30ebc7daf7235
|
|
| MD5 |
e5f56295e6f4f4b5dc28cb0fd92e0174
|
|
| BLAKE2b-256 |
09620a6f61433f573fefe9517b10cc7946f0cd58ef67ab7ad48d15b8a77dda8d
|