Skip to content

MCP Servers

The OpenCode setup wires in a set of Model Context Protocol servers. They give agents documentation lookups, code search, browser control, system data, and dev-server management without shelling out for everything.

ServerTransportPurpose
answer-overflowremoteSearchable archive of programming Discord help channels. Community troubleshooting context.
astro-docsremoteSearch the official Astro framework docs. Loaded only in Astro projects (an astro.config.* marker, see below).
chrome-devtoolslocalDrive Chrome DevTools for frontend debugging: page snapshots, console, network, Lighthouse, performance traces. Loaded only in frontend projects (an index.html or web-framework/bundler config marker, see below).
context7remoteUp-to-date library and framework documentation with code examples. Needs an API key.
convexlocalConvex backend tooling: query data, run functions, inspect deployments. Loaded only in Convex projects (a convex.json or convex/ marker, see below).
fallowlocalCodebase intelligence for JavaScript and TypeScript: unused code, duplication, circular deps, complexity. Opt-in (held out of default tools) and loaded only in JS/TS repos (a package.json marker, see below).
githubremoteRead-only GitHub access: issues, PRs, Actions, code scanning, Dependabot, discussions, projects. Needs a bearer token.
grepremoteSearch real-world code across public GitHub repos via grep.app.
pitchforklocalManage long-running dev-server daemons: start, stop, restart, status, logs. Loaded only in repos with a pitchfork.toml (see below).
system-bridgelocalSystem Bridge: system info modules (cpu, memory, disks, media) and media control.

Remote servers connect over HTTP to a hosted endpoint. Local servers are launched on demand over stdio (opencode x, npx, or an installed binary).

The system-bridge server runs the system-bridge-mcp binary from the system-bridge-git AUR package. That package is listed in the public .dot-public-packages manifest and installed by dot init and dot update, so the MCP command is available on a fully set-up machine without a separate install step.

Every harness’s MCP config is generated from a single private spec, ~/.config/dotfiles-private/mcp.yml, by dot mcp-sync. One edit to the spec regenerates each harness’s native config in the stowed source tree, so the harnesses stay aligned instead of drifting apart by hand.

Active harnesses (generated):

  • OpenCode (agents/.config/opencode/opencode.json, mcp block)
  • Cursor (agents/.cursor/mcp.json, mcpServers)
  • VS Code (agents/.config/Code/User/mcp.json, servers)
  • Copilot CLI (agents/.copilot/mcp-config.json, mcpServers)

The spec defines each server once and enables it for every active harness, so all four expose the same set. Enablement is written out as an explicit per-harness matrix, so any single cell can be flipped later. A canonical {env:VAR} reference is rewritten to each harness’s native syntax ({env:VAR}, ${env:VAR}, or ${VAR}), and commands that differ by harness (such as the OpenCode opencode x runner for chrome-devtools) are carried as per-harness overrides.

The OpenCode config is written as a full catalogue: every server appears with an explicit enabled: true or enabled: false, so a server can be turned off in place while staying documented. The other harnesses list only their enabled servers.

Three more harnesses are kept as documented stubs, not generated:

  • Gemini CLI would need an mcpServers block in ~/.gemini/settings.json using $VAR env syntax.
  • Codex CLI would need [mcp_servers.NAME] TOML tables in ~/.codex/config.toml.
  • Claude Code is special: ~/.claude.json is a live runtime state file Claude rewrites, so it is wired with claude mcp add, not file generation.

Run dot mcp-sync after editing the spec, then dot stow. dot update runs it automatically before re-stowing.

Two kinds of gating keep sessions light without hiding tools you actually want.

Opt-in servers. Fallow is registered but held out of the default tools with a tools glob, so it never runs automatically on a TypeScript edit:

{
"tools": {
"fallow*": false
}
}

It runs only when invoked by name or through a /fallow-* command. The tools glob only holds Fallow’s tools out of the default set; the server itself still connects wherever it is enabled, so it is also repo-gated below to stop it connecting outside JS/TS repos.

Per-repo servers. Some servers are only useful in repos with a matching marker. The mcp-repo-gate plugin prunes them from the merged config at startup when none of their markers are present, so their tools do not load where they are irrelevant. Each server maps to one or more markers (files or directories); any one, found in the project directory, an ancestor, or a nearby descendant (up to two levels down, so a monorepo whose project sits in a subdirectory still counts), keeps the server. For example, pitchfork is dropped in any repo without a pitchfork.toml, fallow outside JS/TS repos, convex outside Convex projects, astro-docs outside Astro projects, and chrome-devtools (~27 tools, ~4.3k tokens of schema) outside frontend projects:

const REPO_REQUIRED_MARKERS: Record<string, readonly string[]> = {
pitchfork: ["pitchfork.toml"],
fallow: ["package.json"],
convex: ["convex.json", "convex"],
"astro-docs": [
"astro.config.mjs",
"astro.config.ts",
"astro.config.mts",
"astro.config.js",
"astro.config.cjs",
],
// Any one frontend signal keeps chrome-devtools loaded (static entry point
// or a web-framework/bundler config). Attach it from a non-frontend
// directory by restarting OpenCode there.
"chrome-devtools": [
"index.html",
"astro.config.mjs",
"vite.config.ts",
"next.config.js",
"nuxt.config.ts",
"svelte.config.js",
"vue.config.js",
"angular.json",
// ...plus the remaining astro/vite/next config extensions
],
};

The plugin is deliberately conservative: only servers listed in that map are ever removed, and only when none of their markers are found upward to the filesystem root or in a short downward scan (which skips hidden and build/vendor directories). Every other server stays on everywhere, so no tool is hidden where it might be wanted.

A trimmed, sanitised opencode.json. Machine-specific repository paths are removed from the permission allow-lists, and secrets are {env:...} references with generic FOO/BAR placeholders standing in for real variable names. Adjust the permission allow-lists to your own trusted paths. In the real generated file every server also carries an explicit "enabled": true (or false), which is omitted here for brevity.

{
"$schema": "https://opencode.ai/config.json",
"autoupdate": false,
"shell": "/bin/zsh -l",
"permission": {
"external_directory": {
"~/.config/dotfiles/**": "allow",
"/tmp/**": "allow",
"**/.ssh/**": "deny",
"**/.aws/**": "deny",
"**/.gnupg/**": "deny",
"**/.kube/**": "deny",
"~/.docker/config.json": "deny",
"~/.config/gh/hosts.yml": "deny",
"~/.local/share/opencode/mcp-auth.json": "deny"
},
"read": {
"/tmp/**": "allow",
"**/.env.example": "allow",
"**/.env": "deny",
"**/.env.*": "deny",
"*.pem": "deny",
"*.key": "deny",
"**/.ssh/**": "deny",
"**/.gnupg/**": "deny"
},
"bash": {
"git commit": "deny",
"git commit *": "deny",
"git commit --amend": "ask",
"dot": "allow",
"dot *": "allow"
},
"lsp": "allow",
"webfetch": "allow",
"websearch": "allow"
},
"lsp": true,
"tools": {
"fallow*": false
},
"mcp": {
"answer-overflow": {
"type": "remote",
"url": "https://www.answeroverflow.com/mcp"
},
"astro-docs": {
"type": "remote",
"url": "https://mcp.docs.astro.build/mcp"
},
"chrome-devtools": {
"type": "local",
"command": ["opencode", "x", "chrome-devtools-mcp@latest"]
},
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/mcp",
"headers": {
"CONTEXT7_API_KEY": "{env:FOO}"
}
},
"fallow": {
"type": "local",
"command": ["npx", "-y", "--package", "fallow@latest", "fallow-mcp"]
},
"github": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/x/all/readonly",
"oauth": false,
"headers": {
"Authorization": "Bearer {env:BAR}"
}
},
"grep": {
"type": "remote",
"url": "https://mcp.grep.app"
},
"pitchfork": {
"type": "local",
"command": ["pitchfork", "mcp"]
},
"system-bridge": {
"type": "local",
"command": ["system-bridge-mcp"]
}
}
}

The dot binary also ships its own MCP server for the notes vault. That is separate from the servers above and is documented under the dot Command MCP Server.