Skip to Content
Teitunnel

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 WindowsApps folder, which is already on the PATH), and uninstalling removes it.
  • Linux: the .deb and .rpm install /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 one sudo 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 3000 asks 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 with teitunnel shares --stop <url>. The first time, the app asks you to allow the command line (choose Always Allow to not be asked again). --for still works, and --here shares from the terminal instead.
  • teitunnel shares lists the app's shares too, and --stop stops any of them.
  • teitunnel routes shows the status the app's connectors report.
  • teitunnel status says 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

OptionMeaning
-a, --account <ACCOUNT>Which account, when several are connected (its name or id).
-y, --yesApply without asking (needed when there's no terminal to ask on, e.g. in scripts).
--replaceAlso 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-overTake 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.
--jsonMachine-readable output, for scripts.
--app, --hereGo through the running app (and fail if it isn't running), or don't use the app even when it runs.

Commands

CommandWhat it does
setupConnect a Cloudflare account with an API token (stored in the OS keychain).
upRun this machine's tunnels in the foreground until stopped (servers, containers).
projectWork with the project file (teitunnel.yml): check, diff, apply, init, down.
local-domainLocal HTTPS domains on this computer: https://shop.test with a trusted certificate.
browserThe Teitunnel browser extension: let it talk to the app from your browsers.
backupMove to another computer: an encrypted backup of Teitunnel's setup (never a token or password), and restoring it.
serveRun this machine's tunnels plus a web dashboard and JSON API (servers).
mcpRun 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-keyCreate, list or revoke API keys for the server API.
always-onKeep this machine's tunnels running as an OS service, even after a restart.
accountsList connected Cloudflare accounts.
routesList this machine's routes and their status.
statusWhether the Teitunnel app is running, and what it serves.
topA live dashboard of shares, routes and traffic (q quits, ? for keys).
routeAdd, or remove, a route.
networksList the private networks (ranges and hostnames) this machine shares with WARP clients.
networkShare, or stop sharing, a private range or hostname with WARP clients.
tunnelsList this machine's tunnels (routes go on the default one unless --tunnel says).
tunnelCreate, or delete, one of this machine's tunnels.
shareShare a local service, or a folder of files, at a temporary public URL until you press Ctrl-C.
inspectInspect 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.
trafficRequests captured by the inspector: list, show, follow, replay, clear, export.
tokenShow the bearer token a shared service expects (share --mcp or --ai on your domain), or make a new one.
reserveReserve 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.
reservationsList the account's reserved hostnames and who holds them (reservations ls).
releaseGive up a hostname's reservation (a route there stays).
sharesList shares (the app's, terminals' and on your domains), or stop, pause or resume one.
scheduleRun 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.
schedulesList schedules of shares and routes.
analyticsTraffic 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.
uptimeUptime of this machine's routes (checked every minute through Cloudflare while the app, up or serve runs).
snapshotPublish static copies of a site to your Cloudflare account (online while this computer sleeps), and list, update, roll back or delete them.
protectProtect 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-tokenService tokens for machines (CI, scripts, servers) to pass a hostname's login.
commentsComments reviewers pinned to your shares and Snapshots: list, reply, resolve.
offlineShow 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).
inboxKeep webhooks while this computer is off and deliver them in order when it's back.
doctorCheck for problems, like the app's Doctor. Exits with 1 when there's an error.
cloudflaredThe cloudflared Teitunnel uses: status, or install (the latest release from Cloudflare, verified, into Teitunnel's data folder; for servers and CI).
completionsPrint 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).
exportPrint 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 setup

Examples:

teitunnel setup  # store an API token in the keychain

See 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]
OptionDescription
-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-projectDon't apply a project file, even if there is one here.
-a, --account <ACCOUNT>Account name or id (default: the file's account).
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation (replacing DNS records Teitunnel didn't create).
--strictDon'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 folder

See Servers and containers and Project files.

project

Work with the project file (teitunnel.yml): check, diff, apply, init, down.

teitunnel project <COMMAND>
CommandWhat it does
project initWrite a starter teitunnel.yml for this folder, from the routes and shares this machine runs for its project.
project checkCheck the project file: every problem with its line and column. Needs no account.
project diffShow what applying the project file would change. Nothing is changed.
project applyApply the project file: its routes and Snapshots, then its shares until Ctrl-C.
project downStop the project's shares; with --remove-routes, also remove the routes it created (never routes that were there before).
project listList 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]
OptionDescription
--forceReplace an existing teitunnel.yml.
-a, --account <ACCOUNT>Account name or id.

Examples:

teitunnel project init  # a starter teitunnel.yml for this folder

project check

Check the project file: every problem with its line and column. Needs no account.

teitunnel project check [OPTIONS]
OptionDescription
-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 column

project diff

Show what applying the project file would change. Nothing is changed.

teitunnel project diff [OPTIONS]
OptionDescription
-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).
--jsonPrint 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]
OptionDescription
-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, --yesApply without asking.
--replaceAlso allow what needs a confirmation (replacing DNS records Teitunnel didn't create).
--strictDon't start a share when the exposure check finds a leak.

Examples:

teitunnel project apply  # apply it; its shares run 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).

teitunnel project down [OPTIONS]
OptionDescription
-f, --file <PATH>The project file, or a folder with one (default: this folder or the nearest one above it in the repository).
--remove-routesAlso remove the routes applying the project created.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.

Examples:

teitunnel project down --remove-routes  # stop its shares, remove the routes it created

project list

List the projects this machine knows.

teitunnel project list [OPTIONS]
OptionDescription
--jsonPrint JSON.

local-domain

Local HTTPS domains on this computer: https://shop.test with a trusted certificate.

Also: local.

teitunnel local-domain <COMMAND>
CommandWhat it does
local-domain addGive a local service an HTTPS address like https://shop.test.
local-domain lsList local domains and whether they're served.
local-domain rmRemove a local domain.
local-domain serveServe every local domain from this terminal until Ctrl-C (or hand them to the running app).
local-domain trustTrust Teitunnel's local certificate authority, so browsers accept local domains.
local-domain untrustStop trusting the local certificate authority.
local-domain statusCertificates, 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>
ArgumentDescription
<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).
OptionDescription
--wildcardSubdomains (*.name) go to the same service.
--no-httpsPlain HTTP only (no certificate).
--inspectRecord its requests (see teitunnel traffic).
--no-serveOnly save it; don't serve it from this terminal when the app isn't running.
--hereServe it from this terminal even if the app runs.

Examples:

teitunnel local-domain add shop.test 3000  # https://shop.test on this computer

local-domain ls

List local domains and whether they're served.

Also: list.

teitunnel local-domain ls [OPTIONS]
OptionDescription
--jsonJSON output.

Examples:

teitunnel local-domain ls  # local domains and whether they're served

local-domain rm

Remove a local domain.

Also: remove.

teitunnel local-domain rm <NAME>
ArgumentDescription
<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]
OptionDescription
--hereServe 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]
OptionDescription
--browsersAlso add it to Chrome's and Firefox's own certificate databases (NSS).
--firefoxTurn on "trust the system's certificates" in Firefox profiles.

Examples:

teitunnel local-domain trust  # browsers accept local domains

local-domain untrust

Stop trusting the local certificate authority.

teitunnel local-domain untrust [OPTIONS]
OptionDescription
--forgetAlso 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]
OptionDescription
--jsonJSON output.

Examples:

teitunnel local-domain status  # CA, trust, ports, .test names, what to fix

browser

The Teitunnel browser extension: let it talk to the app from your browsers.

teitunnel browser <COMMAND>
CommandWhat it does
browser installLet the Teitunnel browser extension talk to the app, in every installed browser.
browser uninstallStop letting the extension talk to the app.
browser statusWhich browsers can use the extension.

browser install

Let the Teitunnel browser extension talk to the app, in every installed browser.

teitunnel browser install [OPTIONS]
OptionDescription
--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]
OptionDescription
--browser <BROWSER>Only this browser.

browser status

Which browsers can use the extension.

teitunnel browser status [OPTIONS]
OptionDescription
--jsonJSON output.

backup

Move to another computer: an encrypted backup of Teitunnel's setup (never a token or password), and restoring it.

teitunnel backup <COMMAND>
CommandWhat it does
backup createWrite an encrypted backup of this computer's setup (settings, tunnels, routes' ownership, projects, alert rules; never tokens or passwords).
backup restoreShow what a backup holds and restore it (asks before replacing anything).

See Move to a new computer.

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]
OptionDescription
-f, --file <PATH>Where to write it (default: teitunnel-setup.teitunnel-backup here).
--passphrase-stdinRead 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>
ArgumentDescription
<FILE>The backup file.
OptionDescription
--passphrase-stdinRead the passphrase from the first line of standard input.
-y, --yesRestore without asking.

Examples:

teitunnel backup restore teitunnel-setup.teitunnel-backup

serve

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]
OptionDescription
--listen <LISTEN>Where to listen. Default: 127.0.0.1:8765.
--allow-remoteAllow listening on a non-loopback address (put TLS in front of it).
--secure-cookiesMark the session cookie Secure (when served over HTTPS).
--set-passwordSet the dashboard password (read from the terminal) and exit.
--no-mcpDon'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-password

See Servers and containers.

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).

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]
OptionDescription
--mode <MODE>read-only, ask (default) or full.
--allow-secretsShow credentials in captured traffic and logs to the agent (off by default).
CommandWhat it does
mcp installAdd Teitunnel to an AI client's MCP configuration (merged; a backup is kept).
mcp uninstallRemove Teitunnel from an AI client's MCP configuration (nothing else changes).
mcp configPrint the configuration to add by hand.
mcp statusShow 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>
ArgumentDescription
<CLIENT>claude-code, claude-desktop, cursor, vscode, codex, windsurf, zed or gemini-cli.
OptionDescription
--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 tool

mcp uninstall

Remove Teitunnel from an AI client's MCP configuration (nothing else changes).

teitunnel mcp uninstall <CLIENT>
ArgumentDescription
<CLIENT>The client (see install).

mcp config

Print the configuration to add by hand.

teitunnel mcp config [OPTIONS] <CLIENT>
ArgumentDescription
<CLIENT>The client (see install).
OptionDescription
--mode <MODE>The mode to run in.

mcp status

Show which AI clients are installed and connected.

teitunnel mcp status [OPTIONS]
OptionDescription
--jsonPrint JSON.

Examples:

teitunnel mcp status  # which AI tools are connected

api-key

Create, list or revoke API keys for the server API.

teitunnel api-key <COMMAND>
CommandWhat it does
api-key createCreate a key (shown once).
api-key listList keys (names only).
api-key revokeRevoke a key by its id (from list).

api-key create

Create a key (shown once).

teitunnel api-key create <NAME>
ArgumentDescription
<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 list

api-key revoke

Revoke a key by its id (from list).

teitunnel api-key revoke <ID>
ArgumentDescription
<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>
ArgumentDescription
<ACTION>on, off or status.
OptionDescription
-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]
OptionDescription
--jsonPrint JSON.

Examples:

teitunnel accounts --json

routes

List this machine's routes and their status.

teitunnel routes [OPTIONS]
OptionDescription
-a, --account <ACCOUNT>Account name or id (needed when several are connected).
--jsonPrint JSON.
--checkExit with 1 unless every route is live (a health check for containers and monitoring). Checks every account when none is named.
--appAsk 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 live

status

Whether the Teitunnel app is running, and what it serves.

teitunnel status [OPTIONS]
OptionDescription
--jsonPrint 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]
OptionDescription
--appOnly with the running app.
--hereWithout 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.

KeyDoes
q, Escquit (Esc first clears a filter)
Tabnext pane
↑ ↓, j kselect
sshare a port (through the app)
x xstop the selected share (press twice)
ccopy 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>
CommandWhat it does
route addRoute a hostname to a service on this machine, e.g. app.yourhost.com 3000.
route balanceLoad 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 unbalanceStop load balancing a route (its DNS record serves it again).
route removeRemove 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>
ArgumentDescription
<HOSTNAME>Public hostname on one of the account's domains.
<ORIGIN>Where traffic goes: a port (3000), host:port, or a URL.
OptionDescription
--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

OptionDescription
--host-header <HOST>Host header sent to the service, e.g. for a dev server that checks it.
--no-tls-verifyAccept any certificate from an HTTPS service (self-signed ones).
--origin-server-name <NAME>Hostname expected on the service's TLS certificate.
--match-sni-to-hostUse the request's hostname as the TLS server name.
--ca-pool <PATH>Certificate authority file for the service's certificate.
--http2-originSpeak HTTP/2 to an HTTPS service.
--disable-chunked-encodingDon'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-eyeballsDon't fall back between IPv4 and IPv6.
--proxy-type <TYPE>socks to use the service as a SOCKS5 proxy (TCP routes).
--strictDon'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, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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):

FlagSetting
--host-headerhttpHostHeader
--no-tls-verifynoTLSVerify
--origin-server-nameoriginServerName
--match-sni-to-hostmatchSNItoHost
--ca-poolcaPool
--http2-originhttp2Origin
--disable-chunked-encodingdisableChunkedEncoding
--connect-timeoutconnectTimeout
--tls-timeouttlsTimeout
--tcp-keep-alivetcpKeepAlive
--keep-alive-timeoutkeepAliveTimeout
--keep-alive-connectionskeepAliveConnections
--no-happy-eyeballsnoHappyEyeballs
--proxy-typeproxyType

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>
ArgumentDescription
<HOSTNAME>Hostname.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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>
ArgumentDescription
<HOSTNAME>Hostname.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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>
ArgumentDescription
<HOSTNAME>Hostname.
OptionDescription
--path <PATH>The route's path rule, if it has one.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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.com

networks

List the private networks (ranges and hostnames) this machine shares with WARP clients.

teitunnel networks [OPTIONS]
OptionDescription
-a, --account <ACCOUNT>Account name or id.
--jsonPrint JSON.

Examples:

teitunnel networks  # the ranges and hostnames this machine shares

network

Share, or stop sharing, a private range or hostname with WARP clients.

teitunnel network <COMMAND>
CommandWhat it does
network addLet WARP clients reach a range or a hostname through this machine, e.g. 192.168.1.0/24 or wiki.internal.
network removeStop 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>
ArgumentDescription
<NETWORK>An IP address, a CIDR range, or a private hostname (resolved by this machine's DNS).
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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 resolves

network remove

Stop routing a range or a hostname through this machine.

teitunnel network remove [OPTIONS] <NETWORK>
ArgumentDescription
<NETWORK>The range or hostname.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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.internal

tunnels

List this machine's tunnels (routes go on the default one unless --tunnel says).

teitunnel tunnels [OPTIONS]
OptionDescription
-a, --account <ACCOUNT>Account name or id.
--jsonPrint JSON.

Examples:

teitunnel tunnels  # this machine's tunnels

tunnel

Create, or delete, one of this machine's tunnels.

teitunnel tunnel <COMMAND>
CommandWhat it does
tunnel createCreate another tunnel for this machine, e.g. staging.
tunnel adoptRun 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 deleteDelete 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>
ArgumentDescription
<NAME>Its name (unique in the account).
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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 machine

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.

teitunnel tunnel adopt [OPTIONS] <NAME>
ArgumentDescription
<NAME>The tunnel's name or id.
OptionDescription
-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>
ArgumentDescription
<NAME>The tunnel's name.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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 staging

share

Share a local service, or a folder of files, at a temporary public URL until you press Ctrl-C.

teitunnel share [OPTIONS] <ORIGIN>
ArgumentDescription
<ORIGIN>What to share: a port (3000), host:port, a URL, or a folder (./dist).
OptionDescription
--for <DURATION>Stop by itself after this long, e.g. 30m, 2h, 90s.
--no-qrDon'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.
--listingWith a folder: list the files of folders that have no index.html (the default when the folder itself has none).
--no-listingWith a folder: never list files, even when it has no index.html.
--spaWith 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-headerPass the visitor's Host header through unchanged, even to a dev server.
--appShare 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.
--hereShare from this terminal, for as long as the command runs, even when the app is running.
--jsonPrint {"url": …, "hostname": …} on stdout once it's live (for scripts and CI).
--strictDon't share when the exposure check finds a leak (a .env file, the git folder, debug pages…); by default it only warns.
--no-inspectDon't send requests through Teitunnel's inspector (it records them for teitunnel traffic, masking credentials).
-q, --quietDon'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).
--commentsLet visitors pin comments on its pages (read and answer them with teitunnel comments or in the app).
--mcpShare 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 /).
--aiShare a local AI server (Ollama, LM Studio, vLLM) behind a bearer token, for OpenAI-compatible clients.
--new-tokenWith --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 token

See 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>
ArgumentDescription
<HOSTNAME>The route's hostname.
OptionDescription
--path <PATH>The route's path rule, if it has one.
-a, --account <ACCOUNT>Account name or id.
--offPoint a route left inspected back at its own service.
-y, --yesDon'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 inspected

See Inspector.

traffic

Requests captured by the inspector: list, show, follow, replay, clear, export.

teitunnel traffic <COMMAND>
CommandWhat it does
traffic lsList captured requests, newest first.
traffic getShow one request and its response.
traffic watchPrint requests as they arrive, until Ctrl-C.
traffic replaySend a captured request to its service again.
traffic clearForget captured requests (all, or one share's or route's).
traffic exportExport captured requests to a file (HAR by default).
traffic openapiDescribe 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]
OptionDescription
--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.
--jsonPrint JSON (one object per request, newest first).

Examples:

teitunnel traffic ls --status 5xx

traffic get

Show one request and its response.

teitunnel traffic get [OPTIONS] <ID>
ArgumentDescription
<ID>The request's id (or the end of it, as ls shows).
OptionDescription
--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.
--revealShow credentials (only possible in the process that captured the request; the history keeps them masked).

Examples:

teitunnel traffic get 7f3a9c1b --format curl

traffic watch

Print requests as they arrive, until Ctrl-C.

teitunnel traffic watch [OPTIONS]
OptionDescription
--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).
--jsonPrint JSON lines.

Examples:

teitunnel traffic watch --path /webhooks

traffic replay

Send a captured request to its service again.

teitunnel traffic replay [OPTIONS] <ID>
ArgumentDescription
<ID>The request's id (or the end of it).
OptionDescription
--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]
OptionDescription
--tap <TAP>Only this tap (as ls --json shows it).

Examples:

teitunnel traffic clear

traffic export

Export captured requests to a file (HAR by default).

teitunnel traffic export [OPTIONS]
OptionDescription
--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.har

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.

teitunnel traffic openapi [OPTIONS]
OptionDescription
--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.
--yamlYAML on stdout.
--title <TITLE>The document's title.

Examples:

teitunnel traffic openapi --out api.yaml  # an OpenAPI 3.1 file from captured requests

token

Show the bearer token a shared service expects (share --mcp or --ai on your domain), or make a new one.

teitunnel token [OPTIONS] <HOSTNAME>
ArgumentDescription
<HOSTNAME>The hostname.
OptionDescription
--newMake a new token (clients with the old one stop working).

Examples:

teitunnel token mcp.yourhost.com  # the token a shared MCP or AI server expects

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.

teitunnel reserve [OPTIONS] <HOSTNAME>
ArgumentDescription
<HOSTNAME>The hostname, e.g. review.dev.yourhost.com.
OptionDescription
--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, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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 yourself

See Teams sharing one account.

reservations

List the account's reserved hostnames and who holds them (reservations ls).

teitunnel reservations [OPTIONS] [ACTION]
ArgumentDescription
[ACTION]ls (the default).
OptionDescription
-a, --account <ACCOUNT>Account name or id.
--jsonPrint JSON.

Examples:

teitunnel reservations ls  # reserved names and who holds them

release

Give up a hostname's reservation (a route there stays).

teitunnel release [OPTIONS] <HOSTNAME>
ArgumentDescription
<HOSTNAME>The hostname.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow what needs a confirmation: replacing or deleting DNS records Teitunnel didn't create, or routing a public range.
--take-overTake 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.com

shares

List shares (the app's, terminals' and on your domains), or stop, pause or resume one.

teitunnel shares [OPTIONS]
OptionDescription
--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.
--jsonPrint JSON.
--appAsk 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.com

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.

teitunnel schedule [OPTIONS] <HOSTNAME> [DAYS HH:MM-HH:MM]...
ArgumentDescription
<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).
OptionDescription
--tz <ZONE>The time zone, e.g. Europe/Berlin (default: this computer's).
--offRemove 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 --off

schedules

List schedules of shares and routes.

teitunnel schedules [OPTIONS]
OptionDescription
--jsonPrint JSON.

Examples:

teitunnel schedules  # every schedule, and when each changes next

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.

teitunnel analytics [OPTIONS] [HOSTNAME]
ArgumentDescription
[HOSTNAME]A route's hostname (default: every route of this machine).
OptionDescription
--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.
--jsonPrint JSON.

Examples:

teitunnel analytics  # traffic of every route, from Cloudflare's edge
teitunnel analytics app.yourhost.com --range week

See Analytics.

uptime

Uptime of this machine's routes (checked every minute through Cloudflare while the app, up or serve runs).

teitunnel uptime [OPTIONS]
OptionDescription
--jsonPrint JSON.

Examples:

teitunnel uptime  # uptime of this machine's routes

snapshot

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>
CommandWhat it does
snapshot publishPublish a folder (or a build, or a running site) as a new Snapshot.
snapshot updatePublish a new version: files from the same place again (or from PATH), and/or new settings. Only changed files are uploaded.
snapshot lsList Snapshots.
snapshot versionsList a Snapshot's kept versions.
snapshot rollbackMake an earlier version live again (default: the one before the live one).
snapshot rmDelete 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]
ArgumentDescription
[PATH]The folder, or the project with --build. Default: the current folder.
OptionDescription
--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-updateIf 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

OptionDescription
--buildBuild 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

OptionDescription
--spaServe index.html for paths that don't exist (single-page apps).
--passwordAsk visitors for a password (read from the terminal, or from TEITUNNEL_SNAPSHOT_PASSWORD). Only a salted hash reaches Cloudflare.
--no-passwordRemove 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.
--commentsLet reviewers pin comments to the pages (kept in a D1 database on your account; every request then runs the Snapshot's Worker).
--no-commentsTurn comments off.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow deleting a DNS record Teitunnel didn't create on the hostname.
--jsonPrint 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  # CI

snapshot 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]
ArgumentDescription
<SNAPSHOT>The Snapshot's name or hostname.
[PATH]Files from here instead of where they came from last time.
OptionDescription
--settings-onlyKeep the live files; change only settings.

Files

OptionDescription
--buildBuild 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

OptionDescription
--spaServe index.html for paths that don't exist (single-page apps).
--passwordAsk visitors for a password (read from the terminal, or from TEITUNNEL_SNAPSHOT_PASSWORD). Only a salted hash reaches Cloudflare.
--no-passwordRemove 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.
--commentsLet reviewers pin comments to the pages (kept in a D1 database on your account; every request then runs the Snapshot's Worker).
--no-commentsTurn comments off.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow deleting a DNS record Teitunnel didn't create on the hostname.
--jsonPrint the result as JSON.

snapshot ls

List Snapshots.

teitunnel snapshot ls [OPTIONS]
OptionDescription
-a, --account <ACCOUNT>Account name or id (default: every account).
--jsonPrint JSON.

Examples:

teitunnel snapshot ls  # Snapshots, their addresses and versions

snapshot versions

List a Snapshot's kept versions.

teitunnel snapshot versions [OPTIONS] <SNAPSHOT>
ArgumentDescription
<SNAPSHOT>The Snapshot's name or hostname.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
--jsonPrint JSON.

snapshot rollback

Make an earlier version live again (default: the one before the live one).

teitunnel snapshot rollback [OPTIONS] <SNAPSHOT> [VERSION]
ArgumentDescription
<SNAPSHOT>The Snapshot's name or hostname.
[VERSION]The version's number (see versions).
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow deleting a DNS record Teitunnel didn't create on the hostname.
--jsonPrint the result as JSON.

Examples:

teitunnel snapshot rollback preview.yourhost.com

snapshot rm

Delete a Snapshot: its address, login and Worker on Cloudflare.

teitunnel snapshot rm [OPTIONS] <SNAPSHOT>
ArgumentDescription
<SNAPSHOT>The Snapshot's name or hostname.
OptionDescription
--missing-okSucceed when there's no such Snapshot (cleanup jobs that may run twice).
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--replaceAlso allow deleting a DNS record Teitunnel didn't create on the hostname.
--jsonPrint the result as JSON.

Examples:

teitunnel snapshot rm pr-7.yourhost.com --missing-ok --yes

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.

teitunnel protect [OPTIONS] <HOSTNAME>
ArgumentDescription
<HOSTNAME>The hostname, e.g. app.yourhost.com (a route, or a share on your domain).
OptionDescription
--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-aiBlock AI crawlers (Cloudflare's verified "AI Crawler" bots).
--allow-aiStop 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-limitRemove 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-headersStart from no header rules (then apply the header options given).
--bypass-cacheStop Cloudflare caching responses, so a dev server's changes show at once (needs the Cache Rules permission).
--no-bypass-cacheLet Cloudflare cache responses again.
--offRemove every rule Teitunnel added for the hostname.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--jsonPrint 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 rules

See Edge protection.

service-token

Service tokens for machines (CI, scripts, servers) to pass a hostname's login.

teitunnel service-token <COMMAND>
CommandWhat it does
service-token createCreate a token machines use to pass the hostname's login (CI, scripts, servers). Its secret is printed once.
service-token lsList Teitunnel's tokens for the hostname, with their expiry.
service-token rotateGive a token a new secret (printed once; the old one stops working).
service-token revokeRevoke 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>
ArgumentDescription
<HOSTNAME>The hostname.
OptionDescription
--name <NAME>What it's for. Default: CLI.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--jsonPrint JSON.

Examples:

teitunnel service-token create api.yourhost.com --name CI  # the secret is printed once

service-token ls

List Teitunnel's tokens for the hostname, with their expiry.

teitunnel service-token ls [OPTIONS] <HOSTNAME>
ArgumentDescription
<HOSTNAME>The hostname.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
--jsonPrint JSON.

Examples:

teitunnel service-token ls api.yourhost.com

service-token rotate

Give a token a new secret (printed once; the old one stops working).

teitunnel service-token rotate [OPTIONS] <HOSTNAME> <TOKEN>
ArgumentDescription
<HOSTNAME>The hostname.
<TOKEN>The token's name or id.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--jsonPrint JSON.

service-token revoke

Revoke a token: machines using it are refused.

teitunnel service-token revoke [OPTIONS] <HOSTNAME> <TOKEN>
ArgumentDescription
<HOSTNAME>The hostname.
<TOKEN>The token's name or id.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.
--jsonPrint JSON.

Examples:

teitunnel service-token revoke api.yourhost.com CI

comments

Comments reviewers pinned to your shares and Snapshots: list, reply, resolve.

teitunnel comments <COMMAND>
CommandWhat it does
comments lsWithout a subject, what has comments; with one (a key, hostname or Snapshot name), its open threads.
comments replyReply to a thread (as you).
comments resolveResolve 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]
ArgumentDescription
[SUBJECT]The subject: snapshot:…, route:…, share:…, a hostname or a Snapshot name.
OptionDescription
--allInclude resolved threads.
--jsonPrint JSON.

Examples:

teitunnel comments ls                             # shares and Snapshots with review comments
teitunnel comments ls preview.yourhost.com --all  # its threads, resolved ones too

comments reply

Reply to a thread (as you).

teitunnel comments reply <SUBJECT> <THREAD> <TEXT>
ArgumentDescription
<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>
ArgumentDescription
<SUBJECT>The subject.
<THREAD>The thread's id.
OptionDescription
--reopenReopen it instead.

Examples:

teitunnel comments resolve preview.yourhost.com c1a2b3

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).

teitunnel offline [OPTIONS] <HOSTNAME>
ArgumentDescription
<HOSTNAME>The route's hostname, e.g. app.yourhost.com.
OptionDescription
--title <TITLE>The page's title (turns the page on).
--message <MESSAGE>A line or two for visitors.
--when-app-downAlso show it when the tunnel is up but the app doesn't answer (502/504).
--offRemove the offline page.
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply without asking.

Examples:

teitunnel offline app.yourhost.com --title "Back soon"  # your page instead of error 1033
teitunnel offline app.yourhost.com --off

See Offline page.

inbox

Keep webhooks while this computer is off and deliver them in order when it's back.

teitunnel inbox <COMMAND>
CommandWhat it does
inbox addKeep webhooks to a path while this computer is off; they're delivered in order when it's back.
inbox rmRemove an inbox (webhooks still waiting stay until their retention ends).
inbox lsOffline pages and inboxes on this computer's records.
inbox itemsAn inbox's recent webhooks: when each arrived and when it was delivered.
inbox secretSave 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 deliverDeliver 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>
ArgumentDescription
<HOSTNAME>The route's hostname.
<PATH>The path, e.g. /webhooks/.
OptionDescription
--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, --yesApply without asking.

Examples:

teitunnel inbox add app.yourhost.com /webhooks/ --days 7  # keep webhooks while you're away

inbox rm

Remove an inbox (webhooks still waiting stay until their retention ends).

teitunnel inbox rm [OPTIONS] <HOSTNAME> <PATH>
ArgumentDescription
<HOSTNAME>The hostname.
<PATH>The path.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
-y, --yesApply 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]
OptionDescription
--jsonPrint JSON.

inbox items

An inbox's recent webhooks: when each arrived and when it was delivered.

teitunnel inbox items [OPTIONS] <HOSTNAME> <PATH>
ArgumentDescription
<HOSTNAME>The hostname.
<PATH>The path.
OptionDescription
-a, --account <ACCOUNT>Account name or id.
--jsonPrint JSON.

Examples:

teitunnel inbox items app.yourhost.com /webhooks/  # arrivals and deliveries

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.

teitunnel inbox secret <HOSTNAME> <PROVIDER>
ArgumentDescription
<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 --verify

inbox deliver

Deliver waiting webhooks now (the app does every 30 seconds).

teitunnel inbox deliver [OPTIONS]
OptionDescription
-a, --account <ACCOUNT>Account name or id.

Examples:

teitunnel inbox deliver  # deliver waiting webhooks now

doctor

Check for problems, like the app's Doctor. Exits with 1 when there's an error.

teitunnel doctor [OPTIONS]
OptionDescription
--fixApply the safe fixes (nothing Teitunnel didn't create is touched).
-y, --yesWith --fix, apply without asking.
--jsonPrint JSON.

Examples:

teitunnel doctor        # check for problems; exits 1 on an error
teitunnel doctor --fix  # apply the safe fixes

It 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]
ArgumentDescription
[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>
ArgumentDescription
<SHELL>The shell. Values: bash, zsh, fish, powershell, elvish.
OptionDescription
--staticCommands and flags only, in a script that never runs teitunnel.

Examples:

teitunnel completions zsh > _teitunnel  # or save it as _teitunnel on your fpath

To 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 $PROFILE

The 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>
ArgumentDescription
<FORMAT>What to export as. Values: config-yaml, docker-compose, terraform.
OptionDescription
-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.tf

See Export.

Edit on GitHub

Last updated on

On this page