mobius-gateway 0.9.13

Headless authenticated gateway for möbius frontends
Documentation
# möbius Gateway

`mobius-gateway` is the headless möbius runtime. One process owns machine
credentials, usage, and scheduled tasks while hosting up to 32 independent
chat agents. Every chat owns its canonical workspace, model, reasoning, agent
features, approval policy, and prompt. The terminal, iPhone, and iPad
clients can independently open different chats or subscribe to the same one.
Chats store enabled optional middleware IDs and generic scalar settings. The gateway advertises
the ordered middleware catalog plus integer and select control schemas, so terminal and iOS
clients render new middleware and settings without capability-specific code. Context offloading
is enabled by default and masks successful tool output after a 50,000-token trailing window. The
gateway always installs sandboxing, workspace tools, turn steering, and durable sessions.
Scheduling is an optional capability and is enabled by default for new chats.

Install `mobius-cli` to get both the client and gateway commands:

```sh
cargo install --locked mobius-cli
```

The separately versioned `mobius-gateway` crate is the runtime library used by those binaries.

Initialize and pair the default gateway:

```sh
mobius-gateway init
```

**Quick Connect** is selected by default. It starts an account-free Cloudflare
Quick Tunnel, captures its temporary `trycloudflare.com` address, and displays
both the public `wss://` endpoint and local `tcp://127.0.0.1:8741` endpoint with
one ten-minute, one-use pairing code. No Cloudflare account, domain, route, or
connector token is required. The address changes whenever the gateway restarts,
so use the advanced stable-hostname option for a durable endpoint. Once a client
pairs through either endpoint, `connect` returns and the gateway keeps running in
the background. Run `mobius-gateway connect` later to advertise a fresh code while
the gateway remains running.

For that advanced option, enter the intended hostname and connector token.
möbius starts the connector first and waits for pairing; you can then publish the
hostname to `http://127.0.0.1:8741` in Cloudflare without the missing-route
failure aborting setup. möbius stores the token in an owner-only file outside
`gateway.toml` and starts `cloudflared` with `--token-file`. The
GitHub binary archives include a pinned `cloudflared` sidecar; source and
`cargo install` builds require `cloudflared` beside `mobius-gateway` or on
`PATH`. The gateway also prints a copyable `mobius-pair:v1` setup code and, in an
interactive terminal, an iPhone/iPad QR. Both contain only the public endpoint
and short-lived möbius pairing code. They prefill the Apple pairing form for
confirmation and never contain the Cloudflare token.

If the selected state directory already exists, interactive initialization asks
for explicit confirmation before stopping the old gateway and deleting its
configuration, chats, providers, and paired devices.

For non-interactive setup, keep the token in an owner-only file and use:

```sh
mobius-gateway init \
  --cloudflare-hostname mobius.example.com \
  --cloudflare-token-file /private/path/tunnel-token
mobius-gateway connect
```

Plaintext listeners and clients are restricted to loopback. An iPhone, iPad,
or another machine therefore needs a routable TLS endpoint with a
publicly trusted certificate whose hostname matches that endpoint:

```sh
mobius-gateway init --listen 0.0.0.0:8741 \
  --tls-cert /absolute/path/fullchain.pem \
  --tls-key /absolute/path/private-key.pem
mobius-gateway connect --endpoint tls://gateway.example:8741
```

On iPhone, iPad, or Mac, choose **Add gateway** and enter the displayed
**Gateway address** and **One-time code**. On another terminal client, run the
displayed `mobius pair` command. Pairing consumes the code and returns a unique
bearer token; Apple clients keep it in Keychain and `mobius` keeps it in its
owner-only gateway account file. Later connections use that token, not the
one-time code.

To add another device while the gateway is already running, an authenticated
Apple client can open **Gateway → Pair another device → Create one-time code**;
an authenticated terminal client can run `/pair`. `mobius-gateway connect` is
the host-side recovery flow for a stopped gateway.

By default, owner-only state is stored under `~/.mobius/gateway`. Set
`MOBIUS_GATEWAY_STATE_DIR` or pass `--state-dir` to use another location.
On Linux, run the gateway account without permitted or ambient capabilities;
Bubblewrap rejects a non-root caller that retains them. Hosts that allow user,
PID, mount, and network namespaces but forbid mounting procfs inside a child PID
namespace can set `MOBIUS_GATEWAY_SANDBOX_PROC=empty`. This keeps PID isolation
and mounts an empty `/proc`; the default `private` mode mounts a private procfs.
Provider credential APIs are write-only and never return stored secret values.
Full-access shell commands can use the host filesystem and network while file tools
remain workspace-scoped. Those shell commands can access gateway state, TLS credentials,
stored provider credentials, and any other files or services available to the gateway
account.
The configured-model catalog and new-chat default live in gateway configuration.
The first configured model becomes the default. A new chat copies that default,
then stores its own selected model and runtime recipe beside its durable
checkpoint; changing one chat never changes the catalog, another chat, or its
workspace.

The gateway also owns the extension catalog. Clients may install a standalone
Agent Skill or OpenAI plugin from a credential-free HTTPS Git source. Packages
are stored as content-addressed snapshots and remain inactive until selected for
the default agent or a chat. Executable plugin hooks require explicit review for
the installed package digest. Update and uninstall require deactivation first;
per-workspace plugin data under `.mobius/extensions` is retained.

Automation may register an OpenRouter-compatible HTTPS endpoint without sending
provider credentials:

```sh
mobius-gateway register-provider --provider openrouter --model MODEL \
  --reasoning-efforts medium,none,low,high,xhigh,max \
  --web-search live \
  --base-url https://connector.example/v1 --credentialless
```

The command authenticates over the running loopback gateway, is idempotent, and
prints `{"provider":"openrouter"}` on success. Credentialless mode is rejected
for the direct OpenRouter endpoint and for providers that do not advertise it.
Replacing a registered provider also updates its new-chat default and durable
chat selections before success. The command fails while a resident chat is busy,
so automation can retry without retiring the previous endpoint prematurely.

On macOS or Linux, open the live dashboard or gracefully stop the configured
gateway from another terminal:

```sh
mobius-gateway
mobius-gateway provider
mobius-gateway exit
```

The no-command form starts the gateway in the background when needed, then
shows every paired device and chat with active entries first, plus configured
providers, editable defaults, and usage. Use Tab plus the arrow, page, or mouse
wheel controls to scroll device and chat history. In Devices, press `u` or
Delete and confirm to unpair the selected device; the dashboard cannot unpair
its own credential. Press `p` for provider setup, `d` for defaults, or `q` to
leave without stopping the gateway. `provider` opens the same provider setup
directly. These views use this machine's saved gateway pairing.

Exit verifies the gateway's locked process record before sending
SIGINT and waits up to five seconds for shutdown.
`serve --background` starts a detached process on macOS or Linux and returns
only after that process owns the gateway process record. Foreground `serve`
continues to run until interrupted. Use `serve --background` for ordinary
restarts after at least one client is paired.

If every client token is lost, stop the gateway and run the supervised pairing
flow again; existing paired clients remain valid:

```sh
mobius-gateway exit
mobius-gateway connect # add --endpoint tls://HOST:PORT for TLS
```

The internal scheduler accepts standard five-field cron expressions. Scheduled
runs use durable möbius sessions and never install system crontab entries or
spawn a child CLI. A frontend starts assisted setup with the protocol's cron
setup operation (`/cron new [task]` in the terminal client); ordinary chat is
not authorized to create schedules. Model-confirmed task files are owner-only
under the gateway state directory. Disabling scheduling for a chat removes its setup tool and
prompt but does not delete or pause existing schedules; history stays visible and the capability
state remains available to management views while agent scheduling is off.
With no clients and no registered cron tasks,
the gateway exits after 72 hours; any scheduled task disables that idle timer.
Stopping the gateway manually also stops scheduled work, and missed runs are not
replayed after restart.