feat: add custom base URL support for Anthropic-compatible endpoints (#246)

Support ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN in .env to route
SDK requests through proxies or gateways. Preflight now validates the
custom endpoint is reachable instead of skipping credential checks.
This commit is contained in:
ezl-keygraph
2026-03-18 00:53:44 +05:30
committed by GitHub
parent 629c52ed3b
commit ae4bd45a30
4 changed files with 73 additions and 9 deletions
+12 -4
View File
@@ -13,7 +13,14 @@ ANTHROPIC_API_KEY=your-api-key-here
# CLAUDE_CODE_OAUTH_TOKEN=your-oauth-token-here
# =============================================================================
# OPTION 2: Router Mode (use alternative providers)
# OPTION 2: Custom Base URL (compatible proxies, gateways, etc.)
# =============================================================================
# Point the SDK at an alternative Anthropic-compatible endpoint.
# ANTHROPIC_BASE_URL=https://your-proxy.example.com
# ANTHROPIC_AUTH_TOKEN=your-auth-token # Auth token for the custom endpoint
# =============================================================================
# OPTION 3: Router Mode (use alternative providers)
# =============================================================================
# Enable router mode by running: ./shannon start ... ROUTER=true
# Then configure ONE of the providers below:
@@ -27,15 +34,16 @@ ANTHROPIC_API_KEY=your-api-key-here
# ROUTER_DEFAULT=openrouter,google/gemini-3-flash-preview
# =============================================================================
# Model Tier Overrides (Anthropic API / OAuth / Bedrock)
# Model Tier Overrides (Anthropic API / OAuth / Custom Base URL / Bedrock)
# =============================================================================
# Override which model is used for each tier. Defaults are used if not set.
# Optional for direct Anthropic and custom base URL modes. Required for Bedrock/Vertex.
# ANTHROPIC_SMALL_MODEL=... # Small tier (default: claude-haiku-4-5-20251001)
# ANTHROPIC_MEDIUM_MODEL=... # Medium tier (default: claude-sonnet-4-6)
# ANTHROPIC_LARGE_MODEL=... # Large tier (default: claude-opus-4-6)
# =============================================================================
# OPTION 3: AWS Bedrock
# OPTION 4: AWS Bedrock
# =============================================================================
# https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/
# Requires the model tier overrides above to be set with Bedrock-specific model IDs.
@@ -49,7 +57,7 @@ ANTHROPIC_API_KEY=your-api-key-here
# AWS_BEARER_TOKEN_BEDROCK=your-bearer-token
# =============================================================================
# OPTION 4: Google Vertex AI
# OPTION 5: Google Vertex AI
# =============================================================================
# https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-partner-models
# Requires a GCP service account with roles/aiplatform.user.
+28
View File
@@ -126,6 +126,7 @@ Shannon Pro supports a self-hosted runner model (similar to GitHub Actions self-
- [Configuration (Optional)](#configuration-optional)
- [AWS Bedrock](#aws-bedrock)
- [Google Vertex AI](#google-vertex-ai)
- [Custom Base URL](#custom-base-url)
- [[EXPERIMENTAL - UNSUPPORTED] Router Mode (Alternative Providers)](#experimental---unsupported-router-mode-alternative-providers)
- [Output and Results](#output-and-results)
- [Sample Reports](#-sample-reports)
@@ -454,6 +455,33 @@ ANTHROPIC_LARGE_MODEL=claude-opus-4-6
Set `CLOUD_ML_REGION=global` for global endpoints, or a specific region like `us-east5`. Some models may not be available on global endpoints — see the [Vertex AI Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) for region availability.
### Custom Base URL
Shannon supports pointing the SDK at any Anthropic-compatible endpoint (proxies, gateways, etc.) via `ANTHROPIC_BASE_URL`.
#### Quick Setup
1. Add your endpoint and auth token to `.env`:
```bash
ANTHROPIC_BASE_URL=https://your-proxy.example.com
ANTHROPIC_AUTH_TOKEN=your-auth-token
```
2. Optionally override model tiers (defaults are used if not set):
```bash
ANTHROPIC_SMALL_MODEL=claude-haiku-4-5-20251001
ANTHROPIC_MEDIUM_MODEL=claude-sonnet-4-6
ANTHROPIC_LARGE_MODEL=claude-opus-4-6
```
3. Run Shannon as usual:
```bash
./shannon start URL=https://example.com REPO=repo-name
```
### [EXPERIMENTAL - UNSUPPORTED] Router Mode (Alternative Providers)
Shannon can experimentally route requests through alternative AI providers using claude-code-router. This mode is not officially supported and is intended primarily for:
+5 -2
View File
@@ -142,9 +142,12 @@ cmd_start() {
exit 1
fi
# Check for API key (Bedrock and router modes can bypass this)
# Check for API key (Bedrock, Vertex, router, and custom base URL modes can bypass this)
if [ -z "$ANTHROPIC_API_KEY" ] && [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then
if [ "$CLAUDE_CODE_USE_BEDROCK" = "1" ]; then
if [ -n "$ANTHROPIC_BASE_URL" ] && [ -n "$ANTHROPIC_AUTH_TOKEN" ]; then
# Custom base URL mode — use auth token as API key for SDK initialization
echo "Using custom base URL: $ANTHROPIC_BASE_URL"
elif [ "$CLAUDE_CODE_USE_BEDROCK" = "1" ]; then
# Bedrock mode — validate required AWS credentials
MISSING=""
[ -z "$AWS_REGION" ] && MISSING="$MISSING AWS_REGION"
+28 -3
View File
@@ -160,10 +160,35 @@ function classifySdkError(
async function validateCredentials(
logger: ActivityLogger
): Promise<Result<void, PentestError>> {
// 1. Router mode — can't validate provider keys, just warn
// 1. Custom base URL — validate endpoint is reachable via SDK query
if (process.env.ANTHROPIC_BASE_URL) {
logger.warn('Router mode detected — skipping API credential validation');
return ok(undefined);
const baseUrl = process.env.ANTHROPIC_BASE_URL;
logger.info(`Validating custom base URL: ${baseUrl}`);
try {
for await (const message of query({ prompt: 'hi', options: { model: resolveModel('small'), maxTurns: 1 } })) {
if (message.type === 'assistant' && message.error) {
return classifySdkError(message.error, `custom endpoint (${baseUrl})`);
}
if (message.type === 'result') {
break;
}
}
logger.info('Custom base URL OK');
return ok(undefined);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
return err(
new PentestError(
`Custom base URL unreachable: ${baseUrl}${message}`,
'network',
false,
{ baseUrl },
ErrorCode.AUTH_FAILED
)
);
}
}
// 2. Bedrock mode — validate required AWS credentials are present