Skip to content

5.7b MCP Advanced ​

💡 TL;DR: Master OAuth authentication, permission management, and common MCP service configuration.

📝 Course Notes ​

Key concepts from this lesson:

MCP Advanced Notes

What You'll Learn ​

  • Use OAuth authentication to connect to secure services
  • Manage MCP tool permissions and enable/disable status
  • Integrate MCP usage in rule files
  • Configure common MCP services

OAuth Authentication ​

OpenCode automatically handles the OAuth authentication flow:

  1. Detects 401 response and initiates OAuth flow
  2. Uses Dynamic Client Registration (RFC 7591) (if server supports it)
  3. Tokens are securely stored in ~/.local/share/opencode/mcp-auth.json

Automatic Authentication ​

In most cases, no special configuration is needed:

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

OpenCode will automatically prompt for authentication on first use.

Pre-registered Client ​

If the server doesn't support dynamic registration, configure client credentials:

jsonc
{
  "mcp": {
    "my-oauth-server": {
      "type": "remote",
      "url": "https://mcp.example.com/mcp",
      "oauth": {
        "clientId": "{env:MY_MCP_CLIENT_ID}",
        "clientSecret": "{env:MY_MCP_CLIENT_SECRET}",
        "scope": "tools:read tools:execute"
      }
    }
  }
}

Management Commands ​

bash
# Manually trigger authentication
opencode mcp auth my-oauth-server

# View authentication status for all servers
opencode mcp auth list

# List all MCP servers
opencode mcp list

# Remove stored credentials
opencode mcp logout my-oauth-server

# Debug connection and OAuth flow
opencode mcp debug my-oauth-server

Debug Command Details ​

When MCP connection issues arise, use the debug command to diagnose:

bash
opencode mcp debug my-oauth-server

Sample Output:

MCP OAuth Debug

Server: my-oauth-server
URL: https://mcp.example.com/mcp
Auth status: ✓ authenticated
  Access token: eyJhbGciOiJSUzI1NiIs...
  Expires: 2026-02-15T12:00:00.000Z
  Refresh token: present

Testing connection...
HTTP response: 200 OK
✓ Server responded successfully

Status Meanings:

StatusDescription
authenticatedAuthenticated, ready to use
expiredToken expired, needs re-authentication
not authenticatedNot authenticated, run opencode mcp auth

Server Status Icons ​

Icons in opencode mcp list output:

IconStatusDescription
✓connectedConnected, tools available
○disabledDisabled via enabled: false
⚠needs_authRequires OAuth authentication
✗failedConnection failed, check error message

Sample Output:

MCP Servers

✓ filesystem connected
    npx -y @modelcontextprotocol/server-filesystem /projects
✓ context7 connected
    https://mcp.context7.com/mcp
○ disabled-server disabled
    npx -y some-command
✗ failed-server failed
    Connection timeout

Disabling OAuth ​

If the server uses API Key instead of OAuth:

jsonc
{
  "mcp": {
    "my-api-key-server": {
      "type": "remote",
      "url": "https://mcp.example.com/mcp",
      "oauth": false,
      "headers": {
        "Authorization": "Bearer {env:MY_API_KEY}"
      }
    }
  }
}

Tool Permission Management ​

MCP tools are registered using {server_name}_{tool_name} format.

Global Disable ​

Use permission configuration to disable MCP tools:

jsonc
{
  "mcp": {
    "my-mcp-foo": {
      "type": "local",
      "command": ["bun", "x", "my-mcp-command-foo"]
    },
    "my-mcp-bar": {
      "type": "local",
      "command": ["bun", "x", "my-mcp-command-bar"]
    }
  },
  "permission": {
    "my-mcp-foo_*": "deny"
  }
}

Use wildcards to batch disable:

jsonc
{
  "permission": {
    "my-mcp*": "deny"
  }
}

Per-Agent Enable ​

After global disable, enable in specific agents:

jsonc
{
  "mcp": {
    "my-mcp": {
      "type": "local",
      "command": ["bun", "x", "my-mcp-command"]
    }
  },
  "permission": {
    "my-mcp*": "deny"
  },
  "agent": {
    "my-agent": {
      "permission": {
        "my-mcp*": "allow"
      }
    }
  }
}

Wildcard Rules ​

  • * matches zero or more characters
  • ? matches exactly one character
  • Other characters match literally

Integration in Rule Files ​

Configure default MCP usage in AGENTS.md or .opencode/agents/*.md:

markdown
## MCP Usage Rules

When querying documentation, use the `context7` tool.

When unsure how to implement a feature, use `gh_grep` to search GitHub for code examples.

This way the AI automatically selects appropriate MCP tools without specifying them in every prompt.


Tool Auto-Discovery and Updates ​

Tool Naming Convention ​

MCP tools are registered using {server_name}_{tool_name} format:

filesystem server's read_file tool → filesystem_read_file
context7 server's search tool     → context7_search

Auto-Discovery Mechanism ​

After configuring an MCP server, OpenCode automatically discovers all tools the server provides:

  1. Connect to MCP server
  2. Call listTools to get tool list
  3. Convert tools to OpenCode format
  4. Add to current session's tool set

Tool Change Notifications ​

If the MCP server's tool list changes (tools added/removed), OpenCode automatically receives notifications and updates:

  • Server sends tool list change notification (notifications/tools/list_changed)
  • OpenCode re-fetches the tool list
  • No need to restart OpenCode

This means: after upgrading an MCP server version, new tools become automatically available.


Sentry ​

Connect to Sentry monitoring platform to query errors and issues:

jsonc
{
  "mcp": {
    "sentry": {
      "type": "remote",
      "url": "https://mcp.sentry.dev/mcp",
      "oauth": {}
    }
  }
}

First-time use requires authentication:

bash
opencode mcp auth sentry

Usage example:

use sentry to view recent unresolved errors

Context7 ​

Search documentation for various libraries and frameworks:

jsonc
{
  "mcp": {
    "context7": {
      "type": "remote",
      "url": "https://mcp.context7.com/mcp"
    }
  }
}

Use API Key for higher rate limits:

jsonc
{
  "mcp": {
    "context7": {
      "type": "remote",
      "url": "https://mcp.context7.com/mcp",
      "headers": {
        "CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}"
      }
    }
  }
}

Usage example:

use context7 to query how Cloudflare Worker caches JSON responses

Grep by Vercel ​

Search code snippets on GitHub:

jsonc
{
  "mcp": {
    "gh_grep": {
      "type": "remote",
      "url": "https://mcp.grep.app"
    }
  }
}

Usage example:

use the gh_grep tool to search how to configure custom domains in SST framework

Filesystem ​

Local filesystem operations (sandbox mode):

jsonc
{
  "mcp": {
    "filesystem": {
      "type": "local",
      "command": [
        "npx", "-y", "@modelcontextprotocol/server-filesystem",
        "/path/to/allowed/directory"
      ]
    }
  }
}

Postgres ​

Query PostgreSQL databases directly:

jsonc
{
  "mcp": {
    "postgres": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-postgres"],
      "environment": {
        "POSTGRES_CONNECTION_STRING": "{env:DATABASE_URL}"
      }
    }
  }
}

Puppeteer ​

Browser automation and web scraping:

jsonc
{
  "mcp": {
    "puppeteer": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-puppeteer"]
    }
  }
}

Memory ​

Persistent key-value storage:

jsonc
{
  "mcp": {
    "memory": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-memory"]
    }
  }
}

SQLite ​

Lightweight database operations:

jsonc
{
  "mcp": {
    "sqlite": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-sqlite", "/path/to/database.db"]
    }
  }
}

Slack ​

Interact with Slack workspace:

jsonc
{
  "mcp": {
    "slack": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-slack"],
      "environment": {
        "SLACK_BOT_TOKEN": "{env:SLACK_BOT_TOKEN}",
        "SLACK_TEAM_ID": "{env:SLACK_TEAM_ID}"
      }
    }
  }
}

Common Pitfalls ​

IssueCauseSolution
MCP tools not appearingGlobally disabled or agent not configuredCheck permission configuration
OAuth authentication failedToken expired or invalid credentialsRun opencode mcp logout && opencode mcp auth
Status shows needs_client_registrationServer doesn't support dynamic registrationConfigure clientId in oauth
Context quickly exhaustedToo many MCP tools enabledDisable unused MCPs, use per-agent enable
Tool name conflictsMultiple MCPs have same-named toolsUse {server_name}_{tool_name} format to distinguish
Still shows needs_auth after authToken storage failedCheck ~/.local/share/opencode/mcp-auth.json permissions
Command format errorcommand written as string instead of array❌ "command": "npx xxx" → ✓ "command": ["npx", "-y", "xxx"]
URL format errorURL missing protocol prefix❌ "url": "example.com/mcp" → ✓ "url": "https://example.com/mcp"
Browser can't auto-openRunning in SSH/remote environmentOpenCode displays URL, manually copy to browser
Timeout too shorttimeout set to 1000msRemote servers recommend 2000+-10000ms, default 30000ms
Forgot to enable serverenabled: false but wondering why it doesn't workEnabled by default, check if mistakenly set to false

Lesson Summary ​

You learned:

  1. OAuth Authentication: Automatic handling or manual client credential configuration
  2. Debug Commands: opencode mcp debug to diagnose connection issues
  3. Status Icons: Meanings of ✓ ○ ⚠ ✗ four states
  4. Permission Management: Using permission to control tool access
  5. Tool Auto-Discovery: Tool naming rules and change notification mechanism
  6. Rule Integration: Configuring default MCP usage in AGENTS.md
  7. Common MCPs: Sentry, Context7, Grep, Postgres, etc.


Next Lesson Preview ​

In the next lesson, we'll learn about IDE integration, making OpenCode work seamlessly with editors like VS Code and JetBrains.