OpenCode is model-agnostic by design — you can point it at Claude, GPT-4.1, Gemini, or a local Ollama model, and it wraps whichever one you choose in the same TUI and the same MCP layer. That flexibility is also where this integration gets interesting: Sequential Thinking MCP behaves identically regardless of provider (it's just a JSON schema), but how faithfully the underlying model uses revision and branching varies a lot depending on which model you've configured. This topic covers the config format, a real planning session, and where that variance actually bites.
Installing and Connecting Sequential Thinking MCP to OpenCode
OpenCode reads MCP server definitions from opencode.json, either at the project root or in ~/.config/opencode/opencode.json for a machine-wide default. The schema differs from the Claude-style mcpServers object — OpenCode uses an mcp key with an explicit type field per server:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"sequential-thinking": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-sequential-thinking"],
"enabled": true
}
}
}
type: "local" tells OpenCode to spawn the process itself over stdio, same as any other MCP client. If you're running the server elsewhere (say, a shared Docker host on your team's network) and exposing it over HTTP/SSE, use type: "remote" instead:
{
"mcp": {
"sequential-thinking": {
"type": "remote",
"url": "http://mcp-host.internal:3900/sse",
"enabled": true
}
}
}
The enabled flag is genuinely useful here in a way it isn't in most other clients — you can leave the server defined in a project-committed opencode.json but flip it off for team members who find it noisy, without deleting the config:
{
"mcp": {
"sequential-thinking": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-sequential-thinking"],
"enabled": false
}
}
}
Verify the connection from inside the TUI with the /mcp command, which lists every configured server and its live status:
> /mcp
sequential-thinking local connected 1 tool (sequentialthinking)
If it shows disconnected, the most common cause on a fresh machine is that npx isn't resolvable from the working directory OpenCode was launched in — run which npx in the same shell first, and if you're using a Node version manager (nvm, volta), make sure the shell OpenCode inherits actually has it on PATH.
Tips
- Commitopencode.jsonat the project root withenabled: trueso the whole team gets it by default, and let individuals override with a localopencode.jsonmerge if they want it off.
- Usetype: "remote"only if you already run infrastructure for it — for a single-tool server like this,localwithnpxis simpler and has no extra moving parts to keep alive.
- Run/mcpafter every OpenCode restart during setup — a silently disconnected local server is the single most common first-time issue, almost always aPATHproblem.
Running Structured Analysis Sessions in OpenCode
OpenCode's TUI shows tool calls inline in the chat pane, with each sequentialthinking invocation rendered as a compact JSON block you can expand. Unlike Claude Code's dedicated panel, there's no separate "reasoning view" — it's part of the same scrollback as everything else, so for a long chain you'll be scrolling.
Start a structured session by naming the tool directly, the same pattern that works across every client in this module:
> Use sequential thinking to work through why the /api/reports endpoint times
out for date ranges over 90 days, before proposing a fix.
With Claude 3.7 Sonnet or Claude 4.x configured as OpenCode's model, the chain reliably includes revisions when new evidence appears mid-session. With GPT-4.1 configured instead, expect thoughts that are individually solid but revise less often — GPT-4.1 tends to fold corrections into the next thought's content rather than explicitly flagging isRevision: true, so the JSON trail is less useful for later auditing even though the reasoning itself is fine. If you're running a local model through Ollama (say, a Qwen2.5-Coder variant), tool-call schema adherence gets noticeably less reliable — expect occasional malformed calls (missing totalThoughts, or thoughtNumber resetting to 1 mid-chain) that OpenCode has to retry or drop.
A representative chain against the reports-timeout example, run with Claude as the backing model:
{
"thought": "Check whether the timeout is query time or response serialization time — the endpoint returns a full JSON payload, so a 90-day range could just be a large payload, not necessarily a slow query.",
"thoughtNumber": 1,
"totalThoughts": 5,
"nextThoughtNeeded": true
}
{
"thought": "Added timing logs around the DB call vs. the serialization step in a local run — DB call is 400ms flat regardless of range, serialization jumps from 200ms at 30 days to 11 seconds at 90 days. This is a serialization problem, not a query problem.",
"thoughtNumber": 2,
"totalThoughts": 5,
"nextThoughtNeeded": true
}
{
"thought": "The serializer is using a naive nested-loop join in application code to attach line items to each report row instead of a SQL join — O(n*m) behavior explains the nonlinear blowup at scale.",
"thoughtNumber": 3,
"totalThoughts": 5,
"nextThoughtNeeded": true
}
{
"thought": "Fix: replace the application-side nested loop with a single SQL query using a LEFT JOIN and GROUP BY, moving the aggregation into the database. Also add response streaming so large payloads don't have to fully buffer before the first byte is sent.",
"thoughtNumber": 4,
"totalThoughts": 5,
"nextThoughtNeeded": false
}
Tips
- If you're running a local model via Ollama, watch the first couple of chains closely for malformed tool calls before trusting it on anything consequential — schema adherence is the main failure mode there, not reasoning quality.
- Scroll back through the chain deliberately after a session, rather than trusting your memory of it — OpenCode's inline rendering makes long chains easy to skim past without absorbing.
- Switch models mid-project if revision auditability matters more than raw reasoning quality for a given task — OpenCode makes that a one-line config change, which is its actual advantage here.
Practical Example: Planning a Database Migration Step by Step
A concrete session: splitting a monolithic orders table (currently ~40 million rows, holding both order records and shipment tracking data as denormalized columns) into orders and shipments tables, with zero downtime, on a service that can't tolerate a maintenance window.
> We need to split the orders table (40M rows) into orders + shipments with
zero downtime. Use sequential thinking to plan the migration — I want to see
schema changes, backfill strategy, and cutover as separate reasoning steps,
and flag anything that could lock the table.
{
"thought": "Schema first: create the new shipments table with a foreign key to orders.id, nullable for now. Do NOT drop the shipment columns from orders yet — this has to be additive until the cutover is verified.",
"thoughtNumber": 1,
"totalThoughts": 7,
"nextThoughtNeeded": true
}
{
"thought": "Backfill: a single INSERT INTO shipments SELECT ... FROM orders across 40M rows will hold long locks and likely blow past any statement timeout. Needs to be batched — e.g. 5,000 rows per batch keyed on orders.id ranges, with a short sleep between batches to let replication catch up.",
"thoughtNumber": 2,
"totalThoughts": 7,
"nextThoughtNeeded": true
}
{
"thought": "During backfill, orders written by the live app still only write shipment data into the old orders columns — the new shipments table will be stale for rows written after the backfill script passed them. Need dual-write in the application layer for the duration of the backfill, not just a one-time copy.",
"thoughtNumber": 3,
"totalThoughts": 8,
"nextThoughtNeeded": true,
"needsMoreThoughts": true
}
{
"thought": "Revising thought 2: batching alone isn't sufficient without dual-write from thought 3. Sequence is: (a) deploy dual-write code first, (b) run the batched backfill only after dual-write is live, so no row written during the backfill window is missed.",
"thoughtNumber": 4,
"totalThoughts": 8,
"nextThoughtNeeded": true,
"isRevision": true,
"revisesThought": 2
}
{
"thought": "Cutover: once backfill is verified complete (row count match, spot-check checksums on a sample), switch reads to the shipments table behind a feature flag, monitor for a full business day, then remove dual-write and drop the old columns in a separate, later migration — never in the same deploy as the read cutover.",
"thoughtNumber": 5,
"totalThoughts": 8,
"nextThoughtNeeded": false
}
That revision at thought 4 is the kind of thing worth pointing out to whoever reviews the migration plan afterward — it's the exact sequencing bug that causes "missing shipment data for orders placed during the migration" incidents in practice.
Tips
- For genuinely risky migrations, ask the model to flag locking risk explicitly in the prompt — it's the single highest-value thing to catch before execution, and models don't always volunteer it unprompted.
- Never let dual-write and column-drop land in the same deploy — if your planning chain doesn't separate those, push back and ask it to.
- Save the full JSON chain (copy it out of the OpenCode scrollback) into your migration's PR description — it's a better paper trail than a prose summary written after the fact.
Known Limitations for Sequential Thinking MCP in OpenCode
A few things worth knowing before you lean on this heavily inside OpenCode specifically, as distinct from the tool's general limitations:
- No persistent reasoning view. Unlike Claude Code's VS Code panel, there's no dedicated collapsible tool-use tree — everything is inline scrollback, which gets genuinely hard to navigate past 10-12 thoughts in a single session.
- Model-dependent schema adherence. As covered above, non-Anthropic and especially local models are less reliable at populating
isRevision/revisesThought/branchFromThoughtcorrectly, sometimes omitting required fields or reusingthoughtNumbervalues. - No cross-session persistence. Closing OpenCode and reopening the project starts a fresh thought history — there's no way to resume a chain from a previous session, so long-running planning work needs to happen in one sitting or you re-summarize manually at the start of a new session.
- Remote server auth is manual. If you're using
type: "remote"for a shared instance, OpenCode doesn't have a built-in secrets manager for bearer tokens the way some other clients do — you're passing auth headers in plain config unless you layer in your own secret injection.
None of these are dealbreakers, but the first two in particular mean OpenCode is a better fit for shorter, focused planning sessions than for very long exploratory chains you intend to review carefully after the fact — for that, Claude Code's VS Code panel is the more legible surface.
Tips
- Keep planning sessions to a single sitting where possible — there's no session resume for an in-progress thought chain.
- If auditability of the final chain matters, copy it out into a file or PR description immediately after the session — don't rely on TUI scrollback as your record.
- Default to Claude models for tasks where you actually need reliable revision tracking; treat local-model chains in OpenCode as directionally useful but not something to trust blindly on schema correctness.
Tips
OpenCode gives you the most model flexibility of any client in this module, which is genuinely useful for cost or provider-lock-in reasons, but that flexibility means the quality of revision and branching tracking rides entirely on which model you've wired up. Configure the server once in opencode.json, but choose your model deliberately based on whether you actually need trustworthy isRevision bookkeeping or just want a reasonable-looking plan.
Tips
- Test/mcpafter setup and after any provider switch — connection status doesn't change, but tool-call quality from the model behind it does.
- Reserve local-model + sequential-thinking combinations for low-stakes exploration, not migration or incident planning you intend to rely on.
- Export chains you care about out of the TUI scrollback promptly — there's no session history browser to come back to later.