·

Setting Up MCP In Opencode

Step-by-step setup of MCP servers in OpenCode, so your AI agent can reach external tools and data from day one.

OpenCode is the odd one out in this module — it's the only fully open-source, terminal-native agent of the four, built to be model-agnostic (works with Claude, GPT, Gemini, and local models via Ollama alike). Its MCP support is solid but the configuration format has shifted between versions more than the other tools', so this guide pins exact syntax and calls out what changed.

What Is OpenCode and How Does It Support MCP?

OpenCode (the sst/opencode project, not to be confused with unrelated same-named tools) is a TUI-based coding agent you run in a terminal, similar in spirit to Claude Code CLI but decoupled from any single model provider. You configure a provider (Anthropic, OpenAI, Google, or a local endpoint) and OpenCode drives that model through its own agent loop, with MCP servers as the extension mechanism for external tools.

Install it via npm or the install script:

npm install -g opencode-ai
curl -fsSL https://opencode.ai/install | bash

opencode --version

OpenCode supports MCP the same way the other tools do conceptually — stdio for local processes, and remote (labeled differently depending on version — check opencode --version against release notes if type values below don't match) for network-based servers. The important architectural difference: OpenCode's config is TOML-first (opencode.toml or config.toml), though newer versions also accept a JSON opencode.json for teams that prefer that format. Both configure the same underlying agent — pick one per project and don't mix them, since OpenCode reads opencode.json first if both exist.

opencode auth login

Tips
- Run opencode --version before following any online guide, including this one — OpenCode ships frequent releases and config keys have been renamed at least twice in its history (mcpmcpServers in one minor version bump).
- If you're standardizing a team on OpenCode specifically for its model-agnostic nature, document which provider each teammate uses in the README — MCP tool availability doesn't change per provider, but token limits and tool-call reliability do.


Adding MCP Servers to OpenCode's config.toml

Project-level config lives at .opencode/config.toml in the repo root (or opencode.toml at the root in some versions — again, check your installed version's docs). Global config lives at ~/.config/opencode/config.toml.

A local stdio server:

[mcp.filesystem]
type = "local"
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."]
enabled = true

A remote server:

[mcp.linear]
type = "remote"
url = "https://mcp.linear.app/http"
enabled = true

[mcp.linear.headers]
Authorization = "Bearer ${LINEAR_MCP_TOKEN}"

If your OpenCode version uses the JSON config path instead, the equivalent looks like this — structurally close to Claude Code's format, which makes migrating a shared server list between the two tools fairly mechanical:

{
  "mcp": {
    "filesystem": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."],
      "enabled": true
    },
    "linear": {
      "type": "remote",
      "url": "https://mcp.linear.app/http",
      "headers": {
        "Authorization": "Bearer ${LINEAR_MCP_TOKEN}"
      },
      "enabled": true
    }
  }
}

A few OpenCode-specific details:

  • enabled = true/false lets you keep a server defined but temporarily switched off — handy for servers you only need occasionally (a load-testing MCP server, for instance) without deleting the config block.
  • command is an array in TOML, not a separate command + args split like Claude Code — the full invocation including the binary name goes in one list.
  • Environment variable interpolation (${VAR}) works the same way as the other tools, resolved from the shell OpenCode was launched in.
python3 -c "import tomllib; tomllib.load(open('.opencode/config.toml','rb'))" && echo "valid TOML"

Tips
- Keep enabled = false blocks in version control rather than deleting them — it documents "this server exists and works, just isn't on by default" for the next person who opens the file.
- TOML is stricter about types than JSON in subtle ways (no trailing commas, distinct table syntax) — validate with a linter before committing, since OpenCode's error messages for malformed TOML are terser than Claude Code's JSON parser errors.


Running OpenCode with MCP in a Real Development Workflow

Launch OpenCode from your project root so it picks up project-scoped config:

cd ~/projects/my-service
opencode

Inside the TUI, list active MCP connections with the built-in command:

/mcp

This shows connected servers and their exposed tools, similar to Claude Code's equivalent panel but rendered in OpenCode's terminal UI rather than a chat sidebar.

A realistic workflow: say you're using OpenCode with a Postgres MCP server to review a migration before running it.

[mcp.postgres]
type = "local"
command = ["npx", "-y", "@modelcontextprotocol/server-postgres"]
enabled = true

[mcp.postgres.environment]
DATABASE_URL = "${STAGING_DATABASE_URL}"

Then in the session:

> Using the postgres MCP tool, show me the current schema for the "orders" table,
> then review migrations/0042_add_shipping_address.sql for compatibility issues.

OpenCode calls the MCP tool, gets the live schema back as tool output, and reasons over both the tool result and the migration file content in the same turn — this is the core value of MCP over just pasting schema dumps into a prompt manually: the agent fetches current, accurate state instead of working from a snapshot you remembered to paste in.

Because OpenCode is provider-agnostic, worth noting: tool-calling reliability varies by which model you've configured. Claude models (via Anthropic API) and GPT-4-class models handle MCP tool selection well; smaller local models via Ollama are noticeably weaker at picking the right tool from a large registered set, so keep server counts down (3-5 max) if you're running OpenCode against a local model.

Tips
- If you switch providers mid-project (say, from Anthropic to a local Ollama model for cost reasons), re-test your MCP tool set — tool-selection quality is not uniform across models even though the MCP servers themselves don't change.
- Use /mcp at the start of every session after a config change, not just once — OpenCode's config reload behavior on file edits is version-dependent and a stale in-memory server list is a common source of "why isn't my new tool showing up" confusion.


Troubleshooting Common OpenCode MCP Setup Issues

Because OpenCode's config format has moved around across releases, most setup failures fall into one of these buckets:

"Unknown key 'mcp' in config" — you're on a version where the section is still named mcpServers, or vice versa. Check the changelog for your installed version:

opencode --version
opencode changelog | grep -i mcp

Server defined but not listed under /mcp — check enabled isn't set to false, and confirm you edited the config file OpenCode actually reads. If both opencode.json and .opencode/config.toml exist in the same repo, OpenCode's JSON-first precedence means your TOML edits are silently ignored.

find . -maxdepth 3 -iname "opencode.json" -o -iname "config.toml" -path "*opencode*"

Environment variable not resolving in ${VAR} syntax — confirm the variable is exported in the exact shell session you launched opencode from:

echo $LINEAR_MCP_TOKEN
export LINEAR_MCP_TOKEN="lin_mcp_..."
opencode

stdio server exits immediately — run the command array manually, exactly as written in the TOML, to see the real error:

npx -y @modelcontextprotocol/server-postgres

TOML parse errors on startup — OpenCode fails closed on malformed config, meaning MCP (and sometimes the whole session) won't start rather than degrading gracefully. Always validate syntax after manual edits as shown earlier in this topic.

Tips
- Because OpenCode is younger and iterates faster than Claude Code or Cursor, pin your team to an exact version (opencode-ai@0.4.2, for example) in your setup docs rather than "latest" — config schema changes between minor versions have broken shared team configs in the past.
- When in doubt about current config format, opencode config --help or the equivalent inspection command for your installed version is more reliable than a blog post (including parts of this one) written against an older release.


Tips

Tips
- Pin an exact OpenCode version for your team and note it in your repo's setup docs — config format drift between releases is the single biggest source of "it works on my machine" MCP issues with this tool.
- Prefer .opencode/config.toml at project scope for team-shared servers, and reserve ~/.config/opencode/config.toml for personal, cross-project tools.
- Keep the MCP server count small (3-5) when your configured provider is a smaller or local model — tool-selection accuracy degrades faster than with frontier models as the registered tool list grows.