Skip to content

Managed Providers

Managed providers are cloud-hosted LLM services that netclaw connects to over HTTPS. Each authenticates with an API key or OAuth: OpenRouter, Anthropic, OpenAI, GitHub Copilot, Venice.ai, and DeepSeek.

Provider config lives in two files. Non-secret fields (type, endpoint, auth method) go in ~/.netclaw/config/netclaw.json. Credentials go in ~/.netclaw/config/secrets.json, which is encrypted at rest. Write plaintext values and netclaw encrypts them on first read. Environment variables override both.

If you’re setting up netclaw for the first time, netclaw init handles provider selection interactively. This page covers manual configuration and the details behind each provider type.

For self-hosted inference (Ollama, llama.cpp, vLLM), see Self-Hosted Providers.

TypeDisplay NameDefault EndpointAuthKey Source
openrouterOpenRouterhttps://openrouter.ai/api/v1API keyopenrouter.ai/keys
anthropicAnthropichttps://api.anthropic.comAPI keyconsole.anthropic.com
openaiOpenAIhttps://api.openai.comChatGPT OAuth (device or browser) or API keyplatform.openai.com
github-copilotGitHub Copilothttps://api.githubcopilot.comOAuth (device)GitHub Copilot subscription
veniceaiVenice.aihttps://api.venice.ai/api/v1API keyvenice.ai/settings/api
deepseekDeepSeekhttps://api.deepseek.com/v1API keyplatform.deepseek.com/api_keys

Each provider is a named entry under the Providers section. The key is a name you choose, and you can have several entries of one type (two Anthropic providers with different keys, say).

FieldTypeDefaultDescription
Typestring"ollama"Provider SDK: openrouter, anthropic, openai, github-copilot, veniceai, or deepseek for managed providers. Always set this explicitly.
Endpointstring""Base URL. Leave empty to use the provider’s default
ApiKeystring?nullAPI key. Store in secrets.json, never netclaw.json
AuthMethodenumNoneNone, ApiKey, OAuthDevice, or OAuthPkce
VendorOptionsobject{}Per-vendor switches: GitHubHost and GitHubApiBase (Copilot), IncludeVeniceSystemPrompt (Venice.ai), ExcludeReasoning (OpenRouter). Self-hosted types have their own, see Self-hosted providers

netclaw provider add <name> <type> takes --api-key, --endpoint, --auth (api-key or oauth-device), and for Copilot Enterprise --github-host and --github-api-base. Browser OAuth (PKCE) is only available from the TUI.

{
"Providers": {
"openrouter": {
"Type": "openrouter",
"Endpoint": "https://openrouter.ai/api/v1"
},
"my-anthropic": {
"Type": "anthropic"
},
"my-openai": {
"Type": "openai",
"AuthMethod": "OAuthPkce"
}
}
}
{
"Providers": {
"openrouter": { "ApiKey": "sk-or-v1-..." },
"my-anthropic": { "ApiKey": "sk-ant-..." }
}
}

OAuth providers (OpenAI via ChatGPT, GitHub Copilot) don’t need an ApiKey in secrets.json. netclaw stores and refreshes the tokens after you authenticate.

You can also manage credentials with netclaw secrets set instead of editing secrets.json directly.

After adding a provider, assign it to a model role (Main, Fallback, or Compaction) with netclaw model set.

One API key, hundreds of models. OpenRouter proxies requests to Anthropic, OpenAI, Meta, Mistral, and others, so you don’t need a separate account with each vendor.

Terminal window
netclaw provider add openrouter openrouter --api-key sk-or-v1-...

Or configure manually in netclaw.json:

{
"Providers": {
"openrouter": {
"Type": "openrouter"
}
}
}

The endpoint defaults to https://openrouter.ai/api/v1. Override it only for a proxy.

Get your key at openrouter.ai/keys. Browse available models in the OpenRouter model catalog.

Connects directly to Claude models via the Anthropic API.

Terminal window
netclaw provider add my-anthropic anthropic --api-key sk-ant-...

The endpoint defaults to https://api.anthropic.com. Netclaw sends the x-api-key header and anthropic-version: 2023-06-01 on probe requests.

Without a configured limit, Anthropic replies get a 32000-token output limit, capped to the model maximum the Anthropic Models API reports. Replies used to stop at 1024 tokens, so the cost per call can rise. Thinking levels come from the capabilities the API reports for each model. max is Anthropic’s highest level and needs an output limit. Set both per model with netclaw model set --max-output-tokens --thinking. OpenRouter, OpenAI, Venice.ai and DeepSeek get the same 32000 default.

Get your key at console.anthropic.com/settings/keys. See the Anthropic API docs for model versions and usage limits.

OpenAI has three auth methods. Two use your ChatGPT subscription: a device-code flow (ChatGPT Subscription (recommended)) and a browser flow with OAuth PKCE (ChatGPT Subscription (browser)). The third is an API key that bills platform.openai.com credits.

If you already pay for ChatGPT Plus or Pro, use this and skip API keys. Open the Provider Manager:

Terminal window
netclaw provider # opens Provider Manager

Select + Add new provider, choose OpenAI, then pick ChatGPT Subscription (recommended).

You can also start the OAuth device flow from the CLI without the TUI:

Terminal window
netclaw provider add my-openai openai --auth oauth-device

The device flow works on a headless server: netclaw prints a code and a URL, and you approve on any machine with a browser. Only the browser variant needs a browser on the same machine as netclaw.

netclaw refreshes the ChatGPT token before it expires. If the Codex backend answers a request with HTTP 401 anyway, netclaw forces one refresh and retries the request once. If the refresh fails, open netclaw provider, select the unhealthy provider, and re-authenticate.

A refresh that OpenAI rejects for good (invalid_grant, refresh_token_reused, refresh_token_expired or refresh_token_invalidated) raises the provider.auth.expired alert with the code in reason, and netclaw status lists the provider as auth-failed. Only a new sign-in helps. A transient failure (network, timeout, HTTP 5xx or 429) gets one retry after 2 seconds. The tokens and their expiry live in secrets.json. If the daemon stops at startup with an error that names Providers:<name>, an older build left an encrypted OAuthTokenExpiry there, and signing in again in netclaw provider fixes it.

netclaw discovers your ChatGPT models live. After you authenticate it probes OpenAI’s Codex backend and reads each model’s context window and modalities from the response, so new models show up without a netclaw release. With ChatGPT sign-in, netclaw talks to https://chatgpt.com/backend-api/codex, not api.openai.com.

Terminal window
netclaw provider add my-openai openai --api-key sk-proj-...

Get your key at platform.openai.com/api-keys. With API key auth, netclaw discovers available models automatically via /v1/models.

Run inference through your GitHub Copilot subscription. There’s no API key. Auth is GitHub’s OAuth device flow:

Terminal window
netclaw provider add copilot github-copilot --auth oauth-device

netclaw prints a one-time code and a verification URL. Enter the code, approve, and you’re connected. It stores the GitHub OAuth token in secrets.json and exchanges it on demand for a short-lived Copilot token that stays in memory. Models are whatever your subscription exposes, discovered from Copilot’s API.

Requires an active GitHub Copilot subscription.

By default the provider authenticates against github.com. For GitHub Enterprise Server or Enterprise Cloud with data residency, point auth at your enterprise host with two vendor options:

Vendor optionDefaultControls
GitHubHosthttps://github.comThe OAuth auth host: device-code, OAuth token, and token-refresh endpoints (<host>/login/device/code, <host>/login/oauth/access_token)
GitHubApiBasehttps://api.github.comThe API base for the Copilot token exchange (<api-base>/copilot_internal/v2/token)

Set them from the CLI with --github-host and --github-api-base:

Terminal window
netclaw provider add copilot-ghe github-copilot --auth oauth-device \
--github-host https://github.example.com \
--github-api-base https://github.example.com/api/v3

Pass --github-host alone and netclaw derives the API base for you: github.com becomes https://api.github.com, a *.ghe.com data-residency tenant becomes api.<host>, and any other host (GitHub Enterprise Server) becomes <host>/api/v3. Both values must be HTTPS, and GitHubHost must be a bare origin with no path.

In the TUI, + Add new provider then GitHub Copilot offers a GitHub.com / GitHub Enterprise auth-host choice. Pick GitHub Enterprise and enter the host (the API base is prefilled from it).

The stored config looks like this:

{
"Providers": {
"copilot-ghe": {
"Type": "github-copilot",
"AuthMethod": "OAuthDevice",
"VendorOptions": {
"GitHubHost": "https://github.example.com",
"GitHubApiBase": "https://github.example.com/api/v3"
}
}
}
}

Two different hosts are in play, and they’re set separately:

  • Auth plane: GitHubHost and GitHubApiBase decide where device OAuth, token refresh, and the Copilot token exchange happen. This is what GitHub Enterprise changes.
  • Model plane: the provider Endpoint decides where chat and /models traffic goes. Leave it at the default (https://api.githubcopilot.com) and netclaw sends chat to the host the token exchange reports in endpoints.api, which is the tenant host data residency requires. Set --endpoint only to force a specific host, such as a corporate proxy. An explicit override always wins.

For a standard GHE setup, set GitHubHost and GitHubApiBase and leave Endpoint alone. The model host is discovered at token-exchange time.

On a headless server, ambient GitHub environment variables seed the host during --auth oauth-device setup: GitHubHost from the first of COPILOT_GH_HOST, GHE_HOST, GH_HOST, or GITHUB_SERVER_URL, and GitHubApiBase from GITHUB_API_URL. An explicit flag always wins over the environment.

Open netclaw provider after setup. The probe hits /models at the token’s real host, so a misconfigured enterprise host fails at setup instead of silently reporting healthy and breaking on the first chat.

SymptomCauseFix
Device flow never shows a codeWrong GitHubHost, so login/device/code is unreachablePoint --github-host at your enterprise host origin (HTTPS, no path)
token exchange failedWrong GitHubApiBase, or the host doesn’t serve copilot_internal/v2/tokenSet --github-api-base to the enterprise API base (<host>/api/v3 for GHES)
authorization expired on a long runOAuth token expired and refresh failed against the enterprise hostRe-authenticate: netclaw provider remove <name> then re-add with --auth oauth-device
token exchange did not return an API host (endpoints.api)Token isn’t scoped to a data-residency hostRe-authenticate, or set an explicit --endpoint to override the model host

Venice.ai is privacy-focused inference with an OpenAI-style API. Auth is an API key:

Terminal window
netclaw provider add venice veniceai --api-key vk-...

The endpoint defaults to https://api.venice.ai/api/v1. Get a key at venice.ai/settings/api.

By default, netclaw tells Venice not to prepend its own system prompt (include_venice_system_prompt = false), so your identity grounding stays the first system message and the context-budget math stays correct. If you actually want Venice’s default prompt, opt in with a vendor option:

{
"Providers": {
"venice": {
"Type": "veniceai",
"VendorOptions": { "IncludeVeniceSystemPrompt": true }
}
}
}

DeepSeek is a hosted inference provider. Auth is an API key:

Terminal window
netclaw provider add deepseek deepseek --api-key sk-...

The endpoint defaults to https://api.deepseek.com/v1. Get a key at platform.deepseek.com/api_keys.

DeepSeek’s /models endpoint doesn’t report capabilities, so netclaw fills them in itself, and only for model ids that start with deepseek-v4-. Those get a 1,000,000-token context window and text-only input and output. Any other model id is listed with unknown limits, so set the context window yourself in the model definition. Model ids change, so take the current ones from the DeepSeek API docs or from the model list in netclaw model discover. The deepseek provider uses the DeepSeek thinking dialect, so netclaw model set --thinking and Thinking on the definition apply: off turns thinking off, and low, high and max turn it on at that effort. There is no medium. DeepSeek’s /models reports no thinking capability, so model set offers only off until you edit Thinking in netclaw.json by hand.

Run netclaw provider to open the Provider Manager. It probes each configured provider and shows whether it’s reachable and authenticated:

Provider Manager listing lab-llama and my-ollama with a check mark, my-deepseek with a warning triangle, and five unconfigured providers below them

One row per configured provider, with the unconfigured types listed below so you can add them. DeepSeek is the second configured row here, and its warning triangle means the placeholder key was rejected.

IndicatorMeaning
✓Healthy, models discovered
⚠Unreachable or auth failure
…Probe in progress

Select a provider to manage it:

KeyAction
KUpdate API key
RRemove provider
NRename (changes the config key only, so update any definition that names it)
VRe-validate connection

Delete removes the highlighted provider from the list.

Skip config files entirely by setting environment variables with the NETCLAW_ prefix. Double underscores (__) separate path segments, following the .NET configuration convention:

Terminal window
# Override a provider's API key
export NETCLAW_Providers__openrouter__ApiKey="sk-or-v1-..."
# Point a model role at a provider (named definition + role reference)
export NETCLAW_Models__Definitions__claude__Provider="openrouter"
export NETCLAW_Models__Definitions__claude__ModelId="anthropic/claude-sonnet-4"
export NETCLAW_Models__Roles__Main="claude"

Environment variables take highest priority, overriding both netclaw.json and secrets.json. On Linux, variable names are case-sensitive: NETCLAW_Providers__openrouter__ApiKey won’t match NETCLAW_PROVIDERS__OPENROUTER__APIKEY. Changes to environment variables need a manual restart.

The Provider Manager, netclaw provider add, and netclaw model discover probe a provider by hitting its model-listing endpoint, with a 10-second timeout for hosted providers.

Common probe errors:

HTTP statusMessage (provider name filled in)
401Invalid credentials. Double-check your <provider> credentials.
403Access denied. Your <provider> credentials may lack model-listing permissions.
404The <provider> models API was not found at <url>. Check the endpoint URL, or the service may be down.
429Rate limited by <provider>. Wait a moment and try again.
5xxThe provider returned an error, so it may be having issues
Connection failureConnection failed: <reason>: check the endpoint and connectivity

When the provider’s error body says why, the 401 and 403 messages end with that detail. URLs in these messages drop any username, password, and query string.

To test a provider now, open netclaw provider and press V, or run netclaw model discover <name>. netclaw doctor validates the config shape and credentials for every provider a role uses, but it doesn’t call the provider.

Azure AI Foundry, OVHcloud AI Endpoints, and similar gateways speak the OpenAI chat API, so people point netclaw’s openai-compatible provider at them. That provider is built for local servers (llama.cpp, vLLM). Hosted gateways that enforce the OpenAI schema strictly can reject it, and some do.

What netclaw sends on every streaming request, on top of the standard model, messages, tools, and stream fields:

FieldWhyStrict gateways
stream_options.include_usageToken counts in the final chunkAccepted by OpenAI-style APIs
return_progress: truellama.cpp prompt-progress keepalivesRejected by some, with an HTTP 400
max_tokensThe output limit, sent when the context window is known (ContextWindow set or probed)Accepted by OpenAI-style APIs
reasoning_effort, thinking or chat_template_kwargsThe thinking level, sent only when Thinking is set and the provider has a thinking dialectDepends on the dialect

The 400 looks like this in the daemon and session logs:

400 {"message":"feature 'extra arguments: {\"return_progress\":true}' is not currently supported"}

In chat you only see LLM provider returned an error (HTTP 400). Please try again. The reason is in the log under ~/.netclaw/logs/. Reported on Azure Foundry and OVHcloud (netclaw#1566, still open). There’s no switch to turn the field off yet.

What “compatible” has to mean for netclaw:

  • GET /v1/models lists the model, and POST /v1/chat/completions streams server-sent events.
  • Unknown request fields are ignored, not rejected.
  • Streaming tool calls arrive as structured tool_calls deltas (netclaw also parses <tool_call> text, but structured is the path that works everywhere).
  • Auth is a Bearer header. netclaw sends Authorization: Bearer <key> and no other header, so a gateway that insists on api-key can’t be reached with this provider.

One reported workaround, unsupported: configure the provider as type openrouter with a custom Endpoint, an API key, and "VendorOptions": { "ExcludeReasoning": false }. In a test against a strict stub that path sent no return_progress. The issue’s reporter found some models then return empty streams, so treat it as a last resort. Self-hosted providers covers the endpoint URL rules, including the /v1 suffix.

SymptomCauseFix
netclaw status says config on disk not applied, or the daemon crash-loops on restart, and the message says requires authenticationA role uses a provider with no API key or OAuth tokenAdd the key (netclaw secrets set or netclaw provider, K), then restart. A provider no role uses isn’t checked
Provider shows a warning in netclaw providerProbe failed: see the probe table aboveFix credentials or endpoint, then press V
Main fails and Fallback answersAutomatic failoverCheck the provider.failover alert for the error

Each role uses one provider, so there’s no per-channel provider selection. Failover between providers is the Fallback role. Changing providers restarts the daemon, automatically for netclaw.json edits and by hand for environment variables and secrets.json.