Start typing to search the documentation.

Docs navigation

MCP servers

OpenCode connects to Model Context Protocol servers and exposes capabilities such as tools, prompts, resources, and instructions. MCP tools consume model context, so add only the servers you need.

Setup

Add a remote server from the project that should use it, then check its connection:

opencode mcp add context7 --url https://mcp.context7.com/mcp
opencode mcp list

The command writes the server to the project configuration. Add --global to make it available in every project:

opencode mcp add context7 --global --url https://mcp.context7.com/mcp

Remote servers use OAuth by default. If the list shows needs authentication, open OpenCode, run /mcps, select the server, and sign in. A connected server is ready for an agent to use:

✓ context7  connected

Config

To configure a server by hand, give it a unique name under mcp.servers. V2 does not place server names directly under mcp.

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "my-server": {
        "type": "local",
        "command": ["npx", "-y", "example-mcp-server"],
      },
    },
  },
}

Servers connect automatically. Use disabled, not an enabled field, to keep one configured without connecting it:

{
  "mcp": {
    "servers": {
      "my-server": {
        "type": "local",
        "command": ["npx", "-y", "example-mcp-server"],
        "disabled": true,
      },
    },
  },
}

A higher-precedence project config replaces the entire server object with the same name. Use different names for separate connections or accounts; otherwise repeat every required field in the override:

opencode.jsonc
{
  "mcp": {
    "servers": {
      "my-server": {
        "type": "remote",
        "url": "https://mcp.example.com/mcp",
      },
    },
  },
}

Local

A local server is a command that OpenCode starts over the MCP stdio transport. Add one with a command after --:

opencode mcp add everything -- npx -y @modelcontextprotocol/server-everything

Use configuration for process options such as a working directory or environment variables:

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "everything": {
        "type": "local",
        "command": ["npx", "-y", "@modelcontextprotocol/server-everything"],
        "cwd": ".",
        "environment": {
          "LOG_LEVEL": "info",
          "MCP_API_KEY": "{env:MCP_API_KEY}",
        },
      },
    },
  },
}
FieldRequiredDescription
typeYesMust be "local".
commandYesExecutable followed by its arguments.
cwdNoProcess directory. Relative paths resolve from the workspace, which is also the default.
environmentNoString variables added to OpenCode’s inherited process environment.
disabledNoPrevents connection when true. Defaults to false.
codemodeNoSet to false to expose tools directly instead of through Code Mode. Defaults to true.
timeoutNoPer-server timeout overrides.
protocolNolegacy (default), auto, or 2026-07-28. See Protocol version.

Use {env:NAME} for environment substitution. Shell expressions such as $NAME are not expanded in JSON strings:

{
  "environment": {
    "MCP_API_KEY": "{env:MCP_API_KEY}",
  },
}

Remote

A remote server uses the MCP Streamable HTTP transport and requires an absolute URL:

opencode mcp add context7 --url https://mcp.context7.com/mcp

Use configuration when the server needs headers or other options. Store secrets in environment variables rather than in the file:

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "context7": {
        "type": "remote",
        "url": "https://mcp.context7.com/mcp",
        "oauth": false,
        "headers": {
          "CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}",
        },
      },
    },
  },
}
FieldRequiredDescription
typeYesMust be "remote".
urlYesAbsolute Streamable HTTP endpoint.
headersNoString HTTP headers sent to the endpoint.
oauthNoOAuth settings, or false to disable OAuth.
disabledNoPrevents connection when true. Defaults to false.
codemodeNoSet to false to expose tools directly instead of through Code Mode. Defaults to true.
timeoutNoPer-server timeout overrides.
protocolNolegacy (default), auto, or 2026-07-28. See Protocol version.

Use oauth: false only when the server exclusively uses an API key or another header credential:

{
  "type": "remote",
  "url": "https://mcp.example.com/mcp",
  "oauth": false,
  "headers": { "Authorization": "Bearer {env:MCP_API_KEY}" },
}

OAuth

OAuth is enabled for remote servers unless oauth is false. OpenCode discovers the authorization server, uses PKCE, refreshes tokens, and attempts dynamic client registration when supported; credentials stay outside project configuration.

For dynamic registration, configure only the server URL:

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "sentry": {
        "type": "remote",
        "url": "https://mcp.sentry.dev/mcp",
      },
    },
  },
}

If the server needs authentication, run /mcps, select it, and complete authorization in the browser. The CLI can start the same flow:

opencode mcp auth sentry

When a provider gives you client credentials, use V2’s snake_case OAuth fields:

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "company-tools": {
        "type": "remote",
        "url": "https://mcp.example.com/mcp",
        "oauth": {
          "client_id": "{env:MCP_CLIENT_ID}",
          "client_secret": "{env:MCP_CLIENT_SECRET}",
          "scope": "tools:read tools:execute",
          "callback_port": 19876,
          "redirect_uri": "http://127.0.0.1:19876/callback",
        },
      },
    },
  },
}
FieldDescription
client_idPre-registered client ID. Omit it to attempt dynamic registration.
client_secretSecret for a pre-registered client.
scopeSpace-delimited scopes to request.
callback_portLocal callback port from 1 through 65535. An available ephemeral port is the default.
redirect_uriPre-registered loopback URI whose path and port reach the local callback listener.

Remove stored OAuth credentials when you need to sign in again or switch accounts:

opencode mcp logout sentry

Timeouts

Timeouts are positive integer milliseconds. Set defaults under mcp.timeout; a server’s timeout object overrides matching defaults.

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "timeout": {
      "startup": 45000,
      "catalog": 30000,
      "execution": 600000,
    },
    "servers": {
      "slow-tools": {
        "type": "remote",
        "url": "https://mcp.example.com/mcp",
        "timeout": {
          "catalog": 60000,
        },
      },
    },
  },
}
TimeoutDefaultApplies to
startup30 secondsTransport connection and server initialization.
catalog30 secondsListing tools, prompts, resources, and resource templates.
execution12 hoursTool calls, prompt retrieval, and resource reads.

Protocol version

OpenCode opens every server with the classic MCP initialize handshake by default. Set a server’s protocol to talk to one built on the 2026-07-28 revision:

opencode.jsonc
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "modern": {
        "type": "remote",
        "url": "https://mcp.example.com/mcp",
        "protocol": "auto",
      },
    },
  },
}
ValueBehavior
legacyDefault. Sends initialize and speaks protocol revisions up to 2025-11-25.
autoProbes with server/discover for the 2026-07-28 revision and falls back to legacy when the server does not support it.
2026-07-28Requires the 2026-07-28 revision. The connection fails against older servers.

Probing a local legacy server adds a short-lived extra process and can wait up to the startup timeout when the server ignores unknown requests, so keep auto scoped to servers that need it.

Names

OpenCode names a tool <server>_<tool>. It replaces characters other than letters, numbers, _, and - with _:

server: context 7
tool:   resolve.library/id
name:   context_7_resolve_library_id

MCP prompts become commands named <server>:<prompt> with the same normalization. For example:

/context_7:find_docs

Choose short server names that remain unique after normalization. Under the default Code Mode, tools are grouped by the normalized server name:

tools.context_7.resolve_library_id(...)

Permissions

Code Mode is the default. Set codemode to false when a server’s tools must stay on the provider’s native tool list:

{
  "mcp": {
    "servers": {
      "context7": {
        "type": "remote",
        "url": "https://mcp.context7.com/mcp",
        "codemode": false,
      },
    },
  },
}

Use permission actions to hide or deny tools without disconnecting their server. Match the normalized <server>_<tool> name:

{
  "permissions": [
    {
      "action": "context7_*",
      "resource": "*",
      "effect": "deny",
    },
  ],
}

Context

For calls made on behalf of a session, OpenCode sends the session ID in CallToolRequest.params._meta.sessionID. This applies to direct tools and Code Mode over stdio and Streamable HTTP:

{
  "method": "tools/call",
  "params": {
    "name": "lookup",
    "arguments": { "query": "example" },
    "_meta": { "sessionID": "ses_..." }
  }
}

The ID is request metadata, not a tool argument, so it is absent from the model-visible schema. Treat it as an opaque correlation value:

RuleBehavior
IdentityIt identifies the invoking OpenCode session, not the MCP transport session.
PresenceIt can be absent for calls without session context.
SecurityDo not use it by itself for authentication or authorization.
PrivacyRemote servers receive the raw ID and may log or retain it.

Management

List servers and their current connection state from any project:

opencode mcp list

Use /mcps in OpenCode to view, connect, disconnect, or authenticate servers. Use the CLI to add servers and manage OAuth credentials:

opencode mcp add sentry --url https://mcp.sentry.dev/mcp
opencode mcp auth sentry
opencode mcp logout sentry

To remove a server, delete its entry from the project or global configuration where it was added:

{
  "mcp": {
    "servers": {},
  },
}

Edit configuration directly for OAuth client settings, timeouts, working directories, or persistent enablement:

{
  "mcp": {
    "servers": {
      "sentry": {
        "type": "remote",
        "url": "https://mcp.sentry.dev/mcp",
        "disabled": true,
      },
    },
  },
}