Capitulo 19: SDK y Server Mode
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ón | Tipo | Default | Descripción |
|---|---|---|---|
hostname | string | 127.0.0.1 | Dirección del servidor |
port | number | 4096 | Puerto del servidor |
baseUrl | string | — | URL completa (alternativa a hostname+port) |
timeout | number | — | Timeout en milisegundos para cada petición |
signal | AbortSignal | — | Signal 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:
- Pipelines de CI: analizar código y tomar decisiones basadas en datos estructurados
- Dashboards: obtener métricas y reportes que se pueden graficar
- Integraciones: alimentar otros sistemas con datos del agente en formato procesable
- Automatización: ejecutar acciones condicionales basadas en la respuesta
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ón | Tipo | Default | Descripción |
|---|---|---|---|
port | number | 4096 | Puerto HTTP del servidor |
hostname | string | 127.0.0.1 | Dirección de escucha |
mdns | boolean | false | Habilitar descubrimiento mDNS |
mdnsDomain | string | — | Dominio para anuncio mDNS |
cors | string[] | [] | 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:
- Búsqueda rápida entre sesiones anteriores
- Durabilidad: las sesiones sobreviven a reinicios
- Portabilidad: puedes copiar la base de datos entre máquinas
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
| Modo | Ideal Para | Comando |
|---|---|---|
| TUI | Desarrollo interactivo diario | opencode |
| Web | Acceso desde navegador/dispositivos | opencode web |
| Serve | APIs, bots, integraciones | opencode serve |
| Attach | Conectar TUI a servidor remoto | opencode attach |
| ACP | Comunicación entre agentes | opencode acp |
| SDK | Aplicaciones programáticas | Importar @opencode-ai/sdk |
| Run | Scripts 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 —>