Skip to main content

CloudFlare Agent First Interface — agent-first CLI for CloudFlare management in the AgentCulture org.

Project description

cultureflare

⚠️ cfafi was renamed to cultureflare. v0.2.2 was the final release under the cfafi PyPI distribution name; install cultureflare for ongoing updates. The cfafi CLI command stays as an alias, and a thin cfafi/__init__.py shim ships in the wheel so existing import cfafi consumers 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: cfafi 0.2.2 is the final release under that name. Switch to uv tool install cultureflare to 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 --service http://localhost:8080 --allow you@example.com --apply
# Tunnel + DNS only (no Cloudflare Access) — the backend service does its own
# auth, e.g. an OpenAI-style bearer token in front of a local model server:
cultureflare remote-login setup --hostname api.culture.dev --service http://127.0.0.1:8000 --no-access --apply

cfafi <verb> works identically as a backward-compat alias.

Security — --no-access: tunnel-only mode puts no Cloudflare Access gate in front of the hostname; the backend at --service is reachable by anyone who resolves the name and must enforce its own authentication (e.g. an OpenAI-style bearer token). Exposing an unauthenticated service this way is unsafe for anything but local testing. Per-service auth and client-usage docs (a model server's API key, /v1 endpoints, SDK examples) live with that service, not in this generic CloudFlare tool.

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. --no-access provisions Tunnel + DNS only (no Access app) for a backend that authenticates itself
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 --service URL --allow EMAIL Provision the full Tunnel + DNS + Access stack for H (dry-run; --apply to commit)
cultureflare remote-login setup --hostname H --service URL --no-access Tunnel + DNS only — no Access app; the backend at URL provides its own auth
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.com is required for remote-login setup unless --no-access is given).
  • Runs read-side preflight (whoami, zone resolution).
  • Prints the plan (or the body it would POST) and exits cleanly.
  • Performs no POST / PUT / DELETE against 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's SKILL.md for 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 generic dns 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 setup errors with a dashboard link.
  • remote-login orchestration 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:

Out-of-scope-for-now items are listed in each spec's "Out of scope" / "Future" section. The rename agentculture/cfafiagentculture/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

cultureflare-0.11.0.tar.gz (330.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cultureflare-0.11.0-py3-none-any.whl (52.0 kB view details)

Uploaded Python 3

File details

Details for the file cultureflare-0.11.0.tar.gz.

File metadata

  • Download URL: cultureflare-0.11.0.tar.gz
  • Upload date:
  • Size: 330.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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

Hashes for cultureflare-0.11.0.tar.gz
Algorithm Hash digest
SHA256 608e27f584f44e8281159e97623b0cd9908709d4b0c9b463d300431fa8070d8f
MD5 dda8ae446c399d33eea6e5760ebfc46f
BLAKE2b-256 d3762889be1f36a3c7d7e68b26bac773e53a1928a48ea2c3d319ed20687417cd

See more details on using hashes here.

File details

Details for the file cultureflare-0.11.0-py3-none-any.whl.

File metadata

  • Download URL: cultureflare-0.11.0-py3-none-any.whl
  • Upload date:
  • Size: 52.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","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

Hashes for cultureflare-0.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a44b04e3abbd2e43e6edda9cd9d194abf2872dc36319caed38c404c54f87594
MD5 c1416f78245906ec77a62407b35ed1e7
BLAKE2b-256 782881fd7e116781388ecefb339578ac259a332c771f563e40d144db939810cc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page