/fling- Ship artifacts from Claude Code to Cloudflare Workers.
One command to deploy anything Claude Code just built - HTML pages, frontend apps, Worker scripts - to a live Cloudflare Workers URL. V3 uses an MCP server for secure credential isolation - your Cloudflare API token never enters the LLM context.
Cloudflare publishes cloudflare/skills — official Agent Skills for their platform. People reasonably ask whether Fling is now redundant. It isn't: they operate at different layers.
cloudflare/skills is a knowledge layer. The cloudflare skill is a documentation-retrieval skill — its own guidance is "prefer retrieval over pre-training." It makes any agent knowledgeable about Workers, and its references/wrangler/ folder documents the wrangler CLI. It does not detect your project's needs, write your config, or run a deploy for you.
Fling is the automation layer on top. One command takes whatever Claude Code just built and ships it live:
| Fling | cloudflare/skills | |
|---|---|---|
| One-command detect → deploy | ✅ /fling |
❌ you run wrangler yourself |
| Auto-detect deploy target (dist / index.html / Worker / framework) | ✅ | ❌ |
| Infer bindings from source (D1/KV/R2/AI/DO/Queues/Vectorize/Workflows) | ✅ | ❌ docs only |
Scaffold wrangler.jsonc (SPA, cron, routes, observability) |
✅ | ❌ manual snippets |
| Billing warnings + size pre-checks before deploy | ✅ | ❌ |
| Protected-workers guardrail | ✅ | ❌ |
| Lifecycle commands (tail / preview / rollback / delete / dev) | ✅ runnable | ❌ reference text |
Use both. Fling owns the detect-scaffold-deploy-lifecycle pipeline; lean on cloudflare/skills for deep platform knowledge (current limits, gotchas, config schema). Fling complements it — it doesn't compete with it.
/plugin marketplace add thepharmer/fling
/plugin install fling@thepharmer-fling
Clone this repo, copy skills/fling/ to ~/.claude/skills/
claude --plugin-dir ./fling- Python 3.10+ installed
- uv (Python package runner):
curl -LsSf https://astral.sh/uv/install.sh | sh - Node.js installed
- Wrangler installed:
npm i -g wrangler - Cloudflare API token with Workers permissions (see Creating a Scoped Token)
/plugin install fling@thepharmer-fling
You'll be prompted to enter your Cloudflare API token. It's stored in your OS keychain (marked sensitive: true in plugin config).
Then: /fling
Inject CLOUDFLARE_API_TOKEN via a secret manager:
# pass
CLOUDFLARE_API_TOKEN=$(pass show cloudflare/api-token) claude
# 1Password
op run --env-file=.env -- claude
# Doppler
doppler run -- claudeenv:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}- Go to Cloudflare Dashboard → API Tokens
- Create a custom token with:
- Account / Workers Scripts → Edit
- Account / Workers Tail → Read (for
/fling tail) - Account / Account Settings → Read (wrangler needs it to resolve the account)
- Account / Workers KV Storage → Edit (if using KV)
- Account / Workers R2 Storage → Edit (if using R2)
- Account / D1 → Edit (if using D1)
- Account / Queues, Vectorize, Workers AI → Edit (only if flinging those bindings)
- Under Account Resources, include only the specific account — not "all accounts"
- Grant no zone-level permissions. Without
Zone / Workers Routes, fling physically cannot touch your domains or DNS — deploys land on*.workers.devonly. (Custom-domain deploys need that zone permission, scoped to the one zone.) - Set a TTL and rotate. Copy the token into
/pluginsettings orCLOUDFLARE_API_TOKEN
An account-scoped token can't enumerate your accounts, so wrangler may also need
CLOUDFLARE_ACCOUNT_IDset in the environment.
Workers Scripts: Edit is account-wide — Cloudflare has no per-worker permissions, so a token that can deploy can also overwrite or delete any Worker in the account, including production ones on *.workers.dev.
Two layers of defense:
- Best: run fling against a separate Cloudflare account (free to create). This is the only true boundary.
- Also set the Protected Workers plugin setting (or
FLING_PROTECTED_WORKERSenv var) to a comma-separated list of names, e.g.license-check, billing-api. The MCP server refuses to deploy over, roll back, or delete those Workers — guarding against the realistic accident: fling auto-derives worker names from directory names, so a name collision can silently replace a production Worker. This is accident protection, not a security boundary — the token itself still permits the operation.
Set the Workers Plan Tier plugin setting (or FLING_WORKERS_TIER) to free or paid and fling enforces your plan's script-size limit before deploying instead of giving a generic advisory.
/fling # Auto-detect and deploy
/fling my-cool-app # Deploy with a custom name
/fling ./dist # Deploy a specific directory
/fling tail # Stream real-time logs
/fling tail --status error # Stream errors only
/fling preview # Upload without deploying to production
/fling rollback # Revert to previous version
/fling rollback <version> # Revert to specific version
/fling delete # Tear down a deployed Worker
/fling dev # Start local dev server
- Checks that your Cloudflare API token is configured
- Detects what to deploy - a
dist/folder,index.html, or Worker script - Generates a
wrangler.jsoncconfig if one doesn't exist - Asks you to confirm the deploy target and project name
- Deploys via MCP tool and returns your live URL
┌──────────────────┐ MCP (stdio) ┌──────────────────┐
│ Claude Code │◄───────────────────►│ fling MCP server │
│ (LLM agent) │ tool calls only │ (server.py) │
│ │ │ │
│ Never sees the │ │ Holds CF_API_ │
│ API token │ │ TOKEN in process │
└──────────────────┘ └────────┬──────────┘
│
wrangler CLI calls
│
┌────────▼──────────┐
│ Cloudflare API │
└───────────────────┘
The MCP server runs as a separate process. The LLM interacts through 6 typed tools (deploy_worker, tail_worker, rollback_worker, delete_worker, preview_worker, dev_worker) - never through raw shell commands that could leak credentials.
Fling scans your Worker code and auto-configures:
- KV, D1, R2 bindings - detected from env.X method calls
- Workers AI - detected from env.AI.run("@cf/...") with billing warning
- Durable Objects - detected from class/namespace usage, scaffolds the required migrations block
- Queues, Vectorize, Workflows - detected from env.X calls and TS types
- Node.js compatibility - adds
nodejs_compatwhen Node built-ins are imported - Observability - enabled on scaffold so
/fling tailactually returns logs - Secrets - detected and flagged (you set them in a separate terminal;
.dev.varsfor local dev) - Build steps - framework detection, auto-build before deploy
- SPA routing - single-page-application mode for React/Vue/Svelte/Angular
- Cron triggers - detected from scheduled() handler
- Size limits - pre-deploy checks against Workers Assets limits (and your plan's script limit when the tier is configured)
V3 uses MCP credential isolation: the Cloudflare API token lives in the MCP server process, never in the LLM context. The LLM cannot extract the token because:
- The token is injected via
userConfig(stored in OS keychain withsensitive: true) - The MCP server only exposes typed tool interfaces - no shell access
- There are no
Bash(wrangler *)permissions - all wrangler calls go through the server
Secret values (API keys in your code) are still never handled - you set them via wrangler secret put in a separate terminal.
- Gradual rollouts (traffic splitting)
- D1 migration management
- /fling promote (preview -> production)
- Project analysis tool (V4 — move detection into MCP server)
MIT