MCP servers and custom tools

Give the agent access to a database, an issue tracker or a browser through MCP, and manage the context cost and trust that comes with it.

Local and remote servers

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "filesystem": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "."],
      "enabled": true
    },
    "postgres": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-postgres"],
      "environment": { "DATABASE_URL": "{env:DATABASE_URL}" }
    },
    "sentry": {
      "type": "remote",
      "url": "https://mcp.sentry.dev/mcp",
      "enabled": false
    }
  }
}
FieldApplies toNotes
typeBothlocal speaks stdio, remote speaks HTTP
commandLocalArgv array - no shell parsing
environmentLocalEnvironment for the child process
urlRemoteThe server endpoint
headersRemoteAuth headers, if the server needs them
enabledBothKeep disabled entries configured but off
  • Tools appear to the agent prefixed with the server name, so postgres contributes tools named postgres_*.
  • Keep unused servers in the file with enabled: false - the configuration is the documentation of what is available.

Every tool has a context price

Tool definitions from connected servers are part of the prompt on every turn. Adding four servers with twenty tools each makes the session permanently more expensive and, more subtly, makes tool selection harder: the model has more ways to be wrong.

# how much context is in play right now
/context

# a rough comparison: connect one server, measure, connect another, measure
opencode run "how many tools do you currently have available?"
⚠️
MCP output is untrusted text that lands in your context. A server that reads an issue tracker can carry a stranger's words straight into the model's reasoning, and a server with a write-capable token can be talked into using it. Use read-only credentials where possible, and prefer a token scoped to one resource over an account-wide key.

Scoping and troubleshooting

{
  "mcp": {
    "postgres": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-postgres"],
      "environment": { "DATABASE_URL": "{env:DATABASE_READONLY_URL}" }
    }
  },
  "permission": {
    "bash": { "*": "ask", "git status*": "allow" }
  }
}
  • Point the agent at a read-only database role so the worst case is a bad query, not a bad write.
  • A local server that fails to start produces no tools and no obvious error in the TUI; run the command by hand to see why.
  • Remote servers usually authenticate with OAuth on first use, and the token is stored with your other credentials.
  • Disable a server rather than deleting it when you are debugging - it is one flag to restore.

The honest test of whether a server is worth its context is whether you would notice its absence. If you would not, disable it.

FAQ

What is the difference between a local and a remote MCP server?
A local server is a process started on your machine and spoken to over stdio; a remote server is an HTTP endpoint you connect to. Local servers can reach localhost-only services and your filesystem. Remote servers are easier to share across a team but send tool arguments to a third party.
My MCP server is enabled but the agent never uses it. Why?
Check that the server actually started - run its command by hand. If it starts, the issue is usually that its tool descriptions are vague, so the agent cannot tell when to use them. Ask the agent to list its tools to confirm they are visible.

Skills, plugins and custom commands Permissions, privacy and secret handling

Last refreshed 2026-09-18.