A ModelProvider over Anthropic’s own SDK. The default for tool-heavy work, and
the path on which native capabilities stay available.
The only package allowed a vendor SDK
The copilot’s domain and server packages must not import one, ever — the same rule that keeps Drizzle and Nest out of any domain layer.
An adapter is where a vendor’s client belongs, because an adapter is the thing you replace.
Install
npm install @apograph/copilot-provider-anthropicimport { createAnthropicProvider } from '@apograph/copilot-provider-anthropic';
CopilotPlugin({
providers: [
{ name: 'claude', provider: createAnthropicProvider(config.plugins.copilot.providers.claude) },
{ name: 'fake', provider: createFakeProvider() }
],
config: config.plugins.copilot
});Configuration
{ apiKey, models, baseUrl?, effort?, maxRetries?, timeoutMs?, promptCaching? }
| Variable | Default | What it does |
|---|---|---|
ANTHROPIC_API_KEY | unset | Setting it is what registers this backend |
COPILOT_ANTHROPIC_MODELS | see below | Comma-separated. The first is the default |
ANTHROPIC_BASE_URL | unset | A gateway, proxy or regional endpoint |
COPILOT_ANTHROPIC_MODELS=claude-opus-5,claude-sonnet-5,claude-haiku-4-5A missing key un-registers the backend, it does not break it
Leave ANTHROPIC_API_KEY empty and there is no claude in the model picker at
all — rather than one that fails on the first message.
That is the composition root’s job: apograph.config.ts omits a provider whose
connection settings are absent, and plugins.ts skips registering it.
The key never leaves the server.
The model list is a list
One key and one client back several models, so a user can switch mid-conversation without a redeploy. The first entry is the default, and it is what the admin’s picker opens on.
A run naming a model outside the list raises an unknown-model error rather than quietly answering on the default. A silent substitution is the kind of thing nobody notices until a bill or an answer looks wrong.
The lazy client
The SDK client is constructed on first use, not in the factory.
A host registers every provider it might route to, but an operator running local inference has no Anthropic key — and an unused adapter must not fail their boot. Constructing eagerly would make registering this package a hard dependency on having configured it.
Capabilities are probed
The adapter asks the Models API what the configured models support, and falls back to a conservative set when that call cannot be made. That is what lets the run engine know whether a native capability is available without a table in this repository going stale every time a model ships.