ManzGPU

MCP servers en Opencode

Hype-Generator 3000™: It's a game-changer

Aprende a crear o añadir servidores MCP (locales o remotos) en OpenCode. Consejos para no quemar contexto innecesariamente.

1. Introducción

MCP (Model Context Protocol) es un protocolo abierto, creado por Anthropic, que estandariza la forma en que un agente se conecta a herramientas externas. Piensa en él como un enchufe universal: en lugar de escribir una integración para cada agente, escribes el servidor una vez y funciona para cualquier tipo de agente: OpenCode, Claude Code, AntiGravity CLI, Crush u otro cliente compatible con MCP.

La arquitectura es sencilla:

  • El cliente (el agente, OpenCode) se conecta a un servidor.
  • El servidor puede ser local (un proceso en tu máquina) o remoto (una URL externa).

En esta guía nos centraremos en la creación de tools mediante MCP (herramientas para ampliar las capacidades del agente), que es lo más habitual.

⚠️ Los MCP consumen contexto: el esquema de las tools de todos los servidores conectados se envía en cada turno, se usen o no. Antes de montar un MCP, comprueba si te basta con una skill o una CLI (utiliza sólo los MCP si no tienes otra opción disponible).

2. Tipos de MCP

OpenCode soporta dos tipos de MCP, y se eligen con el campo type:

🖥️ Local (local)☁️ Remoto (remote)
Transporte Vía stdio: Se lanza proceso y habla por stdin/stdout Vía streams HTTP
Configuración command: ejecutable + argumentos url absoluta
Dónde se ejecuta En tu máquina En un servidor externo
Red No necesita internet Necesita conexión
Autenticación No es necesaria OAuth (default) / API key en headers
Riesgos Puede consumir mucha RAM/CPU en uso Latencia, dependencia externa y red

Ambos tipos tienen algunas opciones comunes, que veremos más adelante, como disabled, codemode, timeout y protocol.

💡 Consejo: Si la tarea se puede hacer en tu máquina, prioriza usar un MCP local. Los MCP remotos son el último recurso, cuando solo existe esa opción. Son cómodos, pero evita abusar de ellos.

3. Configuración

Puedes añadir servidores MCP en Opencode de 2 formas: desde la CLI o editando el JSON de forma manual. La CLI escribe por ti el mismo JSON, así que al final terminan en el mismo sitio.

Vía CLI

# Añadir MCP local / remoto
opencode mcp add fmjson -- node /home/manz/.config/opencode/mcp/fmjson.js
opencode mcp add context7 --url https://mcp.context7.com/mcp

# Añadir MCP remoto para todo el sistema
opencode mcp add context7 --global --url https://mcp.context7.com/mcp

# Listar servidores MCP configurados
opencode mcp list

La CLI también admite credenciales y variables: --header nombre=valor para servidores remotos y --env nombre=valor para locales.

Vía JSON

Puedes editar el fichero ~/.config/opencode.jsonc (global) o el fichero opencode.jsonc o .opencode/opencode.jsonc (a nivel de proyecto) y añadir un nombre único a cada servidor dentro del campo mcp.servers:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "context7": {
        "type": "remote",
        "url": "https://mcp.context7.com/mcp",
        "disabled": true
      },
      "fmjson": {
        "type": "local",
        "command": ["node", "/home/manz/.config/opencode/mcp/fmjson.js"],
        "environment": {
          "LOG_LEVEL": "info",
          "MCP_API_KEY": "{env:MCP_API_KEY}"
        },
        "disabled": true
      }
    }
  }
}

📌 En OpenCode v2 los servidores van dentro de mcp.servers (en OpenCode v1 se añadían directamente en mcp). Se pueden desactivar con disabled: true en lugar del enabled de la V1, y los campos de OAuth son snake_case (client_id, no clientId). Cuidado si usas configuración a nivel de proyecto, ya que sobreescribe por completo la configuración global si tiene el mismo nombre.

4. Ejemplo: MCP local

Vamos a crear un servidor MCP local. Crearemos una tool que únicamente lee la cabecera YAML (frontmatter) de un fichero Markdown. De esta forma evitamos que cargue el resto del fichero en el contexto, ocupando así un espacio valioso de la ventana de contexto.

Crear el servidor

Creamos el servidor fuera del proyecto, por ejemplo en ~/.config/opencode/mcp/, para que esté disponible para todos tus proyectos:

mkdir -p ~/.config/opencode/mcp
cd ~/.config/opencode/mcp
pnpm init --init-type=module
pnpm add @modelcontextprotocol/server yaml zod

Con esto instalamos el SDK oficial de MCP @modelcontextprotocol/server, una librería para gestionar ficheros .yaml y zod, un validador de esquemas. Con el --init-type=module añadimos el "type": "module" en el package.json para prepararlo para ESM.

Entonces, creamos el fichero fmjson.js:

import { readFile } from "node:fs/promises";
import path from "node:path";
import yaml from "yaml";
import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";

const server = new McpServer({ name: "fmjson", version: "1.0.0" });
const FRONTMATTER_REGEX = /^---\s*\r?\n([\s\S]*?)\r?\n---/;
const toAbsolute = (file) => path.resolve(process.env.WORKTREE ?? ".", file);

const fmjson = {
  description: "Lee la cabecera YAML de un Markdown",
  inputSchema: z.object({ file: z.string() })
};

server.registerTool("fmjson", fmjson, async ({ file }) => {
  const text = await readFile(toAbsolute(file), "utf8");
  const yamlText = text.match(FRONTMATTER_REGEX)?.[1];

  if (!yamlText) throw Error(`YAML no encontrado: ${file}`);

  return { content: [{ type: "text", text: JSON.stringify(yaml.parse(yamlText), null, 2) }] };
});

await serveStdio(() => server);

Con esto tendremos nuestro servidor MCP listo para funcionar:

  • 1️⃣ new McpServer({ name, version }): Crea el servidor con su identidad.
  • 2️⃣ FRONTMATTER_REGEX: Extrae el bloque YAML --- ... --- del Markdown.
  • 3️⃣ toAbsolute(): Resuelve la ruta contra WORKTREE; si no existe, contra la carpeta de trabajo
  • 4️⃣ description: Texto que el modelo lee para decidir cuándo llamar a la tool. Claro y descriptivo
  • 5️⃣ inputSchema: Esquema de parámetros con Zod. JSON Schema que verá el modelo
  • 6️⃣ registerTool(name, config, handler): Registra la tool y devuelve info al modelo
  • 7️⃣ await serveStdio(() => server): Arranca el servidor sobre stdio.

Registrarlo en OpenCode

Una vez entendido esto, añadimos la herramienta MCP al opencode.jsonc:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "fmjson": {
        "type": "local",
        "command": ["node", "/home/manz/.config/opencode/mcp/fmjson.js"],
        "environment": {
          "WORKTREE": "{env:PWD}"
        }
      }
    }
  }
}

Observa que en environment pasamos un WORKTREE con {env:PWD}. Esto se resuelve al cargar la configuración y establece el directorio desde el que lanzaste opencode, es decir, la raíz de tu proyecto.

Probando el MCP

Ahora abre OpenCode y pídele algo así:

Usa la tool fmjson para leer `index.md`

El agente llamará a la tool y devolverá únicamente la cabecera YAML en JSON. Si tienes grandes cantidades de ficheros .md en los que sólo quieres buscar en las cabecera, evitas rellenar la ventana de contexto con datos que no te van a ser útiles.

Recuerda que los MCP se cargan al iniciar OpenCode. Si ya tenías una sesión abierta, ciérrala y vuélvela a abrir, o escribe /reload. Además, cuando no vayas a usar un MCP, desactivalo para no pagar coste extra de contexto.

5. Ejemplo: MCP remoto

Los servidores remotos se conectan por URL. El ejemplo clásico es Context7, que sirve documentación actualizada de prácticamente cualquier librería:

opencode mcp add context7 --url https://mcp.context7.com/mcp
opencode mcp list

Con esto lo añadimos a nuestra lista de MCP. Su configuración equivalente en el JSON sería la siguiente:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "servers": {
      "context7": {
        "type": "remote",
        "url": "https://mcp.context7.com/mcp"
      }
    }
  }
}

Este es un MCP sencillo. Sin embargo, si el servidor necesita una API key en cabecera en lugar de OAuth, deberías hacer lo siguiente (veamos sólo el contenido de context7):

{
  "type": "remote",
  "url": "https://mcp.example.com/mcp",
  "oauth": false,
  "headers": {
    "API_KEY": "{env:MY_API_KEY}"
  }
}

Usa oauth: false solo cuando el servidor se autentique exclusivamente con API key u otra credencial por cabecera. Conecta desde OpenCode con /mcps y ya puedes pedirle al modelo que consulte documentación. Comprobarás que el agente usará tools como context7_resolve_library_id o context7_get_library_docs automáticamente.

6. Autenticación

En ciertos casos, puedes necesitar autenticaciones más complejas. La autenticación solo aplica a servidores remotos, los locales se ejecutan en tu máquina y no necesitan credenciales.

OAuth (por defecto)

Para muchos servidores MCP remotos, basta con declarar type y url. Si el servidor necesita autenticación, verás un mensaje needs authentication al ejecutar el comando opencode mcp list. En ese caso, puedes añadirla desde el comando /mcps o desde la terminal con el comando opencode mcp auth nombre (siendo nombre el nombre del MCP).

Credenciales de cliente

Sin embargo, si el proveedor te da un client_id y un client_secret, en OpenCode V2 se usan campos snake_case en el campo oauth. Veamos nuevamente el contenido de mcp.servers:

{
  "company-tools": {
    "type": "remote",
    "url": "https://mcp.example.com/mcp",
    "oauth": {
      "client_id": "{env:MCP_CLIENT_ID}",
      "client_secret": "{env:MCP_CLIENT_SECRET}",
      "scope": "tools:read tools:execute",
      "callback_port": 19876,
      "redirect_uri": "http://127.0.0.1:19876/callback"
    }
  }
}
  • 1️⃣ Los campos client_id y client_secret leen de las variables de entorno.
  • 2️⃣ El campo scope declara los scopes necesarios, separados por espacio.
  • 3️⃣ El campo callback_port declara el puerto local de callback (1-65535).
  • 4️⃣ El campo redirect_uri declara la URL local a la que apunta el callback.

🔐 Nunca guardes secretos en el JSON: usa siempre variables de entorno {env:NAME}.

7. Otras opciones

En los MCP remotos o locales, dentro del campo de opencode.jsonc, pueden haber más campos a parte de type, command, url o disabled.

  • 1️⃣ cwd: Establece el directorio de trabajo. Por defecto, el workspace.
  • 2️⃣ codemode: Puedes exponer las tools directamente con false. Por defecto true.
  • 3️⃣ environment: Establece las variables de entorno a utilizar.
  • 4️⃣ protocol: Estable el protocolo del MCP: "legacy" (por defecto), "auto" o "2026-07-28"
  • 5️⃣ oauth: Ajustes de OAuth. Con false lo desactivas.
  • 6️⃣ timeout: Tiempo máximo para conectar con el MCP.

Un ejemplo de timeouts:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "timeout": {
      "startup": 15000,       /* Por defecto: 30_000 (30s) */
      "catalog": 30000,       /* Por defecto: 30_000 (30s) */
      "execution": 600000,    /* Por defecto: 320_000_000 (12h) */
    },
    /* ... */
  },
}

El campo startup es el tiempo máximo para inicializar el servidor MCP. El campo catalog es el tiempo que puede tardar en listar herramientas, prompts, recursos o plantillas, mientras que execution es el tiempo máximo que puede tardar en ejecutar y respoder el servidor MCP.

8. Consejos importantes

Ahora que sabes utilizar MCP en OpenCode, aquí van algunos consejos que debes tener siempre presentes al utilizarlos:

  • 1️⃣❌ Desactiva MCP siempre que puedas: Consumen contexto, recursos y tokens.
  • 2️⃣✅ Prioriza siempre este orden: Skill → CLI → MCP local → MCP remoto
  • 3️⃣✅ Prefiere MCP locales: No consumen red, no necesitan credenciales y mayor privacidad.
  • 4️⃣✅ Usa nombres cortos y únicos: Los MCP deben ser siempre letras y números.
  • 5️⃣✅ Buenas descripciones: El modelo decide llamar a la tool por la descripción.