npx skills add vm0-ai/vm0-skills --skill cloudflare-tunnel
rolemodel/rolemodel-skills
cloudflare-tunnel
>- Expose locally-running apps to stable public HTTPS URLs using a single per-developer Cloudflare Tunnel (cloudflared). Use whenever you need an external service to reach your local dev server — receiving webhooks (Box, Stripe, GitHub, Twilio, etc.), testing OAuth callbacks, sharing a work-in-progress with a teammate, or previewing on a real device. Also use when the user mentions cloudflared, "tunnel", "trycloudflare", "public URL for localhost", "webhook can't reach my machine", or asks how …
Installation
npx skills add rolemodel/rolemodel-skills --skill cloudflare-tunnel
Similar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Discover and choose Cloudflare products for apps, APIs, AI agents, storage, networking, and sec…
82.5K installsImplement or troubleshoot Cloudflare Email Sending and Email Routing integrations and their del…
59.4K installsDesign, configure, troubleshoot, or review Cloudflare One Zero Trust and SASE deployments. Use …
48.7K installsAssess and plan migrations from existing VPN, SWG, or SASE platforms to Cloudflare One, includi…
48K installsBuilds AI agents on Cloudflare using the Agents SDK with state management, real-time WebSockets…
3.9K installsBuilds remote MCP (Model Context Protocol) servers on Cloudflare Workers with tools, OAuth auth…
3.6K installsAlso in this package
Other skills from rolemodel/rolemodel-skills · top by installs.
npx skills add rolemodel/rolemodel-skills
More details
Agent compatibility
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
Also listed on
Alternate registries and mirrors of this skill.
npx skills add smithery/vm0-ai --skill cloudflare-tunnel
Repository health
main
Skill metadata
Parsed from SKILL.md frontmatter.
Bash Read Edit WriteMore metadata
- author
- rolemodel
- version
- 1.0
- triggers
- cloudflared, cloudflare tunnel, trycloudflare, tunnel, public URL for localhost, webhook can't reach my machine, route domain to local port
Package contents
Files included with this skill beyond the listing page.
-
skill md
SKILL.md7,786 B -
docs
SUMMARY.md561 B
History
- First seen on skills.sh
- First recorded snapshot · 5 installs
SKILL.md
Cloudflare Tunnel
Route public hostnames on a Cloudflare-managed domain to apps running on localhost. A named tunnel gives stable hostnames that survive restarts — register them with external services once and forget them. This is the right choice for webhook development, where re-registering a URL every session is painful.
(If you only need a throwaway URL for a single session and don't own a Cloudflare domain, cloudflared tunnel --url http://localhost:<port> prints a random *.trycloudflare.com URL with no account or config needed. The rest of this skill covers the named-tunnel setup, which is what you want for anything recurring.)
One tunnel per developer
Run a single tunnel named after yourself (<username>) and route every project through it. A tunnel isn't tied to one app — its ingress list maps many hostnames to many local ports, and one cloudflared process serves them all. This keeps setup to one login, one credentials file, one config, and one running process no matter how many projects you work on.
Give each project a hostname suffixed with your username so they never collide with another developer's. Keep it a single label (<app>--<username>, not <app>.<username>) — a nested subdomain adds a DNS level that a one-level wildcard cert won't cover:
- Tunnel name:
<username>(e.g.mhale) - Hostname per project:
<app>--<username>.<your-domain>
(e.g. fmi-atlas--mhale.rolemodel.dev, other-app--mhale.rolemodel.dev)
Substitute your real username, app slugs, and Cloudflare domain throughout.
Prerequisites
cloudflaredinstalled (brew install cloudflaredon macOS).- A domain managed in the team's Cloudflare account (the DNS route step writes a
CNAME into that zone).
- Credentials to authorize that domain during
cloudflared tunnel login.
1. Log in (one-time per machine)
cloudflared tunnel login
This opens a browser. Authenticate with the account that manages the domain and authorize the domain you'll route to. It writes a cert.pem into ~/.cloudflared/.
2. Create the tunnel (one-time per developer)
cloudflared tunnel create <username>
This provisions the tunnel and writes a credentials file ~/.cloudflared/<TUNNEL-ID>.json. You do this once — every project reuses this same tunnel.
3. Route a hostname for each project
Run this once per project, all pointing at your one tunnel:
cloudflared tunnel route dns <username> <app>--<username>.<your-domain>
4. Write the config file
One ~/.cloudflared/config.yml holds an ingress rule per project. Look up the tunnel ID first:
cloudflared tunnel list | awk '$2 == "<username>" { print $1 }' # the ID
tunnel: <tunnel-id>
credentials-file: /Users/<username>/.cloudflared/<TUNNEL-ID>.json
ingress:
- hostname: <app>--<username>.<your-domain>
service: http://localhost:3000 # this project's port
- hostname: <other-app>--<username>.<your-domain>
service: http://localhost:3001 # another project's port
- service: http_status:404 # catch-all; required last rule
The final catch-all http_status:404 rule is mandatory — cloudflared rejects a config whose last ingress rule has a hostname.
Keep credentials-file in sync with the ID from tunnel list. If you ever delete and recreate the tunnel, the ID changes and this line must be updated — a stale ID here points at a tunnel that no longer exists, so cloudflared fails to start and no routes appear in the Cloudflare UI.
5. Allow the hosts in each app (framework-dependent)
Web frameworks reject requests whose Host header isn't in an allowlist, so a tunneled request 403s until you permit the domain. In a Rails app, add a regex covering the whole domain to config/environments/development.rb so every project's hostname is accepted without editing config per app:
config.hosts << /\A.*\.<your-domain-escaped>\z/ # e.g. /\A.*\.rolemodel\.dev\z/
Other frameworks have an equivalent (Vite's server.allowedHosts, Next.js allowedDevOrigins, Django's ALLOWED_HOSTS, etc.) — set it there instead.
6. Install as a service
Rather than babysitting cloudflared tunnel run in a foreground terminal, install it as a background service so the tunnel is always up and reconnects on its own — you never have to remember to start it before your app.
On macOS, install it as a per-user launch agent (starts at login, reads your existing ~/.cloudflared/config.yml — no sudo, no root):
cloudflared service install
Verify the generated plist actually runs the tunnel. Some cloudflared versions write a launch agent whose ProgramArguments is only the binary path with no subcommand, so launchd runs a bare cloudflared, which exits with "use cloudflared tunnel run to start tunnel <name>" and then crash-loops via KeepAlive. Check ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist; if ProgramArguments lacks a tunnel/run entry, fix it to:
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/cloudflared</string>
<string>--no-autoupdate</string>
<string>--config</string>
<string>/Users/<username>/.cloudflared/config.yml</string>
<string>tunnel</string>
<string>run</string>
</array>
then reload it: launchctl unload <plist> && launchctl load <plist>.
Manage the agent through launchd (user domain — no sudo), and reload it after any config.yml change:
launchctl list | grep cloudflared # col 1 = PID (running), col 2 = last exit code
launchctl unload ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist # stop
launchctl load ~/Library/LaunchAgents/com.cloudflare.cloudflared.plist # start
cloudflared service uninstall # remove the service
cloudflared logs everything (including INF lines) to stderr, so watch ~/Library/Logs/com.cloudflare.cloudflared.err.log — look for Registered tunnel connection on success. Then confirm routing end to end:
curl -sS -o /dev/null -w "HTTP %{http_code}\n" https://<app>--<username>.<your-domain>/
(sudo cloudflared service install instead installs a boot-time launch daemon that reads config from /etc/cloudflared/, logs to /Library/Logs/, and is managed with sudo launchctl. The login agent above is the better fit for a dev machine — it runs as you and uses the config you already set up.)
Adding another project later
No new tunnel needed — reuse the one you have:
cloudflared tunnel route dns <username> <new-app>--<username>.<your-domain>- Add an
ingressrule mapping that hostname to the new project's port. - Restart the service to pick up the config change:
launchctl stop com.cloudflare.cloudflared && launchctl start com.cloudflare.cloudflared