Capitulo 19: SDK y Server Mode

Por: Artiko
opencodeaisdkserverapiheadless

Capitulo 19: SDK y Server Mode

< Volver al Indice del Tutorial

OpenCode no está limitado a la TUI. Puedes ejecutarlo como servidor HTTP, accederlo desde el navegador, conectar múltiples terminales al mismo proceso y usarlo programáticamente con el SDK oficial. Este capítulo cubre el SDK en detalle, todas las APIs disponibles, la configuración del servidor y los modos de ejecución avanzados que permiten construir aplicaciones completas sobre OpenCode.

SDK: @opencode-ai/sdk

El SDK oficial de OpenCode permite integrar el agente en cualquier aplicación Node.js o TypeScript. Es la forma programática de interactuar con OpenCode, ideal para construir interfaces personalizadas, bots, herramientas de CI y cualquier aplicación que necesite capacidades de agente AI.

Instalación

npm install @opencode-ai/sdk

El paquete está disponible en npm y es compatible con Node.js, Bun y Deno. Funciona tanto con TypeScript como con JavaScript.

Modos de Conexión

El SDK ofrece dos modos de conexión según tu caso de uso:

Modo Completo (Server Embebido)

Crea una instancia completa de OpenCode que incluye el servidor embebido. Ideal cuando quieres que tu aplicación sea autosuficiente:

import { createOpencode } from "@opencode-ai/sdk"

const { client } = await createOpencode()

Este modo arranca un servidor local de OpenCode internamente y te devuelve un cliente conectado. No necesitas tener opencode serve corriendo por separado.

Modo Cliente (Conectar a Instancia Existente)

Conecta a un servidor de OpenCode que ya está corriendo. Ideal para aplicaciones que se conectan a un servidor compartido:

import { createOpencodeClient } from "@opencode-ai/sdk"

const client = createOpencodeClient({
  baseUrl: "http://localhost:4096"
})

Este modo es más liviano porque no inicia un servidor nuevo. Solo crea un cliente HTTP que se comunica con el servidor existente.

Opciones de Configuración del Cliente

OpciónTipoDefaultDescripción
hostnamestring127.0.0.1Dirección del servidor
portnumber4096Puerto del servidor
baseUrlstringURL completa (alternativa a hostname+port)
timeoutnumberTimeout en milisegundos para cada petición
signalAbortSignalSignal para cancelación de peticiones

El signal es especialmente útil para cancelar operaciones largas. Puedes crear un AbortController y pasar su signal al cliente para cancelar todas las peticiones pendientes cuando lo necesites.

APIs Disponibles

El SDK expone múltiples namespaces organizados por funcionalidad. Cada namespace agrupa operaciones relacionadas:

Global API

Operaciones de salud y versión del servidor:

// Verificar que el servidor está activo
const health = await client.global.health()

// Obtener información de versión
const version = await client.global.version()
console.log(`OpenCode v${version.version}`)

La API de health es fundamental para implementar health checks en entornos de producción o CI. Te permite verificar que el servidor responde antes de enviar solicitudes.

App API

Logging y configuración de la aplicación:

// Obtener logs de la aplicación
const logs = await client.app.logs()

// Listar agentes disponibles
const agents = await client.app.agents()
console.log(`Agentes: ${agents.map(a => a.name).join(", ")}`)

La lista de agentes es útil para aplicaciones que necesitan presentar al usuario las opciones disponibles o seleccionar un agente específico para una tarea.

Project API

Acceso a información del proyecto actual:

// Listar proyectos
const projects = await client.project.list()

// Obtener proyecto actual
const current = await client.project.current()
console.log(`Proyecto: ${current.name} en ${current.path}`)

Session API

CRUD completo de sesiones, mensajería y manejo de prompts. Es la API más rica del SDK:

// Crear una nueva sesión
const session = await client.session.create({
  projectId: current.id
})

// Listar sesiones existentes
const sessions = await client.session.list()

// Enviar un mensaje al agente
const response = await client.session.chat({
  sessionId: session.id,
  message: "Analiza el archivo src/index.ts y sugiere mejoras"
})

// Obtener historial de una sesión
const history = await client.session.messages(session.id)

// Eliminar una sesión
await client.session.delete(session.id)

La Session API también soporta manejo de prompts del agente. Cuando el agente necesita confirmación del usuario (por ejemplo, antes de ejecutar un comando), puedes manejar esos prompts programáticamente:

// Responder a un prompt del agente
await client.session.respondToPrompt({
  sessionId: session.id,
  promptId: prompt.id,
  response: "yes"
})

Files API

Búsqueda, lectura y tracking de archivos del proyecto:

// Buscar archivos por patrón
const files = await client.files.search({
  pattern: "*.ts",
  projectId: current.id
})

// Leer contenido de un archivo
const content = await client.files.read({
  path: "src/index.ts",
  projectId: current.id
})

// Obtener archivos tracked (modificados por el agente)
const tracked = await client.files.tracked(session.id)

La API de archivos tracked es especialmente útil para construir interfaces que muestren qué archivos ha modificado el agente en una sesión.

TUI API

Control programático de la interfaz de terminal:

// Mostrar un toast/notificación
await client.tui.toast({
  message: "Tarea completada",
  level: "info"
})

// Abrir un diálogo
await client.tui.dialog({
  title: "Confirmar",
  message: "¿Deseas continuar?",
  buttons: ["Sí", "No"]
})

// Establecer el prompt actual
await client.tui.setPrompt({
  text: "Refactoriza el módulo de autenticación"
})

La TUI API permite que aplicaciones externas controlen la interfaz de terminal de OpenCode. Esto es útil para extensiones de IDE que quieren enviar comandos a la TUI activa.

Events API

Suscripción a server-sent events (SSE) para actualizaciones en tiempo real:

// Suscribirse a eventos de una sesión
const stream = client.events.subscribe({
  sessionId: session.id
})

for await (const event of stream) {
  switch (event.type) {
    case "message":
      console.log(`Agente: ${event.data.content}`)
      break
    case "tool_call":
      console.log(`Herramienta: ${event.data.tool}`)
      break
    case "complete":
      console.log("Sesión completada")
      break
  }
}

Los eventos SSE son fundamentales para construir interfaces que muestren las respuestas del agente en tiempo real, con streaming de tokens y actualizaciones de progreso.

Salida Estructurada

Una de las capacidades más potentes del SDK es la posibilidad de solicitar respuestas en formato estructurado. En lugar de recibir texto libre, puedes especificar un esquema JSON y el agente devolverá datos que se ajustan a ese esquema:

const response = await client.session.chat({
  sessionId: session.id,
  message: "Analiza este código y encuentra problemas",
  format: {
    type: "object",
    properties: {
      issues: {
        type: "array",
        items: {
          type: "object",
          properties: {
            file: { type: "string" },
            line: { type: "number" },
            description: { type: "string" },
            severity: { type: "string", enum: ["low", "medium", "high", "critical"] }
          }
        }
      },
      summary: { type: "string" },
      overallScore: { type: "number", minimum: 0, maximum: 10 }
    }
  }
})

// response.data es un objeto tipado
for (const issue of response.data.issues) {
  console.log(`[${issue.severity}] ${issue.file}:${issue.line} - ${issue.description}`)
}

La salida estructurada es ideal para:

flowchart LR
    A[Tu App] -->|Mensaje + Schema JSON| B[OpenCode SDK]
    B -->|Procesa con LLM| C[Agente]
    C -->|Respuesta estructurada| B
    B -->|Datos tipados| A
    A --> D[Dashboard]
    A --> E[Pipeline CI]
    A --> F[Otro sistema]

Server Mode

El servidor de OpenCode es el backend que alimenta todos los clientes: TUI, web, extensiones de IDE y aplicaciones del SDK. Entender cómo configurarlo y operarlo es esencial para despliegues avanzados.

Configuración del Servidor

Configura el servidor en la sección server de opencode.json:

{
  "server": {
    "port": 4096,
    "hostname": "0.0.0.0",
    "mdns": true,
    "mdnsDomain": "myproject.local",
    "cors": ["http://localhost:5173", "http://localhost:3000"]
  }
}
OpciónTipoDefaultDescripción
portnumber4096Puerto HTTP del servidor
hostnamestring127.0.0.1Dirección de escucha
mdnsbooleanfalseHabilitar descubrimiento mDNS
mdnsDomainstringDominio para anuncio mDNS
corsstring[][]Orígenes permitidos para CORS

Iniciar el Servidor

Hay varias formas de arrancar el servidor:

# Modo servidor headless (sin TUI)
opencode serve

# Modo servidor con flags
opencode serve --port 4096 --hostname 0.0.0.0

# Usar configuración de opencode.json automáticamente
opencode --server

La flag --server permite iniciar el servidor con la configuración de opencode.json sin necesidad de pasar flags en la línea de comandos. Esto es útil para scripts de inicio y despliegues automatizados.

mDNS (Descubrimiento Local)

Cuando habilitas mDNS, el servidor se anuncia en la red local usando Bonjour/Avahi. Otros dispositivos pueden descubrirlo sin conocer la IP exacta:

{
  "server": {
    "mdns": true,
    "mdnsDomain": "mi-proyecto.local"
  }
}

Con esta configuración, otros dispositivos en la misma red pueden conectarse usando mi-proyecto.local:4096 en lugar de la IP del servidor. Esto es útil en redes domésticas o de oficina donde las IPs pueden cambiar.

CORS

La configuración de CORS es necesaria cuando tu aplicación web frontend está en un dominio diferente al servidor de OpenCode. Sin CORS configurado, el navegador bloqueará las peticiones:

{
  "server": {
    "cors": [
      "http://localhost:5173",
      "http://localhost:3000",
      "https://mi-app.example.com"
    ]
  }
}

Incluye todos los orígenes desde donde tu aplicación hace peticiones al servidor de OpenCode.

Autenticación

Protege el servidor con autenticación HTTP basic:

export OPENCODE_SERVER_PASSWORD="tu-password-seguro"
opencode serve --port 4096

Con el password configurado, todas las peticiones requieren el header Authorization: Basic <base64(opencode:password)>. El SDK maneja la autenticación automáticamente si le pasas las credenciales.

opencode attach

El comando attach permite conectar una TUI local a un servidor remoto de OpenCode:

opencode attach --port 4096

Múltiples Clientes Simultáneos

Varias instancias de TUI pueden conectarse al mismo servidor:

# Terminal 1: arranca el servidor
opencode serve --port 4096

# Terminal 2: conecta una TUI
opencode attach --port 4096

# Terminal 3: conecta otra TUI
opencode attach --port 4096

Todos los clientes comparten la misma sesión. Lo que un cliente envía, los demás lo ven en tiempo real. Esto permite pair programming con AI: dos desarrolladores interactúan con el mismo agente desde terminales separadas.

Conexión Remota

Puedes hacer attach a un servidor en otra máquina:

opencode attach --hostname 192.168.1.100 --port 4096

Workspaces (v1.2.16)

A partir de v1.2.16, OpenCode introduce soporte básico de workspaces. Un workspace agrupa múltiples sesiones bajo un mismo contexto de proyecto:

opencode workspace-serve --port 4096

Cada sesión creada dentro del servidor se asocia automáticamente al workspace activo. Los workspaces remotos permiten flujos de trabajo distribuidos donde el servidor de desarrollo y el cliente pueden estar en máquinas separadas compartiendo el mismo contexto.

Sessions

OpenCode persiste las sesiones en una base de datos SQLite. Puedes exportar, importar y gestionar sesiones programáticamente:

Export e Import

# Exportar sesión como JSON
opencode session export <session-id>

# Importar sesión desde archivo
opencode session import <archivo.json>

El JSON exportado incluye todos los mensajes, herramientas invocadas y resultados. Útil para auditorías, debugging o compartir conversaciones.

Persistencia

Las sesiones se almacenan en SQLite, lo que ofrece:

Arquitectura Completa

Todos los componentes del ecosistema de OpenCode se conectan a través del servidor:

flowchart TD
    subgraph Clientes
        TUI[TUI Terminal]
        WEB[Interfaz Web]
        IDE[Extensión IDE]
        SDK[SDK / App Custom]
        ACP[Agentes via ACP]
    end
    
    subgraph Servidor["Servidor OpenCode"]
        API[API REST]
        SSE[Server-Sent Events]
        AUTH[Autenticación]
    end
    
    subgraph Backend
        LLM[Proveedor LLM]
        TOOLS[Herramientas MCP]
        DB[(SQLite Sessions)]
        FS[Filesystem]
    end
    
    TUI --> API
    WEB --> API
    IDE --> API
    SDK --> API
    ACP --> API
    
    API --> LLM
    API --> TOOLS
    API --> DB
    API --> FS
    SSE --> TUI
    SSE --> WEB
    SSE --> SDK

Cuándo Usar Cada Modo

ModoIdeal ParaComando
TUIDesarrollo interactivo diarioopencode
WebAcceso desde navegador/dispositivosopencode web
ServeAPIs, bots, integracionesopencode serve
AttachConectar TUI a servidor remotoopencode attach
ACPComunicación entre agentesopencode acp
SDKAplicaciones programáticasImportar @opencode-ai/sdk
RunScripts y pipelines (no interactivo)opencode run "prompt"

Cada modo resuelve un caso de uso diferente. Puedes combinarlos: por ejemplo, serve como backend y attach + web como clientes simultáneos, mientras una aplicación del SDK envía tareas automatizadas.


Siguiente: Capitulo 20: Tips de Productividad —>