Skip to content

Signing in

Every CLI command talks to one LangAlpha server with one credential. This page explains how the CLI picks both, and how langalpha login signs you in.

The CLI takes the first credential it finds, in this order:

  1. --token T on the command line.
  2. LANGALPHA_TOKEN_FILE, the path of a file holding a token. Inside a computer the agent’s commands have it set. The file is read again on every request, and once more after a refused one, because the server rewrites it while commands run. Where it is set, nothing below is tried: a file with no token in it is an error, never a reason to fall back to your own sign-in.
  3. Your saved sign-in for the server, from langalpha login.
  4. None, which a self-hosted server that asks for no sign-in accepts.

The server is --server URL if you pass it, then LANGALPHA_URL (an empty value counts as unset), then the server you last signed in to, and finally http://localhost:8000, the default address of a self-hosted install.

Signing in to a server makes it the default for later commands, so you usually pass --server once, to login.

When LANGALPHA_TOKEN_FILE is set, the file names the server its token belongs to, and the CLI refuses to send that token anywhere else: a --server or LANGALPHA_URL naming another server is an error.

langalpha login first asks the server how it takes a sign-in (GET /api/v1/auth/cli, described in Authentication). Then it goes one of two ways.

No sign-in needed. A server that asks for no credential answers so, and login only records it as your default server: “http://localhost:8000 needs no sign-in.”

In the browser. When the server names a sign-in provider, login prints a sign-in link and opens it in your browser. Sign in there, and the browser hands the result back to the CLI on a port of 127.0.0.1 on your machine; the tab then says you can close it. The CLI waits up to 5 minutes. Pass --no-browser to print the link without opening it. To sign in on a machine with no browser, see the next section.

Terminal window
langalpha login --server https://<your-server>

A browser sign-in renews itself. The CLI refreshes the access token shortly before it runs out, and again if the server refuses it. When the refresh itself is refused, the sign-in has ended, and the command says to run langalpha login again (exit code 3).

A server that asks for sign-in but offers the CLI no way to do it answers that it “takes no CLI sign-in”, and login exits with code 3.

On a machine you reach over SSH and that has no browser, run langalpha login --no-browser there. It prints the sign-in page instead of opening it and waits up to 5 minutes. The page sends the browser back to 127.0.0.1 on the machine running langalpha, so a browser on your laptop can only finish the sign-in if you forward that port to the remote machine over SSH.

The port is not fixed. The CLI asks the operating system for a free one each time it runs, so it differs on every login. You read it from the printed page: the redirect_uri part of the link holds the callback address, with the port after 127.0.0.1%3A. In redirect_uri=http%3A%2F%2F127.0.0.1%3A44387%2Fcallback the port is 44387.

  1. On the remote machine, run langalpha login --no-browser --server https://<your-server> and leave it running.

  2. Find the port in the printed link, here 44387.

  3. On your laptop, in a second terminal, forward that port to the remote machine, and keep the connection open:

    Terminal window
    ssh -L 44387:127.0.0.1:44387 <user>@<remote-host>
  4. Open the printed page in the browser on your laptop and sign in. The browser is sent to http://127.0.0.1:44387/callback on your laptop, SSH carries that to the remote machine, and the CLI there finishes the sign-in.

Do steps 3 and 4 within the 5 minutes. The port is free to use on your laptop only if nothing else holds it there; if ssh reports that it cannot listen on the port, stop login and start it again to get a new one. The sign-in is saved on the remote machine, where you ran login.

login saves one sign-in per server in ~/.config/langalpha/credentials.json (or under $XDG_CONFIG_HOME/langalpha/ when that is set), along with which server is the default. The folder is readable only by you and the file is written owner-only.

Commands run side by side share the file safely. A refresh holds a lock beside it, so parallel commands spend the rotating refresh token once and reuse what it bought, and a refresh never writes back a sign-in that logout or a new login replaced in the meantime. If the file cannot be read, the CLI leaves it as it is and asks you to fix or remove it before signing in again.

langalpha logout forgets your saved sign-in for the server (the default one, or --server), and clears the default if it was that server. It does not revoke anything on the server. To end a browser sign-in for good on the hosted platform, disconnect the CLI under Connected apps.

langalpha whoami asks the server who it takes you for:

server http://localhost:8000
user local-dev-user
via session
scopes all

via is how you are signed in: session (the web app’s sign-in, or a server with none), oauth (a browser sign-in), computer (a computer’s own token, which adds a computer line), or service. scopes lists what a token may do; a session holds every permission, and a token holding none prints none.

A token reaches only the routes whose scope it holds. The CLI’s commands need these:

Scope Commands
agent:read Every list and show, threads follow, models list, and the workspace lookup behind -w
agent:run threads new, send, retry, approve, reject, cancel, and automations trigger
workspace:write workspaces create, archive, delete; threads archive, delete; automations create, edit, pause, resume, delete
computer:write computers add, start, stop, remove

A command missing a scope fails with exit code 3 and names the scope. data:read covers market data routes, which the CLI does not call. Some actions take no scope at all and stay with the web app: approving or rejecting a brokerage order is one.