Claude Agent SDK предоставляет мощные элементы управления разрешениями, которые позволяют вам управлять тем, как Claude использует инструменты в вашем приложении.
Это руководство охватывает, как реализовать системы разрешений, используя обратный вызов canUseTool, хуки и правила разрешений settings.json. Для полной документации API см. справочник TypeScript SDK.
Claude Agent SDK предоставляет четыре дополняющих способа контроля использования инструментов:
Случаи использования для каждого подхода:
canUseTool - Динамическое одобрение для непокрытых случаев, запрашивает разрешение у пользователяПорядок обработки: PreToolUse Hook → Правила запрета → Правила разрешения → Правила запроса → Проверка режима разрешений → обратный вызов canUseTool → PostToolUse Hook
Режимы разрешений обеспечивают глобальный контроль над тем, как Claude использует инструменты. Вы можете установить режим разрешений при вызове query() или изменить его динамически во время потоковых сессий.
SDK поддерживает четыре режима разрешений, каждый с разным поведением:
| Режим | Описание | Поведение инструмента |
|---|---|---|
default | Стандартное поведение разрешений | Применяются обычные проверки разрешений |
plan | Режим планирования - без выполнения | Claude может использовать только инструменты только для чтения; представляет план перед выполнением (В настоящее время не поддерживается в SDK) |
acceptEdits | Автоматическое принятие правок файлов | Правки файлов и операции файловой системы автоматически одобряются |
bypassPermissions | Обход всех проверок разрешений | Все инструменты выполняются без запросов разрешений (используйте с осторожностью) |
Вы можете установить режим разрешений двумя способами:
Установите режим при создании запроса:
import { query } from "@anthropic-ai/claude-agent-sdk";
const result = await query({
prompt: "Помоги мне рефакторить этот код",
options: {
permissionMode: 'default' // Стандартный режим разрешений
}
});Измените режим во время потоковой сессии:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Создайте асинхронный генератор для потокового ввода
async function* streamInput() {
yield {
type: 'user',
message: {
role: 'user',
content: "Давайте начнем с разрешениями по умолчанию"
}
};
// Позже в разговоре...
yield {
type: 'user',
message: {
role: 'user',
content: "Теперь давайте ускорим разработку"
}
};
}
const q = query({
prompt: streamInput(),
options: {
permissionMode: 'default' // Начать в режиме по умолчанию
}
});
// Изменить режим динамически
await q.setPermissionMode('acceptEdits');
// Обработать сообщения
for await (const message of q) {
console.log(message);
}acceptEdits)В режиме принятия правок:
Автоматически одобряемые операции:
bypassPermissions)В режиме обхода разрешений:
Режимы разрешений оцениваются в определенной точке потока разрешений:
bypassPermissions - Если активен, разрешает все оставшиеся инструментыcanUseToolcanUseTool - Обрабатывает оставшиеся случаиЭто означает:
bypassPermissionsbypassPermissions переопределяет обратный вызов canUseTool для несовпавших инструментовПример прогрессии режимов:
// Начать в режиме по умолчанию для контролируемого выполнения
permissionMode: 'default'
// Переключиться на acceptEdits для быстрой итерации
await q.setPermissionMode('acceptEdits')Обратный вызов canUseTool передается как опция при вызове функции query. Он получает имя инструмента и входные параметры и должен вернуть решение - либо разрешить, либо запретить.
canUseTool срабатывает всякий раз, когда Claude Code показал бы запрос разрешения пользователю, например, хуки и правила разрешений не покрывают это, и это не в режиме acceptEdits.
Вот полный пример, показывающий, как реализовать интерактивное одобрение инструментов:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function promptForToolApproval(toolName: string, input: any) {
console.log("\n🔧 Запрос инструмента:");
console.log(` Инструмент: ${toolName}`);
// Отобразить параметры инструмента
if (input && Object.keys(input).length > 0) {
console.log(" Параметры:");
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}`);
}
}
// Получить одобрение пользователя (замените на вашу логику UI)
const approved = await getUserApproval();
if (approved) {
console.log(" ✅ Одобрено\n");
return {
behavior: "allow",
updatedInput: input
};
} else {
console.log(" ❌ Отклонено\n");
return {
behavior: "deny",
message: "Пользователь отклонил разрешение для этого инструмента"
};
}
}
// Использовать обратный вызов разрешений
const result = await query({
prompt: "Помоги мне проанализировать эту кодовую базу",
options: {
canUseTool: async (toolName, input) => {
return promptForToolApproval(toolName, input);
}
}
});