# How to Configure Custom AI Providers (Gemini, OpenRouter) in Claude-Mem

> Easily configure custom AI providers like Gemini and OpenRouter in Claude-Mem. Set your provider and API keys in settings.json for a personalized AI experience.

- Repository: [Alex Newman/claude-mem](https://github.com/thedotmack/claude-mem)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Configure custom AI providers in Claude-Mem by setting `CLAUDE_MEM_PROVIDER` to `"gemini"` or `"openrouter"` in `~/.claude-mem/settings.json` and providing the corresponding API keys.**

Claude-Mem, an open-source memory layer for Claude Desktop, supports multiple LLM backends for its observation-extraction workflow. Beyond the default Claude SDK, you can route all AI operations through Google Gemini or any model available on the OpenRouter marketplace. This guide explains the configuration schema, agent implementations, and step-by-step setup based on the `thedotmack/claude-mem` source code.

## Settings-Driven Provider Selection

All provider configuration resides in the persistent settings JSON file located at `~/.claude-mem/settings.json`. The system uses a cascading priority: explicit settings values override environment variables, which in turn override hardcoded defaults.

The central schema is defined in [`src/shared/SettingsDefaultsManager.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/shared/SettingsDefaultsManager.ts). Key configuration fields include:

- `CLAUDE_MEM_PROVIDER` – Backend selector (`"claude"`, `"gemini"`, or `"openrouter"`)
- `CLAUDE_MEM_GEMINI_API_KEY` – Gemini API key (falls back to `GEMINI_API_KEY` env var)
- `CLAUDE_MEM_GEMINI_MODEL` – Model identifier (default: `gemini-2.5-flash-lite`)
- `CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED` – Free-tier throttling toggle
- `CLAUDE_MEM_OPENROUTER_API_KEY` – OpenRouter key (falls back to `OPENROUTER_API_KEY`)
- `CLAUDE_MEM_OPENROUTER_MODEL` – Model path (default: `xiaomi/mimo-v2-flash:free`)
- `CLAUDE_MEM_OPENROUTER_SITE_URL` and `CLAUDE_MEM_OPENROUTER_APP_NAME` – Analytics headers
- `CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES` and `CLAUDE_MEM_OPENROUTER_MAX_TOKENS` – Context window limits

The UI layer consumes these defaults through the `useSettings` hook in [`src/ui/viewer/hooks/useSettings.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/ui/viewer/hooks/useSettings.ts), rendering an editable form in [`src/ui/viewer/components/ContextSettingsModal.tsx`](https://github.com/thedotmack/claude-mem/blob/main/src/ui/viewer/components/ContextSettingsModal.tsx).

At runtime, [`src/services/worker-service.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/services/worker-service.ts) (lines 224-228) selects the active agent:

```typescript
if (isOpenRouterSelected() && isOpenRouterAvailable()) provider = 'openrouter';
else if (isGeminiSelected() && isGeminiAvailable()) provider = 'gemini';
else provider = 'claude';

```

The boolean helpers and configuration loaders reside adjacent to the agent implementations in [`src/services/worker/OpenRouterAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/services/worker/OpenRouterAgent.ts) and [`src/services/worker/GeminiAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/services/worker/GeminiAgent.ts).

## Configuring Google Gemini

### Required Settings

To enable Gemini, set `CLAUDE_MEM_PROVIDER` to `"gemini"` and provide a valid API key via `CLAUDE_MEM_GEMINI_API_KEY` or the `GEMINI_API_KEY` environment variable. The default model is `gemini-2.5-flash-lite`, optimized for low-latency observation extraction.

### Model Validation and Rate Limiting

The `GeminiAgent` class validates model names against an internal whitelist in `getGeminiConfig()` (lines 99-106 of [`src/services/worker/GeminiAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/services/worker/GeminiAgent.ts)). If `CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED` is `"true"` (the default), the agent enforces per-model RPM limits defined in `GEMINI_RPM_LIMITS`, sleeping between requests to stay within free-tier quotas.

The `queryGeminiMultiTurn()` method constructs the prompt, POSTs to `https://generativelanguage.googleapis.com/v1/models/<model>:generateContent`, and parses the XML-styled observation response into `{content, tokensUsed}`.

## Configuring OpenRouter

### Required Settings

Set `CLAUDE_MEM_PROVIDER` to `"openrouter"` and supply `CLAUDE_MEM_OPENROUTER_API_KEY` (or `OPENROUTER_API_KEY` env var). The default model is `xiaomi/mimo-v2-flash:free`, a cost-effective option for high-volume extraction.

### Context Window Management

Before each request, `OpenRouterAgent.truncateHistory()` enforces dual limits: `CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES` (message count) and `CLAUDE_MEM_OPENROUTER_MAX_TOKENS` (estimated token budget). This prevents runaway costs on models with large context windows. The configuration is loaded in `getOpenRouterConfig()` (lines 38-54 of [`src/services/worker/OpenRouterAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/src/services/worker/OpenRouterAgent.ts)).

### Fallback Handling

If a request fails with a non-abort error, `shouldFallbackToClaude(error)` evaluates whether to switch to the Claude provider. When `this.fallbackAgent` is set, the session hands off to `this.fallbackAgent.startSession()`, ensuring continuity even if OpenRouter is unavailable.

## Step-by-Step Configuration Guide

1. **Open the Settings UI** in Claude-Mem and navigate to the Provider section.
2. **Select the provider** from the dropdown: choose **Gemini** or **OpenRouter**.
3. **Enter API credentials** in the provided fields, or set `GEMINI_API_KEY` / `OPENROUTER_API_KEY` in `~/.claude-mem/.env` for secure storage.
4. **Specify the model** identifier (optional). Use `gemini-2.5-flash-lite` for Gemini or `xiaomi/mimo-v2-flash:free` for OpenRouter defaults, or substitute any valid model path.
5. **Adjust advanced options**:
   - For Gemini: toggle **Rate Limiting** if using paid tiers.
   - For OpenRouter: set **Max Context Messages** and **Max Tokens** to cap costs.
6. **Save the configuration**. The UI persists changes to `~/.claude-mem/settings.json` via the `saveSettings` method in [`useSettings.ts`](https://github.com/thedotmack/claude-mem/blob/main/useSettings.ts).
7. **Restart the worker** (or wait for the next automatic restart) to activate the new provider. The [`worker-service.ts`](https://github.com/thedotmack/claude-mem/blob/main/worker-service.ts) constructor reads the updated settings and instantiates the appropriate agent.

## Configuration Examples

### Gemini Configuration

```json
{
  "CLAUDE_MEM_PROVIDER": "gemini",
  "CLAUDE_MEM_GEMINI_API_KEY": "YOUR_GEMINI_API_KEY",
  "CLAUDE_MEM_GEMINI_MODEL": "gemini-2.5-flash-lite",
  "CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED": "false"
}

```

### OpenRouter Configuration

```json
{
  "CLAUDE_MEM_PROVIDER": "openrouter",
  "CLAUDE_MEM_OPENROUTER_API_KEY": "YOUR_OPENROUTER_API_KEY",
  "CLAUDE_MEM_OPENROUTER_MODEL": "anthropic/claude-3-opus:free",
  "CLAUDE_MEM_OPENROUTER_SITE_URL": "https://my-site.example",
  "CLAUDE_MEM_OPENROUTER_APP_NAME": "my-claude-mem-app",
  "CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES": "15",
  "CLAUDE_MEM_OPENROUTER_MAX_TOKENS": "80000"
}

```

### Environment Variable Fallback

Create `~/.claude-mem/.env` to keep credentials out of JSON:

```dotenv
GEMINI_API_KEY=sk-your-gemini-key
OPENROUTER_API_KEY=or-your-router-key

```

The `getCredential` helper checks environment variables before falling back to the settings JSON file.

## Summary

- **Provider selection** is controlled by the `CLAUDE_MEM_PROVIDER` setting in `~/.claude-mem/settings.json`, read by [`SettingsDefaultsManager.ts`](https://github.com/thedotmack/claude-mem/blob/main/SettingsDefaultsManager.ts) and applied in [`worker-service.ts`](https://github.com/thedotmack/claude-mem/blob/main/worker-service.ts).
- **Gemini integration** requires `CLAUDE_MEM_GEMINI_API_KEY` and optionally `CLAUDE_MEM_GEMINI_MODEL`, with built-in rate-limiting for free tiers managed by [`GeminiAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/GeminiAgent.ts).
- **OpenRouter integration** requires `CLAUDE_MEM_OPENROUTER_API_KEY`, supports context window caps via `CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES` and `CLAUDE_MEM_OPENROUTER_MAX_TOKENS`, and implements Claude fallback logic in [`OpenRouterAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/OpenRouterAgent.ts).
- **Environment variables** (`GEMINI_API_KEY`, `OPENROUTER_API_KEY`) take precedence over JSON settings for secure credential management.
- **UI workflow**: Change provider in [`ContextSettingsModal.tsx`](https://github.com/thedotmack/claude-mem/blob/main/ContextSettingsModal.tsx), persist via [`useSettings.ts`](https://github.com/thedotmack/claude-mem/blob/main/useSettings.ts), and restart the worker to activate the new agent.

## Frequently Asked Questions

### How do I switch back to the default Claude provider?

Set `CLAUDE_MEM_PROVIDER` to `"claude"` in your [`settings.json`](https://github.com/thedotmack/claude-mem/blob/main/settings.json) file, or select **Claude** from the provider dropdown in the Settings UI. The [`worker-service.ts`](https://github.com/thedotmack/claude-mem/blob/main/worker-service.ts) automatically defaults to the built-in Claude SDK when Gemini or OpenRouter are not selected or unavailable.

### Can I use environment variables instead of the settings JSON file?

Yes. The credential helpers in [`GeminiAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/GeminiAgent.ts) and [`OpenRouterAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/OpenRouterAgent.ts) check for `GEMINI_API_KEY` and `OPENROUTER_API_KEY` environment variables (or values in `~/.claude-mem/.env`) before reading `CLAUDE_MEM_GEMINI_API_KEY` or `CLAUDE_MEM_OPENROUTER_API_KEY` from the JSON settings. This allows you to keep sensitive keys out of version-controlled configuration files.

### What happens if my OpenRouter request fails?

The [`OpenRouterAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/OpenRouterAgent.ts) implements automatic fallback logic. If a request returns a non-abort error (such as an authentication failure or rate limit), the `shouldFallbackToClaude(error)` method evaluates whether to switch providers. When a fallback agent is configured, the session hands off to the Claude provider via `this.fallbackAgent.startSession()`, ensuring observation extraction continues even if OpenRouter is temporarily unavailable.

### Does Gemini support custom model names?

Yes, but with validation. When you specify a model in `CLAUDE_MEM_GEMINI_MODEL`, the `getGeminiConfig()` method in [`GeminiAgent.ts`](https://github.com/thedotmack/claude-mem/blob/main/GeminiAgent.ts) validates it against an internal whitelist. You can use any valid Gemini model identifier (such as `gemini-2.5-flash-lite` or `gemini-3-flash-preview`), but invalid model names will be rejected before the API call is attempted.