| name | local-preview-server |
| description | Serve local files, HTML reports, static directories, dashboards, or build artifacts through verified private/tailnet browser URLs. Use when asked to serve, preview, expose, share, or make generated local web output accessible, including ์๋ฒ ์ผ์ค, ์ ์ ๊ฐ๋ฅํ๊ฒ ํด์ค, ์น์์ ๋ณผ ์ ์๊ฒ ํด์ค, or HTML ๋ณด์ฌ์ค. Do not use to browse source code or open an existing git worktree in code-server. |
Local / Tailnet Preview Server
Use this skill to serve a local file, HTML page, generated report, dashboard,
static directory, build output, or lightweight web artifact through a verified
private URL.
Security posture
- Default exposure is localhost-only (
127.0.0.1).
- For outside-this-machine access, prefer Tailscale Serve with
--tailscale-serve; this keeps the preview bound to localhost and lets
Tailscale enforce tailnet identity/ACLs.
- Do not bind to
0.0.0.0 by default. Use --lan or --bind 0.0.0.0
only when LAN exposure is explicitly intended and the host firewall/trust
boundary is understood.
- Do not create public internet exposure by default. Only use ngrok,
Cloudflare Tunnel, Tailscale Funnel, Vercel/Netlify, or other public
publishing when the user explicitly requests public exposure.
Commands
Resolve the helper relative to this SKILL.md; for installed copies,
scripts/local-preview-server.sh is next to the skill.
scripts/local-preview-server.sh start --path ./report.html --port 8377
scripts/local-preview-server.sh start --path ./dist --tailscale-serve
scripts/local-preview-server.sh start --path ./dist --lan
scripts/local-preview-server.sh status --port 8377
scripts/local-preview-server.sh stop --port 8377
Workflow
- Resolve the target path.
- File target: copy only the requested file into a private per-port serving root, then report its encoded URL; sibling files are never exposed.
- Directory target: report
/ and rely on index.html if present.
- Start or restart a durable server.
- Prefer tmux session
local-preview-PORT.
- Fall back to background PID/state files only when tmux is unavailable.
- Logs and private JSON state go to
${XDG_STATE_HOME:-$HOME/.local/state}/local-preview-server/ by default.
- Verify before reporting success.
- Confirm the known session/PID exists.
- Confirm the port accepts local connections.
- Curl the exact localhost URL.
- If
--tailscale-serve is used, curl the exact tailnet URL and report
failure rather than claiming it works.
- Report the parseable key/value output from the helper:
STATUS, PREFERRED_URL, LOCAL_URL, optional LAN_URL/TAILNET_URL
ROOT, TARGET, PORT, BIND_ADDR, SESSION, PROCESS_MODE, LOG
STOP_COMMAND
Operational notes
- Restarting a port stops only the matching
local-preview-PORT tmux session
or known PID/state file; it never broadly kills listeners.
- If the requested port is occupied by an unrelated process, the helper chooses
the next free port and reports
REQUESTED_PORT plus the actual PORT.
stop --port PORT clears only the known helper state/PID/session for that
port. If the preview created a Tailscale Serve rule, stop also removes that
helper-owned rule.
- Use
--clear-tailscale-serve-conflict only when a stale Tailscale Serve rule
for that preview port is known to conflict.