> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/opencode-ai/opencode/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Context Protocol (MCP)

> Extend OpenCode's capabilities with external tools and services using the standardized Model Context Protocol

OpenCode implements the Model Context Protocol (MCP) to integrate external tools and services, providing the AI assistant with access to specialized capabilities beyond built-in tools.

## What is MCP?

The Model Context Protocol (MCP) is a standardized way for AI assistants to interact with external tools and services. It provides:

* **Standardized interface** for tool discovery and execution
* **Multiple transport types** (stdio, SSE)
* **Dynamic tool registration** at runtime
* **Consistent permission model** across all tools

<Note>
  OpenCode uses the [mcp-go](https://github.com/mark3labs/mcp-go) library to implement MCP client functionality.
</Note>

## How MCP works in OpenCode

<Steps>
  <Step title="Server configuration">
    You configure MCP servers in `.opencode.json` with connection details and authentication
  </Step>

  <Step title="Initialization">
    When OpenCode starts, it connects to configured MCP servers and discovers available tools
  </Step>

  <Step title="Tool registration">
    MCP tools are registered alongside built-in tools with a `{server-name}_{tool-name}` naming pattern
  </Step>

  <Step title="Tool execution">
    When AI calls an MCP tool, OpenCode creates a new client connection, executes the tool, and returns results
  </Step>
</Steps>

## Connection types

OpenCode supports two MCP transport types:

<Tabs>
  <Tab title="Stdio">
    **Standard Input/Output transport**

    Communicate with tools via stdin/stdout, perfect for local executables.

    ```json theme={null}
    {
      "mcpServers": {
        "filesystem": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"],
          "env": []
        }
      }
    }
    ```

    **Configuration fields:**

    <ParamField path="type" type="string" required>
      Must be `"stdio"`
    </ParamField>

    <ParamField path="command" type="string" required>
      Executable command to run (e.g., `npx`, `python`, `/usr/local/bin/mcp-server`)
    </ParamField>

    <ParamField path="args" type="array">
      Command-line arguments to pass to the executable
    </ParamField>

    <ParamField path="env" type="array">
      Environment variables to set (format: `["KEY=value"]`)
    </ParamField>

    **Best for:**

    * Local tools and scripts
    * Python/Node.js MCP servers
    * Command-line utilities
    * File system access
  </Tab>

  <Tab title="SSE">
    **Server-Sent Events transport**

    Connect to remote MCP servers via HTTP with SSE streaming.

    ```json theme={null}
    {
      "mcpServers": {
        "remote-api": {
          "type": "sse",
          "url": "https://api.example.com/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_TOKEN",
            "X-API-Key": "your-api-key"
          }
        }
      }
    }
    ```

    **Configuration fields:**

    <ParamField path="type" type="string" required>
      Must be `"sse"`
    </ParamField>

    <ParamField path="url" type="string" required>
      HTTP(S) URL of the MCP server endpoint
    </ParamField>

    <ParamField path="headers" type="object">
      HTTP headers to include in requests (useful for authentication)
    </ParamField>

    **Best for:**

    * Remote services and APIs
    * Cloud-hosted tools
    * Shared team resources
    * Services requiring authentication
  </Tab>
</Tabs>

## Configuration

MCP servers are configured in `.opencode.json` under the `mcpServers` key:

```json theme={null}
{
  "mcpServers": {
    "server-name": {
      "type": "stdio" | "sse",
      // ... type-specific configuration
    }
  }
}
```

The server name becomes part of the tool identifier: `{server-name}_{tool-name}`

### Complete configuration example

```json theme={null}
{
  "mcpServers": {
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/allowed-directory"
      ],
      "env": []
    },
    "github": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-github"
      ],
      "env": [
        "GITHUB_TOKEN=ghp_your_token_here"
      ]
    },
    "web-search": {
      "type": "sse",
      "url": "https://mcp.example.com/search",
      "headers": {
        "Authorization": "Bearer your-token",
        "Content-Type": "application/json"
      }
    }
  }
}
```

## Available MCP servers

The MCP ecosystem includes many pre-built servers:

<CardGroup cols={2}>
  <Card title="Filesystem" icon="folder-open">
    **@modelcontextprotocol/server-filesystem**

    * Read/write file operations
    * Directory listing
    * File search
    * Safe path restrictions

    ```bash theme={null}
    npx @modelcontextprotocol/server-filesystem /allowed/path
    ```
  </Card>

  <Card title="GitHub" icon="github">
    **@modelcontextprotocol/server-github**

    * Repository operations
    * Issue management
    * Pull request workflows
    * Code search

    Requires: `GITHUB_TOKEN`
  </Card>

  <Card title="PostgreSQL" icon="database">
    **@modelcontextprotocol/server-postgres**

    * Query execution
    * Schema inspection
    * Table operations
    * Safe query validation

    Requires: Database connection string
  </Card>

  <Card title="Web Search" icon="magnifying-glass">
    **@modelcontextprotocol/server-brave-search**

    * Web search capabilities
    * News search
    * Safe search filtering

    Requires: Brave API key
  </Card>

  <Card title="Slack" icon="slack">
    **@modelcontextprotocol/server-slack**

    * Send messages
    * Channel management
    * User lookup

    Requires: Slack bot token
  </Card>

  <Card title="Google Drive" icon="google-drive">
    **@modelcontextprotocol/server-gdrive**

    * File access
    * Document reading
    * Upload/download

    Requires: OAuth credentials
  </Card>
</CardGroup>

<Note>
  Find more MCP servers at the [MCP Servers Registry](https://github.com/modelcontextprotocol/servers)
</Note>

## Tool naming and discovery

### Tool name format

MCP tools are automatically named: `{server-name}_{tool-name}`

**Example:** If you configure a server named `github` that provides a tool called `create_issue`, the tool becomes available as `github_create_issue`.

### Tool discovery

<Steps>
  <Step title="Server initialization">
    On startup, OpenCode connects to each configured MCP server
  </Step>

  <Step title="Tool listing">
    Sends `ListTools` request to discover available tools
  </Step>

  <Step title="Registration">
    Each discovered tool is registered with schema:

    * Tool name (prefixed with server name)
    * Description
    * Input parameters and types
    * Required fields
  </Step>

  <Step title="Availability">
    Tools become available to the AI assistant alongside built-in tools
  </Step>
</Steps>

### Example: filesystem server

If the `filesystem` server provides these tools:

* `read_file`
* `write_file`
* `list_directory`

They become:

* `filesystem_read_file`
* `filesystem_write_file`
* `filesystem_list_directory`

## Permission model

MCP tools follow the same permission system as built-in tools:

<AccordionGroup>
  <Accordion title="Per-execution permissions" icon="shield-check">
    Each MCP tool execution requires permission approval:

    ```
    ┌─ Permission Required ──────────────────┐
    │ Tool: github_create_issue              │
    │ Action: execute                        │
    │                                        │
    │ Parameters:                            │
    │ {                                      │
    │   "title": "Bug in user auth",        │
    │   "body": "Description...",           │
    │   "labels": ["bug"]                   │
    │ }                                      │
    │                                        │
    │ [Allow] [Allow for Session] [Deny]    │
    └────────────────────────────────────────┘
    ```
  </Accordion>

  <Accordion title="Session-level permissions" icon="key">
    Grant permission for entire session:

    * Press `A` in permission dialog
    * Permission persists for all future calls
    * Scoped to specific tool and session
  </Accordion>

  <Accordion title="Security considerations" icon="lock">
    * Tool parameters are visible in permission prompt
    * Sensitive data (tokens, passwords) shown in permissions
    * Review all parameters before approval
    * Session permissions don't persist across restarts
  </Accordion>
</AccordionGroup>

## Real-world examples

### Example 1: Filesystem operations

**Configuration:**

```json theme={null}
{
  "mcpServers": {
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/projects"
      ],
      "env": []
    }
  }
}
```

**Usage:**
The AI can now use `filesystem_read_file`, `filesystem_write_file`, etc., within the `/Users/username/projects` directory.

### Example 2: GitHub integration

**Configuration:**

```json theme={null}
{
  "mcpServers": {
    "github": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": [
        "GITHUB_TOKEN=ghp_xxxxxxxxxxxx"
      ]
    }
  }
}
```

**Usage:**

```
User: Create an issue for the bug we just found

AI uses: github_create_issue
Parameters:
{
  "owner": "myorg",
  "repo": "myproject",
  "title": "Fix authentication error in login flow",
  "body": "...",
  "labels": ["bug", "priority-high"]
}
```

### Example 3: Database queries

**Configuration:**

```json theme={null}
{
  "mcpServers": {
    "database": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": [
        "DATABASE_URL=postgresql://user:password@localhost:5432/mydb"
      ]
    }
  }
}
```

**Usage:**

```
User: Show me the top 10 users by activity

AI uses: database_query
Parameters:
{
  "query": "SELECT user_id, COUNT(*) as activity FROM events WHERE created_at > NOW() - INTERVAL '7 days' GROUP BY user_id ORDER BY activity DESC LIMIT 10"
}
```

### Example 4: Multi-server workflow

**Configuration:**

```json theme={null}
{
  "mcpServers": {
    "github": { /* ... */ },
    "slack": { /* ... */ },
    "database": { /* ... */ }
  }
}
```

**Usage:**

```
User: When PR #123 is merged, analyze the impact and notify the team

AI workflow:
1. Uses github_get_pr to fetch PR details
2. Uses database_query to check affected tables
3. Uses github_list_files to analyze changed files
4. Uses slack_send_message to notify team with summary
```

## Building custom MCP servers

You can create custom MCP servers for specialized functionality:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    # server.py
    from mcp.server import MCPServer, Tool
    from mcp.types import TextContent

    server = MCPServer("my-custom-tools")

    @server.tool(
        name="analyze_logs",
        description="Analyze application logs for errors",
        parameters={
            "log_path": {
                "type": "string",
                "description": "Path to log file"
            },
            "severity": {
                "type": "string",
                "enum": ["error", "warning", "info"]
            }
        }
    )
    def analyze_logs(log_path: str, severity: str) -> list[TextContent]:
        # Your implementation
        with open(log_path) as f:
            logs = f.read()
        # Analyze logs...
        return [TextContent(text=f"Found {count} {severity} messages")]

    if __name__ == "__main__":
        server.run()
    ```

    **Configuration:**

    ```json theme={null}
    {
      "mcpServers": {
        "custom": {
          "type": "stdio",
          "command": "python",
          "args": ["/path/to/server.py"],
          "env": []
        }
      }
    }
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    // server.js
    import { MCPServer } from '@modelcontextprotocol/sdk';

    const server = new MCPServer({
      name: 'my-custom-tools',
      version: '1.0.0'
    });

    server.addTool({
      name: 'analyze_logs',
      description: 'Analyze application logs for errors',
      parameters: {
        type: 'object',
        properties: {
          log_path: {
            type: 'string',
            description: 'Path to log file'
          },
          severity: {
            type: 'string',
            enum: ['error', 'warning', 'info']
          }
        },
        required: ['log_path']
      },
      handler: async ({ log_path, severity }) => {
        // Your implementation
        const logs = await fs.readFile(log_path, 'utf-8');
        // Analyze logs...
        return {
          content: [{
            type: 'text',
            text: `Found ${count} ${severity} messages`
          }]
        };
      }
    });

    server.start();
    ```

    **Configuration:**

    ```json theme={null}
    {
      "mcpServers": {
        "custom": {
          "type": "stdio",
          "command": "node",
          "args": ["/path/to/server.js"],
          "env": []
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Server not connecting" icon="plug-circle-xmark">
    Check:

    * Command path is correct and executable
    * Required dependencies are installed (`npx` may need to download packages)
    * Environment variables are set correctly
    * Check OpenCode debug logs: `opencode -d`
  </Accordion>

  <Accordion title="Tools not appearing" icon="eye-slash">
    Verify:

    * Server successfully initialized (check logs)
    * Server implements `ListTools` correctly
    * Tool schemas are valid
    * Restart OpenCode after config changes
  </Accordion>

  <Accordion title="Permission denied errors" icon="shield-xmark">
    Ensure:

    * Authentication tokens are valid
    * File paths are within allowed directories
    * Service accounts have necessary permissions
    * Check MCP server logs for auth errors
  </Accordion>

  <Accordion title="Tool execution fails" icon="circle-xmark">
    Debug:

    * Check tool parameters match schema
    * Verify required fields are provided
    * Review MCP server error logs
    * Test tool directly via MCP server CLI
    * Enable debug mode: `"debug": true` in config
  </Accordion>
</AccordionGroup>

## Best practices

<CardGroup cols={2}>
  <Card title="Name servers clearly" icon="tag">
    Use descriptive names that indicate purpose:

    * `github` not `gh`
    * `database-prod` not `db`
    * `filesystem-safe` for restricted access
  </Card>

  <Card title="Scope permissions" icon="shield-halved">
    Configure minimal necessary access:

    * Filesystem servers: specific directories only
    * Database servers: read-only when possible
    * API servers: scope tokens appropriately
  </Card>

  <Card title="Use environment variables" icon="key">
    Store sensitive data securely:

    * Never commit tokens to config files
    * Use environment variables for secrets
    * Consider using secret management tools
  </Card>

  <Card title="Test independently" icon="flask">
    Verify MCP servers work before integration:

    * Test with MCP CLI tools first
    * Verify authentication separately
    * Check tool schemas are valid
  </Card>

  <Card title="Handle errors gracefully" icon="circle-exclamation">
    Design tools for robustness:

    * Validate inputs thoroughly
    * Provide helpful error messages
    * Include fallback behavior
  </Card>

  <Card title="Document tool usage" icon="book">
    Help AI use tools correctly:

    * Write clear tool descriptions
    * Document parameter formats
    * Include usage examples
  </Card>
</CardGroup>

## Security considerations

<Warning>
  MCP tools can access sensitive systems and data. Follow these security practices:
</Warning>

* **Principle of least privilege**: Grant minimum necessary permissions
* **Network isolation**: Use stdio for local tools when possible
* **Token rotation**: Regularly rotate API keys and tokens
* **Audit logs**: Monitor tool usage and review permission grants
* **Input validation**: MCP servers should validate all inputs
* **Safe defaults**: Configure restrictive defaults, expand as needed

## Next steps

<CardGroup cols={2}>
  <Card title="MCP Specification" href="https://modelcontextprotocol.io/" icon="book">
    Learn about the Model Context Protocol specification
  </Card>

  <Card title="MCP Servers" href="https://github.com/modelcontextprotocol/servers" icon="server">
    Browse available MCP server implementations
  </Card>

  <Card title="Configuration" href="/reference/configuration" icon="gear">
    Complete configuration reference
  </Card>

  <Card title="AI Tools" href="/features/ai-tools" icon="wrench">
    Explore OpenCode's built-in tools
  </Card>
</CardGroup>
