Securely share local files and services to the public internet via Cloudflare Tunnel
简体中文 | English
# Install
npm install -g @ystemsrx/cfshare
# Or use as an Agent Skill (Claude Code, Codex, etc.)
npx skills add ystemsrx/cfshare
# Expose a local service
cfshare expose_port '{"port":3000}'
# Share files
cfshare expose_files '{"paths":["./dist"]}'CFShare is a Node.js CLI tool that enables you to:
- 🔗 Expose a local port as a temporary public HTTPS link (
https://*.trycloudflare.com) with one command - 📁 Share files/directories — automatically spins up a local static server + tunnel so recipients can browse/download/preview via a link (encryption supported)
- 🔒 Built-in security — Token/Basic auth, rate limiting, port blacklist, exclusion rules
- ⏱️ Auto-expiry cleanup — tunnels are automatically closed and temp files deleted when the TTL expires
Note
No Cloudflare account required. CFShare uses Cloudflare Quick Tunnel (trycloudflare.com), which is completely free and works out of the box.
flowchart LR
subgraph LOCAL["Your Machine"]
A["Local Service / Files"]
B["[Optional] Reverse Proxy<br/>(Auth + Rate Limit)"]
C["cloudflared tunnel"]
A --> B
B --> C
end
C ==>|Cloudflare Quick Tunnel| D["https://xxx.trycloudflare.com"]
E["Recipient's Browser"] --> D
Internally, CFShare handles: path validation → copy files to a temp directory → start a read-only static server → mount auth/rate-limit reverse proxy → launch cloudflared tunnel → schedule expiry cleanup. All you need to do is tell it "what you want to share" and it takes care of the rest.
CFShare relies on Cloudflare's cloudflared CLI to create tunnels.
🍎 macOS
brew install cloudflare/cloudflare/cloudflared🐧 Linux (Debian / Ubuntu)
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update && sudo apt-get install cloudflared🪟 Windows (inside WSL2)
# Inside WSL2:
curl -fsSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared
chmod +x /usr/local/bin/cloudflaredOr install natively via PowerShell / CMD with winget:
winget install --id Cloudflare.cloudflaredVerify the installation:
cloudflared --version
# Output should be similar to: cloudflared version 2025.x.xImportant
You only need to install cloudflared — there is no need to run cloudflared tunnel login. Quick Tunnel requires no account authentication.
npm install -g @ystemsrx/cfshareVerify:
cfshare --version
cfshare env_checkCFShare provides an Agent Skill that lets AI coding assistants (such as Claude Code, Codex, etc.) automatically call CFShare commands. Install the skill with:
npx skills add ystemsrx/cfshareOnce installed, just talk to your AI coding assistant in natural language:
"Expose port 3000 with token auth"
"Share the
./distdirectory via a public link"
"Stop all active shares"
The agent will automatically invoke the appropriate cfshare commands and return the results.
cfshare <command> [params-json] [options]# Check environment and policy
cfshare env_check
# Expose an existing local service
cfshare expose_port '{"port":3000,"opts":{"access":"token"}}'
# Share files/directories
cfshare expose_files '{"paths":["./dist"],"opts":{"access":"none"}}'
# List active exposures
cfshare exposure_list
# Stop an exposure
cfshare exposure_stop '{"id":"all"}'expose_port and expose_files print the result and exit by default.
Use --keep-alive if you want foreground lifecycle control (Ctrl+C to stop).
| Option | Description |
|---|---|
--params <json> |
Tool parameters as JSON |
--params-file <path> |
Read tool parameters from a JSON file |
--config <json> |
Runtime config JSON |
--config-file <path> |
Read runtime config from a JSON file |
--workspace-dir <dir> |
Workspace dir for expose_files context |
--keep-alive |
Keep process running after expose_* |
--no-keep-alive |
Exit after printing result (default) |
--compact |
Compact JSON output |
-h, --help |
Show help |
-v, --version |
Show version |
CFShare works out of the box. The defaults below suit most use cases. To customize, pass --config or --config-file:
cfshare expose_port '{"port":3000}' --config '{"defaultTtlSeconds":7200}'Or create a config file (e.g. ~/.cfshare/config.json):
{
"cloudflaredPath": "cloudflared",
"defaultTtlSeconds": 3600,
"defaultExposePortAccess": "token"
}cfshare expose_port '{"port":3000}' --config-file ~/.cfshare/config.json| Option | Default | Description |
|---|---|---|
cloudflaredPath |
"cloudflared" |
Path or command name for cloudflared |
stateDir |
~/.cfshare |
Directory for state file storage |
defaultTtlSeconds |
3600 (1 hour) |
Default tunnel time-to-live |
maxTtlSeconds |
86400 (24 hours) |
Maximum TTL cap |
defaultExposePortAccess |
"token" |
Default auth mode for port exposure |
defaultExposeFilesAccess |
"none" |
Default auth mode for file sharing |
blockedPorts |
[22, 2375, 2376] |
Ports blocked from exposure (SSH/Docker) |
rateLimit.enabled |
true |
Whether rate limiting is enabled |
rateLimit.maxRequests |
240 |
Max requests per window |
rateLimit.windowMs |
60000 (1 minute) |
Rate limit window in milliseconds |
Tip
Auth mode reference:
"token"— A token is required to access the link (suitable for port exposure)"basic"— HTTP Basic authentication (username/password)"none"— No authentication, anyone can access (suitable for temporary file sharing)
| Command | Purpose |
|---|---|
env_check |
Check if cloudflared is available & view policy |
expose_port |
Expose a local port to the public internet |
expose_files |
Share files/directories (auto static server) |
exposure_list |
List all active sessions |
exposure_get |
Get details for a specific session |
exposure_stop |
Stop and clean up specific or all sessions |
exposure_logs |
View session logs |
maintenance |
TTL guardian / garbage collection / policy refresh |
audit_query |
Query audit logs |
audit_export |
Export audit logs to a file |
| 🛡️ | Secure by Default | Port exposure defaults to token auth + reverse proxy protection |
| 🚫 | Port Blacklist | SSH (22) and Docker Daemon (2375/2376) are blocked by default |
| ⏳ | Auto Expiry | Sessions automatically close tunnels and delete temp files upon expiration |
| 📊 | Rate Limiting | Per-IP sliding window rate limiting (default: 240 req/min) |
| 📝 | Audit Logging | All operations are logged to a local JSONL file |
| 🙈 | File Exclusion | Automatically excludes .git/, .cfshare/, and respects .gitignore rules |
Q: Do I need a paid Cloudflare account?
No. CFShare uses Cloudflare Quick Tunnel (trycloudflare.com), which is completely free and requires no account registration.
Q: How long do links last?
By default, 1 hour. This can be adjusted via configuration or specified per share (up to 7 days). Links are automatically destroyed upon expiry.
Q: What if cloudflared is not found?
- Confirm
cloudflaredis installed:cloudflared --version - If it's installed in a location not in your
PATH, specify the full path via--config:
cfshare env_check --config '{"cloudflaredPath":"/usr/local/bin/cloudflared"}'Q: Can I use it directly on Windows?
CFShare is recommended for use within a WSL2 environment on Windows.
MIT © ystemsrx