agentproto CLI
Verbs

`agentproto auth`

text agentproto auth login [--host <url>] [--label <name>] [--no-browser] [--scope <s>] agentproto auth status [--host <url>] [--json] agentproto auth logout [--host <url>]

agentproto auth

agentproto auth login   [--host <url>] [--label <name>] [--no-browser] [--scope <s>]
agentproto auth status  [--host <url>] [--json]
agentproto auth logout  [--host <url>]

Manages host-binding tokens — the JWT agentproto serve --connect <host> sends to its tunnel host (Guilde, a self-hosted gateway, anything that exposes the well-known metadata document). Tokens land in ~/.agentproto/credentials.json, mode 0600. See ../concepts/credentials.md and ../reference/credentials-format.md for the on-disk format.

These tokens are not per-adapter setup tokens. Adapter setup secrets live in their own ledger (see setup.md).

Mechanism

OAuth 2.0 Device Authorization Grant (RFC 8628) — same flow as gh auth login, gcloud auth login, stripe login. Three round-trips:

  1. DiscoveryGET <host>/.well-known/agentproto-host.json for the device + token endpoints and client_id.
  2. AuthorizePOST device endpoint → user_code + verification_uri.
  3. PollPOST token endpoint with grant_type=urn:ietf:params:oauth:grant-type:device_code until the user approves in their browser; persist the bearer.

Hosts must expose /.well-known/agentproto-host.json. The CLI is host-agnostic — any host that publishes the metadata works.

login

# First login — host required
agentproto auth login --host wss://guilde.work

# Subsequent logins to the same host can omit --host
agentproto auth login

# Headless / SSH: don't try to open a browser, just print the URL
agentproto auth login --host wss://guilde.work --no-browser

Flags:

FlagPurpose
--host <url>The tunnel host URL. Most-recently-used wins when omitted. wss:// and ws:// are normalised to https:// / http:// for the discovery fetch.
--label <name>Friendly device label shown on the host's approval UI. Default username@hostname.
--scope <space-separated>OAuth scopes to request. Default "tunnel:connect agent-cli:dispatch".
--no-browserSkip open / xdg-open of the verification URL. The URL + user code are always printed.

On success: ~/.agentproto/credentials.json is created/updated with { token, refreshToken?, scope, subject?, expiresAt, deviceLabel } keyed by the (trailing-slash-stripped) host URL.

status

agentproto auth status
agentproto auth status --host wss://guilde.work
agentproto auth status --json

Prints one block per logged-in host with subject, scope, label, and a relative expiry. ✓ active vs ✗ EXPIRED is computed locally; refresh on expiry is handled by serve when reconnecting. --json emits a machine-readable shape for scripts.

status exit code is 0 even when no credentials exist; absence is not an error.

logout

agentproto auth logout --host wss://guilde.work
# Single-host setup: --host can be omitted
agentproto auth logout

Best-effort server-side revocation if the host's discovery document advertises a revocation_endpoint (RFC 7009). The local copy is always deleted, even when the server call fails — you're logged out on this machine either way.

When the credentials file ends up empty, it's removed.

Examples

# Log into a guilde host, status, logout
agentproto auth login --host wss://guilde.work
agentproto auth status
agentproto auth logout --host wss://guilde.work

# Self-hosted gateway with a custom label
agentproto auth login --host wss://acme.internal --label "ci-runner-3"

# Use the stored token implicitly with serve
agentproto auth login --host wss://guilde.work
agentproto serve --connect wss://guilde.work   # picks up the token automatically

Token resolution in serve

agentproto serve --connect <host> looks up the bearer in this order:

  1. --token <jwt> flag
  2. $AGENTPROTO_TOKEN env var
  3. ~/.agentproto/credentials.json[<host>]

An expired credential is still used — serve logs a warning so the host's 401 surfaces a clearer error than a silent disconnect. Re-run agentproto auth login to refresh.