Expose, preview, protect with x402 payments, or keep a local web app, static site, HTTP route set, or explicitly requested TCP/UDP service reachable through Portal, then verify the public endpoint and report its lifecycle. Use when the user asks to deploy, publish, share, tunnel, expose, create a public preview, add a paid route, or configure x402 for a local app with Portal. Do not use for deploying a Portal relay, generic cloud hosting, or publishing this plugin.
npx skills add https://github.com/gosuda/portal-tunnel --skill portal-expose
Portal publishes a service that is already running on the user's machine. It does not build the app or move it to a cloud host. Treat a successful tunnel as dependent on both the local app and the Portal process or agent remaining available.
Read references/portal-cli.md when choosing commands or persistent-agent configuration. Read references/x402.md whenever the user requests x402 or a paid route. Read references/safety-and-verification.md before exposing a nontrivial project, a service with authentication, or any non-HTTP port.
Use the smallest mode that satisfies the request:
portal expose <target>.portal expose --serve <path>.--http-route.portal agent config and managed service.portal agent run --foreground.Default to a temporary preview when the user says only "share", "preview", or "deploy locally". Do not install an OS service unless the user asks for a persistent, managed, or restart-surviving tunnel and accepts that portal agent run without --foreground installs a per-user launchd or systemd unit.
Ask one concise question only when the target, desired lifetime, or transport cannot be discovered safely. An explicit request to deploy, publish, expose, tunnel, or share authorizes creating the public tunnel for the named app; it does not authorize exposing adjacent services.
For x402, do not guess the protected path, payment methods, amount, network, recipient, or network-specific asset. Collect any missing consequential value before building the command or config. Treat an omitted method list as charging every method on the route and confirm that scope when it was not explicit.
portal list unless the user asked for --hide.portal version when portal is available.127.0.0.1:<port> unless the project explicitly needs another address.--name for a temporary preview or derive a stable DNS-label-safe name for a persistent tunnel.portal expose, always pass an absolute --identity-path outside the repository. The CLI default is identity.json in the process working directory and that file contains private key material. For portal agent, omit identity_path so the agent stores identity under its state directory; if you set the field, use an absolute path outside the repository.portal expose, pass --relays <https-url> --discovery=false. In persistent mode those flags are not accepted on portal agent run; put relays = ["https://..."] and discovery = false on the [[tunnels]] entry instead.--ban-mitm / ban_mitm = true, a suspected TLS termination is only logged and the tunnel keeps serving. Do not claim the default path blocks a relay. Add --ban-mitm only when the user wants fail-closed handling. There is no flag that disables the probe.--hide is the exception for listing: mention the default public listing, then add --hide or hide = true only when the user wants the tunnel unlisted.references/x402.md. Keep payment policy on the smallest requested path, use an explicit network, and never place wallet or facilitator secrets in a command, log, committed file, or final response.Before executing, show the exact public target and any important exposure consequence when it is not already obvious from the user's request.
portal expose in a foreground PTY or managed long-running command session. Do not hide it behind an untracked nohup process.run, restart, and stop are service-wide: they affect every [[tunnels]] entry that the selected service owns. Reuse and merge the existing config when the same agent should keep other tunnels. An isolated second agent needs its own config, service_name, state_dir, and loopback control_addr. Changing only service_name still shares the default state directory and 127.0.0.1:4018. Do not stop or replace an agent that already owns unrelated tunnels.portal agent run --config <path> after the user accepts OS-service installation, or portal agent run --foreground --config <path> when the current session should own the process. --foreground opens the interactive dashboard when stdin and stdout are TTYs. Run that command in a non-TTY managed session so logs stay capturable and the TUI does not start.portal agent dashboard. It is an interactive TUI. Give the user that command in the handoff.raw transport endpoints allocated with tcp_addr and/or udp_addr instead of service ready at <URL>. Do not wait for an HTTPS URL on a raw transport.401 or 403; explain that as reachable but protected. Treat unexpected 5xx, TLS errors, or a Portal error page as a failed deployment.402 Payment Required plus a payment-requirements header. Compare the returned network, asset, recipient, amount, and resource with the requested policy. Verify the method scope by requesting an intentionally unprotected method when one exists. Never spend funds merely to verify configuration.tcp_addr/udp_addr without mutating application data. A successful local port open is not enough.Report:
--hide.--ban-mitm.402 challenge was verified. State explicitly when settlement was not tested.Do not call the result permanent when the local machine, app process, or foreground tunnel must remain running.
402 challenge: do not describe it as protected or hand it off as ready. Stop only the tunnel created by this workflow, preserve bounded diagnostics, and report the policy mismatch.--ban-mitm: report the warning and offer --ban-mitm; do not claim the relay was blocked.Take gosuda/portal-expose from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.