Date: 2026-01-25
Patch to enable claude-mem to use local LM Studio models instead of cloud APIs.
Claude-mem's OpenRouter provider requires an API key and only supports the cloud endpoint (https://openrouter.ai/api/v1). No option to point to local OpenAI-compatible APIs like LM Studio.
Added CLAUDE_MEM_OPENROUTER_BASE_URL setting and modified the availability check to allow local endpoints without an API key.
Added new setting to interface and defaults:
// In SettingsDefaults interface:
CLAUDE_MEM_OPENROUTER_BASE_URL: string; // Custom base URL (e.g., LM Studio at http://localhost:1234/v1)
// In DEFAULTS:
CLAUDE_MEM_OPENROUTER_BASE_URL: 'https://openrouter.ai/api/v1', // Default OpenRouter, or set to http://localhost:1234/v1 for LM StudioChanged hardcoded URL to configurable:
// Before:
const OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/chat/completions';
// After:
const DEFAULT_OPENROUTER_BASE_URL = 'https://openrouter.ai/api/v1';Updated getOpenRouterConfig() to return baseUrl:
private getOpenRouterConfig(): { apiKey: string; baseUrl: string; model: string; ... } {
const baseUrl = settings.CLAUDE_MEM_OPENROUTER_BASE_URL || DEFAULT_OPENROUTER_BASE_URL;
return { apiKey, baseUrl, model, siteUrl, appName };
}Skip API key requirement for local endpoints:
const isLocalEndpoint = baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1');
if (!apiKey && !isLocalEndpoint) {
throw new Error('OpenRouter API key not configured...');
}Updated isOpenRouterAvailable() to allow local endpoints:
export function isOpenRouterAvailable(): boolean {
const hasApiKey = !!(settings.CLAUDE_MEM_OPENROUTER_API_KEY || process.env.OPENROUTER_API_KEY);
const baseUrl = settings.CLAUDE_MEM_OPENROUTER_BASE_URL || '';
const isLocalEndpoint = baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1');
return hasApiKey || isLocalEndpoint;
}Updated queryOpenRouterMultiTurn() to use dynamic URL:
const apiUrl = `${baseUrl}/chat/completions`;
const response = await fetch(apiUrl, { ... });Edit ~/.claude-mem/settings.json:
{
"CLAUDE_MEM_PROVIDER": "openrouter",
"CLAUDE_MEM_OPENROUTER_BASE_URL": "http://localhost:1234/v1",
"CLAUDE_MEM_OPENROUTER_MODEL": "ibm/granite-4-h-tiny"
}cd ~/.claude/plugins/marketplaces/thedotmack
npm run build
# Copy to cache (where the active plugin runs from)
cp plugin/scripts/worker-service.cjs ~/.claude/plugins/cache/thedotmack/claude-mem/9.0.6/scripts/
# Restart worker
pkill -f worker-service
bun ~/.claude/plugins/cache/thedotmack/claude-mem/9.0.6/scripts/worker-service.cjs startCheck logs for OpenRouter usage:
tail -f ~/.claude-mem/logs/claude-mem-$(date +%Y-%m-%d).log | grep -E "OpenRouter|granite"Expected output:
[session-X] Generator auto-starting (observation) using OpenRouter
OpenRouter API usage {model=ibm/granite-4-h-tiny, inputTokens=1529, outputTokens=68, totalTokens=1597}
- Zero API costs for observation processing
- Faster inference with local GPU
- Works offline
- Uses Granite 4 H-Tiny (1B active params, 1M context)
Consider submitting these changes to thedotmack/claude-mem to avoid reapplying after plugin updates.
A dedicated LMStudioAgent.ts was added (commit 459a4f4), separate from OpenRouter. Simpler, no API key required.
Settings:
{
"CLAUDE_MEM_PROVIDER": "lmstudio",
"CLAUDE_MEM_LMSTUDIO_BASE_URL": "http://localhost:1234/v1",
"CLAUDE_MEM_LMSTUDIO_MODEL": "ibm/granite-4-h-tiny"
}Instead of installing to marketplace, use local repo directly:
cc --plugin-dir /home/bpd/dev/bpd1069/claude-mem/plugin-
Graceful hook failures - Changed exit code from 2 (blocking) to 0 in
hook-command.tsto avoid ugly errors -
Dynamic plugin root - Fixed hardcoded
thedotmackmarketplace path in:src/shared/worker-utils.tssrc/services/infrastructure/HealthMonitor.ts
Now uses
CLAUDE_PLUGIN_ROOTenv var (set by--plugin-dir) with fallback -
Simplified build -
npm run build-and-syncnow just builds and restarts worker locally
cd ~/dev/bpd1069/claude-mem
npm run build-and-sync
# Verify
curl -s http://127.0.0.1:37777/api/settings | jq '.CLAUDE_MEM_PROVIDER'
curl -s http://127.0.0.1:37777/api/version