How to use OpenCode with a local model in LM Studio
By Flavio Copes
Connect OpenCode to LM Studio, test local tool calling, fix model discovery problems, and check what you need for a coding workflow that works offline.
OpenCode can use a model running on your computer through LM Studio. Your coding agent talks to a local HTTP server, which runs inference using a model you’ve downloaded.
That gives you control over where the model request goes. It also gives your computer the job of running the model while OpenCode and your development tools are working.
We’ll connect the programs, try a small coding task, and check the boundary around the word offline. Selecting a local model doesn’t automatically make every tool the agent can call local.
You’ll need OpenCode, LM Studio, and enough memory for the model you choose. The commands below use OpenCode v2. If you have v1 alongside it, use the opencode2 executable where these examples say opencode.
Choose a model that can use tools
A coding agent needs more than a model that can answer a question about JavaScript.
The model has to ask OpenCode to read a file, understand the result, and request the next operation in the format the server expects. Later, it needs to produce a valid edit and interpret test output.
In LM Studio, download an instruction-tuned coding model that supports tool use. Check its model card and the available LM Studio metadata. A smaller download that fits your computer comfortably is a better first connection test than the largest model you can barely load.
Model size, quantization, and context length all affect memory requirements. The context includes the conversation and tool results, not just your latest prompt. Leave room for your editor, the local server, and the project’s build process.
I wouldn’t give a model a large migration as its first task. Start by checking that it can read one file through a tool. A coherent answer from the chat panel alone doesn’t establish that.
The open weights post explains what you’re downloading and why a model’s license still matters when you run it yourself.
Start the LM Studio server
Load the downloaded model in LM Studio. Open the Developer tab and start the server.
The usual address is:
http://127.0.0.1:1234
Keep it listening locally for this tutorial. You don’t need to enable access from other computers on your network.
If you already have LM Studio’s lms command installed, the server documentation also provides this command:
lms server start
Check the OpenAI-compatible model endpoint from a terminal:
curl http://127.0.0.1:1234/v1/models
The response should contain model IDs. Use the IDs returned by your server; a download’s display name isn’t always the API identifier.
If you’ve enabled server authentication, an unauthenticated request can fail even though the model is loaded. Keep authentication enabled if your setup needs it, and configure the same credentials in OpenCode. Don’t solve a connection error by exposing the server more broadly.
Let OpenCode discover it
OpenCode v2 discovers LM Studio models at the default local address. Start the server before opening the model picker.
From a small project directory, run:
opencode
Then open:
/models
Select the entry under the lmstudio provider. Check that the provider is LM Studio rather than a hosted provider offering a similarly named model.
The selection applies to this session. To make it the project default, create opencode.jsonc and put the exact discovered selector in model.
The OpenCode documentation uses this selector as an LM Studio example:
{
"$schema": "https://opencode.ai/config.json",
"model": "lmstudio/google/gemma-4-26b-a4b"
}
Use that value only if your server has that model available. Otherwise replace it with the exact selector in your picker. This configuration selects a model; it doesn’t download or load one.
The provider prefix and model identifier both matter. A session that already has a model selected can keep that selection after you change the default. Use /models to confirm the active session.
Use another port or authentication
If LM Studio listens elsewhere, configure the endpoint under providers. OpenCode’s built-in integration can still discover its inventory.
For a local server on port 5678, save this in opencode.jsonc:
{
"$schema": "https://opencode.ai/config.json",
"providers": {
"lmstudio": {
"settings": {
"baseURL": "http://127.0.0.1:5678/v1"
}
}
}
}
Notice the /v1 suffix on the compatible API URL. The server address in the LM Studio interface and the API base URL aren’t necessarily the same string.
If authentication is enabled, add "apiKey": "{env:LMSTUDIO_API_KEY}" inside settings. Supply the variable through your secret manager or shell environment. Keep the value out of the config file and Git.
OpenCode’s shared service owns model requests. If a key exists only in a newly opened shell, an already-running service may not have it. For a single command, opencode run --standalone starts a private server that receives that command’s environment. The CLI documentation explains this distinction.
Make a small test project
We’re going to ask the agent to repair a function that loses zero values. The behavior is easy to check and requires no package downloads.
Create a directory:
mkdir local-agent-practice
cd local-agent-practice
git init
Save this as prices.mjs:
export function listedPrices(prices) {
return prices.filter(Boolean)
}
Save this as prices.test.mjs:
import test from 'node:test'
import assert from 'node:assert/strict'
import { listedPrices } from './prices.mjs'
test('keeps zero prices and removes missing entries', () => {
assert.deepEqual(listedPrices([12, 0, null, 5, undefined]), [12, 0, 5])
})
test('handles an empty list', () => {
assert.deepEqual(listedPrices([]), [])
})
Run the tests before asking the agent to change anything:
node --test
The first test should fail. filter(Boolean) removes 0, because zero is falsy in JavaScript.
Our requirement is narrower than “remove every invalid price.” We only want to remove null and undefined. Keep that distinction in the prompt so the model doesn’t invent validation rules.
Commit the starting files:
git add prices.mjs prices.test.mjs
git commit -m "Add price filtering example"
Now open OpenCode in this folder and select your LM Studio model.
Check reading before editing
First send:
Read prices.mjs and prices.test.mjs using your file tools.
Explain why the first test fails. Don't edit files or run commands.
Watch the tool activity. The useful evidence is a real file read and an explanation tied to those contents.
A model that prints something resembling a tool invocation in its final answer hasn’t necessarily called a tool. If OpenCode shows no corresponding tool operation, inspect the model’s tool support and the LM Studio server logs.
Then ask for the repair:
Update listedPrices so it removes only null and undefined.
Preserve zero and preserve the order of the remaining entries.
Don't change the tests. Run node --test. Don't commit anything.
Review the diff yourself:
git diff
node --test
A suitable implementation filters with price !== null && price !== undefined. The point of this task is to observe whether the agent reads the files, makes a focused edit, and runs the requested check. We aren’t measuring a universal coding score.
What fully offline requires
LM Studio supports offline operation after the required models and software are downloaded. The complete coding workflow has more dependencies.
Prepare the project while connected. Install its packages, download any compiler or browser binaries its tests need, and check that its test data is local. A test that contacts a hosted database will still need that database.
OpenCode tools can also reach the internet. Web search, a remote MCP server, Git operations, or a shell command can make a network request even when inference runs locally.
For a task that should work offline, I would start with no external integrations, use local fixtures, and disconnect the computer after everything is ready. Run the same explanation and repair requests again. A completed local request while disconnected is more useful evidence than the provider name alone.
This doesn’t establish that the installation never attempts background network access. If your requirement is a strict network boundary, enforce it through the operating system or network environment and inspect the relevant logs. A prompt saying “stay offline” isn’t network enforcement.
Keep the model running locally too. A server that forwards requests to another machine changes the boundary, even if OpenCode connects to a loopback address.
When chat works but tool calls fail
LM Studio’s tool-use documentation explains the compatible API flow. The model requests a tool; the application executes it and sends back a result.
That involves the model’s capabilities and its chat template. A generic conversational model can produce fluent explanations while struggling to emit reliable tool requests.
If our read-only request fails, try the model’s recommended template and check whether the server reports tool support. Don’t manually mark a model as capable merely to make it appear in a list. That changes what OpenCode attempts, not what the model can do.
If file reading works but editing doesn’t, reduce the task further. Ask for one specific replacement. Separate failures in reasoning about the code from failures in formatting a tool call.
For context errors, start a fresh session with fewer attached files. Increasing the context limit in a client config doesn’t create memory or enlarge the context allocation of the loaded server model.
If the machine starts swapping heavily, load a smaller model or reduce the configured context. Compare total time to a reviewed change, including retries. Token generation speed alone doesn’t tell you whether the workflow is useful.
How I would use this setup
I would try it on a small utility with local tests, especially when I want to keep the model request on my computer. A focused explanation, a rename, or a bug with an existing failing test gives me a result I can judge.
I wouldn’t assume it can replace a hosted coding model for every project. A repair that takes several manual corrections can cost more of my time even when there’s no per-request API bill. Electricity, hardware, and the memory occupied by the model still have costs.
Keep the hosted and local options distinguishable in the model picker. If you switch providers to finish a task, check what context the next request will send before continuing. The files you attached to a local session don’t become suitable for a remote provider just because switching is convenient.
Want me to talk about your product? You can sponsor this site.
Related posts about ai: