Claude Proxy Configuration Reference
This document is the authoritative reference for every configurable aspect of the NeuroLink Claude proxy. It covers CLI flags, the YAML config file schema, environment variables, auto-configured Claude Code settings, and all file locations.
1. CLI Flags
neurolink proxy start
Start the Claude multi-account proxy server.
| Flag | Alias | Type | Default | Description |
|---|---|---|---|---|
--port | -p | number | 55669 | Port to listen on. |
--host | -H | string | 127.0.0.1 | Host/IP to bind to. Use 0.0.0.0 to listen on all interfaces. |
--strategy | -s | string | round-robin | Account selection strategy. Choices: round-robin, fill-first. |
--health-interval | number | 30 | Health check interval in seconds. | |
--quiet | -q | boolean | false | Suppress non-essential output (banner, status messages). |
--debug | -d | boolean | false | Enable debug output (stack traces on errors, verbose logging). |
--config | -c | string | ~/.neurolink/proxy-config.yaml | Path to proxy config file (YAML or JSON). |
Examples:
# Start with defaults (port 55669, round-robin strategy)
neurolink proxy start
# Custom port and round-robin strategy
neurolink proxy start -p 8080 -s round-robin
# Start with 60-second health checks, debug output
neurolink proxy start --health-interval 60 --debug
# Use a custom config file
neurolink proxy start --config /path/to/my-proxy.yaml
neurolink proxy status
Show the current proxy status.
| Flag | Alias | Type | Default | Description |
|---|---|---|---|---|
--format | string | text | Output format. Choices: text, json. | |
--quiet | -q | boolean | false | Suppress non-essential output. |
Examples:
# Human-readable status
neurolink proxy status
# Machine-readable JSON (for scripts)
neurolink proxy status --format json
JSON output shape (when --format json):
{
"running": true,
"pid": 12345,
"port": 55669,
"host": "127.0.0.1",
"strategy": "round-robin",
"startTime": "2025-03-22T10:00:00.000Z",
"uptime": 3600000,
"url": "http://127.0.0.1:55669",
"fallbackChain": [{ "provider": "google-ai", "model": "gemini-2.5-pro" }]
}
neurolink proxy setup
One-command setup: login + start proxy + configure Claude Code.
| Flag | Alias | Type | Default | Description |
|---|---|---|---|---|
--port | -p | number | 55669 | Proxy port. |
--host | string | 127.0.0.1 | Proxy host/IP to bind to. | |
--method | string | oauth | Authentication method. Choices: oauth, api-key. | |
--no-service | boolean | false | Skip launchd install, just start foreground. |
Examples:
# Full setup with defaults (OAuth login, port 55669, launchd service)
neurolink proxy setup
# Setup on a custom port
neurolink proxy setup -p 9000
# Login + start foreground (no auto-restart service)
neurolink proxy setup --no-service
What proxy setup does:
- Checks for existing authenticated accounts in the TokenStore.
- Falls back to the legacy
~/.neurolink/anthropic-credentials.jsonfile. - If no valid accounts are found, runs the OAuth login flow.
- Installs as macOS launchd service (auto-restart on crash/reboot). Use
--no-servicefor foreground start.
neurolink proxy guard (hidden)
Internal fail-open guard process. Spawned automatically by proxy start as a detached child. Monitors the proxy health endpoint and reverts Claude Code settings if the proxy dies unexpectedly.
| Flag | Type | Default | Description |
|---|---|---|---|
--host | string | 127.0.0.1 | Proxy host to monitor. |
--port | number | 55669 | Proxy port to monitor. |
--parent-pid | number | (required) | PID of the parent proxy process. |
--max-wait-ms | number | 0 | Maximum monitoring duration (0 = indefinite). |
--failure-threshold | number | 5 | Consecutive health check failures before triggering cleanup. |
--poll-interval-ms | number | 1000 | Interval between health checks in milliseconds. |
--quiet | boolean | true | Suppress output (guards are silent by default). |
You should never need to run this command manually.
neurolink proxy install
Install the proxy as a persistent macOS launchd service. The service auto-starts on login and auto-restarts on crash (5-second throttle). Currently macOS-only.
| Flag | Alias | Type | Default | Description |
|---|---|---|---|---|
--port | -p | number | 55669 | Proxy port. |
--host | string | 127.0.0.1 | Proxy host/IP to bind to. |
Examples:
# Install with defaults (port 55669)
neurolink proxy install
# Install on custom port
neurolink proxy install -p 9000
What it does:
- Writes a launchd plist to
~/Library/LaunchAgents/com.neurolink.proxy.plist. - Loads the service via
launchctl load. - The service runs
neurolink proxy start --port <port> --host <host> --quiet. - Logs go to
~/.neurolink/logs/proxy-launchd-stdout.logandproxy-launchd-stderr.log.
Management:
# Start/stop manually
launchctl start com.neurolink.proxy
launchctl stop com.neurolink.proxy
# Remove entirely
neurolink proxy uninstall
neurolink proxy uninstall
Remove the proxy launchd background service. Unloads the service and deletes the plist file. Currently macOS-only.
No flags.
Examples:
neurolink proxy uninstall
neurolink auth cleanup
Remove expired and disabled accounts from the token store.
| Flag | Type | Default | Description |
|---|---|---|---|
--force | boolean | false | Skip confirmation when removing disabled accounts. |
Examples:
# Interactive cleanup (prompts before removing disabled accounts)
neurolink auth cleanup
# Force cleanup without confirmation
neurolink auth cleanup --force
What it does:
- Prunes expired entries that have no refresh token.
- Finds permanently disabled entries (e.g., accounts that failed refresh).
- Prompts for confirmation before removing disabled accounts (unless
--force).
neurolink auth enable
Re-enable a previously disabled account so it can be used by the proxy pool again.
| Argument | Type | Required | Description |
|---|---|---|---|
<account> | string | Yes | Account key to re-enable (e.g., anthropic:1-VjRIq). |
Examples:
# Re-enable a disabled account
neurolink auth enable anthropic:1-VjRIq
Run neurolink auth list to see all accounts and their current status.
2. Config File (~/.neurolink/proxy-config.yaml)
The proxy loads its configuration from a YAML (or JSON) file. The default location is ~/.neurolink/proxy-config.yaml. Override it with --config.
YAML parsing uses js-yaml when available; otherwise falls back to JSON.parse.
Environment Variable Interpolation
All string values support ${VAR_NAME} and ${VAR_NAME:-default} syntax for environment variable resolution:
accounts:
anthropic:
- name: production
apiKey: "${ANTHROPIC_API_KEY}" # resolved from env
- name: backup
apiKey: "${BACKUP_KEY:-sk-fallback-123}" # with default value
Resolution order:
- Look up
VAR_NAMEinprocess.env. - If not found, use the
:-defaultvalue when present. - If no default, the literal
${VAR_NAME}token is preserved (validation will catch missing keys).
Full Schema
# ---------------------------------------------------------------------------
# Top-level fields
# ---------------------------------------------------------------------------
# Schema version (optional, default: 1)
version: 1
# Default provider applied when not specified per-account (optional)
defaultProvider: "anthropic"
# Default base URL applied to accounts that omit baseUrl (optional)
defaultBaseUrl: "https://api.anthropic.com"
# ---------------------------------------------------------------------------
# accounts (REQUIRED)
# ---------------------------------------------------------------------------
# Map of provider names to arrays of account configurations.
# At least one provider with at least one account is required.
accounts:
anthropic:
- name: "personal-pro" # Human-readable label (default: "unnamed")
apiKey: "${ANTHROPIC_KEY_1}" # API key or OAuth token (REQUIRED, non-empty)
baseUrl: "https://api.anthropic.com" # Base URL override (optional)
orgId: "org-abc123" # Organization ID (optional)
weight: 2 # Weight for weighted round-robin (default: 1)
enabled: true # Whether this account is active (default: true)
rateLimit: 60 # Max requests per minute (optional)
metadata: # Arbitrary metadata (optional)
tier: "pro"
notes: "Main account"
- name: "team-max"
apiKey: "${ANTHROPIC_KEY_2}"
weight: 3
enabled: true
# ---------------------------------------------------------------------------
# routing (optional)
# ---------------------------------------------------------------------------
# Controls model mapping, fallback chains, and routing strategy.
# Accepts both camelCase and kebab-case keys for YAML-friendliness.
routing:
# Account selection strategy: "round-robin" | "fill-first"
strategy: "round-robin"
# Model mappings: remap incoming model names to different provider/model pairs
# Accepts: model-mappings (kebab) or modelMappings (camel)
model-mappings:
- from: "claude-sonnet-4-20250514" # Model name sent by Claude Code
to: "gemini-2.5-pro" # Target model name
provider: "google-ai" # Target provider (default: "anthropic")
- from: "claude-3-haiku-20240307"
to: "gpt-4o-mini"
provider: "openai"
# Fallback chain: when all Claude accounts are exhausted, try these in order
# Accepts: fallback-chain (kebab) or fallbackChain (camel)
fallback-chain:
- provider: "google-ai"
model: "gemini-2.5-pro"
- provider: "openai"
model: "gpt-4o"
# Passthrough models: model IDs that skip routing and go directly to Anthropic
# Accepts: passthrough-models (kebab) or passthroughModels (camel)
passthrough-models:
- "claude-sonnet-4-20250514"
- "claude-3-5-sonnet-20241022"
- "claude-3-haiku-20240307"
# ---------------------------------------------------------------------------
# cloaking (optional)
# ---------------------------------------------------------------------------
# Cloaking pipeline for making proxy requests indistinguishable from
# genuine Claude Code sessions.
cloaking:
# Mode: "auto" | "always" | "never"
# auto - apply cloaking only to OAuth accounts (default behavior)
# always - apply to all accounts (OAuth and API key)
# never - disable all cloaking plugins
mode: "auto"
plugins:
# Strip proxy-revealing headers (x-forwarded-for, via, etc.)
headerScrubber: true
# Generate consistent session identities per account (1-hour TTL)
sessionIdentity: true
# Inject Claude Code session context into system prompt (OAuth only)
systemPromptInjector: true
# Zero-width character insertion into sensitive words
wordObfuscator:
enabled: true
words: # Custom words to obfuscate
- "proxy"
- "neurolink"
- "load balancer"
- "round-robin"
- "failover"
- "multi-account"
# TLS fingerprint mimicry (stub/placeholder -- not yet implemented)
tlsFingerprint:
enabled: false
Field Reference Table
Top-Level Fields
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
version | number | 1 | No | Config schema version. |
defaultProvider | string | (none) | No | Default provider name applied to accounts that omit it. |
defaultBaseUrl | string | (none) | No | Default base URL applied to accounts that omit baseUrl. |
accounts | Record<string, Account[]> | (none) | Yes | Map of provider names to account arrays. |
routing | RoutingConfig | (none) | No | Routing strategy, model mappings, and fallback chain. |
cloaking | CloakingConfig | (none) | No | Cloaking pipeline configuration. |
Account Fields
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
name | string | "unnamed" | No | Human-readable account label. |
apiKey | string | (none) | Yes | API key or OAuth token. Supports ${ENV_VAR} interpolation. |
baseUrl | string | (none) | No | Override the provider's API base URL. |
orgId | string | (none) | No | Organization ID (e.g., OpenAI organizations). |
weight | number | 1 | No | Weight for weighted round-robin selection. Higher weight = more traffic. |
enabled | boolean | true | No | Whether this account is active. Disabled accounts are skipped. |
rateLimit | number | (none) | No | Maximum requests per minute for this account. |
metadata | Record<string, unknown> | (none) | No | Arbitrary metadata (tier info, notes, tags). |
Routing Fields
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
strategy | "round-robin" | "fill-first" | (none) | No | Account selection strategy. round-robin rotates across accounts. fill-first uses one account until exhausted. |
model-mappings / modelMappings | ModelMapping[] | [] | No | Array of model-to-model remapping rules. |
fallback-chain / fallbackChain | FallbackEntry[] | [] | No | Ordered list of alternative providers to try when primary accounts are exhausted. |
passthrough-models / passthroughModels | string[] | [] | No | Model IDs that bypass routing and go directly to Anthropic. |
ModelMapping Fields
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
from | string | "" | Yes | Incoming model name (what Claude Code requests). |
to | string | "" | Yes | Target model name at the destination provider. |
provider | string | "anthropic" | No | Target provider to route to. |
FallbackEntry Fields
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
provider | string | "" | Yes | Provider name (e.g., google-ai, openai). |
model | string | "" | Yes | Model to use at that provider. |
Cloaking Fields
| Field | Type | Default | Description |
|---|---|---|---|
mode | "auto" | "always" | "never" | "auto" | auto applies cloaking only to OAuth accounts. always applies to all. never disables all plugins. |
plugins.headerScrubber | boolean | false | Strip proxy-revealing headers (x-forwarded-for, via, sec-ch-*, etc.). |
plugins.sessionIdentity | boolean | false | Generate consistent user_id/session_id per account with 1-hour TTL. |
plugins.systemPromptInjector | boolean | false | Inject Claude Code session context (IDE metadata, timestamps) into system prompt. OAuth accounts only. |
plugins.wordObfuscator.enabled | boolean | false | Insert zero-width characters into sensitive words to defeat string matching. |
plugins.wordObfuscator.words | string[] | ["proxy", "neurolink", ...] | Words to obfuscate. Defaults include: proxy, neurolink, load balancer, round-robin, failover, multi-account. |
plugins.tlsFingerprint.enabled | boolean | false | TLS fingerprint mimicry. Currently a stub/placeholder (no-op). |
Validation Rules
The config loader validates the following:
accountsmust be present and be a non-array object.- Each provider key in
accountsmust map to an array. - Each account must have a non-empty string
apiKey. - If
versionis present, it must be a number. - Plaintext API keys (not using
${ENV_VAR}references) trigger a warning.
3. Environment Variables
| Variable | Purpose | Used By |
|---|---|---|
ANTHROPIC_API_KEY | Anthropic API key. Used as a fallback credential when no OAuth accounts are found. | Proxy routes, Anthropic provider |
ANTHROPIC_OAUTH_TOKEN | OAuth access token for Anthropic (alternative to stored tokens). | Anthropic provider, providerConfig |
CLAUDE_OAUTH_TOKEN | Alias for ANTHROPIC_OAUTH_TOKEN. Checked as a fallback. | Anthropic provider, providerConfig |
NEUROLINK_SKIP_MCP | Set to "true" to skip MCP server initialization. Automatically set by proxy start (tools come from Claude Code, not local MCP servers). | NeuroLink constructor |
NEUROLINK_LOG_LEVEL | Log level for the NeuroLink logger. Values: error, warn, info, debug. | Logger utility |
Priority for Anthropic credentials (checked in order by the proxy routes):
- TokenStore compound keys --
anthropic:<label>entries in~/.neurolink/tokens.json. - Legacy credentials file --
~/.neurolink/anthropic-credentials.json(only if no compound keys exist). ANTHROPIC_API_KEYenv var -- Only if no OAuth accounts are found at all.
4. Claude Code Settings
When the proxy starts, it automatically writes to ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:55669",
"ENABLE_TOOL_SEARCH": "true"
}
}
| Key | Value | Description |
|---|---|---|
ANTHROPIC_BASE_URL | http://<host>:<port> | Tells Claude Code to route all Anthropic API requests through the proxy. |
ENABLE_TOOL_SEARCH | "true" | Enables tool search in Claude Code (required for full proxy compatibility). |
Lifecycle:
- On
proxy start-- Both keys are written (or merged into existing settings). - On
proxy stop(Ctrl+C / SIGTERM) -- Both keys are removed. Other env keys in the settings file are preserved. - Fail-open guard -- If the proxy crashes without a clean shutdown, the detached guard process detects the unhealthy endpoint and removes the stale settings automatically.
- Safety -- If the
ANTHROPIC_BASE_URLhas been changed to a different value (e.g., another proxy), the cleanup will not overwrite it.
After starting the proxy, restart Claude Code for the new settings to take effect.
5. File Locations
All NeuroLink proxy files are stored under ~/.neurolink/ (with 0o700 directory permissions).
| File | Permissions | Description |
|---|---|---|
~/.neurolink/tokens.json | 0o600 | TokenStore -- Multi-provider OAuth token storage. Stores tokens keyed by provider:label (e.g., anthropic:personal). XOR-obfuscated by default (not plaintext). |
~/.neurolink/anthropic-credentials.json | 0o600 | Legacy credentials -- Single-account OAuth tokens. Used as a fallback when no compound keys exist in tokens.json. Updated on token refresh (pre-request or on-401). |
~/.neurolink/proxy-config.yaml | user default | Proxy config -- YAML/JSON configuration file. Loaded by proxy start (default path, overridable with --config). |
~/.neurolink/proxy-state.json | user default | Proxy state -- Runtime state persisted by the running proxy (PID, port, host, strategy, start time, fallback chain, guard PID). Used by proxy status and the fail-open guard. |
~/.neurolink/logs/proxy-YYYY-MM-DD.jsonl | 0o600 | Request logs -- One JSONL entry per proxied request. Rotated daily by date. Each entry contains: timestamp, requestId, method, path, model, stream flag, tool count, account label, response status, response time, error info, and token usage. |
~/.neurolink/logs/proxy-debug-YYYY-MM-DD.jsonl | 0o600 | Debug logs -- Full request/response debug entries. Includes complete request headers, body summary (model, max_tokens, message count, tool count, thinking config), response status, response headers, response body (first 2000 chars on errors), and duration. |
~/.neurolink/account-quotas.json | user default | Account quotas -- Cached quota/utilization data from Anthropic's unified-5h and unified-7d rate-limit headers. Flushed to disk every 5 seconds. |
~/.claude/settings.json | user default | Claude Code settings -- Auto-configured with ANTHROPIC_BASE_URL and ENABLE_TOOL_SEARCH when the proxy starts. Cleaned up on shutdown. |
TokenStore Details
The tokens.json file uses this internal structure (after deobfuscation):
{
"version": "2.0",
"lastModified": 1711100000000,
"providers": {
"anthropic:personal": {
"tokens": {
"accessToken": "...",
"refreshToken": "...",
"expiresAt": 1711103600000,
"tokenType": "Bearer",
"scope": "..."
},
"createdAt": 1711100000000,
"lastAccessed": 1711100000000
},
"anthropic:team": {
"tokens": { "...": "..." },
"createdAt": 1711100000000,
"lastAccessed": 1711100000000
}
}
}
The TokenStore class options:
encryptionEnabled(default:true) -- XOR obfuscation with a machine-derived key.customStoragePath-- Override the default~/.neurolink/tokens.jsonpath.
Tokens are automatically refreshed 1 hour before expiration when a TokenRefresher function is registered.
6. Model Mapping Examples
Model mappings let you reroute specific model requests to different providers. The proxy's ModelRouter checks mappings in this order:
- Explicit mapping -- If the requested model has a
frommatch inmodel-mappings, use the correspondingto/provider. - Passthrough list -- If the model is in
passthrough-models, route to Anthropic. - Claude prefix -- Any model starting with
claude-is routed to Anthropic. - Unknown model -- Returns
provider: null(the proxy will attempt Anthropic by default).
Example: Route Haiku to a Cheaper Provider
routing:
model-mappings:
- from: "claude-3-haiku-20240307"
to: "gpt-4o-mini"
provider: "openai"
Claude Code requests claude-3-haiku-20240307 but the proxy sends the request to OpenAI's gpt-4o-mini instead, translating the request format via neurolink.generate().
Example: Use Gemini for All Sonnet Requests
routing:
model-mappings:
- from: "claude-sonnet-4-20250514"
to: "gemini-2.5-pro"
provider: "google-ai"
- from: "claude-3-5-sonnet-20241022"
to: "gemini-2.5-flash"
provider: "google-ai"
Example: Passthrough Specific Models
routing:
passthrough-models:
- "claude-sonnet-4-20250514"
- "claude-3-opus-20240229"
model-mappings:
- from: "claude-3-haiku-20240307"
to: "gemini-2.5-flash"
provider: "google-ai"
Here, Sonnet 4 and Opus requests go directly to Anthropic (passthrough), while Haiku requests are redirected to Gemini.
Example: No Routing (Pure Multi-Account Pool)
Omit the routing section entirely. All requests pass through to Anthropic using the configured accounts with round-robin rotation:
accounts:
anthropic:
- name: "account-1"
apiKey: "${ANTHROPIC_KEY_1}"
- name: "account-2"
apiKey: "${ANTHROPIC_KEY_2}"
- name: "account-3"
apiKey: "${ANTHROPIC_KEY_3}"
7. Fallback Chain Examples
The fallback chain is tried in order when all primary Claude accounts are exhausted (rate-limited, errored, or cooling down). Each entry specifies a provider and model. The proxy translates the Claude-format request into the target provider's format using neurolink.generate() or neurolink.stream().
Example: Gemini then OpenAI
routing:
fallback-chain:
- provider: "google-ai"
model: "gemini-2.5-pro"
- provider: "openai"
model: "gpt-4o"
Request flow:
- Try all Claude accounts (round-robin with retry).
- If all exhausted, try Google AI Studio with
gemini-2.5-pro. - If that also fails, try OpenAI with
gpt-4o.
Example: Multiple Gemini Tiers
routing:
fallback-chain:
- provider: "google-ai"
model: "gemini-2.5-pro"
- provider: "google-ai"
model: "gemini-2.5-flash"
- provider: "openai"
model: "gpt-4o-mini"
Falls back through progressively cheaper models.
Example: Vertex AI as Primary Fallback (Enterprise)
routing:
fallback-chain:
- provider: "google-vertex"
model: "gemini-2.5-pro"
- provider: "amazon-bedrock"
model: "anthropic.claude-3-5-sonnet-20241022-v2:0"
Uses enterprise-grade providers (Vertex AI, Bedrock) as fallbacks. Requires the corresponding provider credentials to be configured in environment variables.
Example: Full Multi-Tier Setup
version: 1
accounts:
anthropic:
- name: "pro-personal"
apiKey: "${CLAUDE_PRO_KEY}"
weight: 1
- name: "max-team"
apiKey: "${CLAUDE_MAX_KEY}"
weight: 3
routing:
strategy: "round-robin"
passthrough-models:
- "claude-sonnet-4-20250514"
model-mappings:
- from: "claude-3-haiku-20240307"
to: "gemini-2.5-flash"
provider: "google-ai"
fallback-chain:
- provider: "google-ai"
model: "gemini-2.5-pro"
- provider: "openai"
model: "gpt-4o"
cloaking:
mode: "auto"
plugins:
headerScrubber: true
sessionIdentity: true
systemPromptInjector: true
wordObfuscator:
enabled: true
words:
- "proxy"
- "neurolink"
This configuration:
- Pools two Claude accounts with 1:3 weighting (Max gets 3x traffic).
- Passes Sonnet 4 requests directly to Anthropic.
- Redirects Haiku requests to Gemini Flash.
- Falls back to Gemini Pro, then GPT-4o when Claude accounts are exhausted.
- Applies cloaking to OAuth accounts (header scrubbing, session identity, system prompt injection, word obfuscation).
Proxy Endpoints
For reference, the running proxy exposes these HTTP endpoints:
| Method | Path | Description |
|---|---|---|
POST | /v1/messages | Anthropic-compatible chat completions (main endpoint). |
GET | /v1/models | List available models. |
POST | /v1/messages/count_tokens | Token counting endpoint. |
GET | /health | Health check. Returns { status, strategy, uptime }. |
GET | /status | Detailed status with per-account stats, request counts, error rates. |
Log Rotation
Log files (proxy-*.jsonl and proxy-debug-*.jsonl) are automatically cleaned up to prevent unbounded growth.
| Parameter | Value | Description |
|---|---|---|
| Max age | 7 days | Files older than 7 days are deleted |
| Max total size | 500 MB | If remaining files exceed 500 MB, oldest are deleted first |
| Cleanup triggers | Startup + hourly | Runs once at proxy start, then every 60 minutes |
The cleanupLogs() function performs two passes:
- Age pass -- delete all files with
mtimeolder than the cutoff. - Size pass -- if remaining files exceed the size limit, delete oldest first until under the cap.
Log rotation is non-fatal. If cleanup fails, the proxy continues operating normally.
Rate Limit Headers from Anthropic
The proxy captures and uses Anthropic's quota headers for per-account utilization tracking:
| Header | Format | Description |
|---|---|---|
anthropic-ratelimit-unified-5h-utilization | float (0.0-1.0) | 5-hour rolling session utilization |
anthropic-ratelimit-unified-5h-status | string | Session status (e.g., ok, warning) |
anthropic-ratelimit-unified-5h-reset | integer (epoch) | When the 5-hour window resets |
anthropic-ratelimit-unified-7d-utilization | float (0.0-1.0) | 7-day rolling weekly utilization |
anthropic-ratelimit-unified-7d-status | string | Weekly status |
anthropic-ratelimit-unified-7d-reset | integer (epoch) | When the 7-day window resets |
anthropic-ratelimit-fallback-percentage | float | Fallback percentage threshold |
anthropic-ratelimit-overage-status | string | Overage status |
These headers are parsed by parseQuotaHeaders() in accountQuota.ts and cached in memory with debounced persistence to ~/.neurolink/account-quotas.json. The neurolink auth list command displays per-account 5h and 7d utilization when available.
Token Refresh
The proxy uses a reactive (not background) refresh strategy. There is no background timer polling for token expiry. Instead, tokens are refreshed on demand:
- Pre-request check — Before each request, if the token's
expiresAt <= now + 1 hour, the proxy refreshes it inline viaPOST https://api.anthropic.com/v1/oauth/token(fallback:https://console.anthropic.com/v1/oauth/token). On success, the credential file is updated atomically (write to.tmp, then rename). - On-401 retry — If Anthropic returns a 401 despite the pre-request check, the proxy refreshes the token and retries the request up to 5 times before failing over to the next account.