O Claude Agent SDK fornece controles de permissão poderosos que permitem gerenciar como Claude usa ferramentas em sua aplicação.
Este guia aborda como implementar sistemas de permissão usando o callback canUseTool, hooks e regras de permissão do settings.json. Para documentação completa da API, consulte a referência do SDK TypeScript.
O Claude Agent SDK fornece quatro maneiras complementares de controlar o uso de ferramentas:
Casos de uso para cada abordagem:
canUseTool - Aprovação dinâmica para casos não cobertos, solicita permissão do usuárioOrdem de Processamento: Hook PreToolUse → Regras de Negação → Regras de Permissão → Regras de Pergunta → Verificação do Modo de Permissão → Callback canUseTool → Hook PostToolUse
Os modos de permissão fornecem controle global sobre como Claude usa ferramentas. Você pode definir o modo de permissão ao chamar query() ou alterá-lo dinamicamente durante sessões de streaming.
O SDK suporta quatro modos de permissão, cada um com comportamento diferente:
| Modo | Descrição | Comportamento da Ferramenta |
|---|---|---|
default | Comportamento padrão de permissão | Verificações normais de permissão se aplicam |
plan | Modo de planejamento - sem execução | Claude pode usar apenas ferramentas somente leitura; apresenta um plano antes da execução (Atualmente não suportado no SDK) |
acceptEdits | Aceitar edições de arquivo automaticamente | Edições de arquivo e operações do sistema de arquivos são aprovadas automaticamente |
bypassPermissions | Contornar todas as verificações de permissão | Todas as ferramentas executam sem prompts de permissão (use com cautela) |
Você pode definir o modo de permissão de duas maneiras:
Defina o modo ao criar uma consulta:
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = await query({
prompt: "Me ajude a refatorar este código",
options: {
permissionMode: 'default' // Modo de permissão padrão
}
});Altere o modo durante uma sessão de streaming:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Crie um gerador assíncrono para entrada de streaming
async function* streamInput() {
yield {
type: 'user',
message: {
role: 'user',
content: "Vamos começar com permissões padrão"
}
};
// Mais tarde na conversa...
yield {
type: 'user',
message: {
role: 'user',
content: "Agora vamos acelerar o desenvolvimento"
}
};
}
const q = query({
prompt: streamInput(),
options: {
permissionMode: 'default' // Começar no modo padrão
}
});
// Alterar modo dinamicamente
await q.setPermissionMode('acceptEdits');
// Processar mensagens
for await (const message of q) {
console.log(message);
}acceptEdits)No modo aceitar edições:
Operações aprovadas automaticamente:
bypassPermissions)No modo contornar permissões:
Os modos de permissão são avaliados em um ponto específico no fluxo de permissões:
bypassPermissions - Se ativo, permite todas as ferramentas restantescanUseToolcanUseTool - Lida com casos restantesIsso significa:
bypassPermissionsbypassPermissions sobrepõe o callback canUseTool para ferramentas não correspondidasExemplo de progressão de modo:
// Começar no modo padrão para execução controlada
permissionMode: 'default'
// Alternar para acceptEdits para iteração rápida
await q.setPermissionMode('acceptEdits')O callback canUseTool é passado como uma opção ao chamar a função query. Ele recebe o nome da ferramenta e parâmetros de entrada, e deve retornar uma decisão - permitir ou negar.
canUseTool dispara sempre que Claude Code mostraria um prompt de permissão para um usuário, por exemplo, hooks e regras de permissão não o cobrem e não está no modo acceptEdits.
Aqui está um exemplo completo mostrando como implementar aprovação interativa de ferramentas:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function promptForToolApproval(toolName: string, input: any) {
console.log("\n🔧 Solicitação de Ferramenta:");
console.log(` Ferramenta: ${toolName}`);
// Exibir parâmetros da ferramenta
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}`);
}
}
// Obter aprovação do usuário (substitua pela sua lógica de UI)
const approved = await getUserApproval();
if (approved) {
console.log(" ✅ Aprovado\n");
return {
behavior: "allow",
updatedInput: input
};
} else {
console.log(" ❌ Negado\n");
return {
behavior: "deny",
message: "Usuário negou permissão para esta ferramenta"
};
}
}
// Use o callback de permissão
const result = await query({
prompt: "Me ajude a analisar esta base de código",
options: {
canUseTool: async (toolName, input) => {
return promptForToolApproval(toolName, input);
}
}
});