Claude Agent SDK fornisce potenti controlli di permesso che ti permettono di gestire come Claude utilizza i tool nella tua applicazione.
Questa guida copre come implementare sistemi di permesso utilizzando il callback canUseTool, gli hook e le regole di permesso in settings.json. Per la documentazione completa dell'API, vedi il riferimento TypeScript SDK.
Claude Agent SDK fornisce quattro modi complementari per controllare l'utilizzo dei tool:
Casi d'uso per ogni approccio:
canUseTool - Approvazione dinamica per i casi non coperti, chiede all'utente il permessoOrdine di Elaborazione: PreToolUse Hook → Deny Rules → Allow Rules → Ask Rules → Permission Mode Check → canUseTool Callback → PostToolUse Hook
Le modalità di permesso forniscono un controllo globale su come Claude utilizza i tool. Puoi impostare la modalità di permesso quando chiami query() o cambiarla dinamicamente durante le sessioni di streaming.
L'SDK supporta quattro modalità di permesso, ognuna con comportamenti diversi:
| Modalità | Descrizione | Comportamento Tool |
|---|---|---|
default | Comportamento di permesso standard | Si applicano i controlli di permesso normali |
plan | Modalità di pianificazione - nessuna esecuzione | Claude può utilizzare solo tool di sola lettura; presenta un piano prima dell'esecuzione (Non attualmente supportato in SDK) |
acceptEdits | Accettazione automatica delle modifiche ai file | Le modifiche ai file e le operazioni del file system vengono approvate automaticamente |
bypassPermissions | Bypass di tutti i controlli di permesso | Tutti i tool vengono eseguiti senza prompt di permesso (usare con cautela) |
Puoi impostare la modalità di permesso in due modi:
Imposta la modalità quando crei una query:
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = await query({
prompt: "Help me refactor this code",
options: {
permissionMode: 'default' // Standard permission mode
}
});Cambia la modalità durante una sessione di streaming:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Create an async generator for streaming input
async function* streamInput() {
yield {
type: 'user',
message: {
role: 'user',
content: "Let's start with default permissions"
}
};
// Later in the conversation...
yield {
type: 'user',
message: {
role: 'user',
content: "Now let's speed up development"
}
};
}
const q = query({
prompt: streamInput(),
options: {
permissionMode: 'default' // Start in default mode
}
});
// Change mode dynamically
await q.setPermissionMode('acceptEdits');
// Process messages
for await (const message of q) {
console.log(message);
}acceptEdits)In modalità accettazione modifiche:
Operazioni auto-approvate:
bypassPermissions)In modalità bypass dei permessi:
Le modalità di permesso vengono valutate in un punto specifico del flusso di permesso:
bypassPermissions - Se attiva, consente tutti i tool rimanenticanUseToolcanUseTool - Gestisce i casi rimanentiQuesto significa:
bypassPermissionsbypassPermissions sovrascrive il callback canUseTool per i tool non corrispondentiEsempio di progressione della modalità:
// Start in default mode for controlled execution
permissionMode: 'default'
// Switch to acceptEdits for rapid iteration
await q.setPermissionMode('acceptEdits')Il callback canUseTool viene passato come opzione quando si chiama la funzione query. Riceve il nome del tool e i parametri di input e deve restituire una decisione - consentire o negare.
canUseTool si attiva ogni volta che Claude Code mostrerebbe un prompt di permesso a un utente, ad es. gli hook e le regole di permesso non lo coprono e non è in modalità acceptEdits.
Ecco un esempio completo che mostra come implementare l'approvazione interattiva dei tool:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function promptForToolApproval(toolName: string, input: any) {
console.log("\n🔧 Tool Request:");
console.log(` Tool: ${toolName}`);
// Display tool parameters
if (input && Object.keys(input).length > 0) {
console.log(" Parameters:");
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}`);
}
}
// Get user approval (replace with your UI logic)
const approved = await getUserApproval();
if (approved) {
console.log(" ✅ Approved\n");
return {
behavior: "allow",
updatedInput: input
};
} else {
console.log(" ❌ Denied\n");
return {
behavior: "deny",
message: "User denied permission for this tool"
};
}
}
// Use the permission callback
const result = await query({
prompt: "Help me analyze this codebase",
options: {
canUseTool: async (toolName, input) => {
return promptForToolApproval(toolName, input);
}
}
});Lo strumento AskUserQuestion consente a Claude di porre domande di chiarimento all'utente durante una conversazione. Quando questo tool viene chiamato, il tuo callback canUseTool riceve le domande e deve restituire le risposte dell'utente.
Quando canUseTool viene chiamato con toolName: "AskUserQuestion", l'input contiene:
{
questions: [
{
question: "Which database should we use?",
header: "Database",
options: [
{ label: "PostgreSQL", description: "Relational, ACID compliant" },
{ label: "MongoDB", description: "Document-based, flexible schema" }
],
multiSelect: false
},
{
question: "Which features should we enable?",
header: "Features",
options: [
{ label: "Authentication", description: "User login and sessions" },
{ label: "Logging", description: "Request and error logging" },
{ label: "Caching", description: "Redis-based response caching" }
],
multiSelect: true
}
]
}Restituisci le risposte in updatedInput.answers come un record che mappa il testo della domanda alle etichette dell'opzione selezionata:
return {
behavior: "allow",
updatedInput: {
questions: input.questions, // Pass through original questions
answers: {
"Which database should we use?": "PostgreSQL",
"Which features should we enable?": "Authentication, Caching"
}
}
}Le risposte multi-select sono stringhe separate da virgole (ad es., "Authentication, Caching").