lmstudio-ollama-mcp

Claude Code for local models. A single binary that bridges LM Studio · Ollama · llama.cpp as coding agents — with hardware-aware parallel sub-agents, intelligent routing, and zero data leaving your machine.

v0.1.0 Node >=18 MIT local-first
TL;DRnpm install -g lmstudio-ollama-mcp → start LM Studio (port 1234) or ollama servelmstudio-ollama-mcp doctorlmstudio-ollama-mcp "fix the failing test". Alias forge works everywhere.

Introduction

lmstudio-ollama-mcp brings the agentic loop from Claude Code / Codex to on-device models. Instead of paying per token and sending code to the cloud, you run a local GGUF (Gemma, Qwen, etc.) via LM Studio, Ollama, or llama.cpp. A frontier model is optional: when configured, it only plans while local models execute.

Private

Code never leaves the laptop. Air-gapped local-only mode for sensitive repos.

Free

No per-token bill. Download a 7–12B Q4 once, run forever.

Parallel

2–6 sub-agents, capped by your cores & RAM (Apple Silicon bonus).

Familiar

7 tools (read/write/edit/bash/glob/grep/list) + exact-string edits.

Installation

Prerequisites

Install

bash
npm install -g lmstudio-ollama-mcp
# aliases keep muscle memory:
forge --help
forgecode --help
# one-off without install:
npx lmstudio-ollama-mcp doctor
Note — Package is named lmstudio-ollama-mcp on npm. forge is a bin alias. Previous name forgecode is still an alias.

Quickstart

bash
git clone https://github.com/your-org/your-project && cd your-project
lmstudio-ollama-mcp init        # creates lmstudio-ollama-mcp.json
lmstudio-ollama-mcp doctor      # verifies providers + hardware
lmstudio-ollama-mcp models      # lists local GGUFs
lmstudio-ollama-mcp "list the codebase structure and suggest 3 small improvements"

Hybrid mode (optional frontier):

bash
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
lmstudio-ollama-mcp "design and implement a rate-limiter middleware"

First run checklist

  1. Start a runtime — LM Studio: Developer → Local Server → Start. Ollama: ollama serve. llama.cpp: ./llama-server -m model.gguf --port 8080
  2. Load a model — LM Studio: pick Gemma 12B QAT or Qwen3 27B. Ollama: ollama pull qwen2.5-coder:7b
  3. Verifylmstudio-ollama-mcp doctor should show ● lmstudio available + models.
  4. Try a small tasklmstudio-ollama-mcp "add JSDoc to src/utils/logger.ts" (routed locally).
  5. Try parallellmstudio-ollama-mcp --parallel 4 "implement auth + tests + docs"

Providers

All providers speak OpenAI-compatible Chat Completions with tools. The bridge normalizes reasoning_content (Gemma/Qwen) and handles tool calling consistently.

ProviderDefault URLDiscoveryNotes
LM Studiohttp://localhost:1234/v1/v1/models + ~/.lmstudio/models/**/*.ggufFilesystem scan when server is off; supports vision models
Ollamahttp://localhost:11434/api/tags native, fallback /v1/modelsollama pull <model> required; /api/pull helper
llama.cpphttp://localhost:8080/health + /v1/modelsAny GGUF; run llama-server
OpenAIhttps://api.openai.com/v1APISet OPENAI_API_KEY
Anthropichttps://api.anthropic.comAPISet ANTHROPIC_API_KEY

LM Studio

Developer → Local Server → Start. Forge detects via GET /v1/models; if the server is down but models exist on disk (~/.lmstudio/models), doctor still lists them but chat will fail until the server is started. Load a model with good tool-calling: Gemma 12B QAT (recommended on 16GB) or Qwen3 27B IQ2_S.

bash
~/.lmstudio/bin/lms ls
~/.lmstudio/bin/lms load google/gemma-4-12b-qat --yes
~/.lmstudio/bin/lms server start
curl -s http://localhost:1234/v1/models | jq .data[].id

Ollama

Uses native /api/tags for rich metadata (size, quantization). Run ollama serve then pull a coder model.

bash
ollama serve &
ollama pull qwen2.5-coder:7b
ollama pull gemma3:12b
curl -s http://localhost:11434/api/tags | jq .models[].name

llama.cpp

Any GGUF via llama-server. The bridge checks /health and /v1/models.

bash
./llama-server -m models/gemma-12b-q4.gguf --port 8080 --ctx-size 8192
curl -s http://localhost:8080/health
lmstudio-ollama-mcp --provider llamacpp --model hf.co/model "explain this repo"

Frontier (hybrid)

When OPENAI_API_KEY or ANTHROPIC_API_KEY is set, a frontier provider is auto-registered. In auto strategy, frontier plans (decomposition, hard reasoning) while local models execute small tasks. Cost drops ~90% vs. cloud-only.

Privacy — In local-only strategy or without API keys, nothing leaves the machine. Hybrid still sends the planner prompt to the frontier.

Custom endpoints

Any OpenAI-compatible endpoint works (e.g., vLLM, local Mistral server, remote LM Studio):

lmstudio-ollama-mcp.json
{
  "providers": {
    "my-remote": { "type": "openai", "baseUrl": "http://192.168.1.10:1234/v1", "apiKey": "not-needed", "enabled": true }
  }
}

Routing & model selection

ModelRouter (src/providers/router.ts:14) classifies every prompt:

ComplexityHeuristicAuto target
trivial<500 tokens, few lines, or kind in preferLocalForlocal 7–12B
small< smallTaskMaxTokens (default 2000)local
medium2000–6000 tokensfrontier if available else local
large>6000 tokensfrontier

preferLocalFor defaults to ["lint","format","test","search","summarize","explain"] — always local even in frontier-first.

lmstudio-ollama-mcp.json
{
  "router": {
    "strategy": "auto",
    "frontierProvider": "openai",
    "frontierModel": "gpt-4o-mini",
    "thresholds": {
      "smallTaskMaxTokens": 2000,
      "preferLocalFor": ["lint","format","test","search","summarize","explain"]
    }
  }
}

Override per run: --model lmstudio:gemma-3-12b or --provider ollama --model qwen2.5-coder:14b.

Hardware-aware scheduling

detectHardware() (src/hardware/detector.ts:12) reads os.cpus(), os.totalmem(), Apple Silicon flag. recommendParallelism():

detector.ts
cpuLimit = floor(cores * overcommit) - 1
memLimit = floor((totalGb*1024 - 2048) / perAgentMb)  // default perAgentMb=1200
unifiedBonus = isAppleSilicon ? 1 : 0
suggested = min(cpuLimit, memLimit) + unifiedBonus
// clamp: 1..8 default, up to 12 on 32GB/12c, up to 16 on 64GB

Scheduler (src/hardware/scheduler.ts:17) is a bounded p-limit queue. Sub-agents run via scheduler.runAll(tasks) preserving order, respecting maxParallel. CLI override: --parallel 4 or --no-parallel.

MachineRecommended
M3 8c / 16GB8 agents
M1 8c / 8GB3–4 agents
32GB / 12c~10–12 agents
64GB workstationup to 16 agents

Orchestrator & sub-agents

Orchestrator (src/core/orchestrator.ts:28) decomposes a goal into 2–6 SubTasks via a planner LLM (frontier if available, else local). Prompt asks for [{"id":"t1","title":"...","prompt":"...","kind":"code|test|search"}] JSON. Tasks with dependsOn are batched topologically.

bash
lmstudio-ollama-mcp --parallel 4 "implement auth module, write tests, update docs"
# planner → 3 sub-tasks:
# t1 Explore & plan [search → local]
# t2 Implement      [code   → local or frontier]
# t3 Verify         [test   → local]
# each sub-agent: Agent(provider, model, ToolExecutor) → 18 tool turns max → synthesis
Fallback — If planner fails or returns invalid JSON, heuristic decomposition is used (explore → implement → verify).

Agent loop & tools

Agent (src/core/agent.ts:22) runs a 25-turn OpenAI tool loop: provider.chat(messages, tools) → execute tool calls → append tool messages → repeat until no tool_calls.

ToolDescriptionGuardrail
read_fileRead file (2MB cap)Directory check
write_fileCreate/overwrite (mkdir -p)Workspace escape blocked
edit_fileExact-string replace (must match once)Prevents sloppy diffs
bashRun command (30s, 5MB)Blocks rm -rf /, etc.
globfast-glob search200 results max
grepRegex search (skips node_modules/dist/.git)100 hits max
list_dirDirectory listing

System prompt enforces: read before edit, small diffs, verify with bash, concise summary.

Configuration

Resolution: DEFAULT < ~/.lmstudio-ollama-mcp/config.json < ./lmstudio-ollama-mcp.json < env vars. Legacy ~/.forgecode/config.json / forgecode.json still read for compat (new path wins).

bash
lmstudio-ollama-mcp config --show   # resolved JSON
lmstudio-ollama-mcp config --path   # file locations
lmstudio-ollama-mcp init            # scaffold lmstudio-ollama-mcp.json

Reference

lmstudio-ollama-mcp.json
{
  "version": 1,
  "providers": {
    "lmstudio": { "type": "lmstudio", "baseUrl": "http://localhost:1234/v1", "enabled": true },
    "ollama":   { "type": "ollama",   "baseUrl": "http://localhost:11434",      "enabled": true },
    "llamacpp": { "type": "llamacpp", "baseUrl": "http://localhost:8080",       "enabled": true },
    "openai":   { "type": "openai",   "baseUrl": "https://api.openai.com/v1",   "apiKey": "sk-..." }
  },
  "router": {
    "strategy": "auto",                       // auto | local-first | frontier-first | local-only
    "frontierProvider": "openai",
    "frontierModel": "gpt-4o-mini",
    "thresholds": {
      "smallTaskMaxTokens": 2000,
      "preferLocalFor": ["lint","format","test","search","summarize","explain"]
    }
  },
  "hardware": {
    "maxParallelAgents": 4,                   // auto if omitted
    "maxMemoryPerAgentMb": 1200,
    "cpuOvercommit": 1                        // 0.5..2
  },
  "permissions": {
    "allowBash": true,
    "allowWriteOutsideWorkspace": false,
    "allowNetwork": true
  }
}

Strategies

CLI reference

CommandDescription
lmstudio-ollama-mcp "task"One-shot (alias: forge "task")
lmstudio-ollama-mcpInteractive REPL (doctor/models/exit)
doctorDiagnose hardware, config, providers
models [--json]List models
config --show --pathShow resolved config
initScaffold lmstudio-ollama-mcp.json
run "task"Alias for one-shot

Flags: --model <provider:model> (e.g. lmstudio:gemma-3-12b), --provider <id>, --parallel <n>, --no-parallel, --verbose, -v/--version

bash
lmstudio-ollama-mcp --model ollama:qwen2.5-coder:14b "explain auth flow"
lmstudio-ollama-mcp --provider lmstudio --model gemma-3-12b "fix test in tests/tools.test.ts"
lmstudio-ollama-mcp --no-parallel "small typo fix"
lmstudio-ollama-mcp --parallel 8 "migrate Jest to Vitest"

MCP

Model Context Protocol support is on the roadmap. Current OpenAI-compatible providers already speak the same tool surface; a future mcp command will expose local models as MCP tools for other agents:

roadmap
# planned
lmstudio-ollama-mcp mcp serve --port 3000
# exposes: lmstudio-ollama-mcp tools as MCP over stdio / SSE
Today — Use the CLI as an MCP-adjacent tool: other agents can call lmstudio-ollama-mcp "task" via bash tool. The OpenAI-compatible endpoints are already MCP-friendly.

Troubleshooting

No provider available

Run lmstudio-ollama-mcp doctor. Common fixes:

Model lists but chat fails

LM Studio filesystem scan can find models even when the server is off. Start the server before chatting.

Slow inference

Use a smaller quantized model (Q4) on 8–16GB. Reduce --parallel or set hardware.maxParallelAgents: 2 to lower contention.

Reasoning models truncated

Gemma/Qwen emit reasoning_content. The bridge already merges it when content is empty, but request at least 1024 max_tokens (default is 2048).

Path escapes workspace

Set permissions.allowWriteOutsideWorkspace: true in config (not recommended).

Architecture

architecture
CLI (commander) → Router (classify) → Orchestrator (decompose → Scheduler) → Agent (tool loop) → Provider (OpenAI-compatible)
                ↓                    ↓                    ↓                     ↓
            Config (Zod)      Hardware (cores/RAM)   Planner LLM         ToolExecutor (fs/glob/grep/bash)

All code in src/ with Zod schemas, Vitest suites, and TypeScript strict mode.

MIT · github.com/fthsrbst/lmstudio-ollama-mcp · npm: lmstudio-ollama-mcp · alias forge