How to Configure Custom AI Providers (Gemini, OpenRouter) in Claude-Mem
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. Key configuration fields include:
CLAUDE_MEM_PROVIDER– Backend selector ("claude","gemini", or"openrouter")CLAUDE_MEM_GEMINI_API_KEY– Gemini API key (falls back toGEMINI_API_KEYenv var)CLAUDE_MEM_GEMINI_MODEL– Model identifier (default:gemini-2.5-flash-lite)CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED– Free-tier throttling toggleCLAUDE_MEM_OPENROUTER_API_KEY– OpenRouter key (falls back toOPENROUTER_API_KEY)CLAUDE_MEM_OPENROUTER_MODEL– Model path (default:xiaomi/mimo-v2-flash:free)CLAUDE_MEM_OPENROUTER_SITE_URLandCLAUDE_MEM_OPENROUTER_APP_NAME– Analytics headersCLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGESandCLAUDE_MEM_OPENROUTER_MAX_TOKENS– Context window limits
The UI layer consumes these defaults through the useSettings hook in src/ui/viewer/hooks/useSettings.ts, rendering an editable form in src/ui/viewer/components/ContextSettingsModal.tsx.
At runtime, src/services/worker-service.ts (lines 224-228) selects the active agent:
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 and 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). 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).
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
- Open the Settings UI in Claude-Mem and navigate to the Provider section.
- Select the provider from the dropdown: choose Gemini or OpenRouter.
- Enter API credentials in the provided fields, or set
GEMINI_API_KEY/OPENROUTER_API_KEYin~/.claude-mem/.envfor secure storage. - Specify the model identifier (optional). Use
gemini-2.5-flash-litefor Gemini orxiaomi/mimo-v2-flash:freefor OpenRouter defaults, or substitute any valid model path. - Adjust advanced options:
- For Gemini: toggle Rate Limiting if using paid tiers.
- For OpenRouter: set Max Context Messages and Max Tokens to cap costs.
- Save the configuration. The UI persists changes to
~/.claude-mem/settings.jsonvia thesaveSettingsmethod inuseSettings.ts. - Restart the worker (or wait for the next automatic restart) to activate the new provider. The
worker-service.tsconstructor reads the updated settings and instantiates the appropriate agent.
Configuration Examples
Gemini Configuration
{
"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
{
"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:
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_PROVIDERsetting in~/.claude-mem/settings.json, read bySettingsDefaultsManager.tsand applied inworker-service.ts. - Gemini integration requires
CLAUDE_MEM_GEMINI_API_KEYand optionallyCLAUDE_MEM_GEMINI_MODEL, with built-in rate-limiting for free tiers managed byGeminiAgent.ts. - OpenRouter integration requires
CLAUDE_MEM_OPENROUTER_API_KEY, supports context window caps viaCLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGESandCLAUDE_MEM_OPENROUTER_MAX_TOKENS, and implements Claude fallback logic inOpenRouterAgent.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, persist viauseSettings.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 file, or select Claude from the provider dropdown in the Settings UI. The 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 and 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 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 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →