portal-expose
Expose, preview, protect with x402 payments, or keep a local web app, static site, HTTP route set, or explicitly requested…
Reach, inspect, or consume a service that someone published through a Portal relay. Turns a Portal hostname, a service name plus relay, or a bare service name into the right public URL (name.relay-host over HTTPS) or raw host:port, lists what is live on a public or self-hosted
$ npx -y skills add gosuda/portal-tunnel --skill portal-connect --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/portal-connectContext preview
The summary Claude sees to decide when to auto-load this skill.
Reach, inspect, or consume a service that someone published through a Portal relay. Turns a Portal hostname, a service name plus relay, or a bare service name into the right public URL (name.relay-host over HTTPS) or raw host:port, lists what is live on a public or self-hosted
name: portal-connect description: Reach, inspect, or consume a service that someone published through a Portal relay. Turns a Portal hostname, a service name plus relay, or a bare service name into the right public URL (name.relay-host over HTTPS) or raw host:port, lists what is live on a public or self-hosted relay through GET /api/state, makes bounded HTTPS requests or protocol probes, connects to raw TCP/UDP endpoints such as game servers, SSH, or databases, and recognizes an x402 402 Payment Required challenge and reports its terms without paying. Use when the user pastes a Portal URL or hostname, asks what is available on a relay, wants to call, fetch, test, browse, or check an app, API, agent, or game server exposed with Portal, asks what a paid route costs, or asks whether a Portal tunnel is reachable from the outside. Do not use for exposing a local app (portal-expose), running or registering a relay (portal-relay), paying for a route (a separate payment workflow), or generic HTTP debugging of hosts that are not behind Portal. license: MIT
A Portal service is an ordinary public endpoint. The consumer needs no Portal account, key, or client: an HTTPS tunnel is reached with any HTTP client at `https://<name>.<relay-host>/`, and a raw TCP or UDP tunnel with any client at the relay-assigned `host:port`. The `portal` CLI has no `connect` subcommand, and `portal list` prints relays, not services, so do not invent one. Behind the URL is the publisher's own machine, often a laptop on a home connection, so keep every request bounded and deliberate.
Run the workflow in order. Open a reference only when that branch is taken: `references/discovery-api.md` for relay endpoints, JSON shapes, the hostname rule, and how to read a `402 Payment Required` challenge; `references/raw-transport.md` for a TCP or UDP endpoint.
Pick the first form that matches what the user gave:
Ask one concise question only when the target cannot be determined safely, for example when several relays host the same name under different owners, or when the requested interaction would mutate data or require a login the user did not mention.
Make one bounded request and record the result:
curl -sS --connect-timeout 5 --max-time 15 -o /dev/null \
-w '%{http_code} %{content_type} exit=%{exitcode} %{errormsg}\n' https://<hostname>/Probe whether or not the name was listed: the listing proves registration, the probe proves service. When there is no HTTP response the status prints as `000`, so read the curl exit code: `35` is a TLS handshake failure, `6` a DNS failure, `7` a refused connection, `28` a timeout.
Read the outcome the same way every time:
Expose local services through self-hosted or public relays.No port forwarding. No inbound firewall rules. No manual DNS setup. No accounts.
Expose, preview, protect with x402 payments, or keep a local web app, static site, HTTP route set, or explicitly requested…
Set up and run a public Portal relay on any Linux host with a public IP — Docker Compose deployment, embedded authoritative DNS…