Thunderbolt Model Providers: Supported Services and Custom Integration Guide

Thunderbolt supports five built-in model providers including native Thunderbolt cloud, OpenAI, OpenRouter, Anthropic, and custom OpenAI-compatible endpoints, with custom providers configurable via base URL and optional API key in the settings interface.

Thunderbolt, the open-source AI chat client from the Thunderbird team, integrates with multiple model providers to deliver flexible LLM access. Understanding which model providers Thunderbolt supports and how to extend functionality with custom endpoints is essential for users seeking to integrate proprietary or locally-hosted models.

Built-in Model Providers Supported by Thunderbolt

The src/settings/models/index.tsx file defines five distinct provider types that Thunderbolt recognizes out of the box. Each provider implements different authentication and model discovery mechanisms.

Thunderbolt Native Cloud Service

The native Thunderbolt provider connects to Thunderbird's own cloud infrastructure. In src/settings/models/index.tsx (lines 16-21), the UI renders a hard-coded list of available models. No API key is required for this provider, as authentication is handled through the user's Thunderbird account session.

OpenAI

Thunderbolt integrates with OpenAI by calling the official https://api.openai.com/v1/models endpoint. As implemented in src/settings/models/index.tsx (lines 388-392), this provider requires a valid API key. The fetch logic retrieves the complete model catalog and filters it for compatible chat completions models.

OpenRouter

The OpenRouter provider offers access to a unified API for multiple LLM hosts. The implementation in src/settings/models/index.tsx (lines 402-406) queries https://openrouter.ai/api/v1/models and requires an API key. This provider enables access to models from Anthropic, Google, and other sources through a single endpoint.

Anthropic

Anthropic support uses a static list of Claude models rather than dynamic fetching. As shown in src/settings/models/index.tsx (lines 416-464), the provider maintains a hard-coded array of available Claude model identifiers. This approach ensures consistent model availability regardless of API response variations.

Custom OpenAI-Compatible Endpoints

The Custom provider accepts any OpenAI-compatible API endpoint. This flexible option, defined in src/settings/models/index.tsx (lines 394-410), allows integration with locally-hosted models (like Ollama or LM Studio) or private API gateways. The system automatically appends /v1/models to the provided base URL and supports optional Bearer token authentication.

How to Add Custom Model Providers in Thunderbolt

Adding a custom model provider requires configuring the base URL and optional authentication credentials through the settings interface. The form validation schema in src/settings/models/index.tsx (lines 48-80) enforces these requirements.

Step-by-Step Configuration

  1. Navigate to the Models settings page and click the "+" button to open the "Add Model" dialog.

  2. Select "Custom" from the Provider dropdown menu. The UI components in src/settings/models/index.tsx (lines 29-41) render the additional URL and API key input fields when this option is selected.

  3. Enter the base URL of your OpenAI-compatible endpoint (for example, http://localhost:11434/v1 for Ollama or http://localhost:1234/v1 for LM Studio).

  4. Optionally provide an API key if your endpoint requires authentication. The validation logic requires the apiKey field for all providers except thunderbolt and custom.

  5. Thunderbolt automatically fetches the available model list by appending /v1/models to your base URL and displaying the results.

  6. Select a model from the list or manually enter a custom model ID, provide a display name, and click "Add Model" to save the configuration.

Programmatic Implementation

For developers extending Thunderbolt, the createModelDAL function persists custom provider configurations to the local database. The following example demonstrates adding a custom provider programmatically:

import { createModelDAL } from '@/dal'
import { v7 as uuidv7 } from 'uuid'

async function addCustomModel() {
  await createModelDAL(db, {
    id: uuidv7(),
    provider: 'custom',               // Custom provider tag
    name: 'MyLocal Llama',
    model: 'llama-2-13b',            // Model ID recognized by endpoint
    url: 'http://localhost:11434/v1', // OpenAI-compatible base URL
    apiKey: null,                     // Optional authentication
    isSystem: 0,
    enabled: 1,
    toolUsage: 1,
    contextWindow: null,
  })
}

The system stores these values in the models table and retrieves them through src/ai/fetch.ts during chat sessions to construct the appropriate API requests.

Technical Implementation Details

Understanding the underlying architecture helps explain how Thunderbolt manages different provider types and where customization occurs.

Provider Selection UI

The provider dropdown component in src/settings/models/index.tsx (lines 15-21) defines the available options:

<Select onValueChange={field.onChange} value={field.value}>
  <SelectTrigger className="w-full rounded-lg">
    <SelectValue placeholder="Select provider" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="thunderbolt">Thunderbolt</SelectItem>
    <SelectItem value="openai">OpenAI</SelectItem>
    <SelectItem value="openrouter">OpenRouter</SelectItem>
    <SelectItem value="anthropic">Anthropic</SelectItem>
    <SelectItem value="custom">Custom</SelectItem>
  </SelectContent>
</Select>

Form Validation Schema

The Zod schema in src/settings/models/index.tsx (lines 48-80) enforces provider-specific validation rules:

const formSchema = z.object({
  provider: z.enum(['thunderbolt', 'anthropic', 'openai', 'custom', 'openrouter']),
  // …
}).refine(
  (data) => data.provider === 'custom' ? !!data.url?.length : true,
  { message: 'URL is required for Custom providers', path: ['url'] }
).refine(
  (data) => data.provider === 'thunderbolt' ? true
    : data.provider === 'custom' ? true
    : !!data.apiKey?.length,
  { message: 'API Key is required for this provider', path: ['apiKey'] }
)

This schema ensures that custom providers require a URL, while API keys are optional for custom endpoints but mandatory for OpenAI, OpenRouter, and Anthropic.

Fetch Logic for Custom Endpoints

The model fetching implementation in src/settings/models/index.tsx (lines 393-410) handles the custom provider logic:

case 'custom':
  if (url) {
    const baseUrl = url.endsWith('/v1') ? url
      : url.endsWith('/') ? `${url}v1` : `${url}/v1`
    endpoint = `${baseUrl}/models`
    if (apiKey) {
      headers = { Authorization: `Bearer ${apiKey}` }
    }
  }
  break
...
if (provider === 'custom' || apiKey) {
  const response = await http.get(endpoint, { headers, fetch }).json<{ data: AvailableModel[] }>()
  // transform and dispatch models
}

The http utility from src/lib/http.ts wraps the native fetch API with application-wide error handling. For custom providers, Thunderbolt automatically normalizes the base URL to ensure proper /v1/models endpoint construction.

Summary

  • Thunderbolt supports five model providers: native Thunderbolt cloud, OpenAI, OpenRouter, Anthropic, and custom OpenAI-compatible endpoints.
  • Custom providers require a base URL (e.g., http://localhost:11434/v1) and optionally an API key, with Thunderbolt automatically fetching available models via the /v1/models endpoint.
  • The provider configuration uses Zod validation in src/settings/models/index.tsx to enforce URL requirements for custom providers and API key requirements for commercial services.
  • Programmatic addition of custom providers uses the createModelDAL function with provider: 'custom' and appropriate url and apiKey fields.

Frequently Asked Questions

What is the exact URL format required for custom model providers in Thunderbolt?

Thunderbolt accepts any base URL pointing to an OpenAI-compatible API endpoint. The system automatically normalizes the URL by appending /v1/models for the model list fetch. For example, if you input http://localhost:11434, Thunderbolt converts this to http://localhost:11434/v1/models. If your endpoint already includes /v1 (such as http://localhost:11434/v1), the system preserves this structure.

Does Thunderbolt require an API key for custom providers?

No, API keys are optional for custom providers. The Zod validation schema in src/settings/models/index.tsx specifically exempts the custom provider from the API key requirement while mandating it for OpenAI, OpenRouter, and Anthropic. If your custom endpoint requires authentication, you can supply a Bearer token in the API key field, which Thunderbolt includes in the Authorization header when fetching models and during chat completion requests.

Which file handles the list of built-in model providers?

The supported providers are defined in the UI component located at src/settings/models/index.tsx. Lines 15-21 contain the Select component that enumerates the five available options: thunderbolt, openai, openrouter, anthropic, and custom. The same file contains the provider-specific fetching logic (lines 388-464) that determines how to retrieve model lists for each provider type, including the OpenAI-compatible endpoint normalization for custom providers.

Can I use Thunderbolt with locally hosted LLMs like Ollama or LM Studio?

Yes, Thunderbolt's custom provider support is specifically designed for locally-hosted OpenAI-compatible servers. To connect to Ollama, configure the custom provider with the URL http://localhost:11434/v1 (or http://localhost:11434 which Thunderbolt normalizes automatically). For LM Studio, use the local server URL provided by the application (typically http://localhost:1234/v1). Since these local servers usually don't require authentication, you can leave the API key field empty, leveraging the optional authentication support in the custom provider implementation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →