# Claude CLI
Source: https://docs.tensormachine.ai/integrations/claude-cli

Claude Code — the `claude` CLI — can send its requests to any endpoint that speaks the
**Anthropic Messages API**. Our `/anthropic` endpoint does, so pointing it at your workspace
takes two environment variables and no code changes.

Once set, `claude` stops using your Anthropic subscription and bills against your Tensor
Machine workspace instead, under your model allow-list, spend limits and audit trail.

## 1. Set the two variables

```bash
export ANTHROPIC_BASE_URL="https://edge.tensormachine.ai/<org>/anthropic"
export ANTHROPIC_AUTH_TOKEN="sk-tm-..."
```

Replace `<org>` with your workspace slug (the exact URL is on the *API Keys* page) and use a
`sk-tm-…` key from that same page.

Two details that decide whether this works:

- **No `/v1` on the base URL.** Claude Code appends `/v1/messages` itself. Ending the base
  URL at `/anthropic` is correct; adding the version yourself produces `/anthropic/v1/v1/messages`
  and a 404.
- **`ANTHROPIC_AUTH_TOKEN`, not `ANTHROPIC_API_KEY`.** They send the credential in different
  headers — `ANTHROPIC_AUTH_TOKEN` as `Authorization: Bearer`, `ANTHROPIC_API_KEY` as
  `x-api-key`. Our endpoint accepts **both**, so either authenticates, but
  `ANTHROPIC_AUTH_TOKEN` takes effect immediately, while `ANTHROPIC_API_KEY` prompts you once
  in interactive mode to approve it over a saved login. Prefer the auth token.

## 2. Make it stick

Environment variables last only as long as the shell. To set them permanently, use Claude
Code's user settings file:

```json title="~/.claude/settings.json"
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://edge.tensormachine.ai/<org>/anthropic",
    "ANTHROPIC_AUTH_TOKEN": "sk-tm-..."
  }
}
```

<Callout type="warn">
Put the credential in `~/.claude/settings.json` (your home directory), **not** in a project's
`.claude/settings.json`. The project file is committed to git — a key placed there ships to
everyone who clones the repository, and needs rotating immediately if it does.
</Callout>

## 3. Choose a model

Behind a custom base URL, Claude Code passes the model name through without checking it —
so pass a `tm/…` alias from *My Team → Model access*:

```bash
export ANTHROPIC_MODEL="tm/qwen3-5-9b"
```

Or set `"model": "tm/..."` at the top level of `settings.json`. Claude Code also runs a
smaller model for background work like titling conversations; point that at an allowed model
too, or those calls will request a model your workspace doesn't serve:

```bash
export ANTHROPIC_DEFAULT_HAIKU_MODEL="tm/qwen3-5-9b"
```

Model names you'd normally use with `claude` — `sonnet`, `opus`, `haiku` — are Anthropic's
own and are not served here. Use your workspace's aliases.

## 4. Verify

Start `claude` from the same shell and run `/status`. Under **Status** you should see an
**Anthropic base URL** line showing your Tensor Machine endpoint — that line only appears
when a gateway address is set. If instead you see a **Login method** line naming a claude.ai
account, the variables didn't take effect and requests are still going to Anthropic.

You can also check the endpoint directly, without involving the CLI:

```bash
curl "$ANTHROPIC_BASE_URL/v1/messages" \
  -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"tm/qwen3-5-9b","max_tokens":16,"messages":[{"role":"user","content":"hi"}]}'
```

A response starting with `{"id":"msg_` means the endpoint, the key and the model alias are
all good, and anything still broken is in the CLI's configuration.

Finally, confirm the request appears under *Usage* in the console — that's the proof it ran
on your workspace rather than somewhere else.

## Things worth knowing

- **A saved Claude login stays saved.** While the variables are set they take precedence;
  unset them and `claude` goes back to your normal account. Claude Code may warn at startup
  that both exist — that warning is expected here.
- **Setting only the base URL is not enough.** Without a credential variable, a saved
  claude.ai login remains the active credential and your requests won't reach us. Set both.
- **Some features need Anthropic's own service** and won't work against any third-party
  endpoint. If one is unavailable while you're pointed here, that's why.
- **`max_tokens` is required** by the Messages API. The CLI sets it for you; it only matters
  if you're testing with raw `curl`.

## Troubleshooting

| What you see | Usual cause |
| --- | --- |
| `401` | Credential in the wrong variable or an inactive key — confirm the key is active in the console |
| `402` / payment required | Workspace balance is ₹0, or a spend limit is exhausted |
| `403` naming the model | Model isn't in your team's allow-list — *My Team → Model access* |
| `404` | `/v1` left on the end of `ANTHROPIC_BASE_URL` |
| Still using your Anthropic account | Variables not visible to the process — check `/status`, and prefer `~/.claude/settings.json` over a project file |
| Model-not-found errors | Still requesting `sonnet`/`opus`/`haiku` — set `ANTHROPIC_MODEL` to a `tm/…` alias |

## What we've verified

That our `/anthropic` endpoint accepts the `Authorization: Bearer` scheme Claude Code sends —
not only the `x-api-key` header the Anthropic SDK uses — is covered by a test in our router,
so this page's central claim is guarded against regression. The variable names and precedence
rules above follow Anthropic's own documentation for connecting Claude Code to a gateway.

How well any given model performs as a coding agent is a separate question from whether the
connection works; see [Models](/models).
