# Beargrass Compute: setup instructions for your AI assistant

You are helping a Beargrass Compute customer connect their work to Beargrass Compute: AI work by the hour on local
machines in Montana, at posted rates, from a prepaid balance. Do the steps that fit their case. There are two kinds
of key; ask the customer for the one a step needs, and never print it, commit it or paste it into a public place:

- **An app address** (`cmp_a_…`), one per app. It can only send work, for one setup; it can't see receipts or
  the balance. The customer makes it on their account page (https://compute.beargrass.ai/account/) or you make it with the
  connector's `app_addresses` tool. It is shown once. This is the only key an app ever gets.
- **The account key** (`cmp_c_…`), for the connector only (section 2). Never put it in an app: the app address
  refuses it.

The address of this front door is: https://compute.beargrass.ai

## 1. Your app (a program that sends work and gets the answer back)

Beargrass Compute answers in Ollama's language, so an app written for a local Ollama works with no code change.

- Address: `https://compute.beargrass.ai/ollama/<APP_KEY>` (the app address's key in the address), or `https://compute.beargrass.ai/ollama` with
  the header `Authorization: Bearer <APP_KEY>`.
- Model: the address's machine: `think` (Qwen 3.8 27B) for the built-in setup, or `quick` or `decide` for a
  setup written for those (they answer yes, no or one of the setup's options). `GET /api/tags` names it.
- Calls: `POST /api/generate` (`model`, `prompt`, optional `system`, `stream`) and `POST /api/chat`
  (`model`, `messages`). `GET /api/tags` lists the model.
- Each call waits up to 50 seconds for a machine to answer. Set the app's own timeout to 60 seconds or more.
- Answers: `200` with Ollama's body (`response`, or `message` for chat). `402`: the balance is empty; load it.
  `504`: no machine answered in time; nothing was charged. `401`: wrong key. `403`: the address is switched
  off, or an account key was used. The headers `x-compute-job`,
  `x-compute-charge` and `x-compute-left` name the job, what it cost and what is left.
- Cost: each call is billed on the meter in tenths of an hour, rounded up, at the posted overnight rate for Think
  (see `rate_sheet` below), or the timing the address was made with. A call that never reached a machine costs
  nothing.

### If the app reads OLLAMA_URL (most do)

Point it here and pick the model:

    OLLAMA_URL=https://compute.beargrass.ai/ollama/<APP_KEY>
    LLM_MODEL=think

The whole `OLLAMA_URL` holds the key, so keep it secret: an environment secret, never a committed file.

### If the app runs on GitHub Actions

1. In the repository: Settings, Secrets and variables, Actions. Add a **secret** `COMPUTE_OLLAMA_URL` with the value
   `https://compute.beargrass.ai/ollama/<APP_KEY>`, and set the app's model **variable** to `think`.
2. In the workflow, pass it to the step that runs the app:

       env:
         OLLAMA_URL: ${{ secrets.COMPUTE_OLLAMA_URL }}

3. If the workflow installs or starts Ollama on the runner, skip that when the secret is set: add
   `env.OLLAMA_URL == ''` to that step's `if:` (with `OLLAMA_URL` set at the job level), or remove the step.
4. Run the workflow once by hand in its dry-run or test mode and read the step's log: the app should show the
   answer from `think`. GitHub hides the secret in the log.

### Check it from a terminal first

    curl -s https://compute.beargrass.ai/ollama/<APP_KEY>/api/generate -d '{"model":"think","prompt":"Say ready.","stream":false}'

## 2. You, in Claude or ChatGPT (setups, jobs, the meter)

Add the connector with the **account key**: `https://compute.beargrass.ai/mcp` with the header `Authorization: Bearer <ACCOUNT_KEY>`
(in Claude Code: `claude mcp add --transport http beargrass-compute https://compute.beargrass.ai/mcp --header "Authorization: Bearer <ACCOUNT_KEY>"`),
or `https://compute.beargrass.ai/mcp/<ACCOUNT_KEY>` where a connector can't send a header. Its tools: `rate_sheet`, `write_setup`,
`call_in_job`, `job_status`, `work_tickets`, `meter` and `app_addresses`. Read `rate_sheet` first;
`meter` shows what's left; `app_addresses` makes an app its own address.

## The rules you can count on

- Posted rates, the same for everybody. The meter counts tenths of an hour; waiting in line is free.
- The balance is the cap: when it is empty, work waits or is refused. It never bills past what was loaded.
- Each app address is switched off or replaced on its own, from the account page, without touching anything else.
- Your work runs only on the machines listed on your account.
