# How to Configure Multiple AI Providers for Server-Side Models in Next AI Draw.io

> Learn how to configure multiple AI providers for server-side models in Next AI Draw.io. Discover its layered system merging env vars, JSON files, and UI settings.

- Repository: [Dayuan Jiang/next-ai-draw-io](https://github.com/DayuanJiang/next-ai-draw-io)
- Tags: how-to-guide
- Published: 2026-07-13

---

**Next AI Draw.io supports multiple AI providers through a layered configuration system that merges environment variables, JSON configuration files, and admin UI settings, defined primarily in [`lib/server-model-config.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/server-model-config.ts).**

The DayuanJiang/next-ai-draw-io repository enables self-hosted AI diagram generation by supporting simultaneous connections to multiple LLM providers. Configuring multiple AI providers for server-side models allows you to load-balance across different API keys, route specific models to distinct endpoints, and maintain fallback options for high-availability deployments.

## Configuration Hierarchy and Priority

The configuration loader implements a three-tier priority system defined in [`lib/server-model-config.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/server-model-config.ts). The system merges these sources with any providers added through the admin interface, which are stored in [`settings.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/settings.json) under the `ADMIN_PROVIDERS` key.

### High-Priority Environment Variables

The `AI_MODELS_CONFIG` environment variable accepts a JSON string containing the full provider array. This takes precedence over all other configuration methods.

### Static Configuration Files

If the environment variable is unset, the system looks for [`ai-models.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/ai-models.json) at the repository root, or at a custom path specified by `AI_MODELS_CONFIG_PATH`.

### Legacy Fallback Options

As a final fallback, the system parses comma-separated values from `AI_MODEL` and `AI_PROVIDER` to create a single provider entry.

## Provider Schema and Model Flattening

Each provider must conform to the `ServerProviderSchema` defined in [`lib/server-model-config.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/server-model-config.ts):

```typescript
// lib/server-model-config.ts
export const ServerProviderSchema = z.object({
    name: z.string().min(1),               // Display name (shown in UI)
    provider: ProviderNameSchema,          // e.g. "openai", "anthropic", "ollama"
    models: z.array(z.string().min(1)),    // Model IDs you want to expose
    apiKeyEnv: z.union([z.string(), z.array(z.string())]).optional(),
    baseUrlEnv: z.string().optional(),
    default: z.boolean().optional(),
})

```

The `loadFlattenedServerModels()` function transforms each provider entry into unique model identifiers following the pattern `server:${slugified-name}:${modelId}`, where the slug is generated by lowercasing the name and replacing non-alphanumeric characters with hyphens. The resulting `FlattenedServerModel` objects contain resolved `apiKeyEnv` and `baseUrlEnv` fields that request handlers use to instantiate SDKs.

## Defining Multiple Providers via Environment Variables

Create an [`ai-models.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/ai-models.json) file or set `AI_MODELS_CONFIG` with an array of provider objects:

```json
{
  "providers": [
    {
      "name": "OpenAI Production",
      "provider": "openai",
      "models": ["gpt-4o", "gpt-4o-mini"],
      "apiKeyEnv": "OPENAI_API_KEY_PROD",
      "default": true
    },
    {
      "name": "Ollama Local",
      "provider": "ollama",
      "models": ["llama2:7b"],
      "baseUrlEnv": "OLLAMA_BASE_URL"
    }
  ]
}

```

Export the corresponding environment variables in your deployment environment. The `default` flag marks the first model of that provider as the server-wide default when no explicit `AI_PROVIDER` or `AI_MODEL` is set.

### Load Balancing with Multiple API Keys

The `apiKeyEnv` field accepts either a string or an array of strings. When an array is provided, the system selects the first non-empty value, enabling automatic failover across multiple keys:

```json
{
  "name": "OpenAI – Team B",
  "provider": "openai",
  "models": ["gpt-4o-mini"],
  "apiKeyEnv": ["OPENAI_API_KEY_B_1", "OPENAI_API_KEY_B_2"]
}

```

## Admin UI Provider Management

The administrative interface writes provider configurations to [`settings.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/settings.json) as a JSON string under `ADMIN_PROVIDERS`. The `adminProvidersToConfig()` function in [`lib/admin/providers.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/admin/providers.ts) converts these entries into the standard configuration format, automatically generating environment variable names such as `ADMIN_OPENAI_API_KEY_2` or `ADMIN_ANTHROPIC_BASE_URL`.

When you mark a provider as `isDefault: true` in the UI, `deriveEnvUpdates()` writes `AI_PROVIDER` and `AI_MODEL` environment variables to designate that model as the server-wide default.

### Validation and Security

When adding providers through the UI, the `/api/validate-model` endpoint in [`app/api/validate-model/route.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/app/api/validate-model/route.ts) performs credential validation. This route:

1. **Blocks SSRF attacks** by rejecting private URLs when `isPrivateUrl()` detects an internal address and `allowPrivateUrls()` returns false.
2. **Instantiates the correct SDK** (OpenAI, Anthropic, Ollama, etc.) using the supplied credentials.
3. **Performs a test request** using `generateText({ prompt: "Say 'OK'" })` to confirm connectivity.

If validation fails, the endpoint returns a user-friendly error before persisting the configuration.

## Runtime SDK Instantiation

During chat requests, [`app/api/chat/route.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/app/api/chat/route.ts) calls `findServerModelById()` to locate the provider configuration. The handler reads the resolved `apiKeyEnv` and `baseUrlEnv` values from `process.env` to instantiate the correct SDK.

For Ollama deployments, the system supports multiple instances through distinct environment variable mappings:

```typescript
// app/api/chat/route.ts (excerpt)
const ollamaApiKey = baseUrl
    ? apiKey || undefined
    : apiKey || process.env.OLLAMA_API_KEY || undefined
const ollamaProvider = createOllama({
    baseURL: baseUrl || process.env.OLLAMA_BASE_URL || "https://ollama.com/api",
    ...(ollamaApiKey && { headers: { Authorization: `Bearer ${ollamaApiKey}` } })
})

```

You can define separate Ollama providers by assigning each a unique `baseUrlEnv` and `apiKeyEnv` in your configuration file.

## Summary

- Next AI Draw.io uses a layered configuration system in [`lib/server-model-config.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/server-model-config.ts) that prioritizes `AI_MODELS_CONFIG` environment variables, then [`ai-models.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/ai-models.json), then legacy fallbacks.
- Provider definitions use the `ServerProviderSchema` with support for custom `apiKeyEnv` and `baseUrlEnv` mappings to handle multiple API keys and endpoints per provider.
- The `loadFlattenedServerModels()` function generates unique IDs in the format `server:${slugified-name}:${modelId}` for each available model.
- Admin UI providers are stored in [`settings.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/settings.json) and converted via `adminProvidersToConfig()` in [`lib/admin/providers.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/admin/providers.ts), with automatic environment variable generation.
- The `/api/validate-model` endpoint enforces SSRF protection via `isPrivateUrl()` and validates credentials before persisting new providers.
- Runtime handlers in [`app/api/chat/route.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/app/api/chat/route.ts) resolve environment variables and instantiate SDKs using the flattened model configuration returned by `findServerModelById()`.

## Frequently Asked Questions

### What is the priority order for configuration sources?

The system evaluates sources in three tiers: first the `AI_MODELS_CONFIG` environment variable, second the [`ai-models.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/ai-models.json) file, and third the comma-separated `AI_MODEL` and `AI_PROVIDER` fallback. Admin UI configurations stored in [`settings.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/settings.json) are merged with these sources via `loadRawServerModelsConfig()` in [`lib/server-model-config.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/server-model-config.ts).

### How do I configure multiple API keys for the same provider?

Set `apiKeyEnv` to an array of environment variable names in your [`ai-models.json`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/ai-models.json) configuration. The runtime loader in [`lib/server-model-config.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/server-model-config.ts) selects the first non-empty value, enabling automatic failover and load balancing across multiple keys for high-throughput deployments.

### Can I use private or internal URLs for self-hosted models?

Yes, but only if the server permits private URL access. The validation endpoint in [`app/api/validate-model/route.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/app/api/validate-model/route.ts) checks `isPrivateUrl()` and `allowPrivateUrls()` before accepting custom base URLs, preventing SSRF attacks against internal networks when private access is disabled.

### How does the system handle default model selection?

Mark a provider with `"default": true` in the JSON configuration file, or set `isDefault: true` in the admin UI. When using the UI, `deriveEnvUpdates()` in [`lib/admin/providers.ts`](https://github.com/DayuanJiang/next-ai-draw-io/blob/main/lib/admin/providers.ts) automatically writes `AI_PROVIDER` and `AI_MODEL` environment variables to designate that model as the server-wide default when users don't specify an explicit model.