Reference
Command line
The teitunnel reference: add routes, share ports and manage Cloudflare Tunnel from the terminal, with every command, option and origin setting.
teitunnel works with the accounts you connected in the app. Every change goes
through the same preview as the app: you see the plan before anything changes.
Install it
The app puts the teitunnel command on your PATH:
- Windows: the installer does it (a copy in your user's
WindowsAppsfolder, which is already on the PATH), and uninstalling removes it. - Linux: the
.deband.rpminstall/usr/bin/teitunnel. With the AppImage, Teitunnel offers once, after setup, to put it in~/.local/bin. - macOS: Teitunnel offers once, after setup, to link it into Homebrew's
bin(or/usr/local/bin; if it can't write there, it shows the onesudo ln -s …command to run). Installed with Homebrew (brew install --cask teispace/tap/teitunnel), it's linked for you.
You can add or remove it any time in Settings ▸ General ▸ Command line. It updates with the app. For servers without the app, download it on its own from the download page.
The first time it reads your Cloudflare token, macOS asks whether teitunnel may use
the keychain item Teitunnel created. Choose Always Allow to not be asked again.
Where routes run
Routes are served by the app while it's open, all the time with
Always-on (teitunnel always-on on), or by teitunnel up on a
server or in a container. Without the app, give the API token in CLOUDFLARE_API_TOKEN or
CLOUDFLARE_API_TOKEN_FILE; it's never stored
(Servers and containers).
With the app running
When the Teitunnel app is running, teitunnel uses it through its
control connection:
teitunnel share 3000asks the app to share the port. The share shows up in the app's Quick Share and keeps running after the command ends; stop it there or withteitunnel shares --stop <url>. The first time, the app asks you to allow the command line (choose Always Allow to not be asked again).--forstill works, and--hereshares from the terminal instead.teitunnel shareslists the app's shares too, and--stopstops any of them.teitunnel routesshows the status the app's connectors report.teitunnel statussays whether the app runs, its tunnels and what it shares.
Without the app every command works on its own.
Sharing from the terminal
Without the app (or with --here), share runs a Quick Share for exactly as long as the
command. Ctrl-C, closing the terminal or --for stops it. The URL is the only line on
standard output, so URL=$(teitunnel share 3000 | head -1) works in scripts. share
doesn't need an account, only cloudflared (the app's copy, or one on your system). Once the
URL is live, share checks it through Cloudflare and, if your dev server refuses the
address or the service streams events a Quick Share can't carry, says what to do on
standard error; it keeps sharing either way. share --on runs the tunnel's connector itself
when neither the app nor an Always-on service does (a server, a CI job; see
Previews in CI).
Shares go through the inspector unless you pass --no-inspect:
each request is printed on standard error (--quiet stops that) and kept for
teitunnel traffic. teitunnel traffic reads the inspector's history in the app's
database, written by the app and by every teitunnel command with an inspector, with
credentials masked; so traffic get --reveal can't show them, and a replay from history
leaves masked headers out (set them again with --set-header).
Before share and route add make a service public, the
exposure check looks at it for leaks (a .env file, the git
folder, debug pages…) and prints what it finds on standard error; --strict makes that an
error (exit status 1) instead of a warning.
Exit status
0 when it worked, 1 when it didn't, 2 for a mistyped command, and 3 when a hostname is held
by someone else (a share never takes one; other commands need --take-over).
Options many commands share
| Option | Meaning |
|---|---|
-a, --account <ACCOUNT> | Which account, when several are connected (its name or id). |
-y, --yes | Apply without asking (needed when there's no terminal to ask on, e.g. in scripts). |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, routing a public range, or routing a hostname on your domains to WARP clients (Private networks). |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route) (Teams). Without it, the command exits with status 3. |
--tunnel <TUNNEL> | Which of this machine's tunnels a change or export is about (Several tunnels). Default: the tunnel carrying the route, or the default tunnel. |
--json | Machine-readable output, for scripts. |
--app, --here | Go through the running app (and fail if it isn't running), or don't use the app even when it runs. |
Commands
| Command | What it does |
|---|---|
setup | Connect a Cloudflare account with an API token (stored in the OS keychain). |
up | Run this machine's tunnels in the foreground until stopped (servers, containers). |
project | Work with the project file (teitunnel.yml): check, diff, apply, init, down. |
local-domain | Local HTTPS domains on this computer: https://shop.test with a trusted certificate. |
browser | The Teitunnel browser extension: let it talk to the app from your browsers. |
backup | Move to another computer: an encrypted backup of Teitunnel's setup (never a token or password), and restoring it. |
serve | Run this machine's tunnels plus a web dashboard and JSON API (servers). |
mcp | Run Teitunnel's MCP server for AI agents (Claude Code, Cursor, VS Code, Codex…) over stdio, or connect a client to it (teitunnel mcp install cursor). |
api-key | Create, list or revoke API keys for the server API. |
always-on | Keep this machine's tunnels running as an OS service, even after a restart. |
accounts | List connected Cloudflare accounts. |
routes | List this machine's routes and their status. |
status | Whether the Teitunnel app is running, and what it serves. |
top | A live dashboard of shares, routes and traffic (q quits, ? for keys). |
route | Add, or remove, a route. |
networks | List the private networks (ranges and hostnames) this machine shares with WARP clients. |
network | Share, or stop sharing, a private range or hostname with WARP clients. |
tunnels | List this machine's tunnels (routes go on the default one unless --tunnel says). |
tunnel | Create, or delete, one of this machine's tunnels. |
share | Share a local service, or a folder of files, at a temporary public URL until you press Ctrl-C. |
inspect | Inspect one of this machine's routes while this command runs: its requests go through Teitunnel's inspector (shown here and in teitunnel traffic), and it's pointed back at its own service when the command ends. The change is shown first. |
traffic | Requests captured by the inspector: list, show, follow, replay, clear, export. |
token | Show the bearer token a shared service expects (share --mcp or --ai on your domain), or make a new one. |
reserve | Reserve a hostname so teammates sharing the account see it's taken (a placeholder DNS record with your name, until a date or until released). Reserving it again changes the end date; a route you add there keeps the reservation. |
reservations | List the account's reserved hostnames and who holds them (reservations ls). |
release | Give up a hostname's reservation (a route there stays). |
shares | List shares (the app's, terminals' and on your domains), or stop, pause or resume one. |
schedule | Run a share on your domain (or a route) only during set hours: visitors see a paused page the rest of the time. Without hours, shows its schedule. |
schedules | List schedules of shares and routes. |
analytics | Traffic from Cloudflare's edge: one route in detail, or every route of this machine side by side. Needs the token's Zone ▸ Analytics ▸ Read permission. |
uptime | Uptime of this machine's routes (checked every minute through Cloudflare while the app, up or serve runs). |
snapshot | Publish static copies of a site to your Cloudflare account (online while this computer sleeps), and list, update, roll back or delete them. |
protect | Protect a hostname at Cloudflare's edge: challenge or block bots and AI crawlers, rate limit visitors, set or remove headers. Without options, shows what it has now. |
service-token | Service tokens for machines (CI, scripts, servers) to pass a hostname's login. |
comments | Comments reviewers pinned to your shares and Snapshots: list, reply, resolve. |
offline | Show your own page instead of Cloudflare's error 1033 while this computer is off (a Worker on your account; without options, shows what the route has). |
inbox | Keep webhooks while this computer is off and deliver them in order when it's back. |
doctor | Check for problems, like the app's Doctor. Exits with 1 when there's an error. |
cloudflared | The cloudflared Teitunnel uses: status, or install (the latest release from Cloudflare, verified, into Teitunnel's data folder; for servers and CI). |
completions | Print a shell completion script, e.g. teitunnel completions zsh. It completes commands and flags, and your hostnames, tunnels, domains, shares and accounts from this machine's records (no network). |
export | Print this machine's tunnel and routes as config.yml, Docker Compose or Terraform. |
Every command takes -h (a summary) and --help (the full help), and teitunnel --version prints the version.
setup
Connect a Cloudflare account with an API token (stored in the OS keychain).
On a server or in a container without a keychain, don't store it: set CLOUDFLARE_API_TOKEN (or CLOUDFLARE_API_TOKEN_FILE) for each command instead. The token needs Cloudflare Tunnel, DNS and Zone permissions; create one from the template at https://dash.cloudflare.com/profile/api-tokens.
teitunnel setupExamples:
teitunnel setup # store an API token in the keychainSee Accounts and permissions and Permissions and scopes for what the token needs, and Servers and containers for giving it in the environment.
up
Run this machine's tunnels in the foreground until stopped (servers, containers).
In a folder with a teitunnel.yml, its plan is shown and applied first, and its shares run as long as this does.
teitunnel up [OPTIONS]| Option | Description |
|---|---|
-f, --file <PATH> | The project file to apply first (default: teitunnel.yml in this folder or the nearest one above it in the repository, when there is one). |
--no-project | Don't apply a project file, even if there is one here. |
-a, --account <ACCOUNT> | Account name or id (default: the file's account). |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation (replacing DNS records Teitunnel didn't create). |
--strict | Don't start a share when the exposure check finds a leak. |
Examples:
teitunnel up # run this machine's tunnels (servers, Docker)
teitunnel up --no-project # ignore the teitunnel.yml in this folderSee Servers and containers and Project files.
project
Work with the project file (teitunnel.yml): check, diff, apply, init, down.
teitunnel project <COMMAND>| Command | What it does |
|---|---|
project init | Write a starter teitunnel.yml for this folder, from the routes and shares this machine runs for its project. |
project check | Check the project file: every problem with its line and column. Needs no account. |
project diff | Show what applying the project file would change. Nothing is changed. |
project apply | Apply the project file: its routes and Snapshots, then its shares until Ctrl-C. |
project down | Stop the project's shares; with --remove-routes, also remove the routes it created (never routes that were there before). |
project list | List the projects this machine knows. |
See Project files.
project init
Write a starter teitunnel.yml for this folder, from the routes and shares this machine runs for its project.
teitunnel project init [OPTIONS]| Option | Description |
|---|---|
--force | Replace an existing teitunnel.yml. |
-a, --account <ACCOUNT> | Account name or id. |
Examples:
teitunnel project init # a starter teitunnel.yml for this folderproject check
Check the project file: every problem with its line and column. Needs no account.
teitunnel project check [OPTIONS]| Option | Description |
|---|---|
-f, --file <PATH> | The project file, or a folder with one (default: this folder or the nearest one above it in the repository). |
Examples:
teitunnel project check # every problem in it, with line and columnproject diff
Show what applying the project file would change. Nothing is changed.
teitunnel project diff [OPTIONS]| Option | Description |
|---|---|
-f, --file <PATH> | The project file, or a folder with one (default: this folder or the nearest one above it in the repository). |
-a, --account <ACCOUNT> | Account name or id (default: the file's account). |
--json | Print JSON. |
Examples:
teitunnel project diff # what applying it would change (nothing changes)project apply
Apply the project file: its routes and Snapshots, then its shares until Ctrl-C.
teitunnel project apply [OPTIONS]| Option | Description |
|---|---|
-f, --file <PATH> | The project file, or a folder with one (default: this folder or the nearest one above it in the repository). |
-a, --account <ACCOUNT> | Account name or id (default: the file's account). |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation (replacing DNS records Teitunnel didn't create). |
--strict | Don't start a share when the exposure check finds a leak. |
Examples:
teitunnel project apply # apply it; its shares run until Ctrl-Cproject down
Stop the project's shares; with --remove-routes, also remove the routes it created (never routes that were there before).
teitunnel project down [OPTIONS]| Option | Description |
|---|---|
-f, --file <PATH> | The project file, or a folder with one (default: this folder or the nearest one above it in the repository). |
--remove-routes | Also remove the routes applying the project created. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
Examples:
teitunnel project down --remove-routes # stop its shares, remove the routes it createdproject list
List the projects this machine knows.
teitunnel project list [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
local-domain
Local HTTPS domains on this computer: https://shop.test with a trusted certificate.
Also: local.
teitunnel local-domain <COMMAND>| Command | What it does |
|---|---|
local-domain add | Give a local service an HTTPS address like https://shop.test. |
local-domain ls | List local domains and whether they're served. |
local-domain rm | Remove a local domain. |
local-domain serve | Serve every local domain from this terminal until Ctrl-C (or hand them to the running app). |
local-domain trust | Trust Teitunnel's local certificate authority, so browsers accept local domains. |
local-domain untrust | Stop trusting the local certificate authority. |
local-domain status | Certificates, trust, ports, .test names and each domain, with what to fix. |
See Local domains.
local-domain add
Give a local service an HTTPS address like https://shop.test.
Names end in .localhost (works in browsers with no setup), .test (every tool, after a one-time resolver entry) or .local (also phones on your network). Served by the Teitunnel app when it runs, otherwise from this terminal until Ctrl-C.
teitunnel local-domain add [OPTIONS] <NAME> <TARGET>| Argument | Description |
|---|---|
<NAME> | The name, e.g. shop.test (".localhost" is added when there's no suffix). |
<TARGET> | The service: a port (3000), host:port, or a URL (https://localhost:5173). |
| Option | Description |
|---|---|
--wildcard | Subdomains (*.name) go to the same service. |
--no-https | Plain HTTP only (no certificate). |
--inspect | Record its requests (see teitunnel traffic). |
--no-serve | Only save it; don't serve it from this terminal when the app isn't running. |
--here | Serve it from this terminal even if the app runs. |
Examples:
teitunnel local-domain add shop.test 3000 # https://shop.test on this computerlocal-domain ls
List local domains and whether they're served.
Also: list.
teitunnel local-domain ls [OPTIONS]| Option | Description |
|---|---|
--json | JSON output. |
Examples:
teitunnel local-domain ls # local domains and whether they're servedlocal-domain rm
Remove a local domain.
Also: remove.
teitunnel local-domain rm <NAME>| Argument | Description |
|---|---|
<NAME> | Its name. |
local-domain serve
Serve every local domain from this terminal until Ctrl-C (or hand them to the running app).
teitunnel local-domain serve [OPTIONS]| Option | Description |
|---|---|
--here | Serve from this terminal even if the app runs. |
local-domain trust
Trust Teitunnel's local certificate authority, so browsers accept local domains.
macOS asks for your password; Windows asks you to confirm. On Linux the system store needs an administrator: the commands to run are printed.
teitunnel local-domain trust [OPTIONS]| Option | Description |
|---|---|
--browsers | Also add it to Chrome's and Firefox's own certificate databases (NSS). |
--firefox | Turn on "trust the system's certificates" in Firefox profiles. |
Examples:
teitunnel local-domain trust # browsers accept local domainslocal-domain untrust
Stop trusting the local certificate authority.
teitunnel local-domain untrust [OPTIONS]| Option | Description |
|---|---|
--forget | Also delete it (a new one is made the next time it's needed). |
local-domain status
Certificates, trust, ports, .test names and each domain, with what to fix.
teitunnel local-domain status [OPTIONS]| Option | Description |
|---|---|
--json | JSON output. |
Examples:
teitunnel local-domain status # CA, trust, ports, .test names, what to fixbrowser
The Teitunnel browser extension: let it talk to the app from your browsers.
teitunnel browser <COMMAND>| Command | What it does |
|---|---|
browser install | Let the Teitunnel browser extension talk to the app, in every installed browser. |
browser uninstall | Stop letting the extension talk to the app. |
browser status | Which browsers can use the extension. |
browser install
Let the Teitunnel browser extension talk to the app, in every installed browser.
teitunnel browser install [OPTIONS]| Option | Description |
|---|---|
--browser <BROWSER> | Only this browser: chrome, chromium, edge, brave, vivaldi, arc or firefox. |
browser uninstall
Stop letting the extension talk to the app.
teitunnel browser uninstall [OPTIONS]| Option | Description |
|---|---|
--browser <BROWSER> | Only this browser. |
browser status
Which browsers can use the extension.
teitunnel browser status [OPTIONS]| Option | Description |
|---|---|
--json | JSON output. |
backup
Move to another computer: an encrypted backup of Teitunnel's setup (never a token or password), and restoring it.
teitunnel backup <COMMAND>| Command | What it does |
|---|---|
backup create | Write an encrypted backup of this computer's setup (settings, tunnels, routes' ownership, projects, alert rules; never tokens or passwords). |
backup restore | Show what a backup holds and restore it (asks before replacing anything). |
backup create
Write an encrypted backup of this computer's setup (settings, tunnels, routes' ownership, projects, alert rules; never tokens or passwords).
teitunnel backup create [OPTIONS]| Option | Description |
|---|---|
-f, --file <PATH> | Where to write it (default: teitunnel-setup.teitunnel-backup here). |
--passphrase-stdin | Read the passphrase from the first line of standard input. |
Examples:
teitunnel backup create # an encrypted copy of this setup (no tokens)backup restore
Show what a backup holds and restore it (asks before replacing anything).
teitunnel backup restore [OPTIONS] <FILE>| Argument | Description |
|---|---|
<FILE> | The backup file. |
| Option | Description |
|---|---|
--passphrase-stdin | Read the passphrase from the first line of standard input. |
-y, --yes | Restore without asking. |
Examples:
teitunnel backup restore teitunnel-setup.teitunnel-backupserve
Run this machine's tunnels plus a web dashboard and JSON API (servers).
Listens on 127.0.0.1:8765 unless told otherwise. Sign in with the password set by --set-password (or TEITUNNEL_WEB_PASSWORD); automation uses API keys.
teitunnel serve [OPTIONS]| Option | Description |
|---|---|
--listen <LISTEN> | Where to listen. Default: 127.0.0.1:8765. |
--allow-remote | Allow listening on a non-loopback address (put TLS in front of it). |
--secure-cookies | Mark the session cookie Secure (when served over HTTPS). |
--set-password | Set the dashboard password (read from the terminal) and exit. |
--no-mcp | Don't serve the MCP endpoint (/mcp, for AI agents with an API key). |
--mcp-mode <MCP_MODE> | The MCP endpoint's mode: read-only, ask (default) or full. |
--mcp-allow-origin <ORIGIN> | A browser origin allowed to call /mcp (repeatable). Agents send none. |
Examples:
teitunnel serve # tunnels + web dashboard, API and /mcp
teitunnel serve --set-passwordmcp
Run Teitunnel's MCP server for AI agents (Claude Code, Cursor, VS Code, Codex…) over stdio, or connect a client to it (teitunnel mcp install cursor).
Agents share local services, manage routes through reviewed plans, diagnose problems and inspect traffic. Modes: read-only, ask (default: every change needs your approval) and full. Secrets never reach the agent.
teitunnel mcp [OPTIONS] [COMMAND]| Option | Description |
|---|---|
--mode <MODE> | read-only, ask (default) or full. |
--allow-secrets | Show credentials in captured traffic and logs to the agent (off by default). |
| Command | What it does |
|---|---|
mcp install | Add Teitunnel to an AI client's MCP configuration (merged; a backup is kept). |
mcp uninstall | Remove Teitunnel from an AI client's MCP configuration (nothing else changes). |
mcp config | Print the configuration to add by hand. |
mcp status | Show which AI clients are installed and connected. |
Examples:
teitunnel mcp # the MCP server itself (AI tools start it)See AI agents.
mcp install
Add Teitunnel to an AI client's MCP configuration (merged; a backup is kept).
teitunnel mcp install [OPTIONS] <CLIENT>| Argument | Description |
|---|---|
<CLIENT> | claude-code, claude-desktop, cursor, vscode, codex, windsurf, zed or gemini-cli. |
| Option | Description |
|---|---|
--mode <MODE> | The mode the client's server runs in (default: the settings file's, else ask). |
Examples:
teitunnel mcp install cursor # connect an AI toolmcp uninstall
Remove Teitunnel from an AI client's MCP configuration (nothing else changes).
teitunnel mcp uninstall <CLIENT>| Argument | Description |
|---|---|
<CLIENT> | The client (see install). |
mcp config
Print the configuration to add by hand.
teitunnel mcp config [OPTIONS] <CLIENT>| Argument | Description |
|---|---|
<CLIENT> | The client (see install). |
| Option | Description |
|---|---|
--mode <MODE> | The mode to run in. |
mcp status
Show which AI clients are installed and connected.
teitunnel mcp status [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
Examples:
teitunnel mcp status # which AI tools are connectedapi-key
Create, list or revoke API keys for the server API.
teitunnel api-key <COMMAND>| Command | What it does |
|---|---|
api-key create | Create a key (shown once). |
api-key list | List keys (names only). |
api-key revoke | Revoke a key by its id (from list). |
api-key create
Create a key (shown once).
teitunnel api-key create <NAME>| Argument | Description |
|---|---|
<NAME> | What it's for, e.g. deploy. |
Examples:
teitunnel api-key create deploy # a key for the API (shown once)api-key list
List keys (names only).
teitunnel api-key listapi-key revoke
Revoke a key by its id (from list).
teitunnel api-key revoke <ID>| Argument | Description |
|---|---|
<ID> | The key's id. |
always-on
Keep this machine's tunnels running as an OS service, even after a restart.
teitunnel always-on [OPTIONS] <ACTION>| Argument | Description |
|---|---|
<ACTION> | on, off or status. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--tunnel <TUNNEL> | Only this tunnel (by name); default: all of the account's. |
Examples:
teitunnel always-on on # as a service (a system unit as root)See Run modes.
accounts
List connected Cloudflare accounts.
teitunnel accounts [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
Examples:
teitunnel accounts --jsonroutes
List this machine's routes and their status.
teitunnel routes [OPTIONS]| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id (needed when several are connected). |
--json | Print JSON. |
--check | Exit with 1 unless every route is live (a health check for containers and monitoring). Checks every account when none is named. |
--app | Ask the running app (its connectors' state is the live one); fails if it isn't running. By default the app is used when it runs. |
Examples:
teitunnel routes # this machine's routes and their status
teitunnel routes --check # exit 1 unless every route is livestatus
Whether the Teitunnel app is running, and what it serves.
teitunnel status [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
Examples:
teitunnel status # is the app running, and what does it serve?top
A live dashboard of shares, routes and traffic (q quits, ? for keys).
teitunnel top [OPTIONS]| Option | Description |
|---|---|
--app | Only with the running app. |
--here | Without the app, from this machine's records. |
Examples:
teitunnel top # a live dashboard (q quits)top shows your shares (address, service, age, requests per second), routes (a status dot, where they go, uptime over 24 hours), traffic, and the requests of a share the app inspects. It reads from the app when it runs; otherwise from this machine's records (then you can see and stop terminals' shares, but not start new ones). It follows the terminal's size and uses no colour when NO_COLOR is set.
| Key | Does |
|---|---|
q, Esc | quit (Esc first clears a filter) |
Tab | next pane |
↑ ↓, j k | select |
s | share a port (through the app) |
x x | stop the selected share (press twice) |
c | copy the selected URL (through the terminal, so it works over SSH too) |
/ | filter everything by text |
? | the keys |
route
Add, or remove, a route.
teitunnel route <COMMAND>| Command | What it does |
|---|---|
route add | Route a hostname to a service on this machine, e.g. app.yourhost.com 3000. |
route balance | Load balance a route across every machine that routes its hostname (Cloudflare Load Balancing, a paid add-on): add the same route on each machine first. |
route unbalance | Stop load balancing a route (its DNS record serves it again). |
route remove | Remove a route (and its DNS record, if Teitunnel created it). |
route add
Route a hostname to a service on this machine, e.g. app.yourhost.com 3000.
teitunnel route add [OPTIONS] <HOSTNAME> <ORIGIN>| Argument | Description |
|---|---|
<HOSTNAME> | Public hostname on one of the account's domains. |
<ORIGIN> | Where traffic goes: a port (3000), host:port, or a URL. |
| Option | Description |
|---|---|
--path <PATH> | Only requests whose path matches this regex, e.g. ^/api. |
--allow <EMAIL|@DOMAIN|github:ORG[/TEAM]> | Require a login: an email address, @domain for anyone at that domain, or github:ORG[/TEAM] for the members of a GitHub organization or team. Repeat for more people. Needs Cloudflare Zero Trust (free). |
--sign-in <METHOD> | With --allow: how people log in, github or google (the account's login method of that kind, set up in Cloudflare Zero Trust), or any (the default). |
--skip-login <PATH> | With --allow: a path that skips the login, e.g. /webhooks, so webhook senders get through; repeatable. |
Origin settings
| Option | Description |
|---|---|
--host-header <HOST> | Host header sent to the service, e.g. for a dev server that checks it. |
--no-tls-verify | Accept any certificate from an HTTPS service (self-signed ones). |
--origin-server-name <NAME> | Hostname expected on the service's TLS certificate. |
--match-sni-to-host | Use the request's hostname as the TLS server name. |
--ca-pool <PATH> | Certificate authority file for the service's certificate. |
--http2-origin | Speak HTTP/2 to an HTTPS service. |
--disable-chunked-encoding | Don't use chunked transfer encoding (some WSGI servers need this). |
--connect-timeout <SECONDS> | Seconds to wait for a connection to the service. |
--tls-timeout <SECONDS> | Seconds to wait for the TLS handshake. |
--tcp-keep-alive <SECONDS> | Seconds between TCP keepalive packets. |
--keep-alive-timeout <SECONDS> | Seconds before an idle keepalive connection closes. |
--keep-alive-connections <COUNT> | Idle keepalive connections kept open. |
--no-happy-eyeballs | Don't fall back between IPv4 and IPv6. |
--proxy-type <TYPE> | socks to use the service as a SOCKS5 proxy (TCP routes). |
--strict | Don't add the route when the exposure check finds a leak in the service; by default it only warns. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel route add app.yourhost.com 3000 # route a hostname to localhost:3000
teitunnel route add api.yourhost.com 8000 --path '^/v1/'
teitunnel route add admin.yourhost.com 3000 --allow team@yourhost.com --allow @yourhost.com
teitunnel route add beta.yourhost.com 4000 --tunnel staging
teitunnel route add secure.yourhost.com https://localhost:8443 --no-tls-verify
teitunnel route add dev.yourhost.com 5173 --host-header localhost
teitunnel route add slow.yourhost.com 8000 --connect-timeout 60 --keep-alive-timeout 300--allow puts a login in front of the route (Require a login); --tunnel picks one of this machine's tunnels (Several tunnels). After adding a route, the command checks it through Cloudflare and exits with status 1 if it doesn't work yet.
The origin settings are cloudflared's originRequest settings, the same as the app's (leave them out for cloudflared's defaults):
| Flag | Setting |
|---|---|
--host-header | httpHostHeader |
--no-tls-verify | noTLSVerify |
--origin-server-name | originServerName |
--match-sni-to-host | matchSNItoHost |
--ca-pool | caPool |
--http2-origin | http2Origin |
--disable-chunked-encoding | disableChunkedEncoding |
--connect-timeout | connectTimeout |
--tls-timeout | tlsTimeout |
--tcp-keep-alive | tcpKeepAlive |
--keep-alive-timeout | keepAliveTimeout |
--keep-alive-connections | keepAliveConnections |
--no-happy-eyeballs | noHappyEyeballs |
--proxy-type | proxyType |
route balance
Load balance a route across every machine that routes its hostname (Cloudflare Load Balancing, a paid add-on): add the same route on each machine first.
teitunnel route balance [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | Hostname. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel route balance app.yourhost.com # load balance across machines (paid add-on)See Load balancing.
route unbalance
Stop load balancing a route (its DNS record serves it again).
teitunnel route unbalance [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | Hostname. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
route remove
Remove a route (and its DNS record, if Teitunnel created it).
teitunnel route remove [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | Hostname. |
| Option | Description |
|---|---|
--path <PATH> | The route's path rule, if it has one. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel route remove app.yourhost.comnetworks
List the private networks (ranges and hostnames) this machine shares with WARP clients.
teitunnel networks [OPTIONS]| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
Examples:
teitunnel networks # the ranges and hostnames this machine sharesnetwork
Share, or stop sharing, a private range or hostname with WARP clients.
teitunnel network <COMMAND>| Command | What it does |
|---|---|
network add | Let WARP clients reach a range or a hostname through this machine, e.g. 192.168.1.0/24 or wiki.internal. |
network remove | Stop routing a range or a hostname through this machine. |
See Private networks.
network add
Let WARP clients reach a range or a hostname through this machine, e.g. 192.168.1.0/24 or wiki.internal.
teitunnel network add [OPTIONS] <NETWORK>| Argument | Description |
|---|---|
<NETWORK> | An IP address, a CIDR range, or a private hostname (resolved by this machine's DNS). |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel network add 192.168.1.0/24 # let WARP users reach a range
teitunnel network add wiki.internal # … or a hostname this machine resolvesnetwork remove
Stop routing a range or a hostname through this machine.
teitunnel network remove [OPTIONS] <NETWORK>| Argument | Description |
|---|---|
<NETWORK> | The range or hostname. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel network remove 192.168.1.0/24
teitunnel network remove wiki.internaltunnels
List this machine's tunnels (routes go on the default one unless --tunnel says).
teitunnel tunnels [OPTIONS]| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
Examples:
teitunnel tunnels # this machine's tunnelstunnel
Create, or delete, one of this machine's tunnels.
teitunnel tunnel <COMMAND>| Command | What it does |
|---|---|
tunnel create | Create another tunnel for this machine, e.g. staging. |
tunnel adopt | Run an existing tunnel of the account on this machine too (nothing changes in Cloudflare). If another machine runs it, requests are split between them. |
tunnel delete | Delete one of this machine's tunnels, with its routes and the DNS records Teitunnel created for them. |
See Several tunnels.
tunnel create
Create another tunnel for this machine, e.g. staging.
teitunnel tunnel create [OPTIONS] <NAME>| Argument | Description |
|---|---|
<NAME> | Its name (unique in the account). |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel tunnel create staging # another tunnel for this machinetunnel adopt
Run an existing tunnel of the account on this machine too (nothing changes in Cloudflare). If another machine runs it, requests are split between them.
teitunnel tunnel adopt [OPTIONS] <NAME>| Argument | Description |
|---|---|
<NAME> | The tunnel's name or id. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
tunnel delete
Delete one of this machine's tunnels, with its routes and the DNS records Teitunnel created for them.
teitunnel tunnel delete [OPTIONS] <NAME>| Argument | Description |
|---|---|
<NAME> | The tunnel's name. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel tunnel delete stagingshare
Share a local service, or a folder of files, at a temporary public URL until you press Ctrl-C.
teitunnel share [OPTIONS] <ORIGIN>| Argument | Description |
|---|---|
<ORIGIN> | What to share: a port (3000), host:port, a URL, or a folder (./dist). |
| Option | Description |
|---|---|
--for <DURATION> | Stop by itself after this long, e.g. 30m, 2h, 90s. |
--no-qr | Don't print a QR code. |
--on [HOSTNAME] | Share at this hostname on one of your domains instead of a random trycloudflare.com address (removed again when the command ends). {project}, {branch} and {user} are filled in from this folder, e.g. --on {branch}.dev.yourhost.com; --on alone uses the name last used here. |
--listing | With a folder: list the files of folders that have no index.html (the default when the folder itself has none). |
--no-listing | With a folder: never list files, even when it has no index.html. |
--spa | With a folder: a single-page app (unknown paths get /index.html). |
--schedule <DAYS HH:MM-HH:MM> | With --on: on only during these hours, paused otherwise, e.g. "mon-fri 09:00-18:00". |
--tz <ZONE> | With --schedule: its time zone, e.g. Europe/Berlin (default: this computer's). |
-a, --account <ACCOUNT> | With --on: the account, when several are connected. |
--allow <EMAIL|@DOMAIN|github:ORG[/TEAM]> | With --on: require a login (an email address, @domain, or github:ORG[/TEAM] for the members of a GitHub organization or team); repeatable. |
--sign-in <METHOD> | With --allow: how people log in, github or google (the account's login method of that kind, set up in Cloudflare Zero Trust), or any (the default). |
--host-header <HOST> | Send this Host header to the service, e.g. localhost:5173 for a dev server that only answers its own address. By default Vite, webpack and Angular dev servers get their own address. |
--no-host-header | Pass the visitor's Host header through unchanged, even to a dev server. |
--app | Share through the running app (it keeps the share after this command ends); fails if the app isn't running. This is the default when the app runs. |
--here | Share from this terminal, for as long as the command runs, even when the app is running. |
--json | Print {"url": …, "hostname": …} on stdout once it's live (for scripts and CI). |
--strict | Don't share when the exposure check finds a leak (a .env file, the git folder, debug pages…); by default it only warns. |
--no-inspect | Don't send requests through Teitunnel's inspector (it records them for teitunnel traffic, masking credentials). |
-q, --quiet | Don't print a line for each request. |
--idle <DURATION> | Stop after this long without a request, e.g. 30m. |
--watch <PATH> | Say so when a request hits this path, e.g. /webhooks/* (repeatable). |
--comments | Let visitors pin comments on its pages (read and answer them with teitunnel comments or in the app). |
--mcp | Share a local MCP server for remote AI clients: checks it answers MCP, keeps streams alive and requires a bearer token (needs --on: Quick Tunnels don't carry event streams). Prints configurations for Claude Code, Cursor and VS Code. |
--mcp-path <PATH> | With --mcp: the server's endpoint path (default: /mcp, then /sse and /). |
--ai | Share a local AI server (Ollama, LM Studio, vLLM) behind a bearer token, for OpenAI-compatible clients. |
--new-token | With --mcp or --ai on your domain: make a new token instead of the saved one. |
Examples:
teitunnel share 3000 # a temporary public URL (in the app when it runs)
teitunnel share 3000 --here --for 30m # in this terminal, until Ctrl-C or 30 minutes
teitunnel share 3000 --on demo.yourhost.com # the same, on your own domain
teitunnel share 3000 --on {branch}.dev.yourhost.com # named after the git branch
teitunnel share 3000 --on # the name used in this folder last time
teitunnel share ./dist # share a folder of files
teitunnel share ./dist --on docs.yourhost.com --spa
teitunnel share 3000 --no-inspect # skip the inspector (on by default)
teitunnel share 8000 --mcp --on mcp.yourhost.com # an MCP server for remote AI clients
teitunnel share 11434 --ai # a local AI server behind a bearer tokenSee Sharing, Dev servers for --host-header, the inspector and the exposure check.
inspect
Inspect one of this machine's routes while this command runs: its requests go through Teitunnel's inspector (shown here and in teitunnel traffic), and it's pointed back at its own service when the command ends. The change is shown first.
teitunnel inspect [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The route's hostname. |
| Option | Description |
|---|---|
--path <PATH> | The route's path rule, if it has one. |
-a, --account <ACCOUNT> | Account name or id. |
--off | Point a route left inspected back at its own service. |
-y, --yes | Don't ask before changing the route. |
Examples:
teitunnel inspect app.yourhost.com # a route's requests, until Ctrl-C
teitunnel inspect app.yourhost.com --off # restore a route left inspectedSee Inspector.
traffic
Requests captured by the inspector: list, show, follow, replay, clear, export.
teitunnel traffic <COMMAND>| Command | What it does |
|---|---|
traffic ls | List captured requests, newest first. |
traffic get | Show one request and its response. |
traffic watch | Print requests as they arrive, until Ctrl-C. |
traffic replay | Send a captured request to its service again. |
traffic clear | Forget captured requests (all, or one share's or route's). |
traffic export | Export captured requests to a file (HAR by default). |
traffic openapi | Describe the API the captured requests show, as OpenAPI 3.1: paths with parameters (/users/123 becomes /users/{id}), methods, parameters, JSON bodies as schemas, status codes. Pages and assets are left out; no captured values are copied in. |
See Inspector and OpenAPI from traffic.
traffic ls
List captured requests, newest first.
teitunnel traffic ls [OPTIONS]| Option | Description |
|---|---|
--host <HOST> | Only this host (text in it). |
--method <METHOD> | Only this method. |
--status <STATUS> | A status (404) or class (5xx). |
--path <PATH> | Text in the path. |
--kind <KIND> | http, ws or sse. Values: http: Plain HTTP; ws: WebSocket; sse: Server-sent events. |
--text <TEXT> | Text anywhere in the request or response (secrets can't be searched). |
--last <LAST> | How many. Default: 20. |
--json | Print JSON (one object per request, newest first). |
Examples:
teitunnel traffic ls --status 5xxtraffic get
Show one request and its response.
teitunnel traffic get [OPTIONS] <ID>| Argument | Description |
|---|---|
<ID> | The request's id (or the end of it, as ls shows). |
| Option | Description |
|---|---|
--format <FORMAT> | markdown, curl, httpie, fetch, http, har or json. Values: markdown: Markdown (issues, chats, agents); curl: A curl command; httpie: An HTTPie command; fetch: A JavaScript fetch call; http: Raw HTTP; har: HAR 1.2; json: JSON. Default: markdown. |
--reveal | Show credentials (only possible in the process that captured the request; the history keeps them masked). |
Examples:
teitunnel traffic get 7f3a9c1b --format curltraffic watch
Print requests as they arrive, until Ctrl-C.
teitunnel traffic watch [OPTIONS]| Option | Description |
|---|---|
--host <HOST> | Only this host (text in it). |
--method <METHOD> | Only this method. |
--status <STATUS> | A status (404) or class (5xx). |
--path <PATH> | Text in the path. |
--kind <KIND> | http, ws or sse. Values: http: Plain HTTP; ws: WebSocket; sse: Server-sent events. |
--text <TEXT> | Text anywhere in the request or response (secrets can't be searched). |
--json | Print JSON lines. |
Examples:
teitunnel traffic watch --path /webhookstraffic replay
Send a captured request to its service again.
teitunnel traffic replay [OPTIONS] <ID>| Argument | Description |
|---|---|
<ID> | The request's id (or the end of it). |
| Option | Description |
|---|---|
--set-header <NAME:VALUE> | Set a header, Name: value (repeatable). |
--method <METHOD> | Another method. |
--path <PATH> | Another path (with query string). |
--body <BODY> | Another body: text, or @file to read it from a file. |
--times <TIMES> | How many times, one after another (1–100). Default: 1. |
Examples:
teitunnel traffic replay 7f3a9c1b --set-header 'X-Debug: 1'traffic clear
Forget captured requests (all, or one share's or route's).
teitunnel traffic clear [OPTIONS]| Option | Description |
|---|---|
--tap <TAP> | Only this tap (as ls --json shows it). |
Examples:
teitunnel traffic cleartraffic export
Export captured requests to a file (HAR by default).
teitunnel traffic export [OPTIONS]| Option | Description |
|---|---|
--har <FILE> | Write a HAR file here. |
--format <FORMAT> | Or write another format (markdown, curl, httpie, fetch, http, json) to stdout. Values: markdown: Markdown (issues, chats, agents); curl: A curl command; httpie: An HTTPie command; fetch: A JavaScript fetch call; http: Raw HTTP; har: HAR 1.2; json: JSON. |
--host <HOST> | Only this host (text in it). |
--method <METHOD> | Only this method. |
--status <STATUS> | A status (404) or class (5xx). |
--path <PATH> | Text in the path. |
--kind <KIND> | http, ws or sse. Values: http: Plain HTTP; ws: WebSocket; sse: Server-sent events. |
--text <TEXT> | Text anywhere in the request or response (secrets can't be searched). |
--last <LAST> | How many (newest first). Default: 100. |
Examples:
teitunnel traffic export --har requests.hartraffic openapi
Describe the API the captured requests show, as OpenAPI 3.1: paths with parameters (/users/123 becomes /users/{id}), methods, parameters, JSON bodies as schemas, status codes. Pages and assets are left out; no captured values are copied in.
teitunnel traffic openapi [OPTIONS]| Option | Description |
|---|---|
--host <HOST> | Only requests to this host, e.g. api.yourhost.com. |
--out <FILE> | Write it here (.yaml/.yml writes YAML); default: JSON on stdout. |
--yaml | YAML on stdout. |
--title <TITLE> | The document's title. |
Examples:
teitunnel traffic openapi --out api.yaml # an OpenAPI 3.1 file from captured requeststoken
Show the bearer token a shared service expects (share --mcp or --ai on your domain), or make a new one.
teitunnel token [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
| Option | Description |
|---|---|
--new | Make a new token (clients with the old one stop working). |
Examples:
teitunnel token mcp.yourhost.com # the token a shared MCP or AI server expectsreserve
Reserve a hostname so teammates sharing the account see it's taken (a placeholder DNS record with your name, until a date or until released). Reserving it again changes the end date; a route you add there keeps the reservation.
teitunnel reserve [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname, e.g. review.dev.yourhost.com. |
| Option | Description |
|---|---|
--until <DATE> | When it ends: 2026-12-31 (end of that day, UTC) or 2026-12-31T18:00Z. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel reserve review.dev.yourhost.com --until 2026-12-31 # hold a name for yourselfSee Teams sharing one account.
reservations
List the account's reserved hostnames and who holds them (reservations ls).
teitunnel reservations [OPTIONS] [ACTION]| Argument | Description |
|---|---|
[ACTION] | ls (the default). |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
Examples:
teitunnel reservations ls # reserved names and who holds themrelease
Give up a hostname's reservation (a route there stays).
teitunnel release [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range. |
--take-over | Take a hostname someone else holds (their reservation, or another machine's route). |
--tunnel <TUNNEL> | One of this machine's tunnels, by name. Default: the tunnel carrying the route, or the default tunnel for a new one. |
Examples:
teitunnel release review.dev.yourhost.comshares
List shares (the app's, terminals' and on your domains), or stop, pause or resume one.
teitunnel shares [OPTIONS]| Option | Description |
|---|---|
--stop <URL|HOSTNAME> | Stop a share: its URL, its hostname on your domain, or its id. |
--pause <URL|HOSTNAME> | Pause a share (on your domain, a route, or one of the app's Quick Shares by its URL or id): the address stays, and visitors see a paused page until it's resumed. |
--resume <URL|HOSTNAME> | Serve a paused share or route again, at the same address. |
-a, --account <ACCOUNT> | With --pause or --resume on a route: the account, when several are connected. |
--json | Print JSON. |
--app | Ask the running app; fails if it isn't running. By default the app is used when it runs. |
Examples:
teitunnel shares # every share: the app's, terminals', your domains'
teitunnel shares --stop demo.yourhost.com
teitunnel shares --pause demo.yourhost.com # a paused page; the address stays
teitunnel shares --resume demo.yourhost.comschedule
Run a share on your domain (or a route) only during set hours: visitors see a paused page the rest of the time. Without hours, shows its schedule.
teitunnel schedule [OPTIONS] <HOSTNAME> [DAYS HH:MM-HH:MM]...| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
[DAYS HH:MM-HH:MM]... | Days and hours, e.g. mon-fri 09:00-18:00, weekends 10:00-16:00 or daily 22:00-02:00 (past midnight). |
| Option | Description |
|---|---|
--tz <ZONE> | The time zone, e.g. Europe/Berlin (default: this computer's). |
--off | Remove the schedule (the share stays as it is now). |
-a, --account <ACCOUNT> | Account name or id. |
Examples:
teitunnel schedule demo.yourhost.com mon-fri 09:00-18:00 # on during office hours
teitunnel schedule demo.yourhost.com --offschedules
List schedules of shares and routes.
teitunnel schedules [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
Examples:
teitunnel schedules # every schedule, and when each changes nextanalytics
Traffic from Cloudflare's edge: one route in detail, or every route of this machine side by side. Needs the token's Zone ▸ Analytics ▸ Read permission.
teitunnel analytics [OPTIONS] [HOSTNAME]| Argument | Description |
|---|---|
[HOSTNAME] | A route's hostname (default: every route of this machine). |
| Option | Description |
|---|---|
--path <PATH> | With a hostname: only requests under this path, e.g. /api. |
--range <RANGE> | hour, day, week or month. Default: day. |
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
Examples:
teitunnel analytics # traffic of every route, from Cloudflare's edge
teitunnel analytics app.yourhost.com --range weekSee Analytics.
uptime
Uptime of this machine's routes (checked every minute through Cloudflare while the app, up or serve runs).
teitunnel uptime [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
Examples:
teitunnel uptime # uptime of this machine's routessnapshot
Publish static copies of a site to your Cloudflare account (online while this computer sleeps), and list, update, roll back or delete them.
teitunnel snapshot <COMMAND>| Command | What it does |
|---|---|
snapshot publish | Publish a folder (or a build, or a running site) as a new Snapshot. |
snapshot update | Publish a new version: files from the same place again (or from PATH), and/or new settings. Only changed files are uploaded. |
snapshot ls | List Snapshots. |
snapshot versions | List a Snapshot's kept versions. |
snapshot rollback | Make an earlier version live again (default: the one before the live one). |
snapshot rm | Delete a Snapshot: its address, login and Worker on Cloudflare. |
See Snapshots.
snapshot publish
Publish a folder (or a build, or a running site) as a new Snapshot.
teitunnel snapshot publish [OPTIONS] [PATH]| Argument | Description |
|---|---|
[PATH] | The folder, or the project with --build. Default: the current folder. |
| Option | Description |
|---|---|
--on <HOSTNAME> | A hostname on one of your domains, e.g. preview.yourhost.com. Default: your account's workers.dev address. |
--name <NAME> | Its name. Default: the folder's or project's. |
--or-update | If a Snapshot with this name exists (on this computer, or published by another computer or an earlier CI job), publish a new version of it instead. |
Files
| Option | Description |
|---|---|
--build | Build the project first (its package manager runs its build script, e.g. pnpm run build), then publish the build's output folder. |
--crawl <URL> | Capture a site running on this computer instead of a folder, e.g. http://localhost:5173 (a bounded crawl of its pages and files). |
Settings
| Option | Description |
|---|---|
--spa | Serve index.html for paths that don't exist (single-page apps). |
--password | Ask visitors for a password (read from the terminal, or from TEITUNNEL_SNAPSHOT_PASSWORD). Only a salted hash reaches Cloudflare. |
--no-password | Remove the password. |
--allow <EMAIL|@DOMAIN|github:ORG[/TEAM]> | Require a Cloudflare Access login: an email address, @domain, or github:ORG[/TEAM]; repeatable (hostnames on your domains only). |
--sign-in <METHOD> | With --allow: how people log in, github or google (the account's login method of that kind), or any (the default). |
--expires <DURATION> | Delete it by itself after this long, e.g. 7d or 12h. |
--comments | Let reviewers pin comments to the pages (kept in a D1 database on your account; every request then runs the Snapshot's Worker). |
--no-comments | Turn comments off. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow deleting a DNS record Teitunnel didn't create on the hostname. |
--json | Print the result as JSON. |
Examples:
teitunnel snapshot publish ./dist --on preview.yourhost.com # a copy online while you sleep
teitunnel snapshot publish . --build # build the project, then publish its output
teitunnel snapshot publish ./dist --on preview.yourhost.com --comments # reviewers can comment
teitunnel snapshot publish dist --name web-pr-7 --on pr-7.yourhost.com --or-update --yes --json # CIsnapshot update
Publish a new version: files from the same place again (or from PATH), and/or new settings. Only changed files are uploaded.
teitunnel snapshot update [OPTIONS] <SNAPSHOT> [PATH]| Argument | Description |
|---|---|
<SNAPSHOT> | The Snapshot's name or hostname. |
[PATH] | Files from here instead of where they came from last time. |
| Option | Description |
|---|---|
--settings-only | Keep the live files; change only settings. |
Files
| Option | Description |
|---|---|
--build | Build the project first (its package manager runs its build script, e.g. pnpm run build), then publish the build's output folder. |
--crawl <URL> | Capture a site running on this computer instead of a folder, e.g. http://localhost:5173 (a bounded crawl of its pages and files). |
Settings
| Option | Description |
|---|---|
--spa | Serve index.html for paths that don't exist (single-page apps). |
--password | Ask visitors for a password (read from the terminal, or from TEITUNNEL_SNAPSHOT_PASSWORD). Only a salted hash reaches Cloudflare. |
--no-password | Remove the password. |
--allow <EMAIL|@DOMAIN|github:ORG[/TEAM]> | Require a Cloudflare Access login: an email address, @domain, or github:ORG[/TEAM]; repeatable (hostnames on your domains only). |
--sign-in <METHOD> | With --allow: how people log in, github or google (the account's login method of that kind), or any (the default). |
--expires <DURATION> | Delete it by itself after this long, e.g. 7d or 12h. |
--comments | Let reviewers pin comments to the pages (kept in a D1 database on your account; every request then runs the Snapshot's Worker). |
--no-comments | Turn comments off. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow deleting a DNS record Teitunnel didn't create on the hostname. |
--json | Print the result as JSON. |
snapshot ls
List Snapshots.
teitunnel snapshot ls [OPTIONS]| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id (default: every account). |
--json | Print JSON. |
Examples:
teitunnel snapshot ls # Snapshots, their addresses and versionssnapshot versions
List a Snapshot's kept versions.
teitunnel snapshot versions [OPTIONS] <SNAPSHOT>| Argument | Description |
|---|---|
<SNAPSHOT> | The Snapshot's name or hostname. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
snapshot rollback
Make an earlier version live again (default: the one before the live one).
teitunnel snapshot rollback [OPTIONS] <SNAPSHOT> [VERSION]| Argument | Description |
|---|---|
<SNAPSHOT> | The Snapshot's name or hostname. |
[VERSION] | The version's number (see versions). |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow deleting a DNS record Teitunnel didn't create on the hostname. |
--json | Print the result as JSON. |
Examples:
teitunnel snapshot rollback preview.yourhost.comsnapshot rm
Delete a Snapshot: its address, login and Worker on Cloudflare.
teitunnel snapshot rm [OPTIONS] <SNAPSHOT>| Argument | Description |
|---|---|
<SNAPSHOT> | The Snapshot's name or hostname. |
| Option | Description |
|---|---|
--missing-ok | Succeed when there's no such Snapshot (cleanup jobs that may run twice). |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--replace | Also allow deleting a DNS record Teitunnel didn't create on the hostname. |
--json | Print the result as JSON. |
Examples:
teitunnel snapshot rm pr-7.yourhost.com --missing-ok --yesprotect
Protect a hostname at Cloudflare's edge: challenge or block bots and AI crawlers, rate limit visitors, set or remove headers. Without options, shows what it has now.
teitunnel protect [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname, e.g. app.yourhost.com (a route, or a share on your domain). |
| Option | Description |
|---|---|
--bots <BOTS> | Automated clients (scripts, headless browsers; verified bots like search engines are let through). Values: off: Nothing; challenge: A managed challenge; block: Refused. |
--block-ai | Block AI crawlers (Cloudflare's verified "AI Crawler" bots). |
--allow-ai | Stop blocking AI crawlers. |
--rate-limit <N/PERIOD[:ACTION]> | Requests per period per visitor, then block or challenge: 30/1m, 100/10s:challenge (Pro plans and up; periods 10s, 1m, 2m, 5m, 10m, 1h). |
--no-rate-limit | Remove the rate limit. |
--set-request-header <NAME:VALUE> | Set a header on requests before they reach your service: Name:value. Repeatable. |
--remove-request-header <NAME> | Remove a header from requests. Repeatable. |
--set-response-header <NAME:VALUE> | Set a header on responses: Name:value, e.g. X-Robots-Tag:noindex. Repeatable. |
--add-response-header <NAME:VALUE> | Add a header to responses (keeps existing values): Name:value. Repeatable. |
--remove-response-header <NAME> | Remove a header from responses. Repeatable. |
--clear-headers | Start from no header rules (then apply the header options given). |
--bypass-cache | Stop Cloudflare caching responses, so a dev server's changes show at once (needs the Cache Rules permission). |
--no-bypass-cache | Let Cloudflare cache responses again. |
--off | Remove every rule Teitunnel added for the hostname. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--json | Print JSON. |
Examples:
teitunnel protect app.yourhost.com --bots challenge --block-ai # rules at Cloudflare's edge
teitunnel protect app.yourhost.com --rate-limit 30/1m # Pro plans and up
teitunnel protect app.yourhost.com --off # remove Teitunnel's rulesSee Edge protection.
service-token
Service tokens for machines (CI, scripts, servers) to pass a hostname's login.
teitunnel service-token <COMMAND>| Command | What it does |
|---|---|
service-token create | Create a token machines use to pass the hostname's login (CI, scripts, servers). Its secret is printed once. |
service-token ls | List Teitunnel's tokens for the hostname, with their expiry. |
service-token rotate | Give a token a new secret (printed once; the old one stops working). |
service-token revoke | Revoke a token: machines using it are refused. |
See Edge protection.
service-token create
Create a token machines use to pass the hostname's login (CI, scripts, servers). Its secret is printed once.
teitunnel service-token create [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
| Option | Description |
|---|---|
--name <NAME> | What it's for. Default: CLI. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--json | Print JSON. |
Examples:
teitunnel service-token create api.yourhost.com --name CI # the secret is printed onceservice-token ls
List Teitunnel's tokens for the hostname, with their expiry.
teitunnel service-token ls [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
Examples:
teitunnel service-token ls api.yourhost.comservice-token rotate
Give a token a new secret (printed once; the old one stops working).
teitunnel service-token rotate [OPTIONS] <HOSTNAME> <TOKEN>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
<TOKEN> | The token's name or id. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--json | Print JSON. |
service-token revoke
Revoke a token: machines using it are refused.
teitunnel service-token revoke [OPTIONS] <HOSTNAME> <TOKEN>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
<TOKEN> | The token's name or id. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
--json | Print JSON. |
Examples:
teitunnel service-token revoke api.yourhost.com CIcomments
Comments reviewers pinned to your shares and Snapshots: list, reply, resolve.
teitunnel comments <COMMAND>| Command | What it does |
|---|---|
comments ls | Without a subject, what has comments; with one (a key, hostname or Snapshot name), its open threads. |
comments reply | Reply to a thread (as you). |
comments resolve | Resolve a thread (or reopen it with --reopen). |
See Comments.
comments ls
Without a subject, what has comments; with one (a key, hostname or Snapshot name), its open threads.
teitunnel comments ls [OPTIONS] [SUBJECT]| Argument | Description |
|---|---|
[SUBJECT] | The subject: snapshot:…, route:…, share:…, a hostname or a Snapshot name. |
| Option | Description |
|---|---|
--all | Include resolved threads. |
--json | Print JSON. |
Examples:
teitunnel comments ls # shares and Snapshots with review comments
teitunnel comments ls preview.yourhost.com --all # its threads, resolved ones toocomments reply
Reply to a thread (as you).
teitunnel comments reply <SUBJECT> <THREAD> <TEXT>| Argument | Description |
|---|---|
<SUBJECT> | The subject. |
<THREAD> | The thread's id (from teitunnel comments ls). |
<TEXT> | The reply, plain text. |
Examples:
teitunnel comments reply preview.yourhost.com c1a2b3 "Fixed, thanks"comments resolve
Resolve a thread (or reopen it with --reopen).
teitunnel comments resolve [OPTIONS] <SUBJECT> <THREAD>| Argument | Description |
|---|---|
<SUBJECT> | The subject. |
<THREAD> | The thread's id. |
| Option | Description |
|---|---|
--reopen | Reopen it instead. |
Examples:
teitunnel comments resolve preview.yourhost.com c1a2b3offline
Show your own page instead of Cloudflare's error 1033 while this computer is off (a Worker on your account; without options, shows what the route has).
teitunnel offline [OPTIONS] <HOSTNAME>| Argument | Description |
|---|---|
<HOSTNAME> | The route's hostname, e.g. app.yourhost.com. |
| Option | Description |
|---|---|
--title <TITLE> | The page's title (turns the page on). |
--message <MESSAGE> | A line or two for visitors. |
--when-app-down | Also show it when the tunnel is up but the app doesn't answer (502/504). |
--off | Remove the offline page. |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
Examples:
teitunnel offline app.yourhost.com --title "Back soon" # your page instead of error 1033
teitunnel offline app.yourhost.com --offSee Offline page.
inbox
Keep webhooks while this computer is off and deliver them in order when it's back.
teitunnel inbox <COMMAND>| Command | What it does |
|---|---|
inbox add | Keep webhooks to a path while this computer is off; they're delivered in order when it's back. |
inbox rm | Remove an inbox (webhooks still waiting stay until their retention ends). |
inbox ls | Offline pages and inboxes on this computer's records. |
inbox items | An inbox's recent webhooks: when each arrived and when it was delivered. |
inbox secret | Save a webhook signing secret for a hostname in the keychain (read from TEITUNNEL_WEBHOOK_SECRET or standard input, never the command line). A verifying inbox sends it to Cloudflare as a Worker secret; the inspector checks signatures with it. |
inbox deliver | Deliver waiting webhooks now (the app does every 30 seconds). |
See Webhook inbox.
inbox add
Keep webhooks to a path while this computer is off; they're delivered in order when it's back.
teitunnel inbox add [OPTIONS] <HOSTNAME> <PATH>| Argument | Description |
|---|---|
<HOSTNAME> | The route's hostname. |
<PATH> | The path, e.g. /webhooks/. |
| Option | Description |
|---|---|
--max <MAX> | Most webhooks kept waiting. Default: 500. |
--days <DAYS> | Days a webhook is kept. Default: 7. |
--verify <VERIFY> | Keep only webhooks signed with the secret saved for this hostname (teitunnel inbox secret, or the app's inspector). Values: github: GitHub (X-Hub-Signature-256); stripe: Stripe (Stripe-Signature); standard: Standard Webhooks (Svix, Clerk, Resend…). |
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
Examples:
teitunnel inbox add app.yourhost.com /webhooks/ --days 7 # keep webhooks while you're awayinbox rm
Remove an inbox (webhooks still waiting stay until their retention ends).
teitunnel inbox rm [OPTIONS] <HOSTNAME> <PATH>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
<PATH> | The path. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
-y, --yes | Apply without asking. |
Examples:
teitunnel inbox rm app.yourhost.com /webhooks/inbox ls
Offline pages and inboxes on this computer's records.
teitunnel inbox ls [OPTIONS]| Option | Description |
|---|---|
--json | Print JSON. |
inbox items
An inbox's recent webhooks: when each arrived and when it was delivered.
teitunnel inbox items [OPTIONS] <HOSTNAME> <PATH>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
<PATH> | The path. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--json | Print JSON. |
Examples:
teitunnel inbox items app.yourhost.com /webhooks/ # arrivals and deliveriesinbox secret
Save a webhook signing secret for a hostname in the keychain (read from TEITUNNEL_WEBHOOK_SECRET or standard input, never the command line). A verifying inbox sends it to Cloudflare as a Worker secret; the inspector checks signatures with it.
teitunnel inbox secret <HOSTNAME> <PROVIDER>| Argument | Description |
|---|---|
<HOSTNAME> | The hostname. |
<PROVIDER> | Who signs the webhooks. Values: github: GitHub (X-Hub-Signature-256); stripe: Stripe (Stripe-Signature); standard: Standard Webhooks (Svix, Clerk, Resend…). |
Examples:
teitunnel inbox secret app.yourhost.com stripe < secret.txt # keychain; for --verifyinbox deliver
Deliver waiting webhooks now (the app does every 30 seconds).
teitunnel inbox deliver [OPTIONS]| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
Examples:
teitunnel inbox deliver # deliver waiting webhooks nowdoctor
Check for problems, like the app's Doctor. Exits with 1 when there's an error.
teitunnel doctor [OPTIONS]| Option | Description |
|---|---|
--fix | Apply the safe fixes (nothing Teitunnel didn't create is touched). |
-y, --yes | With --fix, apply without asking. |
--json | Print JSON. |
Examples:
teitunnel doctor # check for problems; exits 1 on an error
teitunnel doctor --fix # apply the safe fixesIt runs the app's checks and hides the issues you ignored there. See Doctor.
cloudflared
The cloudflared Teitunnel uses: status, or install (the latest release from Cloudflare, verified, into Teitunnel's data folder; for servers and CI).
teitunnel cloudflared [ACTION]| Argument | Description |
|---|---|
[ACTION] | status or install. Default: status. |
Examples:
teitunnel cloudflared install # a verified cloudflared (servers, CI)completions
Print a shell completion script, e.g. teitunnel completions zsh. It completes commands and flags, and your hostnames, tunnels, domains, shares and accounts from this machine's records (no network).
teitunnel completions [OPTIONS] <SHELL>| Argument | Description |
|---|---|
<SHELL> | The shell. Values: bash, zsh, fish, powershell, elvish. |
| Option | Description |
|---|---|
--static | Commands and flags only, in a script that never runs teitunnel. |
Examples:
teitunnel completions zsh > _teitunnel # or save it as _teitunnel on your fpathTo load them in every new shell:
source <(teitunnel completions zsh) # zsh, in ~/.zshrc
eval "$(teitunnel completions bash)" # bash, in ~/.bashrc
teitunnel completions fish > ~/.config/fish/completions/teitunnel.fish
teitunnel completions powershell | Out-String | Invoke-Expression # in $PROFILEThe script asks teitunnel for suggestions on every Tab, from this machine's records without going online. --static prints a script with only commands and flags that never runs teitunnel; Elvish gets that one.
export
Print this machine's tunnel and routes as config.yml, Docker Compose or Terraform.
teitunnel export [OPTIONS] <FORMAT>| Argument | Description |
|---|---|
<FORMAT> | What to export as. Values: config-yaml, docker-compose, terraform. |
| Option | Description |
|---|---|
-a, --account <ACCOUNT> | Account name or id. |
--tunnel <TUNNEL> | One of this machine's tunnels, by name (default: the default tunnel). |
Examples:
teitunnel export terraform > teitunnel.tfSee Export.
Last updated on