# Providers

HooCode supports subscription-based providers via OAuth and API key providers via environment variables or auth file. For each provider, hoocode knows all available models. The list is updated with every hoocode release.

## Table of Contents

- [Subscriptions](#subscriptions)
- [API Keys](#api-keys)
- [Auth File](#auth-file)
- [Cloud Providers](#cloud-providers)
- [Custom Providers](#custom-providers)
- [Corporate proxies / custom CA](#corporate-proxies--custom-ca)
- [Resolution Order](#resolution-order)

## Subscriptions

Use `/login` in interactive mode, then select a provider:

- ChatGPT Plus/Pro (Codex)
- Claude Pro/Max
- GitHub Copilot
- Google Antigravity
- Google Cloud Code Assist (Gemini CLI) — paid Code Assist tiers only, see below

Use `/logout` to clear credentials. Tokens are stored in `~/.hoocode/auth.json` and auto-refresh when expired.

### OpenAI Codex

- Requires ChatGPT Plus or Pro subscription
- Officially endorsed by OpenAI: [Codex for OSS](https://developers.openai.com/community/codex-for-oss)

### Claude Pro/Max

Anthropic subscription auth is active for Claude Pro/Max accounts. Third-party harness usage draws from [extra usage](https://claude.ai/settings/usage) and is billed per token, not against Claude plan limits.

### GitHub Copilot

- Press Enter for github.com, or enter your GitHub Enterprise Server domain
- If you get "model not supported", enable it in VS Code: Copilot Chat → model selector → select model → "Enable"

### Google Antigravity

> **You must supply the OAuth client.** hoocode ships no Google credentials, so
> before `/login` set both:
>
> ```bash
> export HOOCODE_ANTIGRAVITY_CLIENT_ID="...apps.googleusercontent.com"
> export HOOCODE_ANTIGRAVITY_CLIENT_SECRET="..."
> ```
>
> Unlike the Anthropic and OpenAI logins, this cannot run as a public PKCE
> client: Google's token endpoint rejects the exchange with `client_secret is
> missing`. Which client signs in also decides which tiers Google serves, so a
> client you register yourself in Cloud Console reaches the public Gemini API
> but not Antigravity's tiers — those answer a foreign client with `403`. The
> working pair is the one the Antigravity editor uses.

The way to code on a personal Google account, free tier included. The model ids are Antigravity's own, verified against `v1internal:fetchAvailableModels`, and they are not the public Gemini API ids:

| hoocode model | Antigravity calls it |
| --- | --- |
| `gemini-3.8-flash-tiered` | Gemini 3.8 Flash (default after login) |
| `gemini-3.7-flash-tiered` | Gemini 3.7 Flash |
| `gemini-3.6-flash-tiered` | Gemini 3.6 Flash |
| `gemini-pro-agent` | Gemini 3.1 Pro (High) |
| `gemini-3.1-pro-low` | Gemini 3.1 Pro (Low) |
| `gemini-3.1-flash-lite` | Gemini 3.1 Flash Lite |
| `claude-opus-4-6-thinking` | Claude Opus 4.6 (Thinking) |
| `claude-sonnet-4-6` | Claude Sonnet 4.6 (Thinking) |
| `gpt-oss-120b-medium` | GPT-OSS 120B (Medium) |

- The login completes on `http://localhost:51121/oauth-callback`, then discovers or provisions the Cloud project the requests are billed to (Google's managed consumer project for a free-tier account).
- Requests go to the sandbox host (`daily-cloudcode-pa.sandbox.googleapis.com`); the production Code Assist host answers a consumer account with `429 RESOURCE_EXHAUSTED`, and hoocode falls through the hosts in order.
- Claude and GPT-OSS are not served to Enterprise plans; Gemini is served to every plan including the free one.
- Google rotates this catalog often. An id your account is not served fails with `404 Requested entity was not found` — pick another with `alt+m`.
- Usage draws on Antigravity credits; the per-token costs hoocode shows are list prices for comparison, not what the account is charged.
- A 429 naming a reset delay means that model's quota is spent — switch models with `alt+m` or wait it out.
- `HOOCODE_ANTIGRAVITY_VERSION` overrides the client version hoocode reports if Google starts rejecting the default.

### Google Cloud Code Assist (Gemini CLI)

The Gemini CLI's OAuth client against Cloud Code Assist: `gemini-3.8-flash`, `gemini-3.7-flash`, `gemini-3.1-pro-preview`, `gemini-3.1-flash-lite-preview`, `gemini-3-pro-preview`, `gemini-3-flash-preview`, `gemini-2.5-pro`, `gemini-2.5-flash`.

- **You must supply the OAuth client**, as with Antigravity above: set `HOOCODE_GEMINI_CLI_CLIENT_ID` and `HOOCODE_GEMINI_CLI_CLIENT_SECRET` before `/login`.
- **Individual accounts are no longer eligible.** `loadCodeAssist` now answers this client with `UNSUPPORTED_CLIENT` for the free tier: "This client is no longer supported for Gemini Code Assist for individuals. To continue using Gemini, please migrate to the Antigravity suite of products." Use Antigravity above for a personal Google account.
- What remains is the paid **Gemini Code Assist Standard/Enterprise** tier, which requires your own Cloud project: set `GOOGLE_CLOUD_PROJECT` (or `GOOGLE_CLOUD_PROJECT_ID`) before `/login`.
- The login opens a browser and completes on `http://localhost:8085/oauth2callback`; paste the redirect URL instead if the browser is on another machine.
- Quota is the account's, not per-token billing, so these models report zero cost.

## API Keys

### Environment Variables or Auth File

Use `/login` in interactive mode and select a provider to store an API key in `auth.json`, or set credentials via environment variable:

```bash
export ANTHROPIC_API_KEY=sk-ant-...
hoocode
```

### Auth File

Store credentials in `~/.hoocode/auth.json`:

```json
{
  "anthropic": { "type": "api_key", "key": "sk-ant-..." },
  "openai": { "type": "api_key", "key": "sk-..." },
  "deepseek": { "type": "api_key", "key": "sk-..." },
  "google": { "type": "api_key", "key": "..." },
  "opencode": { "type": "api_key", "key": "..." },
  "opencode-go": { "type": "api_key", "key": "..." },
  "together": { "type": "api_key", "key": "..." },
  "xiaomi": { "type": "api_key", "key": "..." },
  "xiaomi-token-plan-cn":  { "type": "api_key", "key": "..." },
  "xiaomi-token-plan-ams": { "type": "api_key", "key": "..." },
  "xiaomi-token-plan-sgp": { "type": "api_key", "key": "..." },
  "nvidia": { "type": "api_key", "key": "..." }
}
```

The file is created with `0600` permissions (user read/write only). Auth file credentials take priority over environment variables.

### Key Resolution

The `key` field supports three formats:

- **Shell command:** `"!command"` executes and uses stdout (cached for process lifetime)
  ```json
  { "type": "api_key", "key": "!security find-generic-password -ws 'anthropic'" }
  { "type": "api_key", "key": "!op read 'op://vault/item/credential'" }
  ```
- **Environment variable:** Uses the value of the named variable
  ```json
  { "type": "api_key", "key": "MY_ANTHROPIC_KEY" }
  ```
- **Literal value:** Used directly
  ```json
  { "type": "api_key", "key": "sk-ant-..." }
  ```

OAuth credentials are also stored here after `/login` and managed automatically.

## Cloud Providers

### Azure OpenAI

```bash
export AZURE_OPENAI_API_KEY=...
export AZURE_OPENAI_BASE_URL=https://your-resource.openai.azure.com
# also supported: https://your-resource.cognitiveservices.azure.com
# root endpoints are auto-normalized to /openai/v1
# or use resource name instead of base URL
export AZURE_OPENAI_RESOURCE_NAME=your-resource

# Optional
export AZURE_OPENAI_API_VERSION=2024-02-01
export AZURE_OPENAI_DEPLOYMENT_NAME_MAP=gpt-4=my-gpt4,gpt-4o=my-gpt4o
```

### Amazon Bedrock

```bash
# Option 1: AWS Profile
export AWS_PROFILE=your-profile

# Option 2: IAM Keys
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...

# Option 3: Bearer Token
export AWS_BEARER_TOKEN_BEDROCK=...

# Optional region (defaults to us-east-1)
export AWS_REGION=us-west-2
```

Also supports ECS task roles (`AWS_CONTAINER_CREDENTIALS_*`) and IRSA (`AWS_WEB_IDENTITY_TOKEN_FILE`).

```bash
hoocode --provider amazon-bedrock --model us.anthropic.claude-sonnet-4-20250514-v1:0
```

Prompt caching is enabled automatically for Claude models whose ID contains a recognizable model name (base models and system-defined inference profiles). For application inference profiles (whose ARNs don't contain the model name), set `AWS_BEDROCK_FORCE_CACHE=1` to enable cache points:

```bash
export AWS_BEDROCK_FORCE_CACHE=1
hoocode --provider amazon-bedrock --model arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123
```

If you are connecting to a Bedrock API proxy, the following environment variables can be used:

```bash
# Set the URL for the Bedrock proxy (standard AWS SDK env var)
export AWS_ENDPOINT_URL_BEDROCK_RUNTIME=https://my.corp.proxy/bedrock

# Set if your proxy does not require authentication
export AWS_BEDROCK_SKIP_AUTH=1

# Set if your proxy only supports HTTP/1.1
export AWS_BEDROCK_FORCE_HTTP1=1
```

### Cloudflare AI Gateway

`CLOUDFLARE_API_KEY` can be set via `/login`. The account ID and gateway slug must be set as environment variables.

```bash
export CLOUDFLARE_API_KEY=...           # or use /login
export CLOUDFLARE_ACCOUNT_ID=...
export CLOUDFLARE_GATEWAY_ID=...        # create at dash.cloudflare.com → AI → AI Gateway
hoocode --provider cloudflare-ai-gateway --model "claude-sonnet-4-5"
```

Routes to OpenAI, Anthropic, and Workers AI through Cloudflare AI Gateway. Workers AI uses the Unified API (`/compat`) and prefixed model IDs (`workers-ai/@cf/...`). OpenAI uses the OpenAI passthrough route (`/openai`) with native OpenAI model IDs such as `gpt-5.1`. Anthropic uses the Anthropic passthrough route (`/anthropic`) with native Anthropic model IDs such as `claude-sonnet-4-5`.

AI Gateway authentication uses `CLOUDFLARE_API_KEY` as `cf-aig-authorization`. Upstream authentication can be one of:

| Mode | Request auth | Upstream auth |
|------|--------------|---------------|
| Workers AI | Cloudflare token only | Cloudflare-native |
| Unified billing | Cloudflare token only | Cloudflare handles upstream auth and deducts credits |
| Stored BYOK | Cloudflare token only | Cloudflare injects provider keys stored in the AI Gateway dashboard |
| Inline BYOK | Cloudflare token plus upstream `Authorization` header | The request supplies the upstream provider key |

For normal hoocode usage, prefer unified billing or stored BYOK. Inline BYOK requires configuring an additional upstream `Authorization` header for the Cloudflare AI Gateway provider, for example via a `models.json` provider/model override.

### Cloudflare Workers AI

`CLOUDFLARE_API_KEY` can be set via `/login`. `CLOUDFLARE_ACCOUNT_ID` must be set as an environment variable.

```bash
export CLOUDFLARE_API_KEY=...           # or use /login
export CLOUDFLARE_ACCOUNT_ID=...
hoocode --provider cloudflare-workers-ai --model "@cf/moonshotai/kimi-k2.6"
```

HooCode automatically sets `x-session-affinity` for [prefix caching](https://developers.cloudflare.com/workers-ai/features/prompt-caching/) discounts.

### Google Vertex AI

Uses Application Default Credentials:

```bash
gcloud auth application-default login
export GOOGLE_CLOUD_PROJECT=your-project
export GOOGLE_CLOUD_LOCATION=us-central1
```

Or set `GOOGLE_APPLICATION_CREDENTIALS` to a service account key file.

## Custom Providers

**Via models.json:** Add Ollama, LM Studio, vLLM, or any provider that speaks a supported API (OpenAI Completions, OpenAI Responses, Anthropic Messages, Google Generative AI). See [models.md](models.md).

**Via extensions:** For providers that need custom API implementations or OAuth flows, create an extension. See [custom-provider.md](custom-provider.md) and [examples/extensions/custom-provider-gitlab-duo](../examples/extensions/custom-provider-gitlab-duo/).

## Corporate proxies / custom CA

On networks that run a TLS-intercepting proxy, hoocode's own outbound traffic
(provider API calls, the GitHub API, and on-demand tool downloads) is presented
with certificates signed by the proxy's internal CA, which Node does not trust by
default. Instead of disabling certificate verification (the insecure
`NODE_TLS_REJECT_UNAUTHORIZED=0` workaround), tell hoocode to **additionally**
trust your CA — verification stays on.

**Recommended — trust an explicit CA bundle:**

```bash
# Point at a PEM file containing your proxy's root/intermediate CA(s)
hoocode --ca-cert /path/to/corporate-ca.pem

# Or via environment variable (equivalent precedence shown below)
export HOOCODE_CA_CERT=/path/to/corporate-ca.pem
```

The CA is added on top of Node's bundled root certificates — it extends the
trust set, it does not replace it. The PEM source is resolved from the first of:
`--ca-cert <path>` > `HOOCODE_CA_CERT` > `NODE_EXTRA_CA_CERTS`.

**Opt in to the OS trust store:**

```bash
hoocode --use-system-ca           # or: export HOOCODE_USE_SYSTEM_CA=1
```

This trusts the certificates already installed in your operating system's store
(where IT-managed machines usually place the corporate CA), in addition to the
bundled roots. It is **opt-in only** so the OS store is never trusted implicitly.

Notes:

- **Verification is never disabled.** hoocode does not support a "trust all" or
  trust-on-first-use mode. A missing or unreadable CA file is warned about once
  and skipped, falling back to the bundled defaults rather than trusting
  everything.
- If `NODE_TLS_REJECT_UNAUTHORIZED=0` is set, hoocode warns once on startup —
  prefer `--ca-cert` / `--use-system-ca` instead.
- **The flags above do not cover the `webfetch`/`websearch` tools.** Those run in
  a separate `webtools` binary with its own TLS stack. Configure them separately
  with the environment variables below.

### webfetch / websearch (webtools binary)

The optional `webfetch`/`websearch` tools shell out to the `webtools` binary,
which does its own TLS. Point it at your proxy's CA so those tools work behind
the proxy with verification kept on:

```bash
# Trust an extra CA for webfetch/websearch (forwarded as --ca-cert)
export HOOCODE_WEBTOOLS_CA_CERT=/path/to/corporate-ca.pem
```

`HOOCODE_WEBTOOLS_CA_CERT` must point at a readable PEM file; an unreadable or
missing path is warned about once and ignored (the flag is not forwarded).

As a last resort on networks where a CA cannot be obtained, you can disable the
binary's TLS verification entirely. This is **insecure and strictly opt-in**, and
hoocode warns once per run when it is active — prefer `HOOCODE_WEBTOOLS_CA_CERT`:

```bash
export HOOCODE_WEBTOOLS_INSECURE=1   # disables webtools TLS verification
```

The per-request timeout is configurable too, via `settings.json`
(`"webtools": { "timeoutSecs": N }`) or the environment; it is clamped to
1–120 seconds and forwarded to the binary as `--timeout`:

```bash
export HOOCODE_WEBTOOLS_TIMEOUT=30   # seconds per request (default 15)
```

Note that the binary bounds a whole fetch — including redirects and retries — at
three times this value, so a 30s timeout permits a fetch of up to 90s.

## Resolution Order

When resolving credentials for a provider:

1. CLI `--api-key` flag
2. `auth.json` entry (API key or OAuth token)
3. Environment variable
4. Custom provider keys from `models.json`
