# inrok — full documentation > Generated from the same sources as https://inrok.in/docs/cli/. Index: https://inrok.in/llms.txt --- # inrok CLI quickstart Put a public HTTPS URL on any local port in under a minute. inrok is a managed tunneling service: the `inrok` CLI runs on your machine, and inrok's hosted edge gives your tunnel a stable public URL like `https://demo.share.inrok.in`. ## 1. Install macOS / Linux: ```sh curl -fsSL https://inrok.in/install.sh | sh ``` Windows (PowerShell): ```powershell irm https://inrok.in/install.ps1 | iex ``` The installer downloads the right binary for your platform. Verify with `inrok version`. ## 2. Log in (once per machine) 1. Create an account at [app.inrok.in](https://app.inrok.in/register) (free — no card required). 2. Generate an API key at [app.inrok.in/settings](https://app.inrok.in/settings) → **CLI access**. 3. Run: ```sh inrok login ``` Paste the key (`inrok_…`) when prompted. Non-interactive alternative: ```sh inrok login --key "$INROK_API_KEY" ``` Credentials are saved to `~/.inrok/config.json` (mode 0600). One key per machine is the recommended setup — keys are listed and revocable in the dashboard. ## 3. Expose a port ```sh inrok http 8080 ``` Output: ``` Forwarding https://http-8080-x7k2.share.inrok.in → http://localhost:8080 TLS 1.3 · persistent name · Ctrl-C to stop ``` The command runs in the foreground and streams request logs. **Ctrl-C stops serving but keeps the name reserved** — the next `inrok http 8080` re-binds the same URL. ## Stable names Pass `--name` to choose the URL label: ```sh inrok http 3000 --name demo # → https://demo.share.inrok.in ``` Without `--name`, a default like `http-8080-x7k2` is derived from the port plus a per-account suffix. Names are reserved to your account until you release them. ## What you can expose Today `inrok` exposes local **HTTP** services — one positional argument (the port, or `host:port`) plus an optional `--name`: ```sh inrok http 8080 # HTTP reverse proxy to a local port inrok http 192.168.1.5:80 # …or a host:port on your network ``` Raw **TCP** and **UDP** endpoints are coming soon. Static sites, Caddyfile, and file-drive modes aren't supported. ## Manage tunnels ```sh inrok status # list tunnels: NAME, URL, TARGET, STATE (aliases: list, ls) inrok stop demo # release a tunnel by name (frees the URL and the slot) inrok logout # remove this machine's credentials and device identity inrok update # self-update to the latest release (--check to only look) ``` `inrok stop` deletes the reservation — the name becomes available to others. Just pressing Ctrl-C in a running `inrok http` keeps it reserved. ## Plan limits The free beta plan includes **100 GiB of bandwidth per month and 3 tunnels**. Current usage is on your [dashboard](https://app.inrok.in/dashboard); tunnels pause when the monthly cap is reached and resume when the cycle resets. ## Next steps - [Configuration](https://inrok.in/docs/cli/configuration.md) — config file, environment variables, state directories. - [Troubleshooting](https://inrok.in/docs/cli/troubleshooting.md) — every error message explained. - [inrok for AI agents](https://inrok.in/docs/cli/agents.md) — a paste-ready block for CLAUDE.md / AGENTS.md. - [Command reference](https://inrok.in/docs/cli/reference/inrok.md) — generated from the CLI itself. --- # inrok CLI configuration The CLI is deliberately low-config: one JSON file written by `inrok login`, one optional environment variable, and a self-contained state directory. ## Config file `inrok login` saves credentials to: ``` ~/.inrok/config.json (directory 0700, file 0600) ``` ```json { "apiBaseUrl": "https://app.inrok.in", "apiKey": "inrok_…" } ``` Don't edit this by hand — re-run `inrok login` to change it, or `inrok logout` to remove it. `inrok logout` also wipes the device identity (see below), so the next login starts clean. ## Environment variables | Variable | Effect | | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `INROK_CONFIG_DIR` | Overrides the `~/.inrok` directory entirely (config file **and** device state live under it). Useful for CI, containers, or running two accounts side by side. | There is no `INROK_API_KEY` environment variable — pass a key explicitly with `inrok login --key`. ## Login flags ```sh inrok login --key inrok_… # skip the interactive prompt inrok login --api-url https://app.inrok.in # point at a different API host ``` `--api-url` defaults to `https://app.inrok.in` (the dashboard host that serves `/api/v1`). You only need it for self-hosted or staging setups. ## Device state The first `inrok http` (or any host command) transparently enrolls this machine with inrok's tunneling fabric. That state lives under `~/.inrok/` and is owned and managed entirely by inrok — don't edit it by hand. It is account-bound: `inrok logout` removes it, and the CLI automatically repairs it if it goes stale (you'll see "re-enrolling and retrying" once, then your tunnel comes up). ## Foreground model and signals The host command (`http`) runs in the foreground and streams request logs until interrupted: - **Ctrl-C / SIGTERM** — stops serving gracefully (the public name stays reserved for your account; re-running re-binds the same URL). - `inrok stop ` — releases the reservation entirely. To run a tunnel unattended, use your platform's service manager (systemd, launchd, NSSM) or a terminal multiplexer; the process is safe to supervise and restart — the same `--name` always re-binds the same URL. ## Updates ```sh inrok update # download + verify + replace the binary in place inrok update --check # only report whether a newer version exists ``` After any command, the CLI may print a one-line nudge if a newer release exists; the check runs at most once every 24 hours and never blocks or fails a command. ## Exit codes `0` on success; non-zero on any error, with a single human-readable message on stderr (see [Troubleshooting](https://inrok.in/docs/cli/troubleshooting.md) for the catalogue). --- # inrok CLI troubleshooting Every error the CLI prints, what it means, and what to do. Messages are quoted as the CLI emits them so you (or your AI assistant) can match them exactly. ## Login and credentials **"not logged in — run `inrok login` first"** No saved credentials on this machine. Run `inrok login` and paste an API key from [app.inrok.in/settings](https://app.inrok.in/settings) → CLI access. **"that doesn't look like an inrok key (expected inrok\_…)"** API keys start with `inrok_`. You probably pasted something else (an email, another tool's token, a truncated copy). Copy the full key from the dashboard. **"key rejected — check it and try again"** (during `inrok login`) The key didn't authenticate. It may have been revoked in the dashboard, or it belongs to a different environment than the `--api-url` you're pointing at. **"your key was rejected — run `inrok login` again"** (during any command) The saved key was valid once but isn't anymore — most likely revoked from the dashboard. Re-login with a fresh key. ## Tunnel names **"this tunnel name belongs to a different inrok account…"** The name was reserved while this machine was logged in as another user. Either `inrok logout` then `inrok login` as the owning account, or pick a different `--name`. Names are globally unique — first account to reserve one keeps it. **"that name is still bound from a previous run — the fabric releases it within a couple of minutes; retry shortly or pick a different --name"** A previous share for that name hasn't fully deregistered yet (common right after a hard kill). Transient — wait a minute or two and retry. **"no tunnel named … — run `inrok status` to list them"** (from `inrok stop`) `stop` matches the tunnel's name or its share name exactly. List them with `inrok status` and copy the NAME column. ## Device enrollment **"Setting up this device…" takes a moment on first run** Normal: the first host command enrolls this machine with the tunneling fabric. Subsequent runs are fast. **"Device credentials were stale — re-enrolling and retrying…"** Self-healing in progress, not an error. The CLI wipes its device state, re-enrolls, and retries once automatically. **"tunnel agent still unauthorized after re-enrolling — your account may be suspended; contact support@inrok.in"** Re-enrollment didn't fix it, which usually means the account is suspended (e.g. over the bandwidth cap) or disabled. Check the dashboard; if your usage looks fine, email support@inrok.in. ## Limits **Tunnel creation fails with a limit message** The free beta plan allows 3 tunnels. Release one with `inrok stop ` (or delete it from the dashboard) and retry. **Tunnel stops accepting traffic mid-month** You've likely hit the monthly bandwidth cap (100 GiB on the free beta plan). The dashboard banner confirms it; tunnels resume when your cycle resets. **"fetch account setup" errors on first host command** The account isn't fully provisioned yet — most commonly the email address isn't verified. Open the verification link from your signup email, then retry. ## Network **`inrok login` or any command hangs / times out** The CLI talks to `https://app.inrok.in`. Check connectivity and any corporate proxy. The tunnel data plane uses outbound TLS connections only — no inbound ports or router changes are ever needed. **Still stuck?** Run `inrok version` and include its output plus the exact error message in a mail to support@inrok.in. --- # inrok for AI agents Working with Claude Code, Cursor, Copilot, or another AI assistant? Paste the block below into your project's `CLAUDE.md` / `AGENTS.md` (or your assistant's custom instructions) and it will know how to drive inrok correctly. Machine-readable docs live at [inrok.in/llms.txt](https://inrok.in/llms.txt) (index) and [inrok.in/llms-full.txt](https://inrok.in/llms-full.txt) (full docs, one file) — point your assistant at either. ## Paste-ready block ```markdown ## Public URLs via inrok inrok exposes local ports at public HTTPS URLs (`https://.share.inrok.in`). - Check auth: `inrok status` exits non-zero with "not logged in" if no key is saved. Log in non-interactively: `inrok login --key ` (keys are created by a human at https://app.inrok.in/settings → CLI access — never invent one). - Expose an HTTP port: `inrok http --name `. This runs in the FOREGROUND until interrupted — run it in the background and poll `inrok status` until STATE shows the tunnel is up, then read the URL column. - The public URL is printed on the "Forwarding" line and is stable: the same --name always re-binds the same URL, across restarts. - Stopping the process (SIGTERM/Ctrl-C) keeps the name reserved; it only stops serving. To free the name and the tunnel slot, run `inrok stop `. - HTTP is the only backend mode today. TCP and UDP are coming soon; there are no static-site, Caddyfile, or file-drive modes. - Free plan limits: 3 tunnels, 100 GiB/month. Tunnel creation failing with a limit error → run `inrok stop` on an unused tunnel first. - Errors are single-line, human-readable, on stderr; exit code is non-zero. Full catalogue: https://inrok.in/docs/cli/troubleshooting.md ``` ## Tips for agent authors - **Foreground semantics are the #1 gotcha.** `inrok http` blocks. Agents should start it as a background process, wait for the `Forwarding` line (or poll `inrok status`), and capture the URL from there. - **Names are idempotent.** `inrok http 8080 --name demo` after a crash or restart re-binds the exact same URL — safe to retry, safe to supervise. - **Never scrape or guess API keys.** Key creation is a human step in the dashboard. If `inrok status` says "not logged in", surface that to the user instead of retrying. - **Cleanup matters.** A polite agent runs `inrok stop ` when the tunnel was created for a temporary task — the free plan has 3 slots. - The full command reference (generated from the CLI itself, always current) starts at https://inrok.in/docs/cli/reference/inrok.md --- ## inrok inrok — put a public HTTPS URL on any local port ### Options ``` -h, --help help for inrok ``` ### SEE ALSO * [inrok http](inrok_http.md) - Expose a local HTTP port at a public URL * [inrok login](inrok_login.md) - Authenticate this machine with your inrok account * [inrok logout](inrok_logout.md) - Remove this machine's saved credentials * [inrok status](inrok_status.md) - List your tunnels and their public URLs * [inrok stop](inrok_stop.md) - Stop a tunnel by name * [inrok update](inrok_update.md) - Update inrok to the latest release * [inrok version](inrok_version.md) - Print the inrok version --- ## inrok http Expose a local HTTP port at a public URL ### Synopsis Expose a local HTTP port at a public URL. Reserves (or re-binds) the public name and runs in the foreground; Ctrl-C stops serving but keeps the name reserved — the next run re-binds the same URL (delete it from the dashboard or with `inrok stop`). ``` inrok http [flags] ``` ### Options ``` -h, --help help for http --name string reserve a stable name for the URL (default derived from the argument) ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port --- ## inrok login Authenticate this machine with your inrok account ### Synopsis Save an API key for this machine. Generate one at https://app.inrok.in/settings → "CLI access". ``` inrok login [flags] ``` ### Options ``` --api-url string API base URL (default https://app.inrok.in) -h, --help help for login --key string API key (inrok_…); omit to be prompted ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port --- ## inrok logout Remove this machine's saved credentials ``` inrok logout [flags] ``` ### Options ``` -h, --help help for logout ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port --- ## inrok status List your tunnels and their public URLs ``` inrok status [flags] ``` ### Options ``` -h, --help help for status ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port --- ## inrok stop Stop a tunnel by name ``` inrok stop [flags] ``` ### Options ``` -h, --help help for stop ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port --- ## inrok update Update inrok to the latest release ### Synopsis Check for the latest inrok release and, if newer, download the matching binary (checksum-verified) and replace this one in place. Use --check to only report whether an update is available. ``` inrok update [flags] ``` ### Options ``` --check check for a newer version without installing it -h, --help help for update ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port --- ## inrok version Print the inrok version ``` inrok version [flags] ``` ### Options ``` -h, --help help for version ``` ### SEE ALSO * [inrok](inrok.md) - inrok — put a public HTTPS URL on any local port