Skip to content

OpenCode CLI Multi-Provider Setup: Configure All AI Providers in One Place

I was tired of managing separate configurations for each AI coding assistant. Claude here, GPT there, Gemini somewhere else. Every time I wanted to switch providers, I had to remember different config file locations, different API key formats, different model names.

Then I discovered OpenCode CLI supports multiple providers in a single configuration file. But the documentation didn’t make the setup process clear, especially for combining cloud and local models.

After several hours of trial and error, I finally got it working. Here’s what I learned.

The Problem: Juggling Multiple AI Assistants

I have accounts with Anthropic, OpenAI, and Google. I also run Ollama locally for privacy-sensitive work. Each provider has its strengths:

  • Claude: Best reasoning, great for complex refactoring
  • GPT: Extensive tool support, reliable for simple tasks
  • Gemini: Competitive pricing, good multimodal capabilities
  • Ollama: Privacy, no rate limits, free after hardware costs

Switching between them was painful. Different config files, different commands, different environment variables. I wanted a unified interface.

Understanding OpenCode Provider Architecture

OpenCode CLI uses a single opencode.json configuration file. By default, it looks for this file in:

  • ~/.opencode/opencode.json (global)
  • ./opencode.json (project-specific)

The configuration supports two types of providers:

  1. Built-in providers: Anthropic, OpenAI, Google Gemini, AWS Bedrock, Azure OpenAI
  2. OpenAI-compatible providers: Ollama, LM Studio, llama.cpp, any custom endpoint

Here’s the architecture:

┌─────────────────────────────────────────────────────────┐
│ opencode.json │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Anthropic │ │ OpenAI │ │ Gemini │ │
│ │ (built-in) │ │ (built-in) │ │ (built-in) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Ollama │ │ LM Studio │ │ llama.cpp │ │
│ │ (compatible)│ │ (compatible)│ │ (compatible)│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
/models command
or CLI flags

Setting Up Cloud Providers

Anthropic Configuration

First, I tried to add Anthropic. The API key format was confusing at first.

terminal
# Set your API key as environment variable
export ANTHROPIC_API_KEY=sk-ant-...

Then in opencode.json:

~/.opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"anthropic": {
"options": {
"apiKey": "{env:ANTHROPIC_API_KEY}",
"timeout": 600000
}
}
}
}

The {env:VARIABLE_NAME} syntax is critical. Never hardcode API keys directly in the config file. I made that mistake initially and almost committed my key to a public repo.

For Claude models with thinking capabilities, you need additional model configuration:

~/.opencode/opencode.json
{
"provider": {
"anthropic": {
"options": {
"apiKey": "{env:ANTHROPIC_API_KEY}"
},
"models": {
"claude-sonnet-4-5-20250929": {
"options": {
"thinking": {
"type": "enabled",
"budgetTokens": 16000
}
}
}
}
}
}
}

OpenAI Configuration

OpenAI setup is similar:

terminal
export OPENAI_API_KEY=sk-...
~/.opencode/opencode.json
{
"provider": {
"openai": {
"options": {
"apiKey": "{env:OPENAI_API_KEY}",
"baseURL": "https://api.openai.com/v1"
},
"models": {
"gpt-5": {
"options": {
"reasoningEffort": "high",
"textVerbosity": "low"
}
}
}
}
}
}

I initially forgot the baseURL and got connection errors. It’s technically optional for OpenAI, but being explicit helps when debugging.

AWS Bedrock Configuration

Bedrock was trickier because it uses IAM profiles instead of API keys:

terminal
export AWS_PROFILE=my-aws-profile
export AWS_REGION=us-east-1
~/.opencode/opencode.json
{
"provider": {
"amazon-bedrock": {
"options": {
"region": "{env:AWS_REGION}",
"profile": "{env:AWS_PROFILE}",
"endpoint": "https://bedrock-runtime.us-east-1.vpce-xxx.amazonaws.com"
}
}
}
}

The endpoint is optional but useful if you’re using VPC endpoints for enterprise compliance.

Setting Up Local Models

This is where I had the most trouble. Local models use the @ai-sdk/openai-compatible package, which wasn’t obvious from the documentation.

Ollama Integration

First, ensure Ollama is running:

terminal
# Start Ollama server
ollama serve
# Pull a model
ollama pull llama2
ollama pull codellama

The configuration uses the OpenAI-compatible adapter:

~/.opencode/opencode.json
{
"provider": {
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama (local)",
"options": {
"baseURL": "http://localhost:11434/v1"
},
"models": {
"llama2": {
"name": "Llama 2"
},
"codellama": {
"name": "Code Llama"
}
}
}
}
}

Common mistake: I initially used http://localhost:11434 (without /v1). The /v1 suffix is required because OpenCode expects an OpenAI-compatible API.

LM Studio Setup

LM Studio provides a GUI for downloading and running models. Start the local server first:

  1. Open LM Studio
  2. Go to the “Local Server” tab
  3. Start the server on port 1234
~/.opencode/opencode.json
{
"provider": {
"lmstudio": {
"npm": "@ai-sdk/openai-compatible",
"name": "LM Studio (local)",
"options": {
"baseURL": "http://127.0.0.1:1234/v1"
},
"models": {
"google/gemma-3n-e4b": {
"name": "Gemma 3n-e4b (local)"
}
}
}
}
}

llama.cpp Configuration

For llama.cpp, start the server with OpenAI-compatible mode:

terminal
llama-server -m model.gguf --port 8080 --host 127.0.0.1
~/.opencode/opencode.json
{
"provider": {
"llama.cpp": {
"npm": "@ai-sdk/openai-compatible",
"name": "llama-server (local)",
"options": {
"baseURL": "http://127.0.0.1:8080/v1"
},
"models": {
"qwen3-coder:a3b": {
"name": "Qwen3-Coder: a3b-30b (local)",
"limit": {
"context": 128000,
"output": 65536
}
}
}
}
}
}

The limit configuration is important for local models. Without it, OpenCode may request more tokens than your model supports, causing silent failures.

The Complete Multi-Provider Configuration

After all my experimentation, here’s my working configuration:

~/.opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"anthropic": {
"options": {
"apiKey": "{env:ANTHROPIC_API_KEY}",
"timeout": 600000
},
"models": {
"claude-sonnet-4-5-20250929": {
"options": {
"thinking": {
"type": "enabled",
"budgetTokens": 16000
}
}
}
}
},
"openai": {
"options": {
"apiKey": "{env:OPENAI_API_KEY}",
"baseURL": "https://api.openai.com/v1"
},
"models": {
"gpt-5": {
"options": {
"reasoningEffort": "high",
"textVerbosity": "low"
}
}
}
},
"amazon-bedrock": {
"options": {
"region": "{env:AWS_REGION}",
"profile": "{env:AWS_PROFILE}"
}
},
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama (local)",
"options": {
"baseURL": "http://localhost:11434/v1"
},
"models": {
"llama2": {
"name": "Llama 2"
},
"codellama": {
"name": "Code Llama"
}
}
},
"lmstudio": {
"npm": "@ai-sdk/openai-compatible",
"name": "LM Studio (local)",
"options": {
"baseURL": "http://127.0.0.1:1234/v1"
},
"models": {
"google/gemma-3n-e4b": {
"name": "Gemma 3n-e4b (local)"
}
}
},
"llama.cpp": {
"npm": "@ai-sdk/openai-compatible",
"name": "llama-server (local)",
"options": {
"baseURL": "http://127.0.0.1:8080/v1"
},
"models": {
"qwen3-coder:a3b": {
"name": "Qwen3-Coder: a3b-30b (local)",
"limit": {
"context": 128000,
"output": 65536
}
}
}
}
}
}

Switching Between Providers

Now comes the satisfying part. With all providers configured, switching is instant.

Interactive Mode

Inside OpenCode’s interactive session:

OpenCode interactive session
> /models

This opens a searchable list of all configured models across all providers. Select one, and you’re switched.

CLI Flags

For scripting or one-off commands:

terminal
# Use Anthropic Claude
opencode run "Explain this code" --model anthropic/claude-sonnet-4-5
# Use local Ollama
opencode run "Refactor this function" --model ollama/llama2
# List all models
opencode models
# List models from specific provider
opencode models anthropic
opencode models ollama

Troubleshooting Common Issues

Connection Refused for Local Models

Symptom: ECONNREFUSED errors when using Ollama/LM Studio.

Cause: The local server isn’t running or is on a different port.

terminal
# Check if Ollama is running
curl http://localhost:11434/api/tags
# Check if LM Studio is running
curl http://127.0.0.1:1234/v1/models

API Authentication Failures

Symptom: 401 Unauthorized or Invalid API key.

Cause: Environment variable not set or wrong variable name.

terminal
# Verify environment variables
echo $ANTHROPIC_API_KEY
echo $OPENAI_API_KEY
# Common mistake: using wrong variable name
# Wrong: ANTHROPIC_KEY (missing API_)
# Right: ANTHROPIC_API_KEY

Model Not Found

Symptom: Model not found error.

Cause: Model name in config doesn’t match what the provider exposes.

terminal
# For Ollama, list available models
ollama list
# For OpenAI-compatible endpoints
curl http://localhost:11434/v1/models

Context Limit Exceeded

Symptom: Silent failures or truncated responses from local models.

Cause: Missing limit configuration for local models.

Add the limit block to your model configuration:

{
"models": {
"my-model": {
"limit": {
"context": 128000,
"output": 4096
}
}
}
}

Security Best Practices

I almost made a critical mistake early on: hardcoding API keys in the config file. Here’s what I learned:

  1. Always use environment variables: The {env:VAR_NAME} syntax keeps secrets out of your config.

  2. Never commit opencode.json with keys: Even with environment variables, be careful. Use a .gitignore entry.

  3. Use separate profiles for different environments: I have different AWS profiles for dev and prod.

  4. Rotate keys regularly: If you accidentally expose a key, rotate it immediately.

terminal
# Add to your shell profile
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
export AWS_PROFILE=my-profile
export AWS_REGION=us-east-1
# Optional: enable experimental models
export OPENCODE_ENABLE_EXPERIMENTAL_MODELS=true

Adding Custom OpenAI-Compatible Providers

If you use a provider not listed here, you can add it as long as it offers an OpenAI-compatible API:

~/.opencode/opencode.json
{
"provider": {
"myprovider": {
"npm": "@ai-sdk/openai-compatible",
"name": "My Custom Provider",
"options": {
"baseURL": "https://api.myprovider.com/v1"
},
"models": {
"my-model-name": {
"name": "My Model Display Name"
}
}
}
}
}

Why This Matters

Multi-provider setup isn’t just about convenience. It’s about:

  • Cost optimization: Use cheaper models for simple tasks, premium models for complex reasoning
  • Reliability: When one provider has an outage, switch to another
  • Privacy: Keep sensitive code on local models, use cloud for general tasks
  • Flexibility: Access unique capabilities (Claude’s thinking, GPT’s tool support) as needed

The Reddit community emphasizes this flexibility as a key advantage: “The best part is having so many different inference providers that you’re never going to run out of them.”

Key Takeaways

  1. Use {env:VAR_NAME} syntax for all API keys
  2. Local models require the @ai-sdk/openai-compatible adapter
  3. The /v1 suffix is required for OpenAI-compatible endpoints
  4. Set limit values for local models to prevent context overflow
  5. Use /models command to switch providers interactively

OpenCode CLI’s multi-provider support eliminated my configuration sprawl. One file, all providers, secure by default. Start with one provider and expand as your needs grow.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments