# Provider Configuration
A provider setup registers an AI model backend with Valdr. It defines what a provider *is* — display name, integration type, available models, API key requirements, and enablement status. Provider setups are managed in **Settings > Providers** and can be exported/imported as JSON.

{{< callout type="info" >}}
Provider setups define the provider catalog. [Presets](../presets/) define how to *launch* a session with that provider. They're separate concerns — a provider says "Claude is available with these models," a preset says "launch with Opus, bypass permissions, create a worktree."
{{< /callout >}}

## JSON schema

Each provider setup is a JSON object with this shape:

```json
{
  "providerId": "codex",
  "providerType": "codex",
  "displayName": "Codex",
  "isEnabled": true,
  "apiKeyEnvVar": "CODEX_API_KEY",
  "baseUrl": null,
  "defaultModel": "gpt-5.4",
  "defaultTemperature": null,
  "defaultMaxTokens": null,
  "models": [
    { "id": "gpt-5.4", "label": "GPT-5.4" },
    { "id": "gpt-5.4-mini", "label": "GPT-5.4 Mini" }
  ]
}
```

## Field reference

| Field | Type | Required | Purpose |
|-------|------|----------|---------|
| `providerId` | string | Yes | Unique identifier for this setup record. Built-in providers use stable IDs; custom providers get a generated ULID. |
| `providerType` | string | Yes | Integration type. Must be a registered provider type (see below). |
| `displayName` | string | Yes | Human-readable name shown in UI dropdowns and tables. |
| `isEnabled` | boolean | Yes | Whether this provider is available. Set `false` to disable without deleting. |
| `apiKeyEnvVar` | string \| null | No | Environment variable name for the API key (e.g., `"CODEX_API_KEY"`). Used during preset resolution to auto-inject `config.apiKey` when absent. Set `null` if no key is needed. |
| `baseUrl` | string \| null | No | Default/suggested endpoint URL. Required for Ollama (`"http://localhost:11434"`). `null` uses the provider's default. |
| `defaultModel` | string \| null | No | Suggested default model. Informs UI model selection and export metadata. |
| `defaultTemperature` | number \| null | No | Suggested default temperature (`0`–`2`). Informs UI and exports. |
| `defaultMaxTokens` | number \| null | No | Suggested default max output tokens (positive integer). Informs UI and exports. |
| `models` | array | No | Available model options. Each entry: `{ "id": "model-id", "label": "Display Name" }`. |

## Registered provider types

These are the valid `providerType` values:

| Type | Runtime launcher | Notes |
|------|-----------------|-------|
| `claude` | Claude (native) | Claude Agent SDK with agentic tool execution |
| `codex` | Codex (native) | Codex SDK with CLI streaming and keep-alive |
| `ollama` | TanStack adapter | Local Ollama server via `@tanstack/ai-ollama` |

Native providers (`claude`, `codex`) use the vendor's SDK directly with full agentic capabilities including session resumption. `ollama` routes through the TanStack adapter layer where Valdr manages tool execution server-side.

## What provider setups affect at runtime

Not all provider setup fields become runtime launcher defaults. This distinction matters:

| Field | Runtime effect |
|-------|---------------|
| `apiKeyEnvVar` | **Yes** — used during preset resolution to auto-inject `config.apiKey` when absent |
| `displayName`, `isEnabled`, `models` | UI/operator metadata only |
| `baseUrl`, `defaultModel`, `defaultTemperature`, `defaultMaxTokens` | Export/UI/default-selection metadata — **not** automatically merged into runtime config |

Runtime defaults for native launchers come from environment variables (see [per-provider config](#per-provider-config-keys) below). Launch-time behavior comes from the resolved preset `config`.

## Per-provider config keys

Each provider accepts different `config` keys in presets. These are the operator-facing fields your presets can set:

### Claude

| Key | Type | Notes |
|-----|------|-------|
| `model` | string | Per-session model override |
| `permissionMode` | `default` \| `acceptEdits` \| `bypassPermissions` \| `dontAsk` \| `plan` | `bypassPermissions` is a high-trust mode and also sets `allowDangerouslySkipPermissions` |
| `allowedTools` | string[] | Merged with required Valdr internal tools. Default: `["Read", "Edit", "Write", "Glob", "Grep", "Bash"]` |
| `disallowedTools` | string[] | Forwarded as-is |
| `maxTurns` | number | Max SDK turns |
| `mcpServers` | object | External MCP servers to attach (Valdr's internal server is always injected) |
| `keepAliveMs` | number | Session keep-alive timeout in ms |

**Current launcher fallback:** If `permissionMode` is omitted, Claude currently falls back to `bypassPermissions`. For clearer human review and audit posture, set the mode explicitly and prefer stricter modes unless you intentionally want unattended local execution. `allowedTools` defaults to `["Read", "Edit", "Write", "Glob", "Grep", "Bash"]`.

**Environment variables:** `CLAUDE_MODEL`, `CLAUDE_PERMISSION_MODE`, `CLAUDE_MAX_TURNS`, `CLAUDE_ALLOWED_TOOLS`, `CLAUDE_DISALLOWED_TOOLS`.

### Codex

| Key | Type | Notes |
|-----|------|-------|
| `model` | string | Model identifier |
| `temperature` | number | Sampling temperature (`0`–`2`, default `0.2`) |
| `maxOutputTokens` | number | Output length cap (`16`–`32768`, default `8192`) |
| `topP` | number | Nucleus sampling |
| `stopSequences` | string[] | Termination markers |
| `reasoning_effort` / `model_preferences.reasoning_effort` | string | `"low"`, `"medium"`, `"high"` |
| `env` | object | Process environment overrides |
| `mcpServers` | object | MCP servers (Valdr auto-injects unless `disableInternalValdrMcp: true`) |
| `keepAliveMs` | number | Session keep-alive timeout |
| `sessionIdleCloseMs` | number | Explicit idle-close delay |

**Authentication:** Dual strategy — cached login (`~/.codex/auth.json`) first, API key fallback via `CODEX_API_KEY` (falls back to `OPENAI_API_KEY`).

**Environment variables:** `CODEX_API_KEY`, `CODEX_BASE_URL`, `CODEX_MODEL`, `CODEX_TEMPERATURE`, `CODEX_MAX_OUTPUT_TOKENS`.

### Ollama

| Key | Type | Notes |
|-----|------|-------|
| `model` | string | **Required** — model identifier |
| `temperature` | number | Sampling temperature |
| `maxOutputTokens` | number | Output length limit |
| `baseUrl` | string | Base URL override for the Ollama API |
| `keepAliveMs` | number | Optional idle retention window; converted to seconds and passed as `keep_alive` |

Ollama uses the TanStack adapter layer with Valdr-managed tool execution, so `permissionMode`, `allowedTools`, and `mcpServers` are **not** supported.

## Examples

### Claude Code

```json
{
  "providerId": "claude",
  "providerType": "claude",
  "displayName": "Claude Code",
  "isEnabled": true,
  "apiKeyEnvVar": null,
  "baseUrl": null,
  "defaultModel": "sonnet",
  "defaultTemperature": null,
  "defaultMaxTokens": null,
  "models": [
    { "id": "default", "label": "Default" },
    { "id": "sonnet", "label": "Sonnet" },
    { "id": "sonnet[1m]", "label": "Sonnet 1M" },
    { "id": "opus", "label": "Opus" },
    { "id": "haiku", "label": "Haiku" },
    { "id": "opusplan", "label": "Opus Plan" }
  ]
}
```

### Codex

```json
{
  "providerId": "codex",
  "providerType": "codex",
  "displayName": "Codex",
  "isEnabled": true,
  "apiKeyEnvVar": "CODEX_API_KEY",
  "baseUrl": null,
  "defaultModel": "gpt-5.4",
  "defaultTemperature": null,
  "defaultMaxTokens": null,
  "models": [
    { "id": "gpt-5.4", "label": "GPT-5.4" },
    { "id": "gpt-5.4-mini", "label": "GPT-5.4 Mini" },
    { "id": "gpt-5.3-codex", "label": "GPT-5.3 Codex" },
    { "id": "gpt-5.3-codex-spark", "label": "GPT-5.3 Codex Spark" }
  ]
}
```

### Ollama (local)

```json
{
  "providerId": "ollama",
  "providerType": "ollama",
  "displayName": "Ollama Local",
  "isEnabled": true,
  "apiKeyEnvVar": null,
  "baseUrl": "http://localhost:11434",
  "defaultModel": "qwen3-coder-next",
  "defaultTemperature": null,
  "defaultMaxTokens": null,
  "models": [
    { "id": "qwen3-coder-next", "label": "Qwen3-Coder-Next" },
    { "id": "qwen3", "label": "Qwen3" },
    { "id": "deepseek-r1", "label": "DeepSeek R1" }
  ]
}
```

## Import and export

Use **Export** and **Import** in Settings > Providers. The export produces a JSON array of provider setup objects. Import on another machine to replicate the provider catalog instantly.

## Next steps

Providers define *what* Valdr can talk to. [Presets](../presets/) define *how* — the specific model, permissions, and runtime config for each agent launch.

