I dance between Harnesses, I do. I like the big players like Copilot, Claude and Antigravity CLI, but really the up and comers are the ones that catch my attention.
I lasted spoke on OpenCode in August of 2025. While I noted it was from sst.dev I didn’t really dig into what SST was (or why one would use it). At that time, I was comparing OpenCode to OllamaCode and Qwen3 Coder Plus (along with the much loved and now defunct Gemini CLI).
A lot has changed in a year and today I’m using OpenCode yet again, though this time it’s much more functional.
Setup
We can see the install steps from Opencode.ai. The easiest is just
$ curl -fsSL https://opencode.ai/v2/install | bash
Or just natively in NodeJS
$ npm install -g @opencode/cli
Let’s do the latter
isaac@isaac-G707:~/Workspaces/innersourcedemo2$ nvm use lts/jod
Now using node v22.23.2 (npm v10.9.8)
isaac@isaac-G707:~/Workspaces/innersourcedemo2$ npm install -g @opencode/cli
added 5 packages in 7s
If we fire it up and look at models with /models we can see there are a few free ones but at the bottom you also see two in Ollama
I know it was finding the local Ollama by looking locally
isaac@isaac-G707:~/Workspaces/innersourcedemo2$ ollama list
NAME ID SIZE MODIFIED
medgemma1.5:4b 433252621ab1 3.3 GB 3 weeks ago
gemma4:12b 4eb23ef187e2 7.6 GB 2 months ago
Let’s add some models from an Ollama running locally
isaac@isaac-G707:~/Workspaces/innersourcedemo2$ vi ~/.config/opencode/opencode.json
isaac@isaac-G707:~/Workspaces/innersourcedemo2$ cat ~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama (220)",
"options": {
"baseURL": "http://192.168.1.220:11434/v1"
},
"models": {
"qwen3.5:latest": {
"name": "qwen3.5"
},
"qwen3.8:27b": {
"name": "qwen3.8 27b"
},
"gemma4:e4b": {
"name": "Gemma4 e4b"
},
"gemma4:12b": {
"name": "Gemma4 12b"
},
"ministral-3:8b": {
"name": "Ministral-3 8b"
},
"granite4.1:8b": {
"name": "Granite4.1 8b"
},
"gpt-oss:20b": {
"name": "gpt-oss 20b"
}
}
}
}
}
Now I can see them all in the list
Here is where some of the new features come into to play with OpenCode (I’m running version 2.2.5)
We can use “goal” mode to run until completion
Let’s use /goal with a detailed goal for a full featured To-Do app
I’ll fire it up and it will go to work
It quickly moved past this error, but I scrolled up to show you - in Goal mode, if it hits a bump, it just moves on and keeps working
Without any inputs, it ran to completion (while I went upstairs and refreshed my coffee)
I did see an error, but I know it’s just a comment line in a Dockerfile not in the correct place
My next error looks suspiciously like a missing requirements.txt entry for sqlalchemy (used for db migrations)
I’m still sticking with local Qwen, but prompting with a hint - that I suspect we are missing an import and noting the container output:
Qwen concurred and added the proper import and suggested I try again
More errors - perhaps it didn’t test the app:
web-1 exited with code 1 (restarting)
web-1 | Traceback (most recent call last):
web-1 | File "/app/app/app.py", line 42, in <module>
web-1 | @app.route('/')
web-1 | ^^^
web-1 | NameError: name 'app' is not defined
web-1 exited with code 1 (restarting)
web-1 | Traceback (most recent call last):
web-1 | File "/app/app/app.py", line 42, in <module>
web-1 | @app.route('/')
web-1 | ^^^
web-1 | NameError: name 'app' is not defined
web-1 exited with code 1 (restarting)
web-1 | Traceback (most recent call last):
web-1 | File "/app/app/app.py", line 42, in <module>
web-1 | @app.route('/')
web-1 | ^^^
web-1 | NameError: name 'app' is not defined
web-1 exited with code 1 (restarting)
Another fix
And another error
Container innersourcedemo2-web-1 Stopping
web-1 | Traceback (most recent call last):
web-1 | File "/app/app/app.py", line 42, in <module>
web-1 | app = create_app() # Initialize Flask app instance at module level
web-1 | ^^^^^^^^^^^^
web-1 | File "/app/app/app.py", line 15, in create_app
web-1 | db.init_app(app)
web-1 | File "/usr/local/lib/python3.11/site-packages/flask_sqlalchemy/extension.py", line 374, in init_app
web-1 | engines[key] = self._make_engine(key, options, app)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/flask_sqlalchemy/extension.py", line 665, in _make_engine
web-1 | return sa.engine_from_config(options, prefix="")
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 832, in engine_from_config
web-1 | return create_engine(url, **options)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "<sqlalchemy generated warned() wrapper for sqlalchemy.engine.create.create_engine>", line 2, in create_engine
web-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/util/deprecations.py", line 281, in warned
web-1 | return fn(*args, **kwargs) # type: ignore[no-any-return]
web-1 | ^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 602, in create_engine
web-1 | dbapi = dbapi_meth(**dbapi_args)
web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^
web-1 | File "/usr/local/lib/python3.11/site-packages/sqlalchemy/dialects/postgresql/psycopg.py", line 497, in import_dbapi
web-1 | import psycopg
web-1 | ModuleNotFoundError: No module named 'psycopg'
```A
I'm going to try `/goal` mode again here to say work until the `docker compose up` works
[](/img/2026-11-opencode-13.png)
I won't capture and reply all the output, but it waiting for the containers to launch, but then checked logs to see if there were missing modules in output. It found a minor compile error, fixed that, then noted the race condition on the DB launch
[](/img/2026-11-opencode-14.png)
I watched it work until the containerrs were running successfully
[](/img/2026-11-opencode-15.png)
However, I still get refused (likely forgot to add 0.0.0.0 as allowed hosts)
[](/img/2026-11-opencode-16.png)
I asked
[](/img/2026-11-opencode-17.png)
And fix
[](/img/2026-11-opencode-18.png)
Let's see if 5th times the charm...
It's running but giving me a 404 on the root document
web-1 | * Serving Flask app ‘app’ web-1 | * Debug mode: on web-1 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. web-1 | * Running on all addresses (0.0.0.0) web-1 | * Running on http://127.0.0.1:5000 web-1 | * Running on http://172.27.0.3:5000 web-1 | Press CTRL+C to quit web-1 | * Restarting with stat web-1 | * Debugger is active! web-1 | * Debugger PIN: 991-369-536 web-1 | 172.27.0.1 - - [03/Nov/2026 12:48:08] “GET / HTTP/1.1” 404 - web-1 | 172.27.0.1 - - [03/Nov/2026 12:48:08] “GET /favicon.ico HTTP/1.1” 404 - web-1 | 172.27.0.1 - - [03/Nov/2026 12:48:09] “GET / HTTP/1.1” 404 - web-1 | 172.27.0.1 - - [03/Nov/2026 12:48:12] “GET / HTTP/1.1” 404 - web-1 | 172.27.0.1 - - [03/Nov/2026 12:49:02] “GET / HTTP/1.1” 404 -
[](/img/2026-11-opencode-19.png)
hmm.. i do see the proper "/" route in the app python code.
I worked it a bit and you can see it rewrite (i should have committed first) and have more errors. I restart the last session and switch to goal mode:
<video controls width="100%"><source src="/vid/2026-11-opencode-20.webm" type="video/webm"></video>
The goal mode worked for a while, fixing things till it hit a wall on token limits
[](/img/2026-11-opencode-21.png)
And I now see it working!
[](/img/2026-11-opencode-22.png)
And in browser:
[](/img/2026-11-opencode-23.png)
i even went wide screen, while it runs, it's a bit goofy
[](/img/2026-11-opencode-24.png)
It shows up and has the basic criteria, but it does not work
<video controls width="100%"><source src="/vid/2026-11-opencode-25.webm" type="video/webm"></video>
## Gemma4 12b
Let's use a punchier heavier model to see if we can sort things out - same harness, same destination GPU enabled Ollama host, just different model
[](/img/2026-11-opencode-26.png)
But 12b just timed out and e4b didnt do the work
[](/img/2026-11-opencode-27.png)
Though Qwen 3.5 was convinced it sorted the issue
[](/img/2026-11-opencode-28.png)
The UI is still trash though. It needs help
# Browser MCP
One of my go-tos to help LLMs test is [Browser MCP](https://browsermcp.io).
We can add it to OpenCode by [following the docs](https://browsermcp.io/docs/ai-apps)
~/.config/opencode/opencode.json { “$schema”: “https://opencode.ai/config.json", “mcp”: { “browsermcp”: { “type”: “local”, “command”: [“npx”, “@browsermcp/mcp@latest”], “enabled”: true } } }
For instance, here it is in mine
```json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama (220)",
"options": {
"baseURL": "http://192.168.1.220:11434/v1"
},
"models": {
"qwen3.5:latest": {
"name": "qwen3.5"
},
"qwen3.8:27b": {
"name": "qwen3.8 27b"
},
"gemma4:e4b": {
"name": "Gemma4 e4b"
},
"gemma4:12b": {
"name": "Gemma4 12b"
},
"ministral-3:8b": {
"name": "Ministral-3 8b"
},
"granite4.1:8b": {
"name": "Granite4.1 8b"
},
"gpt-oss:20b": {
"name": "gpt-oss 20b"
}
}
}
},
"mcp": {
"browsermcp": {
"type": "local",
"command": ["npx", "@browsermcp/mcp@latest"],
"enabled": true
}
}
}
I tried with Gemma4 in the hopes that the Google model would succeed, but it just didn’t.
I went back to Qwen 3.5 which seemed to note the problems pretty quickly
And you can see the OpenCode session tied to Chrome in the window
The layout looks good, but the state change movement still fails as does assignment
Let’s see if the same pattern can help here. Note: before I did this next step, I did save the app as it stood
I would make progress, but then hit a wall on context limits.. I decided to to try /compact
I could now go back and try and prompt it to the next fix
However, it would just get back to broken trying to fix drag and drop which would fail
Because I check in along the way, I can revert the wild JavaScript edits so at least assignee works
However, later, when thinking about how to handle this, I did one more docker compose down and docker compose up --build -d to test and low and behold the movement works
Though, as you see, it doesn’t stick
A bit more prompting and testing and I got it so 1 move works (and sticks) but a sortable.js error keeps cropping up.
Now I did get this to work by moving to Qwen 3.8 27b. It took a good 50+ minutes on my 12Gb 3070 to get a response. I was accepting of some rather crazy times because frankly I was asking my hardware to do things well outside the bounds of norm.
So here it is, a finally preview of Kanban app written by local LLMs (primarily Qwen models) over the course of a couple of days.
Summary
I found it easy to setup and use the latest OpenCode’s latest 2.2.5 version. The game changer for me was the very functional /goal (plan) mode that would let me set some objectives to meet before getting my attention.
I tried several Ollama based models running on a Lenovo Legion with a 12Gb 3070 card. It was quick and easy to setup and use. I added the browsermcp server in the later stages to debug issues with the browser.
In comparing with frontier models like Gemini in Antigravity or Copilot, I might argue this process took longer. I operated in spurts over a 2 to 3 days. I found the last bit hardest as Qwen kept rewriting the JavaScript which my browsers kept caching.
But I did this to prove we can do this locally. It is possible to build out basic apps without falling back on paid frontier models.