Skip to content

Week 8: MCP Servers & Plugins

Teaching Goal

Learners should leave this session able to explain MCP vs plugins, add existing MCP servers safely, and design a tiny custom MCP server with one tool and one resource.


Where We Are

So far, learners can customize OpenCode from inside the project:

  • Commands
  • Skills
  • Agents
  • Multi-agent workflows

This week connects agents to outside systems.


The New Boundary

Agents become more useful when they can access external systems.

Examples:

  • GitHub
  • Notion
  • Browser state
  • Databases
  • Internal APIs

MCP is one standard way to expose those capabilities.


What Is MCP?

MCP means Model Context Protocol.

Simple model:

OpenCode agent -> MCP server -> external system

The MCP server is a bridge. It is not the agent.


MCP Server Examples

  • GitHub MCP server: read PRs, issues, comments
  • Filesystem MCP server: expose a safe directory
  • Database MCP server: query development data
  • Browser MCP server: inspect UI behavior
  • Custom MCP server: expose one internal workflow

The server decides what tools and resources exist.


Tools vs Resources

Tool:

Do something.

Resource:

Read something.

Examples:

  • Tool: create_issue_comment
  • Resource: pull_request_diff

OpenCode Plugins Are Different

MCP extends what the agent can reach.

Plugins extend OpenCode itself.

Plugins can:

  • Hook into events
  • Modify tool behavior
  • Add OpenCode-specific tools
  • Integrate telemetry or notifications

MCP vs Plugin

Question MCP Plugin
Main job Connect external systems Customize OpenCode
Shape Server process or URL JS/TS package
Scope Agent capability OpenCode behavior
Portability MCP-capable clients OpenCode-specific

Ask: "external system or OpenCode behavior?"


Config Shape: MCP

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "server-name": {
      "enabled": true
    }
  }
}

Each key names one server.


Local Server Example

{
  "mcp": {
    "filesystem": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/safe/dir"],
      "enabled": true
    }
  }
}

Local server means OpenCode starts a command on your machine.


Remote Server Example

{
  "mcp": {
    "remote-tools": {
      "type": "remote",
      "url": "https://mcp.example.com/mcp",
      "enabled": true
    }
  }
}

Remote server means OpenCode connects to an HTTP endpoint.


Config Shape: Plugin

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-helicone-session", "@my-org/custom-plugin"]
}

Plugins are packages OpenCode loads.


Security Questions

Before enabling an MCP server, ask:

  • What can it read?
  • What can it write?
  • Does it touch secrets?
  • Can access be scoped?
  • Is it maintained?
  • What happens if the agent calls the wrong tool?

Begin with read-only access.


Demo Part 1: Wire Existing Server

Demo flow:

  1. Pick a real use case.
  2. Add the server config.
  3. Restart OpenCode.
  4. Ask a bounded prompt.
  5. Confirm the agent stayed in scope.

Keep the demo small.


Bounded MCP Prompt

Use the GitHub MCP server to read PR #42 only.
Do not comment, approve, close, or edit anything.
Return a five-bullet summary of the diff.

The prompt still matters. MCP access does not replace judgment.


Demo Part 2: Tiny Custom Server

Design before code:

Server: release-helper
Tool: format_release_note
Resource: release-note-style-guide
Safety: no network, no file writes

One useful tool is enough.


Lab 8.1 Preview

Learners wire two existing MCP servers.

Deliverables:

  • Use case for each server
  • Config snippet
  • Safety notes
  • Test prompt
  • Result summary

Lab 8.2 Preview

Learners author a tiny MCP server.

Deliverables:

  • One tool
  • One resource
  • OpenCode config entry
  • Test prompt
  • Reflection on whether MCP was necessary

Common Confusion

"Should this be a skill, command, agent, MCP server, or plugin?"

Decision guide:

  • Prompt template -> command
  • Reusable knowledge -> skill
  • Role and permissions -> agent
  • External system -> MCP
  • OpenCode behavior -> plugin

Closing Thought

MCP makes agents powerful.

Boundaries make that power usable.