Turn one remote HTML file into a temporary preview link that opens cleanly on a phone, in Codex App, or in any normal browser.
Coding agents increasingly produce HTML artifacts that are easier to review than plain Markdown: research reports, QA notes, design reviews, comparison pages, and small dashboards. The problem is that those files often live on a remote Linux or SSH machine, while the person reviewing them may be on a phone or inside Codex App on Windows or macOS.
Opening links in Codex App is already polished and easy to use. Phone browsers
are built for the same thing. HTML Portal connects a freshly generated
report.html to that existing preview path, instead of asking you to set up SSH
port forwarding from a phone.
html-portal report.html --shareExample output:
Preview URL:
https://example.trycloudflare.com/p/8f3a9c2e/index.html?t=9d7b4f0c91a63e8a
Expires: 2026-05-23T13:30:00Z
Stop: html-portal stop 8f3a9c2e
The usual options are to start an HTTP server on the remote machine or set up SSH port forwarding. A raw HTTP server can expose more of the project than you intended. SSH forwarding is a developer debugging workflow: it assumes shell access, local port setup, and an open connection. That is awkward on a phone, and it is the wrong burden for a teammate who only needs to review the result.
HTML Portal turns the workflow into one agent-friendly action:
- Take one
.htmlfile. - Copy it into a private temporary directory.
- Start a local preview bound to
127.0.0.1. - Optionally create a temporary public URL through Cloudflare Quick Tunnel.
- Return the URL, expiry time, stop command, and JSON output.
Use it when you want to:
- Open an agent-generated report from your phone, Windows Codex App, or another browser.
- Reuse the link-opening experience that already works well in Codex App.
- Preview rich HTML deliverables without turning the repo into a web server.
- Share a temporary preview with a teammate without exposing your project folder.
- Let an agent produce a machine-readable preview URL with
--json. - Stop previews cleanly instead of leaving ad hoc servers and tunnels behind.
HTML Portal is designed as a temporary preview tool, not a hosting platform:
- It previews one HTML file, not a whole repo.
- It serves a private temporary copy, not the source directory.
- Its local server binds to
127.0.0.1. - Preview links include a random path, random token, and expiry time.
- Public URLs are checked for possible secrets and scripts first.
- Reviews can be ended explicitly with
html-portal stop <id>.
See "Guardrail Model" below for the full safety details.
SSH port forwarding is for developers connecting to remote services. HTML Portal is for handing an agent-generated single-file HTML artifact to a human reviewer.
| Need | SSH port forwarding | HTML Portal |
|---|---|---|
| Open on a phone | Awkward | Open the URL directly |
| View in Codex App | First map a service yourself | Reuse Codex App link opening |
| Share with a reviewer | Explain connection steps | Send one temporary link |
| Scope of exposure | Depends on the mapped service | Only serves the copied HTML file |
| Automation | Hard to report cleanly | Stable --json output |
From the latest release:
curl -fsSL https://raw.githubusercontent.com/GRD-Chang/html-portal/main/install.sh | shFrom source:
go build -o ~/.local/bin/html-portal ./cmd/html-portalPublic sharing uses Cloudflare Quick Tunnel, so cloudflared must be available
on PATH when you pass --share.
Check your setup:
html-portal doctorLocal-only preview:
html-portal report.htmlPreview from your phone, Codex App, or another browser:
html-portal report.html --share --ttl 30mAgent-friendly JSON output:
html-portal report.html --share --jsonInspect a file before previewing it:
html-portal inspect report.html
html-portal inspect report.html --jsonList and stop previews:
html-portal list
html-portal stop <id>
html-portal cleanup| Command | Use it for |
|---|---|
html-portal <file.html> |
Start a local temporary preview. |
html-portal <file.html> --share |
Create a public temporary URL through Cloudflare Quick Tunnel. |
html-portal <file.html> --json |
Return structured output for agents and scripts. |
html-portal inspect <file.html> |
Check size, scripts, external scripts, event handlers, and possible secrets. |
html-portal list |
Show known previews and whether their local server is still running. |
html-portal stop <id> |
Stop a preview and remove its temporary directory. |
html-portal cleanup |
Remove previews that are expired or no longer running. |
html-portal doctor |
Print version, state directory, and cloudflared status. |
HTML Portal is deliberately boring to automate. The contract is small, stable, and easy for an agent to report back to a human. The human only needs to open the link:
- The agent generates one
.htmlartifact. - It runs
html-portal inspect <file.html> --json. - It creates a local or shared preview with
--json. - It reports the preview URL, expiry time, stop command, and security warnings.
- It stops the preview when the review is done.
This repo also includes ready-to-use agent skills:
skills/html-portal/SKILL.mdfor English workflows.skills/html-portal-zh/SKILL.mdfor Chinese workflows.
HTML Portal is for temporary previews of non-sensitive HTML. It is not a hosting platform, strong authentication, or a security sandbox.
It provides guardrails, not a security boundary. The checks catch common mistakes, but they do not prove that a file is safe or non-sensitive.
Defaults:
- Accepts only one
.htmlfile. - Refuses directories and non-HTML inputs.
- Refuses files larger than 10 MB.
- Never serves the source directory.
- Binds the local server to
127.0.0.1. - Uses a random path and random query token.
- Uses a 30 minute TTL by default.
- Requires
--allow-long-ttlfor TTLs over 4 hours. - Stores only a token hash in metadata, not the plaintext token.
- Sends
Cache-Control: no-store. - Sends
X-Robots-Tag: noindex, nofollow. - Sends
Referrer-Policy: no-referrer. - Blocks scripts through CSP by default.
- Refuses public sharing of
<script>HTML unless--allow-scriptsis explicit. - Refuses possible secrets unless
--allow-sensitiveis explicit.
Do not use it for customer data, credentials, private logs, production docs, or long-lived hosting. If a complete preview URL leaks, anyone with that URL may be able to access the page until it expires or is stopped.
By default, preview responses use a Content Security Policy that blocks scripts:
script-src 'none'
For public sharing, HTML containing <script> is refused unless you pass:
html-portal report.html --share --allow-scriptsUse this only for non-sensitive pages. JavaScript can send page content or the complete preview URL to external services.
{
"id": "abc123",
"url": "https://x.trycloudflare.com/p/abc123/index.html?t=...",
"local_url": "http://127.0.0.1:49152/p/abc123/index.html?t=...",
"public_url": "https://x.trycloudflare.com",
"expires_at": "2026-05-23T13:30:00Z",
"stop_command": "html-portal stop abc123",
"warnings": ["public_temporary_url"],
"security": {
"secret_scan": "pass",
"scripts": "none",
"public": true,
"level": "guardrails",
"security_boundary": false,
"warning": "HTML Portal provides guardrails, not a security boundary..."
}
}go test ./...
go build -o bin/html-portal ./cmd/html-portalThe end-to-end tests build the CLI, start real local preview subprocesses, verify token checks and security headers, and use a mock tunnel provider so tests do not expose public URLs.
