Prerrequisitos

  • Node.js 18+

Instalación

Instala @anthropic-ai/claude-code desde NPM:

npm install -g @anthropic-ai/claude-code

Para ver el código fuente del SDK de TypeScript, visita la página de @anthropic-ai/claude-code en NPM.

Uso básico

La interfaz principal a través del SDK de TypeScript es la función query, que devuelve un iterador asíncrono que transmite mensajes a medida que llegan:

import { query } from "@anthropic-ai/claude-code";

for await (const message of query({
  prompt: "Analizar el rendimiento del sistema",
  abortController: new AbortController(),
  options: {
    maxTurns: 5,
    systemPrompt: "Eres un ingeniero de rendimiento",
    allowedTools: ["Bash", "Read", "WebSearch"]
  }
})) {
  if (message.type === "result") {
    console.log(message.result);
  }
}

Opciones de configuración

ArgumentoTipoDescripciónPor defecto
abortControllerAbortControllerControlador de aborto para cancelar operacionesnew AbortController()
additionalDirectoriesstring[]Directorios adicionales para incluir en la sesiónundefined
allowedToolsstring[]Lista de herramientas que Claude puede usarTodas las herramientas habilitadas por defecto
appendSystemPromptstringTexto para agregar al prompt del sistema por defectoundefined
canUseToolCanUseToolFunción de permisos personalizada para el uso de herramientasundefined
continuebooleanContinuar la sesión más recientefalse
customSystemPromptstringReemplazar completamente el prompt del sistema por defectoundefined
cwdstringDirectorio de trabajo actualprocess.cwd()
disallowedToolsstring[]Lista de herramientas que Claude no puede usarundefined
envDict<string>Variables de entorno a establecerundefined
executable'bun' | 'deno' | 'node'Qué runtime de JavaScript usarnode cuando se ejecuta con Node.js, bun cuando se ejecuta con Bun
executableArgsstring[]Argumentos para pasar al ejecutable[]
fallbackModelstringModelo a usar si el modelo principal fallaundefined
maxThinkingTokensnumberTokens máximos para el proceso de pensamiento de Claudeundefined
maxTurnsnumberNúmero máximo de turnos de conversaciónundefined
mcpServersRecord<string, McpServerConfig>Configuraciones de servidor MCPundefined
modelstringModelo de Claude a usarUsa el por defecto de la configuración CLI
pathToClaudeCodeExecutablestringRuta al ejecutable de Claude CodeEjecutable que viene con @anthropic-ai/claude-code
permissionModePermissionModeModo de permisos para la sesión"default" (opciones: "default", "acceptEdits", "bypassPermissions", "plan")
permissionPromptToolNamestringNombre de la herramienta MCP para prompts de permisosundefined
resumestringID de sesión a reanudarundefined
stderr(data: string) => voidCallback para salida stderrundefined
strictMcpConfigbooleanAplicar validación estricta de configuración MCPundefined

Conversaciones de múltiples turnos

Para conversaciones de múltiples turnos, tienes dos opciones.

Puedes generar respuestas y reanudarlas, o puedes usar el modo de entrada de streaming que acepta un async/generator para un array de mensajes. Por ahora, el modo de entrada de streaming es la única forma de adjuntar imágenes a través de mensajes.

Reanudar con gestión de sesiones

import { query } from "@anthropic-ai/claude-code";

// Continuar la conversación más reciente
for await (const message of query({
  prompt: "Ahora refactoriza esto para mejor rendimiento",
  options: { continue: true }
})) {
  if (message.type === "result") console.log(message.result);
}

// Reanudar sesión específica
for await (const message of query({
  prompt: "Actualizar las pruebas",
  options: {
    resume: "550e8400-e29b-41d4-a716-446655440000",
    maxTurns: 3
  }
})) {
  if (message.type === "result") console.log(message.result);
}

Modo de entrada de streaming

El modo de entrada de streaming te permite proporcionar mensajes como un iterable asíncrono en lugar de una sola cadena. Esto habilita conversaciones de múltiples turnos, adjuntos de imágenes y generación dinámica de mensajes:

import { query } from "@anthropic-ai/claude-code";

// Crear un generador asíncrono para mensajes de streaming
async function* generateMessages() {
  yield {
    type: "user" as const,
    message: {
      role: "user" as const,
      content: "Comenzar a analizar esta base de código"
    }
  };
  
  // Esperar alguna condición o entrada del usuario
  await new Promise(resolve => setTimeout(resolve, 1000));
  
  yield {
    type: "user" as const,
    message: {
      role: "user" as const,
      content: "Ahora enfócate en el módulo de autenticación"
    }
  };
}

// Usar entrada de streaming
for await (const message of query({
  prompt: generateMessages(),
  options: {
    maxTurns: 5,
    allowedTools: ["Read", "Grep", "Bash"]
  }
})) {
  if (message.type === "result") {
    console.log(message.result);
  }
}

Entrada de streaming con imágenes

El modo de entrada de streaming es la única forma de adjuntar imágenes a través de mensajes:

import { query } from "@anthropic-ai/claude-code";
import { readFileSync } from "fs";

async function* messagesWithImage() {
  // Enviar una imagen con texto
  yield {
    type: "user" as const,
    message: {
      role: "user" as const,
      content: [
        {
          type: "text",
          text: "Analiza esta captura de pantalla y sugiere mejoras"
        },
        {
          type: "image",
          source: {
            type: "base64",
            media_type: "image/png",
            data: readFileSync("screenshot.png", "base64")
          }
        }
      ]
    }
  };
}

for await (const message of query({
  prompt: messagesWithImage()
})) {
  if (message.type === "result") console.log(message.result);
}

Prompts de sistema personalizados

Los prompts de sistema definen el rol, experiencia y comportamiento de tu agente:

import { query } from "@anthropic-ai/claude-code";

// Agente de respuesta a incidentes SRE
for await (const message of query({
  prompt: "La API está caída, investigar",
  options: {
    systemPrompt: "Eres un experto SRE. Diagnostica problemas sistemáticamente y proporciona soluciones accionables.",
    maxTurns: 3
  }
})) {
  if (message.type === "result") console.log(message.result);
}

// Agregar al prompt del sistema por defecto
for await (const message of query({
  prompt: "Refactorizar esta función",
  options: {
    appendSystemPrompt: "Siempre incluye manejo de errores integral y pruebas unitarias.",
    maxTurns: 2
  }
})) {
  if (message.type === "result") console.log(message.result);
}

Herramientas personalizadas vía MCP

El Protocolo de Contexto de Modelo (MCP) te permite dar a tus agentes herramientas y capacidades personalizadas:

import { query } from "@anthropic-ai/claude-code";

// Agente SRE con herramientas de monitoreo
for await (const message of query({
  prompt: "Investigar la interrupción del servicio de pagos",
  options: {
    mcpConfig: "sre-tools.json",
    allowedTools: ["mcp__datadog", "mcp__pagerduty", "mcp__kubernetes"],
    systemPrompt: "Eres un SRE. Usa datos de monitoreo para diagnosticar problemas.",
    maxTurns: 4
  }
})) {
  if (message.type === "result") console.log(message.result);
}

Herramientas personalizadas usando MCPs

Puedes implementar herramientas personalizadas usando MCPs, por ejemplo aquí está cómo puedes crear una herramienta de manejo de permisos personalizada.

const server = new McpServer({
  name: "Test permission prompt MCP Server",
  version: "0.0.1",
});

server.tool(
  "approval_prompt",
  'Simular una verificación de permisos - aprobar si la entrada contiene "allow", de lo contrario denegar',
  {
    tool_name: z.string().describe("El nombre de la herramienta que solicita permiso"),
    input: z.object({}).passthrough().describe("La entrada para la herramienta"),
    tool_use_id: z.string().optional().describe("El ID único de solicitud de uso de herramienta"),
  },
  async ({ tool_name, input }) => {
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(
            JSON.stringify(input).includes("allow")
              ? {
                  behavior: "allow",
                  updatedInput: input,
                }
              : {
                  behavior: "deny",
                  message: "Permiso denegado por la herramienta de prueba approval_prompt",
                }
          ),
        },
      ],
    };
  }
);

// Usar en SDK
import { query } from "@anthropic-ai/claude-code";

for await (const message of query({
  prompt: "Analizar la base de código",
  options: {
    permissionPromptTool: "mcp__test-server__approval_prompt",
    mcpConfig: "my-config.json",
    allowedTools: ["Read", "Grep"]
  }
})) {
  if (message.type === "result") console.log(message.result);
}

Formatos de salida

Salida de texto (por defecto)

// Salida de texto por defecto
for await (const message of query({
  prompt: "Explicar archivo src/components/Header.tsx"
})) {
  if (message.type === "result") {
    console.log(message.result);
    // Salida: Este es un componente React que muestra...
  }
}

Salida JSON

// Recopilar todos los mensajes para acceso tipo JSON
const messages = [];
for await (const message of query({
  prompt: "¿Cómo funciona la capa de datos?"
})) {
  messages.push(message);
}

// Acceder al mensaje de resultado con metadatos
const result = messages.find(m => m.type === "result");
console.log({
  result: result.result,
  cost: result.total_cost_usd,
  duration: result.duration_ms
});

Formatos de entrada

// Prompt directo
for await (const message of query({
  prompt: "Explicar este código"
})) {
  if (message.type === "result") console.log(message.result);
}

// Desde variable
const userInput = "Explicar este código";
for await (const message of query({ prompt: userInput })) {
  if (message.type === "result") console.log(message.result);
}

Ejemplos de integración de agentes

Agente de respuesta a incidentes SRE

import { query } from "@anthropic-ai/claude-code";

// Agente automatizado de respuesta a incidentes
async function investigateIncident(
  incidentDescription: string,
  severity = "medium"
) {
  const messages = [];

  for await (const message of query({
    prompt: `Incidente: ${incidentDescription} (Severidad: ${severity})`,
    options: {
      systemPrompt: "Eres un experto SRE. Diagnostica el problema, evalúa el impacto y proporciona elementos de acción inmediatos.",
      maxTurns: 6,
      allowedTools: ["Bash", "Read", "WebSearch", "mcp__datadog"],
      mcpConfig: "monitoring-tools.json"
    }
  })) {
    messages.push(message);
  }

  return messages.find(m => m.type === "result");
}

// Uso
const result = await investigateIncident("API de pagos devolviendo errores 500", "high");
console.log(result.result);

Revisión de seguridad automatizada

import { query } from "@anthropic-ai/claude-code";
import { execSync } from "child_process";

async function auditPR(prNumber: number) {
  // Obtener diff del PR
  const prDiff = execSync(`gh pr diff ${prNumber}`, { encoding: 'utf8' });

  const messages = [];
  for await (const message of query({
    prompt: prDiff,
    options: {
      systemPrompt: "Eres un ingeniero de seguridad. Revisa este PR en busca de vulnerabilidades, patrones inseguros y problemas de cumplimiento.",
      maxTurns: 3,
      allowedTools: ["Read", "Grep", "WebSearch"]
    }
  })) {
    messages.push(message);
  }

  return messages.find(m => m.type === "result");
}

// Uso
const report = await auditPR(123);
console.log(JSON.stringify(report, null, 2));
import { query } from "@anthropic-ai/claude-code";

async function legalReview() {
  // Iniciar sesión de revisión legal
  let sessionId: string;

  for await (const message of query({
    prompt: "Iniciar sesión de revisión legal",
    options: { maxTurns: 1 }
  })) {
    if (message.type === "system" && message.subtype === "init") {
      sessionId = message.session_id;
    }
  }

  // Revisión de múltiples pasos usando la misma sesión
  const steps = [
    "Revisar contract.pdf para cláusulas de responsabilidad",
    "Verificar cumplimiento con requisitos GDPR",
    "Generar resumen ejecutivo de riesgos"
  ];

  for (const step of steps) {
    for await (const message of query({
      prompt: step,
      options: { resume: sessionId, maxTurns: 2 }
    })) {
      if (message.type === "result") {
        console.log(`Paso: ${step}`);
        console.log(message.result);
      }
    }
  }
}

Esquema de mensajes

Los mensajes devueltos por la API JSON están estrictamente tipados según el siguiente esquema:

type SDKMessage =
  // Un mensaje del asistente
  | {
      type: "assistant";
      uuid: string;
      session_id: string;
      message: Message; // del SDK de Anthropic
      parent_tool_use_id: string | null;
    }

  // Un mensaje del usuario (entrada)
  | {
      type: "user";
      uuid?: string;
      session_id: string;
      message: MessageParam; // del SDK de Anthropic
      parent_tool_use_id: string | null;
    }

  // Un mensaje del usuario (salida/repetición con UUID requerido)
  | {
      type: "user";
      uuid: string;
      session_id: string;
      message: MessageParam; // del SDK de Anthropic
      parent_tool_use_id: string | null;
    }

  // Emitido como el último mensaje en caso de éxito
  | {
      type: "result";
      subtype: "success";
      uuid: UUID;
      session_id: string;
      duration_ms: number;
      duration_api_ms: number;
      is_error: boolean;
      num_turns: number;
      result: string;
      total_cost_usd: number;
      usage: Usage;
      permission_denials: SDKPermissionDenial[];
    }

  // Emitido como el último mensaje en caso de error o máximo de turnos
  | {
      type: "result";
      subtype: "error_max_turns" | "error_during_execution";
      uuid: UUID;
      session_id: string;
      duration_ms: number;
      duration_api_ms: number;
      is_error: boolean;
      num_turns: number;
      total_cost_usd: number;
      usage: Usage;
      permission_denials: SDKPermissionDenial[];
    }

  // Emitido como el primer mensaje al inicio de una conversación
  | {
      type: "system";
      subtype: "init";
      uuid: UUID;
      session_id: string;
      apiKeySource: "user" | "project" | "org" | "temporary";
      cwd: string;
      tools: string[];
      mcp_servers: {
        name: string;
        status: string;
      }[];
      model: string;
      permissionMode: "default" | "acceptEdits" | "bypassPermissions" | "plan";
      slash_commands: string[];
      output_style: string;
    };

  type SDKPermissionDenial = {
    tool_name: string;
    tool_use_id: string;
    tool_input: Record<string, unknown>;
  }

Tipos de soporte adicionales:

Los tipos Message, MessageParam y Usage están disponibles en el SDK de TypeScript de Anthropic.

Recursos relacionados