feat: support custom baseURL via opencode.json and ANTHROPIC_BASE_URL…#229
feat: support custom baseURL via opencode.json and ANTHROPIC_BASE_URL…#229anxjok wants to merge 1 commit into
Conversation
… env var - Add support for configuring custom base URL in opencode.json via provider.anthropic.options.baseURL - Add fallback to ANTHROPIC_BASE_URL environment variable - Maintain backward compatibility with default Anthropic API endpoint - Priority: config > env var > default This enables routing Anthropic API requests through proxies, API gateways, and custom endpoints while maintaining OAuth authentication through Claude Code credentials. Features: - Custom headers from provider.anthropic.options.headers are automatically forwarded - Useful for authentication headers (e.g., X-Gateway-Key) - Verified to work with proxies and load balancers Closes: Support for proxy/gateway setups requested by users
Greptile SummaryThis PR adds support for routing Anthropic API requests through a custom base URL, configurable via
Confidence Score: 3/5Safe to merge for the baseURL routing itself, but ships with a documented feature (custom header forwarding) that has no implementation and a README table that misstates the priority order. The baseURL resolution logic is correct and backward-compatible. However, the README's env-var table says the env var overrides the config file when the opposite is true, and the custom headers feature advertised in both the README and the PR description is entirely absent from the code — users who configure Files Needing Attention: src/index.ts (missing headers forwarding implementation) and README.md (inverted priority description in the env-var table)
|
| Filename | Overview |
|---|---|
| src/index.ts | Adds effectiveBaseURL resolution (config > env var > default) and returns it in the auth config object. However, provider.options?.headers — which is documented as being forwarded — is never read or applied. |
| README.md | Documents the new feature correctly in the priority-list section but contradicts it in the env-var table, which says ANTHROPIC_BASE_URL "Takes precedence over config file" — the opposite of the actual behaviour. |
| src/index.test.ts | Adds 5 tests covering default baseURL, config baseURL, env-var baseURL, priority order, and no-double-/v1. Tests verify the baseURL property on the returned config object; no test covers the missing headers forwarding. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[auth loader called] --> B{provider.options?.baseURL set?}
B -- yes --> C[use config baseURL]
B -- no --> D{ANTHROPIC_BASE_URL env var set?}
D -- yes --> E[use env var baseURL]
D -- no --> F[use default: https://api.anthropic.com/v1]
C --> G[return auth config with baseURL]
E --> G
F --> G
G --> H[framework builds request URL from baseURL]
H --> I[fetch called with constructed URL]
I --> J[buildRequestUrl — add ?beta=true if path == /v1/messages]
J --> K[buildRequestHeaders — adds auth, beta, stainless headers]
K --> L[fetchWithRetry]
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
README.md:215
**README env-var table priority is inverted**
The table entry for `ANTHROPIC_BASE_URL` says "Takes precedence over config file," but the code and the priority section above it both say the opposite: `provider.anthropic.options.baseURL` wins over the env var. A user reading only the table will believe they can override a config-file URL with the env var, try it, and find it silently doesn't work.
### Issue 2 of 3
README.md:217
The description incorrectly says the env var takes precedence over the config file. The actual priority (reflected both in the code and the priority list above the table) is config file > env var > default.
```suggestion
| `ANTHROPIC_BASE_URL` | Custom base URL for Anthropic API requests (e.g., proxy or custom endpoint). Overridden by `provider.anthropic.options.baseURL` in `opencode.json` when both are set. | `https://api.anthropic.com/v1` |
```
### Issue 3 of 3
src/index.ts:321-328
**Custom headers from `provider.options.headers` are documented but not forwarded**
The README and PR description prominently state that `provider.anthropic.options.headers` entries are "automatically forwarded to all API requests" (useful for `X-Gateway-Key` etc.). However, only `provider.options?.baseURL` is consumed here — `provider.options?.headers` is never read. `buildRequestHeaders` takes its input only from the `init` argument supplied by the framework, not from provider config headers. Any user who configures headers in `opencode.json` expecting them to reach the proxy will receive a silent failure.
Reviews (1): Last reviewed commit: "feat: support custom baseURL via opencod..." | Re-trigger Greptile
| @@ -182,6 +214,7 @@ All configurable parameters can be overridden via environment variables. If Anth | |||
|
|
|||
| | Variable | Description | Default | | |||
There was a problem hiding this comment.
README env-var table priority is inverted
The table entry for ANTHROPIC_BASE_URL says "Takes precedence over config file," but the code and the priority section above it both say the opposite: provider.anthropic.options.baseURL wins over the env var. A user reading only the table will believe they can override a config-file URL with the env var, try it, and find it silently doesn't work.
Prompt To Fix With AI
This is a comment left during a code review.
Path: README.md
Line: 215
Comment:
**README env-var table priority is inverted**
The table entry for `ANTHROPIC_BASE_URL` says "Takes precedence over config file," but the code and the priority section above it both say the opposite: `provider.anthropic.options.baseURL` wins over the env var. A user reading only the table will believe they can override a config-file URL with the env var, try it, and find it silently doesn't work.
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| | Variable | Description | Default | | ||
| | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | ||
| | `ANTHROPIC_BASE_URL` | Custom base URL for Anthropic API requests (e.g., proxy or custom endpoint). Takes precedence over config file. | `https://api.anthropic.com/v1` | |
There was a problem hiding this comment.
The description incorrectly says the env var takes precedence over the config file. The actual priority (reflected both in the code and the priority list above the table) is config file > env var > default.
| | `ANTHROPIC_BASE_URL` | Custom base URL for Anthropic API requests (e.g., proxy or custom endpoint). Takes precedence over config file. | `https://api.anthropic.com/v1` | | |
| | `ANTHROPIC_BASE_URL` | Custom base URL for Anthropic API requests (e.g., proxy or custom endpoint). Overridden by `provider.anthropic.options.baseURL` in `opencode.json` when both are set. | `https://api.anthropic.com/v1` | |
Prompt To Fix With AI
This is a comment left during a code review.
Path: README.md
Line: 217
Comment:
The description incorrectly says the env var takes precedence over the config file. The actual priority (reflected both in the code and the priority list above the table) is config file > env var > default.
```suggestion
| `ANTHROPIC_BASE_URL` | Custom base URL for Anthropic API requests (e.g., proxy or custom endpoint). Overridden by `provider.anthropic.options.baseURL` in `opencode.json` when both are set. | `https://api.anthropic.com/v1` |
```
How can I resolve this? If you propose a fix, please make it concise.| const effectiveBaseURL = | ||
| provider.options?.baseURL || | ||
| process.env.ANTHROPIC_BASE_URL || | ||
| "https://api.anthropic.com/v1" | ||
|
|
||
| return { | ||
| apiKey: "", | ||
| baseURL: "https://api.anthropic.com/v1", | ||
| baseURL: effectiveBaseURL, |
There was a problem hiding this comment.
Custom headers from
provider.options.headers are documented but not forwarded
The README and PR description prominently state that provider.anthropic.options.headers entries are "automatically forwarded to all API requests" (useful for X-Gateway-Key etc.). However, only provider.options?.baseURL is consumed here — provider.options?.headers is never read. buildRequestHeaders takes its input only from the init argument supplied by the framework, not from provider config headers. Any user who configures headers in opencode.json expecting them to reach the proxy will receive a silent failure.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/index.ts
Line: 321-328
Comment:
**Custom headers from `provider.options.headers` are documented but not forwarded**
The README and PR description prominently state that `provider.anthropic.options.headers` entries are "automatically forwarded to all API requests" (useful for `X-Gateway-Key` etc.). However, only `provider.options?.baseURL` is consumed here — `provider.options?.headers` is never read. `buildRequestHeaders` takes its input only from the `init` argument supplied by the framework, not from provider config headers. Any user who configures headers in `opencode.json` expecting them to reach the proxy will receive a silent failure.
How can I resolve this? If you propose a fix, please make it concise.
Summary
Add support for configuring a custom Anthropic API base URL via
opencode.jsonor theANTHROPIC_BASE_URLenvironment variable. This enables routing Anthropic API requests through proxies, API gateways, and custom endpoints while maintaining OAuth authentication through Claude Code credentials.Key features:
opencode.jsonviaprovider.anthropic.options.baseURLANTHROPIC_BASE_URLenvironment variableprovider.anthropic.options.headersare automatically forwarded (useful for authentication headers likeX-Gateway-Key)Related issue
Closes #160 (FR: Anthropic API mode for e.g. CLIProxyAPI)
Testing
X-Gateway-Key) forwarded correctlyTest coverage includes:
provider.anthropic.options.baseURLfrom opencode.json when providedANTHROPIC_BASE_URLenvironment variable when set (no config)/v1path segment (correct URL merging)Checklist
feat:)make allpasses locally (runs lint, build, and test)src/index.test.ts)ANTHROPIC_BASE_URLenv var documentation)