# How to Configure Custom LLM Providers in Open Code Review

> Configure custom LLM providers in Open Code Review easily. Define them in config.json or use the interactive wizard for seamless integration.

- Repository: [Alibaba/open-code-review](https://github.com/alibaba/open-code-review)
- Tags: how-to-guide
- Published: 2026-08-06

---

**Set custom LLM providers in Open Code Review by defining a `custom_providers` entry in `~/.ocr/config.json` with a unique name, URL, and protocol, or use the interactive `ocr config provider` wizard.**

Open Code Review (OCR) supports any HTTP-compatible LLM service through a flexible, layered configuration system. Whether you run Ollama locally, host a private vLLM endpoint, or connect to an enterprise API, you can configure custom providers without modifying source code. This guide explains OCR's provider resolution architecture and gives you practical, runnable steps based on the [alibaba/open-code-review](https://github.com/alibaba/open-code-review) source code.

## How OCR Discovers LLM Endpoints

OCR resolves LLM endpoints through four configuration layers, as implemented in [`internal/llm/resolver.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/resolver.go):

| Layer | Source | Purpose |
|-------|--------|---------|
| **Built-in providers** | [`internal/llm/providers.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/providers.go) | Static registry of Anthropic, OpenAI, DashScope, etc. |
| **Provider overrides** | `configFile.Providers` | Override URL, model list, or auth for preset providers |
| **Custom providers** | `configFile.CustomProviders` | Add any HTTP-compatible LLM service |
| **Manual configuration** | [`cmd/opencodereview/provider_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/cmd/opencodereview/provider_cmd.go) | Direct `Llm.URL`, `Llm.Model` settings bypassing abstractions |

When OCR starts a request, `llm.ResolveEndpoint()` executes this flow:

1. Loads [`config.json`](https://github.com/alibaba/open-code-review/blob/main/config.json) from `$XDG_CONFIG_HOME/ocr` or `~/.ocr` via `tryOCRConfig`
2. Looks up `cfg.Provider` against the built-in registry
3. Merges user overrides (URL, protocol, auth header, models)
4. Validates protocol via `ValidateProtocol`, auth via `NormalizeAuthHeader`, and model presence via `ModelListContains`
5. Returns a `ResolvedEndpoint` that [`internal/llm/client.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/client.go) uses for API calls

## Configuring a Custom Provider via JSON

The custom provider flow requires two mandatory fields. From [`resolver.go`](https://github.com/alibaba/open-code-review/blob/main/resolver.go) lines 15-22:

```go
// Custom provider: url and protocol are required; model can come from cfg.Model.
if entry.URL == "" || entry.Protocol == "" {
    return ResolvedEndpoint{}, false,
        fmt.Errorf("custom provider %q requires url and protocol fields", cfg.Provider)
}

```

Create or edit `~/.ocr/config.json` with this structure:

```json
{
  "provider": "my-ollama",
  "model": "llama3:8b",
  "custom_providers": {
    "my-ollama": {
      "url": "http://localhost:11434/v1",
      "protocol": "openai",
      "model": "llama3:8b",
      "auth_header": "authorization"
    }
  }
}

```

### Supported Configuration Fields

| Field | Required | Description |
|-------|----------|-------------|
| `url` | **Yes** | Full endpoint URL including API version path |
| `protocol` | **Yes** | One of `openai`, `anthropic`, `openai-responses` |
| `model` | No* | Default model; overrides global `config.model` |
| `models` | No | List of available models for validation |
| `auth_header` | No | Header name for API key (default: `authorization`) |
| `extra_body` | No | Additional JSON fields merged into request body |
| `extra_headers` | No | Additional HTTP headers |

*Required if not specified at top-level `config.model`.

## Using the Interactive Provider Wizard

OCR includes a TUI for provider management implemented in [`cmd/opencodereview/provider_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/cmd/opencodereview/provider_cmd.go). Launch it with:

```bash
ocr config provider

```

The wizard (`newProviderTUI`) guides you through:

1. Selecting **"Add custom provider"**
2. Entering a unique name (e.g., `my-vllm`)
3. Providing the endpoint URL
4. Choosing the protocol format
5. Specifying default model and optional authentication
6. Running `ocr llm test` automatically to validate connectivity

The wizard writes selections back via `applyCustomProviderConfig`, ensuring valid JSON structure.

## Validating and Testing Your Configuration

After configuration, verify your custom provider works:

```bash
ocr llm test

```

This command attempts a live request using the resolved endpoint. If the test fails, check:

- **URL accessibility**: Ensure the endpoint responds to HTTP requests
- **Protocol mismatch**: Confirm your server speaks the selected protocol format
- **Model availability**: Verify the model exists in your provider's model list
- **Authentication**: Check that `auth_header` matches your service's requirements

## Managing and Removing Custom Providers

### Update an existing provider

Edit `~/.ocr/config.json` directly or re-run `ocr config provider` to modify fields.

### Switch to a different provider

```bash
ocr config set provider=anthropic model=claude-sonnet-4-20250514

```

### Remove a custom provider

```bash
ocr config unset custom_providers.my-ollama

```

This clears the entry and, if it was active, triggers fallback to the previous selection per [`provider_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/provider_cmd.go) implementation.

## Key Implementation Files

Understanding these source files helps debug configuration issues:

- **[`internal/llm/providers.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/providers.go)**: Built-in registry with default URLs, supported models, and environment variable mappings
- **[`internal/llm/resolver.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/resolver.go)**: Core resolution logic including merge, validation, and `ResolvedEndpoint` construction
- **[`cmd/opencodereview/provider_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/cmd/opencodereview/provider_cmd.go)**: Interactive TUI and CLI commands for provider management
- **[`internal/llm/client.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/client.go)**: HTTP client that consumes `ResolvedEndpoint` for actual API calls

## Summary

- Open Code Review configures custom LLM providers through `custom_providers` in `~/.ocr/config.json`
- Required fields are **`url`** and **`protocol`**; optional fields include `model`, `models`, `auth_header`, `extra_body`, and `extra_headers`
- The **`ocr config provider`** wizard provides an interactive alternative to manual JSON editing
- Validation occurs through `ValidateProtocol`, `NormalizeAuthHeader`, and `ModelListContains` in [`resolver.go`](https://github.com/alibaba/open-code-review/blob/main/resolver.go)
- Use **`ocr llm test`** to verify connectivity after configuration changes

## Frequently Asked Questions

### What protocols does OCR support for custom providers?

OCR accepts `openai`, `anthropic`, and `openai-responses` as valid protocol values. The protocol determines request serialization format and response parsing logic in [`internal/llm/client.go`](https://github.com/alibaba/open-code-review/blob/main/internal/llm/client.go). Choose `openai` for OpenAI-compatible endpoints including Ollama, vLLM, and LiteLLM proxies.

### Can I use a custom provider without authentication?

Yes. Omit the `auth_header` field or leave it empty. If your endpoint requires no API key, OCR sends requests without authentication headers. For services using non-standard auth schemes, use `extra_headers` to inject custom header values.

### Where does OCR store configuration files?

OCR follows XDG Base Directory specification. It checks `$XDG_CONFIG_HOME/ocr/config.json` first, then falls back to `~/.ocr/config.json`. The CLI commands `ocr config` automatically read from and write to this location.

### How do I override a built-in provider's URL?

Add an entry under `providers` (not `custom_providers`) with the same name as the built-in preset. For example, override DashScope's endpoint by setting `providers.dashscope.url` in your config. This preserves the preset's model list and environment variable mapping while changing the target URL.