# Sign in to Hyperscale

Read [how Hyperscale fits](https://hyperscale0.ai/docs/runtime.md#how-hyperscale-fits). Browser approval delegates access to the same operation API used by every client.

Sign in through the CLI. Never search environment files, shell history, rc files,
Keychain, or process environments for tokens. Never ask a founder to paste a
token into chat.

## Credentials and approval

Human portal sessions and personal access tokens carry the human's authority.
Product API keys admit Product operations. CLI and hosted MCP browser consent
issue delegated agent credentials for a named agent member. Its grant limits
the client, API audience, permissions and any selected Products and Builds.
Each request also checks the delegating human's current permissions.

The founder's own `hyperscale auth login` is the founder at the keyboard. In
sandbox it acts as the founder, including for a customer with `onBehalfOf`.
MCP agents and other OAuth clients never act for a customer.

Revoke one grant to stop its credentials and sandbox keys, or revoke the agent
member to stop all its grants. The delegator, company owner or admin can revoke
access from a browser session. Revocation cannot undo completed actions or
disclosed reads.

Sandbox work within the grant runs directly. Every live action, including
reads, and operations that cross a live boundary require request-bound browser
approval. Only the agent's own status reads skip this gate. When an operation
returns `agent_approval_required`, show its browser link to the delegating human.
They approve in their browser session and re-enter their password. The agent
cannot approve its own request.

Approval binds the operation, arguments, Product, Build digest, resource
revisions and idempotency key. It expires after ten minutes and can be consumed
once. After approval, retry the same request with the same idempotency key.
Denial or expiry ends the request without effects.

## CLI

Install the CLI once with Node 20 or later. Either command installs the
`hyperscale` binary on your `PATH`:

```sh
npm i -g @hyperscale0/cli
bun add -g @hyperscale0/cli
```

An installed CLI answers to `hyperscale <command>`, and the examples on this
page use it. On a machine without the install,
`bunx @hyperscale0/cli@latest <command>` runs the newest release.
`hyperscale upgrade` says when a newer release is out.

Run `hyperscale whoami`. It shows the founder's email and
team role, and when the login ends. If you are not signed in and the founder
has an account, pipe the founder's password on stdin:

```sh
hyperscale auth login --email founder@example.com --json
```

The CLI checks the password, solves a short proof of work and mails a
six-digit code. Ask the founder for it, then finish:

```sh
hyperscale auth login --code 123456 --json
```

`--json` prints one JSON object per line on stdout: `solving`, `code_sent`
and `code_needed`, then `signed_in` on the second call. This works on a second
machine with no browser. It signs in to sandbox only.

To approve in a browser instead, run `auth login` without `--email`, with a
10-minute tool timeout. Under `--json` the first line is
`{"step":"approval_needed","code":...,"url":...}`. Tell the founder the URL
and code. The founder opens the URL, checks the code, and approves. If your
tool call times out, run the same command again. It resumes the pending
request.

Either login ends after 30 days, or after 7 days unused. The CLI keeps it in
the macOS Keychain (service `hyperscale-cli-session`) or, without a Keychain,
in a private file in the config folder. `hyperscale doctor` names which. For
CI, pipe a personal access token to `auth login --with-token`, or set
`HYPERSCALE_TOKEN` and skip login.

For a founder without an account, pipe the founder's password on stdin:

```sh
hyperscale auth signup --email founder@example.com --name 'Founder Name' --company 'Company Name' --json
```

The CLI solves a short proof of work and mails the founder a six-digit code.
Ask the founder for it, then finish:

```sh
hyperscale auth signup --code 123456 --json
```

The account starts in sandbox with its email confirmed, and the CLI is signed
in. Five wrong codes retire the code; run the first command again for a new
one. `auth verify --email <email>` and `auth verify --code <code>` confirm an
existing account's email the same way.

Signed in, run `hyperscale init` in an empty folder, then
`hyperscale scenario run day.json`; [the docs](https://hyperscale0.ai/docs)
say what each writes and posts.

## Product keys

`hyperscale key create --name 'Checkout agent'` makes a sandbox Product key
and shows its secret once. `key list` shows each key's name and expiry. A key
made from a CLI login acts for that login, so it ends when the login ends:
on the date `key create` prints, or after 7 days with neither in use. A key
made in the browser lasts 90 days. MCP returns no credential, so no MCP tool
creates a key; a coding agent runs `hyperscale key create` with its own token.
A live key needs you: `hyperscale key create-live`.

## Device protocol

The CLI uses the REST resource `https://hyperscale0.ai/v1`. A client using the
wire protocol sends form data:

```sh
curl -sS -X POST https://hyperscale0.ai/v1/oauth/device \
  -d client_id=hyperscale-cli \
  -d resource=https://hyperscale0.ai/v1 \
  --data-urlencode 'scope=products:read products:write blueprints:read blueprints:write catalog:read keys:read keys:write activity:read'
```

For sign-up, add `login_hint`, `name`, and `company`. Show the returned
`verification_uri_complete` and `user_code` to the founder. Poll only after
the returned `interval`:

```sh
curl -sS -X POST https://hyperscale0.ai/v1/oauth/token \
  -d grant_type=urn:ietf:params:oauth:grant-type:device_code \
  -d client_id=hyperscale-cli \
  -d device_code=DEVICE_CODE_FROM_FIRST_RESPONSE
```

Keep polling on `authorization_pending`. Add five seconds to the interval on
`slow_down`. Stop on `access_denied` or `expired_token`. Keep the returned
access token in the client's private credential store. Do not put it in chat.

A headless MCP agent sends `resource=https://hyperscale0.ai/v1/mcp` and its
own name as `agent_name`, so the consent page names the agent instead of the
CLI. The access token lasts ten minutes. Before it expires, post
`grant_type=refresh_token` with the same `client_id`, `resource` and the
latest `refresh_token`. Each refresh returns a new pair. Reusing an old
refresh token revokes the grant.

## Connect MCP

Use the hosted server URL. Each client opens browser sign-in on first use.
No custom headers or pasted keys are needed.

```sh
claude mcp add --transport http hyperscale https://hyperscale0.ai/v1/mcp
codex mcp add hyperscale --url https://hyperscale0.ai/v1/mcp
gemini mcp add hyperscale https://hyperscale0.ai/v1/mcp --transport http
```

In Cursor, add an HTTP MCP server named `hyperscale` with URL
`https://hyperscale0.ai/v1/mcp` in Settings > MCP. Approve the browser request
when Cursor first connects.

### Coding agents

A coding agent such as Claude Code, Codex or Cursor gets its own login with
one command. Sign in first, then run:

```sh
hyperscale agent setup claude-code
export HYPERSCALE_TOKEN="$(hyperscale agent token claude-code)"
claude
```

`agent setup` uses your CLI login to make a named agent member, "Claude
Code", with a sandbox-only grant. It writes the host's MCP entry
(`.mcp.json`, `.codex/config.toml` or `.cursor/mcp.json`) and installs the
Hyperscale skill (`.claude/skills/hyperscale`, `.agents/skills/hyperscale` or
`.cursor/skills/hyperscale`). Add `--scope user` to write into your home
directory. The MCP entry names `HYPERSCALE_TOKEN` and never holds the token,
so the file is safe to commit.

Each project can keep its own agent. Name it with `--name`, and `agent token`
finds it by name or by the folder you set it up in:

```sh
cd ~/rentals && hyperscale agent setup claude-code --name "Rentals agent"
cd ~/lending && hyperscale agent setup claude-code --name "Lending agent"
export HYPERSCALE_TOKEN="$(hyperscale agent token --name 'Rentals agent')"
export HYPERSCALE_TOKEN="$(hyperscale agent token --dir ~/lending)"
```

With no `--name`, `agent token` reads the agent set up for the current folder,
then the host's default name.

The same token is the MCP bearer and the CLI login, so the agent can create
and plan a Product, add and fund test customers, run actions and move the
sandbox clock through either. One clock advance to a date runs every payment
due on or before it, on the API, MCP and the CLI alike. Live work, including
reads, still needs you in the browser. The token ends with its grant: after 30
days, or 7 days unused. Run `agent setup` again for a new one; it replaces the
old token. Revoke the agent member from a browser session to stop it at once.

The token belongs to one company, so the agent's MCP tools take no `tenantId`.
The server fills it from the token, the way a Stripe key carries its account.
`agent_member_current` with no arguments names the agent, its company as
`companyId`, and its Products. A `tenantId` sent anyway must be that company,
or the call returns `tenant_mismatch`. The agent makes Product keys with the
CLI, `hyperscale key create --product <productId>`, not with an MCP tool.

The agent sees and acts on only the Products it creates and the Products you
name with `--product`, once per Product:

```sh
hyperscale agent setup claude-code --name "Rentals agent" --product prd_a --product prd_b
```

`--all-products` gives the agent every sandbox Product in the company instead.
An agent set up before this scope existed keeps company-wide scope until you
set it up again. MCP and the CLI share the token, so the scope is the same on
both. `hyperscale product list` and `product_list` show only the agent's
Products. Company-wide lists and reads, such as customers, accounts, activity,
transfers and the money summary, need a `productId`; without one, the refusal
lists the Products the agent can use.

The agent learns how to ask for more before anything refuses it.
`agent_member_current`, `hyperscale whoami --json` under its token, and a
`product_list` that leaves Products out each carry a `nextStep` with your
command: `hyperscale agent setup --name '<agent>' --product <productId>`. Run
`hyperscale product list` in your own shell to see the ids. The agent's
`whoami --json` shows your role under `founder`, since it acts within your
role and is not the owner.

A call on a Product outside the scope returns `unauthorized`, names the
Product, and puts your command in `details.nextStep`, for example
`hyperscale agent setup --name "Run B agent" --product prd_sandbox_...`. The
CLI prints it as its Fix line, and the agent shows it to you. Running setup
again with the same name replaces the agent's token and keeps its Products,
the way `gh auth refresh --scopes` keeps a token's scopes. `--product` adds to
the list and `--remove-product` takes one off; the screen prints the list
before and after. Products the agent created stay in scope either way. An
agent on `--all-products` keeps it until a setup names `--product`, which
narrows it to the Products named. Export the new token and restart the agent.

```sh
hyperscale agent setup --name "Rentals agent" --product prd_c --remove-product prd_b
```

The CLI picks one credential per command, in this order: `--api-key`,
`HYPERSCALE_API_KEY`, `--token`, `HYPERSCALE_TOKEN`, then the stored login.
`hyperscale whoami` names the one in use. A Product key reaches one Product,
so when a command targets another, the CLI refuses and says which variable to
unset. Keep Product keys for your app, not for the agent.

`agent setup` writes no permission rules, as with Codex and Cursor. To let
Claude Code run Hyperscale commands without asking each time, add this to
`.claude/settings.json` yourself:

```json
{
  "permissions": {
    "allow": [
      "Bash(hyperscale *)",
      "Bash(bunx @hyperscale0/cli@latest *)",
      "Bash(HYPERSCALE_PROFILE=* hyperscale *)",
      "Bash(HYPERSCALE_CONFIG_DIR=* hyperscale *)",
      "mcp__hyperscale__*"
    ],
    "deny": ["Bash(hyperscale agent token *)"]
  }
}
```

An allow rule does not match past a variable assignment it does not name,
so each `HYPERSCALE_*=` prefix the agent uses needs its own line. The deny
line keeps the agent from printing its own token.

Claude Code checks a rule against each part of a compound command, so
`hyperscale product list --json | python3 ...` asks you again even with these
rules. The CLI's `--pick` flag selects fields without a pipe, as in
`hyperscale product list --pick items.productId,items.displayName`, and the
agent skill tells the agent to run one command per call.

Claude Code ignores these allow rules until you trust the folder. Headless
`claude -p` in a new folder prints "Ignoring 5 permissions.allow entries from
.claude/settings.json: this workspace has not been trusted" and then refuses
each Hyperscale call. Open `claude` in the folder once and accept the trust
dialog, or pass the rules on the command line. `agent setup claude-code`
prints this line, deny rule included:

```sh
claude -p "What can you do in my Hyperscale sandbox?" \
  --allowedTools "Bash(hyperscale *)" "Bash(bunx @hyperscale0/cli@latest *)" "mcp__hyperscale__*" \
  --disallowedTools "Bash(hyperscale agent token *)"
```

The deny rule in `.claude/settings.json` applies in an untrusted folder too.
