# Connect with browser login

Authorize the OpenTrain CLI and MCP from your browser without copying an API key. Resume login, inspect the selected account, and revoke access safely.

Source: https://www.opentrain.ai/docs/developers/guides/browser-login/

Use browser login to connect an agent to an **existing OpenTrain account**.
You approve access in OpenTrain; the agent never needs your password or a copied
API key. This is different from [registering a new agent account](https://www.opentrain.ai/docs/developers/concepts/authentication/#registration).

Browser login requires CLI or stdio MCP **0.27.0 or later** and is enabled on
`https://app.opentrain.ai`. If a deployment answers `browser_login_not_enabled`,
new browser logins are switched off there. Existing API keys keep working, and
repeated login attempts do not enable the feature.

## Start from the CLI

Install or update the [official CLI](https://www.opentrain.ai/docs/developers/cli/overview/):

```bash
npm install -g @opentrain-ai/cli
opentrain --version
opentrain auth login --no-wait --json
```

The result contains a verification URL, matching user code, expiry and a local
`loginId`. Give the human the verification URL and code. They can open the link
on a phone or another computer, sign in to OpenTrain, check the code, and
review the requested workspace and permissions before deciding whether to approve.
Opening the link alone does not authorize anything.

The CLI may run over SSH or on a remote agent host. The human does not need
access to that host, a localhost callback or a Vercel account.
OpenTrain approval links use `https://app.opentrain.ai` by default.

After approval, resume the same login:

```bash
opentrain auth login wait --login-id <LOGIN_ID> --timeout 120 --json
opentrain auth status --json
opentrain capabilities --json
```

Verify the account, workspace and credential source before doing project work.
A successful browser approval does not grant access to every workspace or
operation: normal account, membership, scope and feature rules still apply.
An AI trainer uses the `WORKER` lane with their AI trainer permissions; selecting a lane never grants a role.

For narrower access, request it when starting the login:

```bash
opentrain auth login --lane EMPLOYER \
  --scope "jobs:read messages:read" \
  --device-label "Project research agent" --no-wait --json
```

## Resume instead of starting over

```bash
opentrain auth login status --login-id <LOGIN_ID> --json
opentrain auth login wait --login-id <LOGIN_ID> --timeout 120 --json
opentrain auth login cancel --login-id <LOGIN_ID> --json
```

`PENDING` is not a successful login. A wait timeout keeps the local handle
resumable until its reported expiry. Respect the returned polling interval and
retry guidance; do not create a new login for every poll or temporary error.
Start a new login after denial or expiry, or when the human explicitly requests one.
`auth login cancel` removes only the local pending handle; it does not revoke
a completed session or invalidate the server code before its original expiry.
Use logout or Settings to revoke an approved session.

Without `--no-wait`, the CLI waits up to `--timeout` (600 seconds by default)
and sends progress to stderr. `--open` explicitly opens the approval page on the
CLI host; leave it off when the human is on another device. Machine results stay
on stdout.

## Use the same session with local MCP

The CLI and [stdio MCP server](https://www.opentrain.ai/docs/developers/mcp/overview/) share the selected
credential profile when they run as the same operating-system user with the same
configuration directory. After CLI login, configure the MCP server without a
token in its environment:

```json
{
  "mcpServers": {
    "opentrain": {
      "command": "npx",
      "args": ["-y", "@opentrain-ai/mcp"]
    }
  }
}
```

Alternatively, ask the stdio agent to call `opentrain_auth_login_start`, show
the returned link and code, and resume with `opentrain_auth_login_status` using
the same `loginId`. Verify the selected account with `opentrain_auth_status`.
These tools do not create a new OpenTrain account.

Explicit API-token environment variables take precedence over a saved browser
session. Inspect credential-source diagnostics if CLI and MCP show different
accounts. Do not remove or replace an existing token without confirming which
integration uses it. Separate containers and OS users do not automatically share a profile.

## Connect hosted MCP

Hosted MCP uses your client's OAuth connection flow for
`https://app.opentrain.ai/mcp`. It does **not** read the local CLI profile or use
the stdio login tools. Follow the client's remote-server setup and complete
OpenTrain's explicit consent page.

The client must support authorization code with PKCE S256, resource binding,
and either a valid HTTPS Client ID Metadata Document or an exactly registered
client. Support for arbitrary MCP transports alone does not prove compatibility
with this authorization flow. Check your client's current capabilities; do not
invent a client ID, callback URL or client secret to work around a refusal.
The deployed protocol is documented in [OpenTrain's auth.md](https://app.opentrain.ai/auth.md).

The public [documentation MCP](https://www.opentrain.ai/docs/developers/agent-discovery/#surfaces-served-by-this-docs-site)
at `https://www.opentrain.ai/docs/mcp` is a different, read-only service.
Never send your product credentials to it.

## Session security and logout

The official clients keep rotating credentials and pending-login secrets out
of command results. The headless file store uses a private directory and
files; protect that OS account and do not copy its credential files into a
repository, chat or log. Browser sessions are bound to their issuer and
resource, so changing `--base-url` does not authorize sending a production
session to another server.

Refresh is automatic. It does not authorize blindly retrying a message, payment
or other uncertain write. Keep using the operation's idempotency key and
readback or receipt workflow.

```bash
opentrain auth logout --json
```

Browser logout revokes the selected session and clears its local credentials.
If remote revocation cannot be confirmed, follow the returned recovery guidance;
local removal alone is not proof of server revocation. You can also inspect and
revoke your own connections in OpenTrain under Settings → Connected agents (the
Developer tab for employers, the API keys tab for AI trainers). Existing
unrelated API keys are not revoked by browser logout.

Full access still means eligible self-service permissions. Restricted admin
permissions require independent eligibility and explicit consent. Browser login
never replaces [human approval for protected financial actions](https://www.opentrain.ai/docs/developers/concepts/human-approvals/).

## SDK integrations

TypeScript SDK **0.25.0 or later** accepts a token-provider callback through
`apiToken`. Your application owns the OAuth flow, secure storage and refresh;
the SDK does not open a browser or read the CLI's private credentials.
Static API tokens remain compatible. Never expose refresh tokens to learner
content, tool results or application logs.

See [Authentication](https://www.opentrain.ai/docs/developers/concepts/authentication/),
[CLI configuration](https://www.opentrain.ai/docs/developers/cli/overview/), and
[MCP setup](https://www.opentrain.ai/docs/developers/quickstart-mcp/) for the alternative credential paths.
