El SDK del Agente Claude proporciona controles de permisos poderosos que te permiten gestionar cómo Claude usa las herramientas en tu aplicación.
Esta guía cubre cómo implementar sistemas de permisos usando el callback canUseTool, hooks y reglas de permisos de settings.json. Para documentación completa de la API, consulta la referencia del SDK de TypeScript.
El SDK del Agente Claude proporciona cuatro formas complementarias de controlar el uso de herramientas:
Casos de uso para cada enfoque:
canUseTool - Aprobación dinámica para casos no cubiertos, solicita permiso al usuarioOrden de Procesamiento: Hook PreToolUse → Reglas de Denegación → Reglas de Permiso → Reglas de Pregunta → Verificación de Modo de Permisos → Callback canUseTool → Hook PostToolUse
Los modos de permisos proporcionan control global sobre cómo Claude usa las herramientas. Puedes establecer el modo de permisos al llamar query() o cambiarlo dinámicamente durante sesiones de streaming.
El SDK soporta cuatro modos de permisos, cada uno con comportamiento diferente:
| Modo | Descripción | Comportamiento de Herramientas |
|---|---|---|
default | Comportamiento estándar de permisos | Se aplican verificaciones normales de permisos |
plan | Modo de planificación - sin ejecución | Claude solo puede usar herramientas de solo lectura; presenta un plan antes de la ejecución (Actualmente no soportado en el SDK) |
acceptEdits | Auto-aceptar ediciones de archivos | Las ediciones de archivos y operaciones del sistema de archivos se aprueban automáticamente |
bypassPermissions | Omitir todas las verificaciones de permisos | Todas las herramientas se ejecutan sin solicitudes de permisos (usar con precaución) |
Puedes establecer el modo de permisos de dos formas:
Establece el modo al crear una consulta:
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = await query({
prompt: "Ayúdame a refactorizar este código",
options: {
permissionMode: 'default' // Modo de permisos estándar
}
});Cambia el modo durante una sesión de streaming:
acceptEdits)En modo aceptar ediciones:
Operaciones auto-aprobadas:
bypassPermissions)En modo omitir permisos:
Los modos de permisos se evalúan en un punto específico del flujo de permisos:
bypassPermissions - Si está activo, permite todas las herramientas restantescanUseToolcanUseTool - Maneja los casos restantesEsto significa:
bypassPermissionsbypassPermissions anula el callback canUseTool para herramientas no coincidentesEjemplo de progresión de modos:
// Comenzar en modo predeterminado para ejecución controlada
permissionMode: 'default'
// Cambiar a acceptEdits para iteración rápida
await q.setPermissionMode('acceptEdits')El callback canUseTool se pasa como una opción al llamar la función query. Recibe el nombre de la herramienta y los parámetros de entrada, y debe devolver una decisión - ya sea permitir o denegar.
canUseTool se activa cuando Claude Code mostraría una solicitud de permiso a un usuario, por ejemplo, los hooks y las reglas de permisos no lo cubren y no está en modo acceptEdits.
Aquí hay un ejemplo completo que muestra cómo implementar aprobación interactiva de herramientas:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Crear un generador asíncrono para entrada de streaming
async function* streamInput() {
yield {
type: 'user',
message: {
role: 'user',
content: "Comencemos con permisos predeterminados"
}
};
// Más tarde en la conversación...
yield {
type: 'user',
message: {
role: 'user',
content: "Ahora aceleremos el desarrollo"
}
};
}
const q = query({
prompt: streamInput(),
options: {
permissionMode: 'default' // Comenzar en modo predeterminado
}
});
// Cambiar modo dinámicamente
await q.setPermissionMode('acceptEdits');
// Procesar mensajes
for await (const message of q) {
console.log(message);
}import { query } from "@anthropic-ai/claude-agent-sdk";
async function promptForToolApproval(toolName: string, input: any) {
console.log("\n🔧 Solicitud de Herramienta:");
console.log(` Herramienta: ${toolName}`);
// Mostrar parámetros de la herramienta
if (input && Object.keys(input).length > 0) {
console.log(" Parámetros:");
for (const [key, value] of Object.entries(input)) {
let displayValue = value;
if (typeof value === 'string' && value.length > 100) {
displayValue = value.substring(0, 100) + "...";
} else if (typeof value === 'object') {
displayValue = JSON.stringify(value, null, 2);
}
console.log(` ${key}: ${displayValue}`);
}
}
// Obtener aprobación del usuario (reemplazar con tu lógica de UI)
const approved = await getUserApproval();
if (approved) {
console.log(" ✅ Aprobado\n");
return {
behavior: "allow",
updatedInput: input
};
} else {
console.log(" ❌ Denegado\n");
return {
behavior: "deny",
message: "El usuario denegó el permiso para esta herramienta"
};
}
}
// Usar el callback de permisos
const result = await query({
prompt: "Ayúdame a analizar esta base de código",
options: {
canUseTool: async (toolName, input) => {
return promptForToolApproval(toolName, input);
}
}
});