Skip to main content

Three-Tier MCP System

oh-my-opencode supports MCPs from three sources:
TierSourceMechanismPriority
1. Built-insrc/mcp/3 remote HTTP MCPsHighest
2. Claude Code.mcp.json${VAR} env expansionMedium
3. Skill-embeddedSKILL.md YAMLManaged by SkillMcpManagerLowest
All three tiers can coexist in a single session.

Built-in MCPs

oh-my-opencode provides 3 built-in remote MCPs:

Websearch

websearch
object
Web search via Exa AI (default) or Tavily.Default provider: Exa AI
{
  "websearch": {
    "provider": "exa"
  }
}
Switch to Tavily:
{
  "websearch": {
    "provider": "tavily"
  }
}
Environment variables:
  • EXA_API_KEY (optional for Exa)
  • TAVILY_API_KEY (required for Tavily)
MCP URL:
  • Exa: https://mcp.exa.ai
  • Tavily: https://mcp.tavily.com

Context7

context7
object
Library documentation search.
{
  // Enabled by default, no config needed
}
Environment variables:
  • CONTEXT7_API_KEY (optional)
MCP URL:
  • https://mcp.context7.com/mcp

Grep App

grep_app
object
GitHub code search via grep.app.
{
  // Enabled by default, no config needed
}
Environment variables:
  • None required
MCP URL:
  • https://mcp.grep.app

Disabling Built-in MCPs

Two methods to disable built-in MCPs:

Method 1: Global Array

{
  "disabled_mcps": ["websearch", "context7", "grep_app"]
}

Method 2: Per-MCP Config

{
  "websearch": { "enabled": false },
  "context7": { "enabled": false }
}

Claude Code MCP Loading

Tier 2 loads MCPs from .mcp.json files using the claude-code-mcp-loader.

Supported Locations

ScopePath
Home (legacy)~/.claude.json
User~/.config/opencode/.mcp.json
Project (1).mcp.json
Project (2).claude/.mcp.json

Environment Variable Expansion

Supports ${VAR} syntax for environment variables:
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}/workspace"],
      "env": {
        "API_KEY": "${MY_API_KEY}"
      }
    }
  }
}

Example Configuration

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/Documents"]
    },
    "postgres": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "mcp/postgres"],
      "env": {
        "POSTGRES_CONNECTION_STRING": "${POSTGRES_URL}"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

Enabling/Disabling

claude_code.mcp
boolean
default:true
Enable/disable Claude Code MCP loading.Disable all .mcp.json files:
{
  "claude_code": {
    "mcp": false
  }
}
Keep built-in MCPs, disable .mcp.json:
{
  "claude_code": {
    "mcp": false
  }
  // Built-in MCPs (websearch, context7, grep_app) still active
}

Skill-Embedded MCPs

Tier 3 loads MCPs embedded in skill YAML frontmatter.

MCP Definition in Skills

Skills can bundle MCPs using YAML frontmatter:
---
name: my-skill
description: Custom skill with MCP
mcp:
  type: stdio
  command: npx
  args:
    - -y
    - @my-org/my-mcp-server
  env:
    API_KEY: ${MY_API_KEY}
---

# Skill content here...

Supported MCP Types

Stdio MCP (command-based):
mcp:
  type: stdio
  command: npx
  args:
    - -y
    - @modelcontextprotocol/server-filesystem
    - /path/to/dir
  env:
    DEBUG: "true"

Built-in Skills with MCPs

Some built-in skills include MCPs:
SkillMCP TypeMCP Server
playwrightstdio@playwright/mcp
Disable skill-embedded MCP:
{
  "disabled_skills": ["playwright"]  // Disables skill + its MCP
}

MCP OAuth Support

oh-my-opencode supports OAuth 2.0 + PKCE + Dynamic Client Registration (RFC 7591) for MCP servers. Manage OAuth flows:
bunx oh-my-opencode mcp-oauth
Commands:
  • list — Show all OAuth tokens
  • revoke <server> — Revoke token for server
  • clear — Clear all tokens

Listing Active MCPs

Check which MCPs are active:
bunx oh-my-opencode doctor --verbose
Output:
MCPs       websearch · context7 · grep_app
User MCPs  filesystem · github · postgres

Complete Example

A comprehensive MCP configuration:
{
  // Disable built-in websearch, keep others
  "disabled_mcps": ["websearch"],

  // Configure context7 (still enabled)
  "context7": {
    // Uses default settings
  },

  // Enable Claude Code MCP loading
  "claude_code": {
    "mcp": true
  },

  // Skills with embedded MCPs
  "skills": {
    "sources": [
      { "path": "./my-skills", "recursive": true }
    ],
    "enable": ["playwright"]  // Includes @playwright/mcp
  },

  "disabled_skills": ["agent-browser"]  // Disable this skill + its MCP
}
Corresponding .mcp.json:
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}/workspace"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

Debugging MCPs

Check MCP Status

bunx oh-my-opencode doctor

View MCP Logs

Logs are written to:
/tmp/oh-my-opencode.log
Tail the log:
tail -f /tmp/oh-my-opencode.log | grep MCP

Common Issues

Check:
  1. Command path is correct (which npx, which docker)
  2. Environment variables are set
  3. Permissions for stdio commands
Debug:
# Test command directly
npx -y @modelcontextprotocol/server-filesystem /path
Issue: ${VAR} not replacedSolution:
  1. Verify variable is exported: echo $MY_VAR
  2. Check .mcp.json syntax (no spaces: ${VAR}, not ${ VAR })
  3. Restart OpenCode after setting env vars
Check:
  1. Skill is enabled (not in disabled_skills)
  2. YAML frontmatter is valid
  3. Skill source path is correct
Debug:
bunx oh-my-opencode doctor --verbose

Next Steps

Skills

Learn about skill system and skill-embedded MCPs

Hooks

Customize lifecycle hooks

Build docs developers (and LLMs) love