15. SDK de TypeScript y desarrollos programáticos

Objetivo del tema

Comprender cómo usar el SDK oficial de TypeScript de Qwen Code para ejecutar consultas de forma programática, incrustar el agente en aplicaciones Node.js, controlar permisos, trabajar con conversaciones multi-turno y exponer herramientas propias mediante MCP embebido.

Este tema se apoya en la documentación oficial disponible al 11 de abril de 2026, especialmente en Typescript SDK.

15.1 Qué es el SDK de TypeScript

La documentación oficial define a @qwen-code/sdk como un SDK mínimo y experimental para acceder a Qwen Code de forma programática. Eso significa que, en lugar de usar siempre el CLI de manera interactiva, podés controlar al agente desde tu propio código.

Este cambio es muy importante conceptualmente. Hasta ahora en el curso vimos a Qwen Code como una herramienta para personas que escriben prompts en la terminal. Con el SDK, en cambio, pasa a ser también un componente integrable dentro de aplicaciones, servicios, automatizaciones o plataformas internas.

El SDK no reemplaza al CLI: se apoya en él. La idea es reutilizar la capacidad operativa de Qwen Code desde programas propios.

15.2 Cuándo conviene usarlo

El SDK resulta especialmente útil cuando querés:

  • lanzar consultas a Qwen Code desde una aplicación Node.js
  • construir flujos de automatización con lógica propia
  • integrar al agente en una plataforma interna
  • controlar permisos con reglas programáticas
  • inyectar herramientas MCP creadas dentro del mismo proceso

En otras palabras, el SDK aparece cuando la terminal sola ya no alcanza y necesitás que Qwen Code forme parte de otro sistema.

15.3 Requisitos

La documentación actual marca estos requisitos mínimos:

Node.js >= 20.0.0
Qwen Code >= 0.4.0 instalado y accesible en PATH

Además, la guía incluye una advertencia importante para usuarios de nvm: la autodetección del ejecutable puede fallar. En esos casos conviene especificar manualmente pathToQwenExecutable.

15.4 Instalación

La instalación oficial es directa:

npm install @qwen-code/sdk

Esto agrega el paquete del SDK a tu proyecto, pero no elimina la necesidad de tener Qwen Code instalado. El SDK necesita encontrar el ejecutable del CLI para poder lanzar sesiones reales.

15.5 La función central: query()

La documentación organiza casi todo el uso del SDK alrededor de una función principal:

import { query } from '@qwen-code/sdk';

query() crea una nueva sesión de consulta con Qwen Code. Puede usarse para un prompt simple o para una conversación de varias vueltas. El valor que devuelve es un objeto iterable de forma asíncrona, lo que permite ir recibiendo mensajes a medida que la sesión avanza.

15.6 Primer ejemplo mínimo

La guía oficial propone un arranque como este:

import { query } from '@qwen-code/sdk';

const result = query({
  prompt: '¿Qué archivos hay en el directorio actual?',
  options: {
    cwd: '/ruta/al/proyecto',
  },
});

for await (const message of result) {
  console.log(message);
}

La idea es sencilla: definís un prompt, indicás el directorio de trabajo y luego iterás sobre los mensajes que produce la sesión.

15.7 Qué recibe query()

La documentación resume dos parámetros principales:

  • prompt: puede ser un string o un AsyncIterable<SDKUserMessage>
  • options: un objeto QueryOptions con la configuración de la sesión

Esto es importante porque muestra dos modos mentales distintos:

  • usar un string cuando querés una consulta puntual
  • usar un flujo asíncrono de mensajes cuando querés una conversación real de varias vueltas

15.8 Opciones más importantes

Opciones frecuentes de query()
Opción Función
cwd Directorio de trabajo de la sesión.
model Modelo a utilizar en esa consulta.
pathToQwenExecutable Ruta explícita al ejecutable qwen.
abortController Permite cancelar la sesión desde código.
debug Activa logs detallados.
maxSessionTurns Límite máximo de turnos conversacionales.
coreTools Define qué herramientas base quedan disponibles.
excludeTools Bloquea herramientas o patrones concretos.
allowedTools Aprueba automáticamente herramientas que requieran confirmación.
authType Tipo de autenticación, por ejemplo openai o qwen-oauth.
agents Subagentes disponibles en esa sesión.
includePartialMessages Emite mensajes parciales para streaming en tiempo real.

Este conjunto de opciones deja claro que el SDK no es una simple envoltura decorativa. Expone bastante control sobre el comportamiento del agente.

15.9 Mensajes y streaming

El SDK entrega mensajes de distintos tipos mientras la consulta avanza. La documentación incluye type guards como:

import {
  isSDKAssistantMessage,
  isSDKResultMessage,
  isSDKPartialAssistantMessage
} from '@qwen-code/sdk';

Esto permite distinguir entre:

  • mensajes del asistente
  • resultados finales
  • mensajes parciales aún en construcción

Si activás includePartialMessages, podés construir interfaces tipo chat con streaming visible en tiempo real.

15.10 Conversaciones multi-turno

Uno de los puntos más interesantes del SDK es que no se limita a preguntas aisladas. También permite conversaciones multi-turno usando un AsyncIterable de mensajes de usuario.

import { query, type SDKUserMessage } from '@qwen-code/sdk';

async function* generateMessages(): AsyncIterable<SDKUserMessage> {
  yield { type: 'user', message: 'Explicá la estructura del proyecto' };
  yield { type: 'user', message: 'Ahora proponé una refactorización mínima' };
}

const result = query({
  prompt: generateMessages(),
  options: {
    cwd: '/ruta/al/proyecto',
  },
});

Este patrón es útil cuando querés conectar Qwen Code a una interfaz propia, a una cola de eventos o a un flujo generado dinámicamente por tu aplicación.

15.11 Métodos del objeto de consulta

La instancia devuelta por query() no solo se itera. También expone métodos operativos importantes:

const q = query({ prompt: 'Hola', options: {} });

const sessionId = q.getSessionId();
const closed = q.isClosed();

await q.interrupt();
await q.setPermissionMode('yolo');
await q.setModel('qwen-max');
await q.close();

Esto permite controlar una sesión viva sin reiniciarla. Por ejemplo, podrías cambiar de modelo o de modo de permisos mientras una interfaz gráfica sigue usando la misma conversación.

15.12 Modos de permisos en el SDK

El SDK incorpora los mismos grandes modos de permisos que ya vimos en el CLI, pero ahora controlados desde código:

  • default
  • plan
  • auto-edit
  • yolo

La documentación describe su comportamiento así:

Permission modes en el SDK
Modo Comportamiento
default Las herramientas de escritura se niegan salvo aprobación explícita o allowlist.
plan Bloquea herramientas no solo de lectura y fuerza una planificación previa.
auto-edit Aprueba edición de archivos, pero no el resto de herramientas sensibles.
yolo Aprueba todas las herramientas automáticamente.

15.13 Cadena de prioridad de permisos

La documentación del SDK insiste en un detalle fino que conviene entender bien: no todas las reglas de permiso pesan lo mismo. El orden actual es:

  1. excludeTools
  2. permissionMode: 'plan'
  3. permissionMode: 'yolo'
  4. allowedTools
  5. canUseTool
  6. comportamiento por defecto del SDK

Esto es importante porque evita errores de diseño. Por ejemplo, no sirve aprobar una herramienta en allowedTools si antes la bloqueaste con excludeTools.

15.14 Aprobación personalizada con canUseTool

Una de las capacidades más potentes del SDK es poder decidir desde código si una herramienta debe ejecutarse o no. La documentación muestra el callback canUseTool para ese fin.

const result = query({
  prompt: 'Creá un archivo nuevo',
  options: {
    canUseTool: async (input) => {
      if (input.toolName === 'write_file') {
        return { behavior: 'allow', updatedInput: input };
      }

      return { behavior: 'deny', message: 'Operación no permitida' };
    },
  },
});

Este mecanismo es ideal cuando tu aplicación necesita reglas de aprobación propias, por ejemplo según usuario, entorno, horario, repositorio o tipo de archivo.

15.15 Timeouts

El SDK define timeouts por defecto para varias operaciones sensibles. La documentación actual enumera estos:

  • canUseTool: 1 minuto
  • mcpRequest: 1 minuto
  • controlRequest: 1 minuto
  • streamClose: 1 minuto

También se pueden personalizar:

const result = query({
  prompt: 'Tu consulta',
  options: {
    timeout: {
      canUseTool: 60000,
      mcpRequest: 600000,
      controlRequest: 60000,
      streamClose: 15000
    }
  }
});

Esto resulta útil cuando un servidor MCP tarda mucho o cuando tu aplicación necesita una política de espera más estricta.

15.16 MCP externo desde el SDK

El SDK puede usar servidores MCP externos exactamente igual que el CLI. La documentación muestra un patrón como este:

const result = query({
  prompt: 'Usá la herramienta personalizada de mi servidor MCP',
  options: {
    mcpServers: {
      'my-server': {
        command: 'node',
        args: ['path/to/mcp-server.js'],
        env: { PORT: '3000' }
      }
    }
  }
});

Esto significa que tu aplicación puede lanzar una sesión con Qwen Code y, al mismo tiempo, conectarla a herramientas externas sin pasar por la configuración global del usuario.

15.17 MCP embebido con tool() y createSdkMcpServer()

Uno de los puntos más potentes del SDK es que permite crear herramientas MCP que viven dentro del mismo proceso de tu aplicación. Para eso existen dos piezas:

  • tool()
  • createSdkMcpServer()

La documentación explica que esto evita correr un servidor MCP separado cuando solo querés exponer algunas herramientas internas simples.

import { z } from 'zod';
import { query, tool, createSdkMcpServer } from '@qwen-code/sdk';

const calculatorTool = tool(
  'calculate_sum',
  'Suma dos números',
  { a: z.number(), b: z.number() },
  async (args) => ({
    content: [{ type: 'text', text: String(args.a + args.b) }],
  }),
);

const server = createSdkMcpServer({
  name: 'calculator',
  tools: [calculatorTool],
});

const result = query({
  prompt: '¿Cuánto es 42 + 17?',
  options: {
    permissionMode: 'yolo',
    mcpServers: {
      calculator: server,
    },
  },
});

Este patrón es excelente para prototipos, aplicaciones internas y asistentes integrados donde necesitás exponer una o dos herramientas propias sin desplegar infraestructura adicional.

15.18 Subagentes en sesiones del SDK

La opción agents permite declarar subagentes disponibles en la sesión creada por el SDK. Esto es coherente con lo que ya vimos en el tema de subagentes: la aplicación puede decidir qué especialistas ofrecerle al agente principal en cada contexto.

Eso vuelve posible construir experiencias muy controladas, por ejemplo una aplicación de revisión de código que siempre incluya un revisor de seguridad y un generador de pruebas.

15.19 Cancelar una consulta

La documentación también cubre cancelación explícita con AbortController:

import { query, isAbortError } from '@qwen-code/sdk';

const abortController = new AbortController();

const result = query({
  prompt: 'Tarea larga...',
  options: {
    abortController,
  },
});

setTimeout(() => abortController.abort(), 5000);

Esto es fundamental para aplicaciones reales. Si integrás Qwen Code en una UI, un job o un backend, necesitás poder interrumpir operaciones largas cuando el usuario cancela o cuando el sistema impone un timeout mayor.

15.20 Errores frecuentes

Problemas habituales con el SDK
Problema Causa probable Primer paso razonable
El SDK no encuentra el ejecutable Qwen Code no está en PATH o falla la autodetección. Usar pathToQwenExecutable.
La consulta no puede escribir archivos El modo de permisos o la política por defecto lo bloquea. Revisar permissionMode, allowedTools y canUseTool.
Una herramienta MCP tarda demasiado El timeout por defecto resulta insuficiente. Ajustar timeout.mcpRequest.
Con nvm no arranca bien La ruta del binario no se detecta correctamente. Declarar la ruta manualmente al ejecutable.
La app recibe mensajes difíciles de procesar No se distinguen los tipos de mensaje emitidos. Usar type guards como isSDKAssistantMessage.

15.21 Buenas prácticas

  1. Probá primero el flujo equivalente en el CLI antes de integrarlo por SDK.
  2. Definí siempre cwd de forma explícita para evitar contexto ambiguo.
  3. No uses yolo por defecto en aplicaciones multiusuario o sensibles.
  4. Si dependés de herramientas propias, empezá con MCP embebido antes de desplegar un servidor separado.
  5. Manejá cancelación, timeouts y errores como parte normal del diseño.

15.22 Síntesis final

El SDK de TypeScript convierte a Qwen Code en una pieza reutilizable dentro de aplicaciones Node.js. En lugar de limitarse a la terminal interactiva, el agente puede ser invocado, controlado y extendido desde código.

En este tema vimos las ideas centrales:

  1. El paquete oficial es @qwen-code/sdk.
  2. query() es la puerta principal para consultas simples o conversaciones multi-turno.
  3. El SDK expone control sobre mensajes, permisos, timeouts y cancelación.
  4. Puede conectarse a MCP externo o crear herramientas MCP embebidas en el mismo proceso.
  5. Su verdadero valor está en integrar Qwen Code dentro de sistemas propios con reglas y herramientas personalizadas.

Con esta base, el siguiente paso natural es cerrar el recorrido con buenas prácticas, diagnóstico y troubleshooting, donde se consolidan muchos de los conceptos operativos vistos a lo largo del curso.