Pointing your coding agent at LM Studio instead of the cloud

The server part takes five minutes. The part where the agent still finishes the task is the interesting one.

Short answer: yes, you can point a coding agent at LM Studio, and for a decent slice of the work it holds up. LM Studio ships a local HTTP server that speaks the OpenAI REST shape at http://localhost:1234/v1, with /v1/models, /v1/chat/completions, /v1/completions and /v1/embeddings. Any tool that lets you override its base URL and accepts an arbitrary API key string can be aimed at it. Start the server from the Developer tab in the app, or headless with the lms CLI, load a model, and point the client at that address.

The longer answer is that the endpoint being compatible is not the same as the agent working. A chat UI asks a model for prose. A coding agent asks it for a long sequence of correctly-shaped tool calls against a context that keeps growing, and one malformed call in the middle costs you the whole run. That gap is where most of the local-model disappointment comes from, and it is fixable if you know which knobs matter.

What connects cleanly and what needs a translator

Agents that already speak the OpenAI chat completions format are the easy case. Codex and Cursor both let you define a custom provider with a base URL and a model name, so LM Studio drops in with two config lines. Point the base URL at your LM Studio address, use the exact model identifier that /v1/models reports, and put any non-empty string in the key field because the local server does not check it.

Claude Code is the awkward one. It talks the Anthropic Messages API, not the OpenAI one, so setting ANTHROPIC_BASE_URL to an LM Studio port gets you protocol errors rather than local inference. You need something in between that accepts Anthropic-shaped requests and re-emits them as OpenAI-shaped ones, then converts streaming deltas and tool_use blocks back on the way out. Several projects do this. It is real translation work, not a header rewrite, and the tool-call conversion is where the buggy implementations show up.

Before you debug anything else, curl the endpoint yourself. Hit /v1/models to confirm the identifier, then send one chat completion with a tool definition attached and read the raw response. If the model returns the tool call in a prose block instead of the structured field, no amount of agent config will save the run.

The settings that actually decide whether it works

Most failures I have seen trace back to four things, and only one of them is the model choice.

  • Context length. LM Studio lets you set the context per loaded model, and the default is usually far below what the model supports. A coding agent sends the system prompt, the tool schemas, the file contents it has read and the full turn history on every single call. That crosses tens of thousands of tokens early in a session. If your loaded context is short, the agent does not error, it silently loses the top of the conversation and starts contradicting itself.
  • KV cache memory. Raising context is not free. The cache grows with context length and eats unified memory alongside the weights. On a laptop this is the real ceiling: you often have to pick between a bigger model at short context and a smaller model that can actually hold a repo conversation. For agent work the second choice usually wins.
  • Tool calling support. This is a property of the specific model and its chat template, not of LM Studio. Some models emit clean structured calls, some emit JSON wrapped in prose, some invent parameters that were never in the schema. Test with your agent's real tool definitions rather than a toy weather function, because agent schemas are much larger and more nested.
  • Prompt processing speed. Generation tokens per second is the number everyone quotes and the wrong one to care about here. Agents resubmit a large prompt on every turn, so time-to-first-token under a long prefix dominates the felt latency. Measure that specifically. MLX builds on Apple Silicon and GGUF builds through llama.cpp behave differently under long prefixes, and it is worth trying both for the same model.

Which work to keep local

I run local models for the boring high-volume half of agent traffic. Commit message drafting, summarising a diff, naming things, one-file edits with clear instructions, explaining an unfamiliar function, generating a test skeleton from a signature I paste in. That work is short-horizon, tolerant of a mediocre answer, and cheap to redo. It also happens constantly, which is why it costs real money in aggregate even though each call feels trivial.

What I send to the cloud: anything where the agent has to plan across files, anything touching a build or migration, anything where a wrong tool call rewrites something I care about. The failure mode of a weak local model on a long agentic task is not a bad answer you can spot, it is a plausible answer forty tool calls deep, and the cost of unwinding that exceeds whatever you saved.

The question is not whether the local model is good enough. It is whether you can tell, in the moment, when it was not.

Where Probe0 fits

I built Probe0 because I got tired of making that routing decision by hand, and worse, of switching my agent's config back and forth depending on what I was about to ask it. Probe0 is a proxy that runs on your own machine. You install it once with a local certificate, and every coding agent CLI on the box routes through it, Claude Code and Codex and Cursor alike. There is no per-tool provider config and no Probe0 server anywhere, because there is no Probe0 server at all.

The Local Routing module is the part relevant here. It sends eligible work to a model already loaded in LM Studio or Ollama, and when the answer comes back weak it retries the same request against the cloud automatically. That auto-retry is the whole reason I trust local routing on real work. The downside of a bad local answer stops being a corrupted run and becomes a few seconds of extra latency. Alongside it, Recording keeps a full ledger of every call: model, tokens, real cost, latency, and which process made it, so after a week you can see exactly which categories of request your local model handled without a retry and widen the rules from evidence instead of vibes.

Honest limits. Probe0 is macOS only and in private beta. It is a single-developer tool, not a team gateway with shared keys and org policy, and the provider coverage is what coding agents actually call rather than a catalogue of a hundred endpoints. If you want a hosted gateway with dashboards for a whole engineering org, look at the managed options instead. And if you only ever use one agent and are happy editing its config file, pointing it straight at LM Studio works fine and costs you nothing.

One last practical note. Keep the LM Studio server running headless with JIT model loading rather than juggling the GUI, and give the loaded model a context length you have actually tested against a real session rather than the one that fits comfortably in memory at rest. Almost every local coding setup that gets abandoned after a day was abandoned because of truncated context, not because of the model.

Related