ДовідникІнструкція 02 · Claude Code v2.1.295 · оновлено 09.10.2026 · 195 параметрів

Повна конфігурація settings.json

Повний довідник по всіх параметрах .claude/settings.json: дозволи, моделі, хуки, MCP-сервери, пісочниця, плагіни та корпоративні блокування.

01

що нового

Головні зміни березень → жовтень 2026 (Claude Code v2.1.66 → v2.1.295)

#
changelog 2026summary
Що робить

Короткий перелік змін, що впливають на існуючі settings.json. Перевір свої конфіги на ці пункти.

Що зміниться

Деякі старі значення тепер мовчки ігноруються або ламають валідацію файлу — наприклад cleanupPeriodDays: 0 чи matcher: "Bash(git push*)".

моделі Opus 5.5 — default (Microsoft Foundry: Sonnet 4.5; Enterprise-адмін може задати organization default, v2.1.196+); аліаси opus/sonnet/haiku/fable → Opus 5.5 / Sonnet 5.5 / Haiku 5.5 / Fable 5.1
defaultMode новий режим "auto" — стартовий в інтерактивному терміналі; "manual" = аліас "default"
effort рівні low…max; /effort зберігає в modelSettings; новий ліміт maxEffortLevel (v2.1.267+, також по-модельно в modelSettings)
hooks 33 події; тип mcp_tool; аргументи фільтруються полем "if", а не в matcher
cleanupPeriodDays мінімум 1 — значення 0 тепер не проходить валідацію
ANTHROPIC_SMALL_FAST_MODEL deprecated → ANTHROPIC_DEFAULT_HAIKU_MODEL
BASH_DEFAULT_TIMEOUT_MS default 120000 мс (2 хв), а не 30 с
settings.local.json з v2.1.211 читається з кореня git-репозиторію
managed drop-in каталог managed-settings.d/*.json; managedSourcesBehavior: "merge" (v2.1.242+)
attribution можна false — сховати все; нове поле sessionUrl
нові ключі моделі advisorModel, modelPicker, modelPricing, modelOverrides, availableModelsMatch, promptCacheTtl, ultracode — див. розділ model
нові ключі організації allowedProviders (v2.1.285+), policyHelper, disableSideloadFlags, parentSettingsBehavior, wslInheritsWindowsSettings — див. розділ enterprise / managed
файли і пріоритети усі шляхи, порядок managed-джерел і винятки зібрані в розділі файли і пріоритети
Актуальна версія CLI: 2.1.295 (latest) · 2.1.286 (stable). Повний довідник ключів — code.claude.com/docs/en/settings-reference
02

Файли налаштувань і пріоритети

Де лежить кожен файл, що перемагає при конфлікті і як зливаються managed-джерела

#

Claude Code читає налаштування з чотирьох файлів (user, shared project, project local і managed-settings.json); організація може доставляти managed-налаштування й іншими механізмами. Окремий файл ~/.claude.json Claude Code пише сам для себе. Нічого з цього не створюється при встановленні: файл з’являється, коли ти змінюєш опцію в /config або даєш постійний дозвіл у запиті прав.

Файли і області

ОбластьШляхКого стосуєтьсяДля чого
User~/.claude/settings.json
Windows: %USERPROFILE%\.claude\settings.json
ти, у всіх проєктах на машиніособисте: тема, editorMode, модель, власні правила. Каталог можна перенести змінною CLAUDE_CONFIG_DIR
Shared project.claude/settings.jsonусі, хто працює в проєкті (комітиться)дозволи команди, hooks, плагіни, env проєкту
Project local.claude/settings.local.jsonлише ти, у цьому проєктіособисті перевизначення й експерименти; сюди Claude Code пише «Yes, and don’t ask again»
Global config~/.claude.jsonти (Claude Code пише сам)сесія входу, MCP-сервери, довіра по проєктах, global config keys (autoConnectIde, diffTool тощо). Ці ключі поза цим файлом ігноруються
Managedдив. таблицю нижчеусі, кому розгорнуто політикубезпека й compliance; сильніше за все інше

Де саме лежить local-файл. У git-репозиторії його читають і пишуть у корені репо (у worktree — корінь основного checkout), з v2.1.211. Він лишається поруч із .claude/settings.json, якщо проєкт поза git, корінь репо — це $HOME, ОС — Windows або корінь/.git/.claude належать не вам. Старий файл у стартовій теці ще читається (при конфлікті виграє корінь; правила прав зливаються з обох). Перший запис додає **/.claude/settings.local.json у глобальні git excludes (core.excludesFile, інакше $XDG_CONFIG_HOME/git/ignore або ~/.config/git/ignore); файл, створений руками, до .gitignore додай сам. Його allow-правила не чекають довіри, поки файл не під git.

Спільний .claude/settings.json читається з основної робочої теки сесії: щоб діяв файл у корені репо, запускай Claude Code саме там. Після /cd обидва проєктні файли читаються з нової теки (v2.1.246+).

Managed: звідки і де лежить

МеханізмmacOSLinux / WSLWindowsКоли читається
Server-managedконсоль claude.ai або self-hosted Claude apps gatewayте самете самеfetch на старті, опитування щогодини
MDM / політика ОСconfiguration profile, домен com.anthropic.claudecode—реєстр HKLM: HKLM\SOFTWARE\Policies\ClaudeCode, значення Settings (REG_SZ або REG_EXPAND_SZ) з JSONна старті + перевірка кожні 30 хв
Файли/Library/Application Support/ClaudeCode//etc/claude-code/C:\Program Files\ClaudeCode\на старті, перезавантаження при зміні файлу
HKCU (резерв)—WSL: коли HKLM/Windows-файл вмикає wslInheritsWindowsSettings і HKCU теж ставить йогоHKCU\SOFTWARE\Policies\ClaudeCode → Settings; user-writableна старті + кожні 30 хв; лише коли вище немає admin-документа

У каталозі файлів лежать managed-settings.json, необов’язковий managed-settings.d/*.json і managed-mcp.json. Старий C:\ProgramData\ClaudeCode\managed-settings.json не читається. Шаблони для Jamf, Iru, Intune і Group Policy є в репозиторії anthropics/claude-code (examples/mdm). Є ще parent settings — managed-налаштування від процесу-хоста (опція managedSettings в Agent SDK, Claude Desktop); керує ними parentSettingsBehavior.

Хмарні сесії

Cloud-сесія на свіжому клоні читає лише закомічений .claude/settings.json (якщо в сесії один репозиторій) та server-managed settings. User- і local-файли, а також MDM/файл з пристрою, туди не доходять.

Порядок пріоритету

  1. Managed — нічим не перевизначається (з винятками нижче). Managed model — стартовий default, а не замок: замки це availableModels і deniedModels.
  2. Командний рядок --settings <файл-або-JSON> — лише на цю сесію. Інші прапори (--model) задають одну річ і не входять у стек.
  3. Project local .claude/settings.local.json.
  4. Shared project .claude/settings.json.
  5. User ~/.claude/settings.json.

Змінні середовища — не рівень стека. Для кожної пари «змінна ↔ ключ» вирішено окремо: ANTHROPIC_MODEL перебиває ключ model з будь-якого файлу, а ANTHROPIC_DEFAULT_MODEL діє, лише якщо жоден файл не задає model. Блок env у файлі — звичайний ключ, що йде за рівнями вище.

Порядок усередині managed

  1. Remote / server-managed — лише коли сесія автентифікується прямо в Anthropic прийнятним credential або входить у gateway через /login. На інших провайдерах чи з іншим ANTHROPIC_BASE_URL починається з наступного пункту.
  2. MDM — plist або HKLM.
  3. Файли — managed-settings.json разом з managed-settings.d/*.json.
  4. HKCU — лише коли вище немає жодного admin-документа (документ «присутній», якщо задає будь-який ключ політики не-null, навіть нечитабельний, або якщо HKLM-значення / файл / каталог існує, але нечитабельний).

managedSourcesBehavior

ЗначенняПоведінка
"first-wins" (default)діє найвище джерело, що несе хоча б один ключ політики; решту ігноровано без попередження (джерело видно в /status → Setting sources). Виняток — ключі, які читаються з усіх admin-джерел (нижче). Файл із самими лише managedSourcesBehavior / wslInheritsWindowsSettings джерелом політики не вважається.
"merge" (v2.1.242+)застосовуються всі admin-джерела, поєднані за видом ключа. Задавай у найвищому джерелі, яке розгортаєш (на машині без server-managed — і в MDM-профілі); у managed-settings.json він марний, бо нижче немає з чим зливати. HKCU і parent settings у злитті не беруть участі. Вмикай лише там, де всі нижчі джерела під контролем адміністратора: з них підтягнуться навіть permissions.allow.
Вид ключа при mergeЯк поєднується
списки (permissions.allow, sandbox.network.allowedDomains…)записи з усіх джерел
замки (allowManagedPermissionRulesOnly, permissions.disableBypassPermissionsMode…)найсуворіше значення будь-якого джерела
allowlist-обмеження (availableModels, allowedMcpServers, allowedProviders, strictKnownMarketplaces, allowedChannelPlugins, ланцюг fallbackModel)список цілком з найвищого джерела, що його задає, без додавання з нижчих
значення цілком (sandbox.credentials.awsPairs, sandbox.ripgrep, v2.1.257+)з найвищого джерела цілком
managedMcpServersімена з усіх джерел; однакове ім’я — запис вищого цілком
лише з найвищого джерелаapiKeyHelper, awsAuthRefresh, awsCredentialExport, gcpAuthRefresh, otelHeadersHelper, proxyAuthHelper, forceLoginOrgUUID, значення "claudeai"/"console" у forceLoginMethod, parentSettingsBehavior, modelPicker, policyHelper, permissions.defaultMode
envпо змінних, і при first-wins теж (v2.1.223+)
рештазначення найвищого джерела

Ключі, що читаються з усіх admin-джерел навіть при first-wins (HKCU у цьому скануванні не бере участі): замки sandbox.network.allowManagedDomainsOnly і sandbox.filesystem.allowManagedReadPathsOnly; allowAllClaudeAiMcps; allowManagedMcpServersOnly; deniedMcpServers і disableClaudeAiConnectors (v2.1.273+); sandbox.bwrapPath, socatPath, ripgrep; sandbox.filesystem.disabled, sandbox.network.strictAllowlist; useAutoModeDuringPlan, syncClaudeAiSkills, syncClaudeAiPlugins (false з будь-якого); enableArtifact; maxEffortLevel (найнижча стеля); відмова від commit-trailer у attribution; forceRemoteSettingsRefresh; env по змінних. Ключі gateway-входу (forceLoginGatewayUrl, gatewayInternalNetworks, "gateway") ніколи не читаються з server-managed.

Розбиття політики на файли: managed-settings.d

Якщо частинами політики володіють різні команди, поклади кожну в окремий файл у managed-settings.d/ поруч з managed-settings.json. Спершу зливається managed-settings.json, потім усі *.json в алфавітному порядку (префікси 10-telemetry.json, 20-security.json); приховані файли й не-.json ігноруються.

ЩоПравило злиття
одиничні значення ("model", "cleanupPeriodDays")пізніший файл замінює
списки (permissions.deny, sandbox.network.allowedDomains)об’єднуються без дублікатів
вкладені блоки (env, sandbox)зливаються ключ за ключем, кожен ключ — за цими ж правилами
fallbackModel, modelPicker, однойменні записи extraKnownMarketplaces / managedMcpServersпізніший замінює цілком

Правила злиття між user / project / local / --settings

  • Скаляри: виграє файл вищого пріоритету.
  • Списки (permissions.allow/deny/ask, масиви sandbox, allowedHttpHookUrls, httpHookAllowedEnvVars, allowedMcpServers/deniedMcpServers): об’єднуються, кожен файл лише додає.
  • Винятки зі злиття: fallbackModel (весь ланцюг з найвищого файлу), modelPicker (цілком з найвищого з managed, --settings, user; у project/local ігнорується), availableModels (managed-список застосовується як є, не-managed області зливаються), modelSettings (по моделях разом з effortLevel), extraKnownMarketplaces (однойменний запис вищого файлу замінює цілком, з v2.1.228).
  • hooks зливаються між файлами, а hooks з managed видалити не можна.
  • Довіра до робочої теки: у проєктному файлі лише після довіри діють permissions.allow, additionalDirectories, extraKnownMarketplaces, більшість env, hooks / statusLine / fileSuggestion і project apiKeyHelper. Правила deny і ask діють одразу.

Винятки: коли нижчий рівень сильніший за managed

Для ключів-обмежень Claude Code шанує суворіше значення навіть з області, яка інакше не може перевизначити managed.

КлючЩо шануєтьсяПримітка
disableClaudeAiConnectorstrue з будь-якої областінавіть коли managed ставить false
enableArtifact / disableArtifactfalse / true з будь-якої областінічого не вмикає Artifact назад; v2.1.242+
isolatePeerMachinestrue з будь-якої області—
permissions.blockReadsOutsideWorkingDirectoriestrue з будь-якої областіv2.1.257+
autoMode.classifyAllShelltrue з user або --settingsнавіть над managed false
remoteControlAtStartupfalse з project / localtrue з project/local ігнорується
crossSessionInboundсуворіше значення з project / localдрабина accept < hold < refuse
useAutoModeDuringPlanfalse з managed, --settings, user, localfalse у .claude/settings.json ігнорується
syncClaudeAiSkills / syncClaudeAiPluginsfalse з managed, --settings, user, localfalse у .claude/settings.json ігнорується
maxEffortLevelнижча стеля з будь-якої області, включно з --settingsv2.1.267+

Окремий виняток — застосунок-хост, що задає CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: його модельна конфігурація перекриває managed-ключі model, fallbackModel, modelPicker, modelOverrides та змінні вибору моделі в managed env; managed availableModels лишається в силі, якщо хост не дає свій.

Де що тримати: Django + Vue команда

ЩоКудиЧому
Спільні allow / deny (Bash(python manage.py test *), Bash(npm run lint), deny на Read(./.env)).claude/settings.json, комітитиоднакові правила для всіх; allow діє після довіри до теки, deny — одразу
Hooks (ruff / eslint після Edit), плагіни команди.claude/settings.jsonhooks зливаються з особистими й managed
env проєкту (DJANGO_SETTINGS_MODULE, API_BASE для Vue dev-сервера).claude/settings.json → envне клади сюди секрети: значення лежать у файлі відкритим текстом
Особисте: model, theme, editorMode, outputStyle, autoUpdatesChannel~/.claude/settings.jsonдіє в усіх проєктах, не торкається колег
Особисті експерименти й «don’t ask again» для цього репо.claude/settings.local.json (Claude Code створює сам)не потрапляє в коміти; allow-правила тут не чекають довіри
API-ключі, токенине в settings: apiKeyHelper (Vault), змінні shellключ не лежить на диску розробника
MCP-сервери.mcp.json проєкту або ~/.claude.json (див. розділ mcp)MCP-конфігурація живе окремо від settings.json
Організаційні вимоги (availableModels, deniedModels, allowManagedPermissionRulesOnly, sandbox-замки, requiredMinimumVersion)managed: server-managed (Team/Enterprise без MDM) або файли в /Library/Application Support/ClaudeCode/, /etc/claude-code/нічим не перевизначається; розбивай на 10-telemetry.json, 20-security.json
.claude/settings.json (комітиться в репозиторій)
{
  "permissions": {
    "allow": ["Bash(python manage.py test *)", "Bash(npm run lint)", "Bash(npm run test:unit *)"],
    "deny": ["Read(./.env)", "Bash(python manage.py flush *)"]
  },
  "env": {
    "DJANGO_SETTINGS_MODULE": "config.settings.dev"
  }
}
Перевірка

Щоб побачити, які джерела реально застосувалися, виконай /status — рядок Setting sources називає managed-джерело, яке діє, і пропущені. Розбір «чому ключ не діє» — claude --debug і claude doctor.

03

permissions

Що Claude може і не може робити з файлами та командами

#

Як Claude Code ухвалює рішення про виклик інструмента

Правила дозволів виконує Claude Code, а не модель: інструкції в промпті чи CLAUDE.md впливають на те, що Claude намагається зробити, але не на те, що йому дозволено. Порядок такий:

  1. Хуки PreToolUse запускаються перед запитом на підтвердження. Хук з exit code 2 зупиняє виклик ще до перевірки правил — навіть якщо збігається allow-правило і навіть у bypassPermissions. Рішення хука allow не обходить правила deny та ask.
  2. Правила перевіряються в порядку deny → ask → allow. Виграє перше співпадіння, специфічність не має значення: широкий Bash(aws *) у deny блокує навіть виклик, який збігається з вужчим Bash(aws s3 ls) в allow.
  3. Немає жодного збігу — вирішує режим дозволів (defaultMode): default питає, acceptEdits автоматично приймає редагування, dontAsk відхиляє, bypassPermissions пропускає.
  4. Запобіжники, які не відключає жоден режим: явні ask-правила, rm/rmdir по «критичних шляхах» (корінь, домашня тека, робоча тека і її батьки), інструменти з requiresUserInteraction, AskUserQuestion.
Між файлами налаштувань

Якщо інструмент заборонений на будь-якому рівні, жоден інший рівень його не дозволить: deny з user-файлу блокує allow з проєкту, managed deny не перебити через --allowedTools. Прапор --disallowedTools лише додає обмеження.

«Yes, and don’t ask again» для Bash зберігає правило на постійно для репозиторію й команди (у .claude/settings.local.json у корені git-репозиторію, з v2.1.211). Для складеної команди зберігається окреме правило на кожну підкоманду, до 5 штук. Дозволи на редагування файлів діють лише до кінця сесії.

Синтаксис правил за типом інструмента

Загальна форма — Tool або Tool(специфікатор). Дужки всередині специфікатора літеральні, екранувати їх не треба. Bash(*) — те саме, що Bash.

ІнструментФорма правилаПрикладЯк збігається
Будь-якийToolWebFetch, ReadУсі виклики інструмента. Голе ім’я в deny прибирає інструмент з контексту Claude, а Bash(rm *) лишає інструмент і блокує лише збіги
BashBash(команда)Bash(npm run build), Bash(git log *)Увесь текст команди; без * — точний збіг. Складені команди розбираються на підкоманди (див. нижче)
PowerShellPowerShell(...)PowerShell(Get-ChildItem *)Та сама форма, що й Bash. Аліаси канонізуються (gci, ls, dir = Get-ChildItem), регістр не важливий
Read / EditRead(шлях), Edit(шлях)Read(./.env), Edit(/src/**/*.ts)Синтаксис gitignore з префіксами //, ~/, / (таблиця нижче). Edit діє на всі інструменти редагування
WebFetchWebFetch(domain:хост)WebFetch(domain:*.djangoproject.com)Ім’я хоста з URL, без урахування регістру, кінцева крапка ігнорується
MCPmcp__сервер, mcp__сервер__*, mcp__сервер__інструментmcp__github__get_*Перші дві форми — усі інструменти сервера. Плагінні сервери: mcp__plugin_<плагін>_<сервер>__<інструмент>, конектори claude.ai: mcp__claude_ai_<сервер>__<інструмент>
AgentAgent(Назва)Agent(Explore), Agent(my-reviewer)Субагент за назвою; зазвичай у deny або --disallowedTools
SkillSkill, Skill(name), Skill(name *)Skill(deploy *)Skill — усі скіли; Skill(name) — точна назва; Skill(name *) — префікс з будь-якими аргументами. Deny-правило у параметричній формі Skill(skill:name) збігається зі скілом під будь-якою його назвою (аліас, display name)
CdCd(шлях)Cd(~/code/**)Лише для команди /cd, яку запускаєте ви (Claude її викликати не може). Голе Cd у deny вимикає /cd; будь-яке Cd у allow вмикає режим allowlist. * — один сегмент шляху, ** — багато
ПараметрTool(param:value)Agent(model:opus), Bash(run_in_background:true)Лише deny та ask, див. нижче
Glob за іменем"mcp__*", "*""deny": ["mcp__*"]У deny/ask glob має збігатися з повним іменем інструмента. В allow glob дозволений лише після літерального префікса mcp__<сервер>__; неприв’язаний "*" чи "mcp__*" в allow пропускається з попередженням
Помилки в іменах

Якщо в deny/ask назва інструмента нікому не відповідає, Claude Code попереджає при старті. Користуйтеся канонічними іменами (TaskStop), а не підписами з UI («Stop Task»). Правила зі шляхами для Write, NotebookEdit, Glob, MultiEdit приймаються, але ніколи не перевіряються — пишіть Edit(...) і Read(...).

Bash: wildcard-и, складені команди й обгортки

* у правилі Bash збігається з будь-яким текстом, включно з пробілами, і може стояти будь-де. Ставте * після підкоманди: для git log --oneline main програма — git, підкоманда — log, тому Bash(git log *) дозволяє лише git log, а Bash(git *) — усі git-команди. Для allow-правила з * перед підкомандою (Bash(git * main)) є попередження при старті.

ПравилоЗбігаєтьсяНе збігається
Bash(npm run build)npm run buildnpm run build --watch
Bash(npm run *)npm run build, npm run test --watch, npm runnpm install
Bash(ls *)ls -la, lslsof
Bash(ls*)ls -la, lsof—
Bash(git log * main)git log --oneline maingit log main
Bash(* --version)node --versionnode -v
  • Кінцевий * (з пробілом) збігається й з «голою» командою (Bash(ls *) = ls), але лише якщо це єдиний wildcard у правилі. Пробіл перед * — частина правила.
  • :* на кінці (Bash(ls:*)) — застарілий синонім кінцевого *; розпізнається лише в кінці шаблону. Діалог дозволів пише канонічну форму з пробілом.
  • Складені команди. Роздільники: &&, ||, ;, |, |&, &, нові рядки. Allow-правило має збігатися з кожною підкомандою окремо; deny/ask спрацьовують, якщо збіглась будь-яка підкоманда, навіть всередині $(), підоболонки чи циклу for. Команда із завислим && на кінці вважається нерозбірною, і allow її не схвалює.
  • Обгортки, які прибираються перед порівнянням: timeout, time, nice, nohup, stdbuf, command, builtin, zsh noglob, «голий» xargs (без прапорців). Відомі безпечні змінні середовища на початку (NODE_ENV=test npm test) прибираються для allow; для deny/ask правило збігається поверх будь-якого присвоєння.
  • Не прибираються: direnv exec, devbox run, mise exec, npx, docker exec — Bash(devbox run *) збігається з devbox run rm -rf .. Пишіть правило з бігунком і внутрішньою командою: Bash(devbox run npm test). watch, setsid, ionice, flock і find -exec/-delete префіксним правилом не схвалюються.
  • Завжди без запиту (набір вшитий, не налаштовується): ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat, du, cd і read-only git. Щоб вимагати підтвердження — ask-правило. Все одно питають: нецитовані glob-и з небезпечними прапорцями, docker -H/--context, file -m/-f, UNC-шляхи, запис у PATH/IFS, нерозбірні команди та команди довші за 10 000 символів, cd + git, cd + редирект.
  • Редиректи. Цілі >, >>, 2> перевіряються за правилами Edit, protected paths та робочими теками; ціль < — за правилами Read (з v2.1.257); цілі tee — з v2.1.269. /dev/null, 2>&1 та heredoc не перевіряються.
Deny-правило для Bash — не межа безпеки

Правило збігається з текстом команди, яку написав Claude, а не з програмою. Воно зупиняє першу форму й не зупиняє решту:

Правило в deny/askЗупиняєНе зупиняє
Bash(curl *)curl https://example.com/usr/bin/curl ..., sh -c 'curl ...'
Bash(rm *)rm -rf build//bin/rm -rf build/, bash -c 'rm -rf build/'
Bash(git push *)git push origin maingit -C . push ..., git -c push.default=current push, git 'push' ...

Для реального обмеження використовуйте sandbox (мережевий allowlist і файлові правила на рівні ОС) або хук PreToolUse, який перевіряє повний текст команди. Правила, що обмежують аргументи (Bash(curl http://github.com/ *)), ще крихкіші: їх обходять прапорці перед URL, інший протокол, змінні та редиректи.

Read / Edit: шляхи у стилі gitignore

ПрефіксЗначенняПрикладРеальний шлях
//pathАбсолютний шлях від кореня файлової системиRead(//Users/alice/secrets/**)/Users/alice/secrets/**
~/pathВід домашньої текиRead(~/Documents/*.pdf)/Users/alice/Documents/*.pdf
/pathВідносно джерела налаштуваньEdit(/src/**/*.ts)<основна робоча тека>/src/**/*.ts у project-налаштуваннях
path або ./pathВідносно поточної текиRead(*.env)<cwd>/*.env
Пастка: «/path» — не абсолютний шлях

/Users/alice/file прив’язується до джерела налаштувань, а не до кореня диска; абсолютний шлях — //Users/alice/file. Те саме правило означає різне залежно від файлу, де воно лежить:

Де визначено/path перетворюється на
.claude/settings.json і .claude/settings.local.json<основна робоча тека>/path
~/.claude/settings.json~/.claude/path
файл із --settings <file><тека файла>/path
прапорці CLI, правила сесії<основна робоча тека>/path

Тож Read(/secrets/**) у user-налаштуваннях блокує ~/.claude/secrets/**, а не теку secrets у проєкті. Для правил, що діють у кожному проєкті, пишіть //… або ~/….

  • Голе ім’я файла працює на будь-якій глибині: Read(.env) = Read(**/.env). Правило Read(//**/.env) закриває .env будь-де на диску. На Windows шляхи нормалізуються до /c/Users/...: //c/**/.env або //**/.env для всіх дисків.
  • Однокомпонентна тека типу src/**: в allow збігається лише з <cwd>/src, у deny/ask — з текою src на будь-якій глибині. Якщо потрібна будь-яка глибина в allow — **/src/**.
  • !-заперечення вирізає виняток із попередніх deny/ask того ж джерела (лише відносно cwd, не відкриває вміст цілком заблокованої теки).
  • Deny на Read блокує також Edit і Write на тому шляху (Edit з v2.1.208, Write з v2.1.228); NotebookEdit не покривається — додайте deny на Edit. Файл .claudeignore нічого не робить.
  • Read/Edit deny працюють для вбудованих файлових інструментів, для розпізнаних Bash-команд (cat, head, tail, sed, tee) і цілей редиректів, але не для grep -r pattern . чи скриптів, що самі відкривають файли. Для всіх процесів потрібен sandbox. Для симлінків allow потребує збігу і посилання, і цілі, а deny спрацьовує, якщо збігається будь-що одне.
  • Ці правила живлять і sandbox: шляхи з Edit-allow потрапляють до sandbox.filesystem.allowWrite, Edit-deny — до denyWrite, Read-deny — до denyRead.

WebFetch: домени й «весь інтернет»

  • WebFetch(domain:example.com) — точний хост; domain:*.example.com — піддомени будь-якої глибини, але не сам example.com. Wildcard у будь-якому іншому місці (example.*) охоплює лише один сегмент між крапками. Wildcard-и працюють з v2.1.172.
ПравилоВ allowВ deny
WebFetchClaude завантажує без запиту. Не змінює мережу sandboxІнструмент прибирається з контексту. Не змінює мережу sandbox
WebFetch(domain:*)Без запиту, і sandbox-команди можуть звертатися до будь-якого хостаІнструмент лишається, але кожне завантаження відхиляється, а sandbox-команди не бачать жодного хоста

Тільки форма domain: потрапляє до мережевого allow/deny-списку sandbox, і sandbox враховує лише wildcard-и *.example.com та голий * (з v2.1.186); example.* на sandbox-команди не впливає. Зверніть увагу: заборона WebFetch не закриває мережу, якщо Bash дозволений — curl все одно дістанеться будь-якого URL.

Правила за параметром виклику

deny та ask (не allow) можуть збігатися з одним верхньорівневим скалярним параметром будь-якого вбудованого інструмента:

ПравилоЗбігається
Agent(model:opus)Виклики субагента з моделлю opus (порівнюється літеральне значення, не повний ID)
Agent(isolation:worktree)Субагент у git worktree
Bash(run_in_background:true)Bash у фоні
Bash(dangerouslyDisableSandbox:true)Спроба вийти з sandbox (див. секцію sandbox)
  • Одне правило — один параметр; для двох умов пишіть два правила. Параметр, якого модель не передала, ніколи не збігається (Agent(model:*) не зачепить виклик без model). Значення підтримує *.
  • Основні поля (command, file_path, path, notebook_path, url) так зіставити не можна: правило Bash(command:rm *) ігнорується з попередженням при старті.
  • Для MCP-інструментів параметрні правила працюють лише через --disallowedTools; у файлах налаштувань будь-яке правило mcp__… з дужками пропускається.

Режими дозволів

Режим задає базову поведінку для викликів, яких не торкнулося жодне правило. Правила працюють поверх режиму: deny блокує в усіх режимах, включно з bypassPermissions, а allow у bypassPermissions не має ефекту. Перемикання в сесії — Shift+Tab; dontAsk у цикл не входить ніколи (лише --permission-mode dontAsk), bypassPermissions з’являється лише якщо сесію запущено з ним (або з --allow-dangerously-skip-permissions).

РежимБез запиту виконуєтьсяЗапис у protected pathsНевідомий хост у sandbox
default / manualЧитання (і read-only Bash)ПитаєПитає
acceptEditsЧитання, редагування файлів і mkdir, touch, rm, rmdir, mv, cp, sed — у робочій теці та additionalDirectories (також з безпечними змінними/обгортками на початку). Решта Bash питаєПитаєПитає
planЧитання. Shell-команди: якщо доступний auto і useAutoModeDuringPlan (за замовчуванням true), їх переглядає класифікатор, інакше команди поза read-only набором питають. Редагування заблоковане, доки ви не схвалите планКласифікатор або питає (у терміналі з доступним bypass — дозволено)Питає (у терміналі з доступним bypass — дозволено)
autoУсе, але фонова модель-класифікатор перевіряє дії (shell, мережа та ін.)КласифікаторВідхилено, якщо команда не перелічила хост у власному списку (v2.1.271+) і класифікатор його не схвалив
dontAskЧитання, read-only Bash, allow-правила, виклики, схвалені хуком. Усе, що спитало б, відхиляється (включно з ask-правилами та AskUserQuestion)ВідхиленоВідхилено
bypassPermissionsУсе, окрім «запобіжників, що не відключаються» (ask-правила, критичні rm, AskUserQuestion)ДозволеноДозволено
Protected paths

Записи в .git, .claude, .vscode, .idea, .husky, .devcontainer, .mcp.json, .claude.json, .gitconfig, shell-rc (.zshrc, .bashrc …), .npmrc, .pre-commit-config.yaml та ін. ніколи не схвалюються автоматично (крім bypassPermissions і plan-режиму в терміналі з доступним bypass). Allow-правило типу Edit(.claude/**) у settings це не змінює — перевірка йде раніше за allow. Для .claude/ проєкту та ~/.claude/ промпт може запропонувати дозвіл «на сесію».

permissions.allowarray
Що робить

Список операцій які Claude виконує без запиту підтвердження. Claude просто робить — не питає.

Що зміниться

Додавши правило — Claude більше не зупинятиметься для підтвердження. Прибравши — знову питатиме або блокуватиме залежно від defaultMode.

команда Django/Vue
settings.json
"allow": [
  "Bash(git status)", "Bash(git diff *)", "Bash(git log *)",
  "Bash(git add *)",
  "Bash(python manage.py showmigrations *)",  // без * збіглась би лише точна команда
  "Bash(npm run lint)", "Bash(npm run test:unit)",
  "Edit(/src/**/*.vue)",       // / = від кореня проєкту (у project settings), НЕ абсолютний
  "Edit(/src/**/*.ts)",
  "WebFetch(domain:docs.djangoproject.com)",
  "mcp__github__get_*"         // * лише в частині назви інструменту
]
Синтаксис: Tool · Tool(pattern) · Bash(cmd *) · mcp__server__tool. Форма Bash(cmd:*) ще працює, але канонічна — з пробілом. Повна таблиця правил — на початку розділу
Allow-правила з проєктного .claude/settings.json діють лише після довіри до папки. Allow у mcp__ допускає glob лише після літерального префікса mcp__сервер__; неприв’язані "*"/"mcp__*" пропускаються з попередженням. У режимі bypassPermissions allow-правила не мають ефекту.
⚠ Правила для Write / Glob / MultiEdit / NotebookEdit з шляхами не перевіряються — використовуй Edit(...) і Read(...)
permissions.denyarray
Що робить

Заборона. Перевіряється першою — блокує виклик навіть якщо він є в allow, і діє в усіх режимах, включно з bypassPermissions. Але для Bash вона збігається з текстом команди, тому не є межею безпеки (див. попередження нижче).

Що зміниться

Scoped-правило (Bash(rm *)) лишає інструмент, але блокує збіги; голе ім’я (Bash, mcp__*) прибирає інструмент із контексту Claude повністю. Deny-правила з проєкту діють одразу, навіть до довіри до папки. Deny на Read(path) блокує також Edit/Write на тому шляху.

обов’язкова безпека
settings.json
"deny": [
  "Read(**/.env)", "Read(**/.env.*)",  // .env — ніколи
  "Read(~/.ssh/**)", "Read(~/.aws/**)",
  "Bash(sudo *)", "Bash(su *)",
  "Bash(rm -rf *)", "Bash(dd *)",   // без * правило — точний збіг
  "Bash(curl *)", "Bash(wget *)", "Bash(ssh *)",
  "mcp__*"                        // у deny можна glob по назві інструменту
]
⚠ Порядок: deny → ask → allow. Перше співпадіння виграє незалежно від специфічності.
⚠ Bash(curl *), Bash(wget *), Bash(ssh *) не зупинять /usr/bin/curl, sh -c 'curl …' чи bash -c 'rm …': це не межа безпеки навколо програми. Для реальної заборони мережі використовуйте sandbox (network.allowedDomains / strictAllowlist) або хук PreToolUse. Також Read/Edit deny не зупиняють grep -r . чи скрипт, що сам відкриває файли.
permissions.askarray
Що робить

Операції де Claude завжди питає підтвердження — навіть якщо є в allow. Показує що саме збирається зробити.

Що зміниться

Додавши в ask — Claude зупиниться перед виконанням. Корисно для незворотних операцій: push, migrate, deploy. Дає контроль без повного блокування.

незворотні операції
settings.json
"ask": [
  "Bash(git commit *)", "Bash(git push *)", "Bash(git merge *)",
  "Bash(python manage.py migrate)",
  "Bash(docker compose up *)", "Bash(docker compose down *)",
  "Bash(gh pr create *)"
]
Ask виграє над allow, навіть якщо allow вужче. Явні ask-правила не відключає жоден режим: у bypassPermissions вони все одно питають, у dontAsk — відхиляють виклик. З autoAllowBashIfSandboxed голе Bash в ask пропускається для команд у sandbox (не в plan-режимі), але вузькі правила на кшталт Bash(git push *) і далі питають.
Для виходу з sandbox: "Bash(dangerouslyDisableSandbox:true)" в ask змушує підтверджувати кожну спробу, навіть в auto і bypassPermissions, і має пріоритет над збіжним allow.
permissions.defaultModeenum
Що робить

Поведінка для операцій яких немає в жодному з масивів (allow/deny/ask). Режим за замовчуванням для всього нового.

Що зміниться

Визначає скільки підтверджень побачать розробники: від класифікатора, що сам вирішує, до read-only. Якщо не задано: інтерактивний термінал і VS Code (з v2.1.283) стартують в auto; -p/SDK — в default у сесіях, що завантажують feature flags, а без них (сторонній провайдер, вимкнена телеметрія) — в auto з v2.1.285. Пріоритет: прапорець --permission-mode → defaultMode → вбудований default. Якщо auto недоступний сесії — старт у Manual.

"default" / "manual" Без запиту — лише читання (і read-only Bash); решта питає. У UI та --help називається «Manual», значення "manual" — синонім. ✓ Рекомендовано для команди
"auto" Фонова модель-класифікатор перевіряє дії (shell, мережа) і блокує те, що не відповідає запиту. Вбудований стартовий режим терміналу й VS Code з v2.1.283; потребує підтримуваної моделі, організація може його вимкнути
"acceptEdits" Авто-приймає редагування файлів і типові файлові команди — mkdir, touch, rm, rmdir, mv, cp, sed — у робочій теці та additionalDirectories (рішення перевіряє й симлінки). Решта Bash, шляхи поза зоною та protected paths — питають. Добре для швидкого рефакторингу
"plan" Читає файли та запускає shell-команди для розвідки, пише план, але не редагує код, доки ви не схвалите план. Якщо доступний auto, команди перевіряє класифікатор (useAutoModeDuringPlan), інакше команди поза read-only набором питають. Корисно для code review без ризику
"dontAsk" Авто-відхиляє кожен виклик, що інакше питав би: працюють читання у робочих теках, read-only Bash, allow-правила та виклики, схвалені хуком PreToolUse. Ask-правила, AskUserQuestion та MCP-інструменти з requiresUserInteraction відхиляються. Зручно для CI з --allowedTools. Не входить у цикл Shift+Tab
"bypassPermissions" ⚠ Вимикає запити й перевірки protected paths, але deny-правила діють, а ask-правила, критичні rm та AskUserQuestion усе одно питають; allow-правила не мають ефекту. ТІЛЬКИ в ізольованих контейнерах/VM/CI. Ніколи на машині розробника. На Linux/macOS відмовляється стартувати від root/sudo
⚠ "auto" і "bypassPermissions" ігноруються з .claude/settings.json і settings.local.json — лише user або managed (або --settings). Для auto береться вбудований default, для bypassPermissions сесія стартує в Manual. Інші значення діють з будь-якого файлу.
Хмарні сесії (claude.ai/code) приймають лише acceptEdits, plan, default і auto; dontAsk та bypassPermissions із settings ігноруються. Розширення VS Code читає значення лише з user, managed і --settings (проєктні — ні; є окреме claudeCode.initialPermissionMode).
autoMode / disableAutoModeobject / enum
Що робить

Налаштовує класифікатор режиму auto: опис середовища та прозові правила що дозволено, що «м’яко» і що жорстко заборонено. disableAutoMode: "disable" вимикає режим повністю.

Що зміниться

Дає змогу підлаштувати auto під політику компанії замість переліку сотень allow-правил. autoMode задається лише в user або managed settings (і --settings); disableAutoMode — у будь-якому файлі (також приймається як permissions.disableAutoMode), але має сенс у managed. З ним auto зникає з циклу Shift+Tab, а сесії, що стартували б в auto, стартують в default.

settings.json
"autoMode": {
  "environment": ["Django монорепо, prod-доступу з ноутбуків немає"],
  "allow":       ["$defaults", "запуск тестів і лінтерів"],
  "soft_deny":   ["$defaults", "зміни в міграціях"],
  "hard_deny":   ["$defaults", "будь-які дії з prod-базою"]
},
"disableAutoMode": "disable"   // повністю заборонити auto
Масиви з кількох файлів конкатенуються. Рядок "$defaults" зберігає вбудовані правила на цій позиції; без нього ваші правила їх замінюють. Додатковий підключ classifyAllShell — окремою карткою нижче.
permissions.disableBypassPermissionsModeenumрекомендовано managed
Що робить

Повністю забороняє режим bypassPermissions. Єдине значення — "disable". Працює з будь-якого файлу, але для організації його ставлять у managed.

Що зміниться

Ключ має пріоритет над --dangerously-skip-permissions, який Claude Code відхиляє, поки ключ задано. Також нейтралізує permissionMode: bypassPermissions у frontmatter субагентів.

settings.json
"permissions": { "disableBypassPermissionsMode": "disable" }
✓ Рекомендовано для всіх enterprise налаштувань
allowManagedPermissionRulesOnlybooleanmanaged only
Що робить

Блокує можливість юзерам і проєктам додавати власні правила allow/deny/ask. Діють лише правила з managed settings.

Що зміниться

true — ігноруються правила з user/project/local/--settings і прапор --allowedTools, зникають кнопки «always allow», а також allowed-tools у не-managed скілах (з v2.1.282) і командах .claude/commands/. Нові правила більше не зберігаються.

settings.json
"allowManagedPermissionRulesOnly": true
Прапорець --disallowedTools і deny/ask правила поточної сесії далі діють, бо лише обмежують. Skills з managed і вбудовані зберігають свій allowed-tools. Цей ключ не обмежує список MCP-серверів — для цього є allowManagedMcpServersOnly.
permissions.additionalDirectoriesarray
Що робить

Розширює "зону дозволів" Claude за межі поточної директорії проєкту.

Що зміниться

Claude отримає доступ до файлів суміжних проєктів. Важливо: на відміну від --add-dir, конфігурація .claude/ з цих папок не завантажується. Записи з проєкту діють після довіри до папки. Вони також розширюють область запису для sandbox (з обмеженнями для project/local-файлів у admin-required режимі).

settings.json
"additionalDirectories": [
  "../backend-api",
  "../docs/"
]
Це лише доступ до файлів. З --add-dir (але не з цього ключа) підхоплюються .claude/skills, commands, agents; CLAUDE.md — тільки з CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1. Додати мережевий UNC-шлях не можна.
permissions.blockReadsOutsideWorkingDirectoriesboolean
Що робить

Новий (v2.1.257). Забороняє Claude читати файли поза робочими директоріями (проєкт + additionalDirectories).

Що зміниться

Діє на Read, Grep, Glob, LSP в усіх режимах, включно з bypassPermissions. true з будь-якого файлу перемагає — його не можна «скасувати» з іншого файлу. Простий спосіб закрити доступ до ~/.ssh, ~/.aws та інших проєктів без довгого deny-списку.

settings.json
"permissions": { "blockReadsOutsideWorkingDirectories": true }
Shell-команди не відхиляються, а питають підтвердження (навіть в auto/bypass); це стосується розпізнаних Bash-команд читання та повторів поза sandbox, що потребують схвалення. Потребує v2.1.257+. У sandbox блок також закриває /Users, /home, /root, /Volumes, /mnt, /media, /run/media, /srv. Теки, додані лише в репозиторних налаштуваннях, робочими для блоку не вважаються. У auto Claude Code запропонує ввімкнути цей ключ при першому читанні поза межами.
autoMode.classifyAllShellbooleanuser / managed
Що робить

Пропускати кожну Bash- і PowerShell-команду через класифікатор auto-режиму. За замовчуванням auto призупиняє лише allow-правила, що можуть виконати довільний код (Bash(*), Bash(python *)); команда, якій відповідає вузьке правило на кшталт Bash(npm test), класифікатор оминає.

Що зміниться

З true усі shell-allow-правила призупиняються на час auto-режиму, тож класифікатор бачить кожну команду (вони продовжують діяти поза auto). Закриває випадок, коли небезпечний аргумент проскакує повз префіксне правило. Default false. Потребує v2.1.193+.

settings.json
"autoMode": {
  "classifyAllShell": true
}
Ключ читається з user, managed і --settings. true з user-налаштувань чи --settings перемагає false з managed.
useAutoModeDuringPlanbooleanuser / local / managed
Що робить

Чи використовувати класифікатор auto-режиму для shell-команд у режимі plan. Показується в /config як «Use auto mode during plan».

Що зміниться

Default true: якщо auto доступний, команди під час планування переглядає класифікатор, а не ви (окрім видалення критичних шляхів). З false кожна команда поза вшитим read-only набором питатиме підтвердження.

settings.json
"useAutoModeDuringPlan": false
false з будь-якого з цих файлів вимикає опцію; false у закоміченому .claude/settings.json ігнорується — репозиторій не може вимкнути її за вас.
skipDangerousModePermissionPromptbooleanuser / local / managed
Що робить

Пропускає діалог-попередження, який Claude Code показує перед тим, як сесія увійде в bypassPermissions (через --dangerously-skip-permissions або defaultMode: "bypassPermissions").

Що зміниться

Claude Code сам записує true у user-налаштування після першого прийняття діалогу. Щоб побачити діалог знову — приберіть ключ або поставте false. Репозиторій не може пропустити діалог за вас.

settings.json
"skipDangerousModePermissionPrompt": true
У non-interactive режимі (-p) діалогу немає; фонова сесія --bg відхиляється, доки ви не приймете діалог в інтерактивній.
skipAutoPermissionPromptbooleanuser / managed
Що робить

Пропускає одноразове повідомлення про auto-режим, яке з’являється, коли ви самі вперше вмикаєте auto (через свої налаштування або селектор режиму), а не коли вбудований default стартує сесію в ньому.

Що зміниться

Без ключа повідомлення показується один раз і запам’ятовується. Корисно для розгортання через managed settings, коли не хочете, щоб команда бачила це повідомлення.

settings.json
"skipAutoPermissionPrompt": true
Репозиторій цього ключа задати не може.

Робочі директорії

За замовчуванням Claude має доступ до теки, де запущений; це основна робоча тека сесії. Розширити доступ можна так:

  • --add-dir <path> при старті, /add-dir у сесії або permissions.additionalDirectories у налаштуваннях. Файли там підкоряються тим самим правилам: читання без запиту, редагування — за режимом.
  • /cd <path> переносить основну теку: підвантажує її CLAUDE.md, project-налаштування (правила й хуки), .mcp.json та плагіни нової теки. Для незнайомої теки показує діалог довіри. Обмежити цілі можна правилами Cd(...).
  • Мережеві UNC-шляхи (\\server\share) додати не можна — на Windows підмонтуйте диск літерою.
  • Теки з additionalDirectories дають лише доступ до файлів, не конфігурацію. З --add-dir підхоплюються .claude/skills, .claude/commands, .claude/agents та лише ключі enabledPlugins і extraKnownMarketplaces із settings; CLAUDE.md — тільки з CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1.

Довіра до робочої теки (workspace trust)

  • permissions.allow і additionalDirectories з .claude/settings.json проєкту діють лише після діалогу довіри. deny та ask діють одразу — вони тільки обмежують.
  • claude -p і SDK діалог не показують: project allow-правила там не використовуються, хоча хуки з project-налаштувань — використовуються. Для чужого репозиторію запускайте з --setting-sources user або --bare.
  • .claude/settings.local.json, який відстежується git (або симлінкований), вважається репозиторним: його правила чекають довіри.

Ключі, доступні лише в певних файлах

КлючДе дієНюанс
allowManagedPermissionRulesOnlyЛише managedПравила з інших файлів ігноруються; --disallowedTools і сесійні deny/ask усе ще діють
autoMode, autoMode.classifyAllShellUser, managed (і --settings)Масиви з кількох файлів конкатенуються; "$defaults" зберігає вшиті правила
disableAutoMode / permissions.disableAutoModeБудь-який файлТипово ставиться в managed
permissions.disableBypassPermissionsModeБудь-який файлТипово в managed; користувач може сам заблокувати собі bypass
permissions.blockReadsOutsideWorkingDirectoriesБудь-який файлtrue з будь-якого файлу перемагає
skipDangerousModePermissionPromptUser, local, managedНе з committed project-файлу
skipAutoPermissionPromptUser, managed—
useAutoModeDuringPlanUser, local, managedfalse з committed project-файлу ігнорується
permissions.defaultMode: auto, bypassPermissionsUser, managed, --settingsЗ project/local ці значення не діють

Приклад для Django + Vue команди

Налаштування проєкту, яке комітиться в .claude/settings.json. Зверніть увагу: allow-правила Bash з * після підкоманди; шляхи /backend/… і /frontend/… прив’язані до кореня проєкту; реальну заборону мережі дає sandbox, а не deny.

.claude/settings.json
{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(git status)", "Bash(git diff *)", "Bash(git log *)", "Bash(git add *)",
      "Bash(python manage.py check *)",
      "Bash(python manage.py showmigrations *)",
      "Bash(python manage.py makemigrations --dry-run *)",
      "Bash(pytest *)",
      "Bash(npm run lint *)", "Bash(npm run test:unit *)",
      "Edit(/backend/**/*.py)", "Edit(/frontend/src/**)",
      "WebFetch(domain:docs.djangoproject.com)", "WebFetch(domain:vuejs.org)"
    ],
    "ask": [
      "Bash(git commit *)", "Bash(git push *)",
      "Bash(python manage.py migrate *)",
      "Bash(docker compose *)",
      "Bash(dangerouslyDisableSandbox:true)"   // підтверджувати кожен вихід із sandbox
    ],
    "deny": [
      "Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)",
      "Read(~/.ssh/**)", "Read(~/.aws/**)",
      "Edit(/backend/config/settings/production.py)",
      "Bash(sudo *)", "Bash(rm -rf *)"
    ],
    "additionalDirectories": ["../shared-ui"],       // діє після довіри до теки
    "blockReadsOutsideWorkingDirectories": true
  }
}
04

env

Змінні середовища — встановлюються автоматично в кожній сесії

#
envobject
Що робить

Встановлює змінні середовища при кожному старті Claude Code. Аналог export у .bashrc, але тільки для Claude — не впливає на shell.

Що зміниться

Централізовано задати модель, таймаути, вимкнути телеметрію для всіх без ручного налаштування кожної машини. Змінні, які Claude Code вважає безпечними (вибір моделі, таймаути й ліміти, перемикачі функцій), застосовуються на старті з будь-якого файлу; решта з проєктних файлів — після довіри до папки (у режимі -p діалогу довіри немає, тож вони діють на старті).

приватність — вимкнути телеметрію
settings.json
"env": {
  "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
  // ↑ вимикає все нижче + /feedback, release notes, feature flags
  //   увага: "0" чи "false" теж ВИМИКАЮТЬ — щоб увімкнути, видали змінну
  "DISABLE_AUTOUPDATER": "1",     // фонові оновлення (claude update працює)
  "DISABLE_TELEMETRY": "1",       // вимкнути аналітику
  "DISABLE_ERROR_REPORTING": "1"  // вимкнути звіти про помилки
}
вибір моделей
settings.json
"env": {
  "ANTHROPIC_MODEL": "claude-sonnet-5-5",
  // ↑ перевизначає ключ model з будь-якого файлу
  "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-5-5",
  // ↑ на що вказує аліас haiku + фонові задачі
  //   (замість deprecated ANTHROPIC_SMALL_FAST_MODEL)
  "CLAUDE_CODE_SUBAGENT_MODEL": "sonnet"
  // ↑ лише fallback: model у frontmatter агента важливіший
  //   CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 — перебити все
}
таймаути і поведінка
settings.json
"env": {
  "BASH_DEFAULT_TIMEOUT_MS": "300000",
  // ↑ таймаут bash команд у мс. Default 120000 (2 хв)
  //   стеля — BASH_MAX_TIMEOUT_MS, default 600000 (10 хв)
  "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "70",
  // ↑ % вікна для авто-стиснення — може лише ЗНИЗИТИ поріг
  "CLAUDE_CODE_EFFORT_LEVEL": "high"
  // ↑ low|medium|high|xhigh|max|auto — найвищий пріоритет
}
⚠ MAX_THINKING_TOKENS на Opus/Sonnet/Haiku 5.5 та Fable ігнорується — ці моделі думають адаптивно, керуй через effort
⚠ Проєктні (.claude/settings.json) і локальні (settings.local.json) файли не можуть задати змінні, якими не повинен керувати склонований репозиторій; Claude Code мовчки відкидає їх (видно в claude --debug). Задавай їх у shell, user- або managed-settings: шляхи (CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, HOME, TMPDIR, TMP, TEMP, XDG_*); системні змінні Windows (SystemRoot, ComSpec, PATHEXT тощо); експорт вмісту сесії (OTEL_LOG_RAW_API_BODIES, ENABLE_BETA_TRACING_DETAILED, BETA_TRACING_ENDPOINT); змінні, що вмикають і спрямовують OpenTelemetry: CLAUDE_CODE_ENABLE_TELEMETRY (і бета-пара enhanced telemetry), OTEL_LOGS_EXPORTER / OTEL_METRICS_EXPORTER / OTEL_TRACES_EXPORTER, OTEL_LOG_USER_PROMPTS / OTEL_LOG_TOOL_DETAILS / OTEL_LOG_TOOL_CONTENT / OTEL_LOG_ASSISTANT_RESPONSES і OTEL_EXPORTER_OTLP_* з суфіксами _ENDPOINT, _HEADERS, _PROTOCOL, _CERTIFICATE, _CLIENT_KEY, _INSECURE, а також OTEL_EXPORTER_PROMETHEUS_HOST / _PORT; старт і синхронізація (CLAUDE_CODE_PROCESS_WRAPPER, CLAUDE_CODE_SYNC_SKILLS, CLAUDE_CODE_SYNC_PLUGINS, CLAUDE_CODE_PLUGIN_CACHE_DIR, CLAUDE_CODE_PLUGIN_SEED_DIR); таймери діалогів (CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS, CLAUDE_AFK_TIMEOUT_MS, CLAUDE_AFK_COUNTDOWN_MS, з v2.1.290) і CLAUDE_CODE_DISABLE_ATTACHMENTS. Лише «вимикаючі» значення OTel усе ж діють з проєктних файлів: none для трьох OTEL_*_EXPORTER і 0 для OTEL_LOG_USER_PROMPTS, OTEL_LOG_TOOL_CONTENT, OTEL_LOG_TOOL_DETAILS. Ігнорування OTel-групи у project/local потребує v2.1.282+.

Як env взаємодіє з shell

  • Значення в env перезаписує ту саму змінну, експортовану в shell. Між файлами діє звичайний пріоритет (див. файли і пріоритети), managed — найвищий.
  • Виняток: якщо сесію запустили Claude Desktop або self-hosted runner, перемагає середовище запуску — env із файлів для змінних, які воно вже задало, ігнорується (debug-лог називає кожну).
  • Щоб скасувати експорт зі shell, задай "": порожнє значення для вибору провайдера рахується як «не задано».
  • NO_COLOR / FORCE_COLOR з env доходять лише до підпроцесів — кольори самого інтерфейсу міняй у shell до запуску.
  • Значення лежать у файлі відкритим текстом і потрапляють у кожен підпроцес. Для OTLP-токена, що ротується, є otelHeadersHelper, для API-ключів — apiKeyHelper.
  • Зміни в файлі підхоплюються працюючою сесією, але те, що читається лише на старті (наприклад, OpenTelemetry), чекає перезапуску; видалення змінної з файлу скасовується лише при наступному запуску.
Булеві змінні

Для перемикачів працюють 1/true/yes/on і 0/false/no/off у будь-якому регістрі. Є змінні, що перевіряють лише факт наявності: будь-яке непорожнє значення, навіть 0, вмикає поведінку (як DISABLE_TELEMETRY і CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC). Числові змінні приймають 2e3 і 64_000, якщо в рядку не сказано «лише цифри».

Довідник змінних

В офіційній таблиці Variables документовано 390 змінних середовища. Нижче — близько п’ятдесяти тих, що справді потрібні в командній роботі, за групами. Повний перелік: code.claude.com/docs/en/env-vars.

Моделі, провайдер і автентифікація

ЗміннаЗначення / defaultЩо робить
ANTHROPIC_DEFAULT_OPUS_MODELID моделіНа що вказує аліас opus; його ж бере opusplan у Plan Mode.
ANTHROPIC_DEFAULT_SONNET_MODELID моделіНа що вказує sonnet; його ж бере opusplan поза Plan Mode.
ANTHROPIC_DEFAULT_FABLE_MODELID моделіНа що вказує fable; за цим ID Claude Code впізнає Fable для автоматичного fallback на сторонніх провайдерах.
CLAUDE_CODE_MAX_OUTPUT_TOKENSціле; залежить від моделіМаксимум вихідних токенів для більшості запитів. Для невідомої моделі default 32000, стеля 128000. Більше значення зменшує ефективне вікно до авто-стиснення.
CLAUDE_CODE_DISABLE_1M_CONTEXT1Вимикає підтримку вікна 1M: прибирає варіанти [1m] з пікера, моделі з 1M за замовчуванням тримає на 200K. Корисно для вимог compliance.
CLAUDE_CODE_DISABLE_THINKING1Не передавати параметр thinking узагалі — сумісність з проксі, що його відкидають. Справжнє вимкнення: MAX_THINKING_TOKENS=0. Ні те, ні інше не вимикає thinking на моделях 5.5 і Fable.
ANTHROPIC_API_KEYрядокЙде як X-Api-Key і використовується замість підписки, навіть якщо ти залогінений. В інтерактивному режимі ключ треба схвалити один раз, у -p він діє завжди.
ANTHROPIC_AUTH_TOKENрядокЗначення заголовка Authorization (з префіксом Bearer ).
ANTHROPIC_BASE_URLURLМаршрут через проксі чи gateway. На не-Anthropic хості вимикає MCP tool search за замовчуванням (ENABLE_TOOL_SEARCH=true, якщо проксі пропускає tool_reference) і, з v2.1.196, Remote Control.
ANTHROPIC_CUSTOM_HEADERSName: Value по рядкахДодаткові заголовки запитів; з v2.1.227 некоректні символи (напр. «розумні» лапки) дають помилку з позицією пари.
CLAUDE_CODE_USE_BEDROCK
CLAUDE_CODE_USE_VERTEX
CLAUDE_CODE_USE_FOUNDRY
1Працювати через Amazon Bedrock / Google Cloud Agent Platform / Microsoft Foundry.
CLAUDE_CODE_OAUTH_TOKENрядокOAuth-токен claude.ai (з claude setup-token) для CI та SDK. Має пріоритет над ключами з keychain.

Таймаути, повтори і Bash

ЗміннаЗначення / defaultЩо робить
API_TIMEOUT_MSмс; 600000 (10 хв), макс. 2147483647Таймаут API-запиту. Значення більше максимуму ламають таймер, і запити падають одразу.
BASH_MAX_OUTPUT_LENGTHсимволи; 30000, макс. 150000Скільки виводу Bash повертається в результат. Ігнорується, якщо задано ключ bashOutputMaxChars.
CLAUDE_CODE_MAX_RETRIESціле; 10, стеля 15 (з v2.1.186)Кількість повторів невдалих API-запитів.
CLAUDE_CODE_RETRY_WATCHDOG1 (з v2.1.199)Для unattended-сесій (CI, eval, remote workers): повторювати 429/529 без ліміту й без стелі. Одразу падає, якщо ліміт витрат вичерпано.
CLAUDE_STREAM_IDLE_TIMEOUT_MSмс; при явному заданні мінімум 300000Таймаут простою стріму; byte-level watchdog обмежений 30 хв. CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS має пріоритет для нього.
CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR1Повертатися в початкову теку після кожної Bash/PowerShell-команди в головній сесії.
CLAUDE_CODE_SHELLшлях до bash/zshShell для Bash-інструмента; fish не підтримується. Некоректний шлях ігнорується (авто-визначення).
CLAUDE_CODE_SHELL_PREFIXкомандаОбгортка для Bash-викликів, hooks, status line і старту stdio MCP — для логування й аудиту.
CLAUDE_ENV_FILEшлях до скриптаСкрипт, що виконується перед кожною Bash-командою в тому ж процесі (venv, conda). Також наповнюється hooks SessionStart, Setup, CwdChanged, FileChanged.
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB1Прибрати облікові дані із середовища підпроцесів (Bash, hooks, stdio MCP). Токени GitHub і налаштування проксі лишаються.

Контекст, стиснення, пам’ять, кеш

ЗміннаЗначення / defaultЩо робить
CLAUDE_CODE_AUTO_COMPACT_WINDOWціле 100000–1000000 (лише цифри)Вікно авто-стиснення в токенах. Сильніше за /autocompact, --autocompact і ключ autoCompactWindow; обмежене вікном моделі.
DISABLE_AUTO_COMPACT1Вимкнути авто-стиснення (ручний /compact лишається). Сильніше за autoCompactEnabled.
DISABLE_COMPACT1Вимкнути все стиснення, включно з /compact.
CLAUDE_CODE_DISABLE_AUTO_MEMORY1 / 01 вимикає auto memory; 0 примусово вмикає навіть при --bare чи autoMemoryEnabled: false.
CLAUDE_CODE_DISABLE_CLAUDE_MDS1Не завантажувати жодних CLAUDE.md (user, project, auto memory).
DISABLE_PROMPT_CACHING1Вимкнути prompt caching для всіх моделей (сильніше за налаштування окремих моделей).
ENABLE_PROMPT_CACHING_1H1Запитувати TTL кешу 1 год замість 5 хв (API key, Bedrock, Agent Platform, Foundry, Claude Platform on AWS).
CLAUDE_CODE_PROMPT_CACHE_TTL5m | 1h (v2.1.242+)TTL кешу головної розмови; сильніший за ключ promptCacheTtl і ENABLE_PROMPT_CACHING_1H, слабший за FORCE_PROMPT_CACHING_5M.

Приватність і телеметрія

ЗміннаЗначення / defaultЩо робить
DISABLE_UPDATES1Заблокувати всі оновлення, включно з ручними claude update / claude install. Суворіше за DISABLE_AUTOUPDATER — для корпоративної дистрибуції.
DO_NOT_TRACK1Те саме, що DISABLE_TELEMETRY, але читається як стандартний булевий: 0 лишає телеметрію ввімкненою.
OTEL_LOG_USER_PROMPTS1Включати текст промптів в OpenTelemetry (за замовчуванням редагується). У project/local ігнорується, крім вимикаючих значень.
OTEL_LOG_TOOL_DETAILS1Включати аргументи інструментів, імена MCP тощо в OTel. Ті самі обмеження.
CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY1Вимкнути опитування «How is Claude doing?». Вони вимикаються й при DISABLE_TELEMETRY, DO_NOT_TRACK, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC. Частота — ключ feedbackSurveyRate.
DISABLE_COST_WARNINGS1Прибрати попередження про вартість.

Мережа, проксі, сертифікати

ЗміннаЗначення / defaultЩо робить
HTTPS_PROXY / HTTP_PROXYURLПроксі для мережевих з’єднань.
NO_PROXYсписок доменів/IPКуди ходити напряму, повз проксі.
CLAUDE_CODE_CERT_STOREbundled, system; default bundled,systemДжерела CA для TLS: набір Mozilla з Claude Code та/або сховище ОС (потребує нативного бінарника або Node 22.15+).
CLAUDE_CODE_CLIENT_CERT
CLAUDE_CODE_CLIENT_KEY
CLAUDE_CODE_CLIENT_KEY_PASSPHRASE
шлях / шлях / рядокКлієнтський сертифікат і ключ для mTLS; пароль до зашифрованого ключа — необов’язковий.

MCP

ЗміннаЗначення / defaultЩо робить
MCP_TIMEOUTмс; 30000Таймаут запуску MCP-сервера.
MCP_TOOL_TIMEOUTмс; 100000000 (~28 год)Таймаут виконання MCP-інструмента. Для HTTP/SSE/claude.ai-конекторів кожен запит окремо обмежений 60 с, доки це значення або per-server timeout у .mcp.json не більше 60000. Per-server timeout перебиває змінну.
MAX_MCP_OUTPUT_TOKENSціле; 25000Максимум токенів у відповіді MCP-інструмента; попередження вище 10 000.
ENABLE_TOOL_SEARCHtrue | auto | auto:N | falseMCP tool search. Не задано — усі MCP-інструменти відкладені. auto вантажить одразу, якщо описи ≤10% контексту; auto:5 — свій поріг у %; false — вантажить усе одразу.
ENABLE_CLAUDEAI_MCP_SERVERSfalseНе підтягувати MCP-сервери claude.ai (для окремого проєкту чи організації є ключ disableClaudeAiConnectors).

Вимкнення функцій і службове

ЗміннаЗначення / defaultЩо робить
CLAUDE_CODE_DISABLE_FAST_MODE1Вимкнути fast mode.
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS1Вимкнути фонові задачі: run_in_background, авто-бекграунд, Ctrl+B.
CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING1Вимкнути знімки файлів; /rewind не відновить код. Сильніше за fileCheckpointingEnabled.
CLAUDE_CODE_DISABLE_WEB_FETCH1 (v2.1.285+)Вимкнути WebFetch; WebSearch лишається.
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS1Прибрати pre-release anthropic-beta заголовки й бета-поля схем. Для gateway, що відповідає Unexpected value(s) чи Extra inputs are not permitted.
CLAUDE_CODE_TMPDIRшляхТека для внутрішніх тимчасових файлів (default /tmp на macOS, os.tmpdir() інакше). У project/local ігнорується.
USE_BUILTIN_RIPGREP0Використовувати системний rg замість вбудованого.
05

model / effort / fastMode

Вибір моделі, рівень обчислень, швидкий режим

#
modelstring
Що робить

Задає модель, з якої стартує сесія. Аліас або повний ID. Навіть у managed — це стартовий default, а не блокування.

Що зміниться

Пріоритет: --model > ANTHROPIC_MODEL > ключ model > ANTHROPIC_DEFAULT_MODEL. Щоб заборонити інші моделі — availableModels. Без ключа Default залежить від акаунта: Opus 5.5 на Pro/Max/Team/Enterprise, Anthropic API, Claude Platform on AWS, Bedrock і Google Cloud Agent Platform; Sonnet 4.5 на Microsoft Foundry.

settings.json
"model": "sonnet"       // → Sonnet 5.5 · $2/$10 · баланс ціна/якість
"model": "opus"         // → Opus 5.5 · $4/$20 · default (крім Foundry)
"model": "haiku"        // → Haiku 5.5 · найшвидша та найдешевша
"model": "fable"        // → Fable 5.1 · $10/$50 · найскладніші задачі
"model": "opusplan"     // Opus у plan mode, Sonnet для виконання
"model": "claude-opus-5-5"  // повний ID — не оновиться з новим релізом
✓ Аліаси автоматично переходять на нові моделі. Opus 5.5 потребує CLI v2.1.280+, Sonnet 5.5 — v2.1.284+, Haiku 5.5 — v2.1.293+
Pro, Max, Team, Enterprise, Anthropic APIDefault = Opus 5.5 (до v2.1.280: Sonnet 5 на Pro/Team Standard, Opus 5 на решті)
Claude Platform on AWS, Bedrock, Google Cloud Agent PlatformDefault = Opus 5.5
Microsoft FoundryDefault = Sonnet 4.5; перевірки доступності моделі при старті там немає, тож недоступна модель дає помилки (на Bedrock/Agent Platform — повідомлення й відкат до попередньої версії)
Enterprise: organization default (v2.1.196+)адмін задає модель в консолі claude.ai для всієї організації або для ролі; Default показується як «Org default». Це старт, а не обмеження: --model, ANTHROPIC_MODEL, managed і --settings сильніші. З опцією override він перебиває ключ model з user/project/local. Діє лише для сесій через Anthropic API; для gateway — ключ model у managed.
Fableне є Default-моделлю жодного плану чи провайдера; вибір у /model зберігається в user settings
availableModels / enforceAvailableModels / deniedModelsarray / boolean
Що робить

Обмежує список моделей у /model. enforceAvailableModels обмежує ще й пункт «Default». deniedModels — явний чорний список (managed).

Що зміниться

["sonnet","haiku"] — розробники не зможуть переключитись на Opus/Fable і витрачати більше. Managed-список застосовується як є, без злиття з іншими файлами.

settings.json
"availableModels": ["sonnet", "haiku"],
"enforceAvailableModels": true,
"deniedModels": ["fable"]           // managed only
effortLevel / maxEffortLevel / modelSettingsenum / object
Що робить

Глибина міркувань моделі. effortLevel: low | medium | high | xhigh (max — лише через CLI/env). maxEffortLevel — стеля для всіх. /effort тепер зберігає рівень окремо для кожної моделі в modelSettings.

Що зміниться

low — швидко й дешево. xhigh/max — глибокий аналіз, більше токенів. Default: medium для Opus/Sonnet/Haiku 5.5, high для Fable 5.1 та старших. У user settings верхньорівневий effortLevel не діє на Opus 5.5+ — використовуй modelSettings.

settings.json
"effortLevel": "high",        // project / managed — для всіх моделей
"maxEffortLevel": "xhigh",     // найнижча стеля серед файлів виграє
"modelSettings": {
  "claude-opus-5-5":  { "effortLevel": "high", "maxEffortLevel": "xhigh", "autoCompactWindow": 500000 },
  "claude-haiku-5-5": { "effortLevel": "low" }
}
modelSettingsз v2.1.251; об’єкт «модель → поля». Claude Code пише запис під канонічною назвою (claude-opus-5-5) і зіставляє з ним аліас, версії з датою, [1m] та ID провайдерів
effortLevellow | medium | high | xhigh; сильніший за верхньорівневий effortLevel у тому ж файлі. Між файлами кожна модель вирішується окремо: переможе файл найвищого пріоритету, що задає або рівень для цієї моделі, або застосовний верхньорівневий. /effort auto стирає збережений рівень
maxEffortLevelз v2.1.267; стеля для однієї моделі ("max" = без стелі, звільняє модель від стелі цього джерела). Загальний верхньорівневий maxEffortLevel: діє найнижча стеля з усіх областей, її не можна підняти з іншого файлу
autoCompactWindowз v2.1.288; число від 100000 до 1000000 або "auto"; сильніше за верхньорівневий autoCompactWindow у тому ж файлі; його пише /autocompact
Enterprise-адмін може ще й обмежити effort по ролях (v2.1.195+). Коли діють і така стеля, і maxEffortLevel — застосовується нижча. Пріоритет рівня: CLAUDE_CODE_EFFORT_LEVEL > --effort > збережене.
fastMode / fastModePerSessionOptInboolean
Що робить

Fast Mode (research preview) — та ж модель, але до 2.5x швидший output. Працює лише на Opus 5.5, Opus 5 та Opus 4.8.

Що зміниться

fastMode true = сесії стартують у швидкому режимі. fastModePerSessionOptIn true = юзери самі вмикають /fast коли потрібно — контроль витрат. Ціна на Opus 5.5 — $8/$40.

settings.json
"fastMode": false,
"fastModePerSessionOptIn": true  // вмикають /fast вручну
⚠ На підписках оплачується лише з usage credits; у Team/Enterprise має увімкнути Owner. Недоступно на Bedrock / Vertex / Foundry
alwaysThinkingEnabledboolean
Що робить

Extended Thinking тепер увімкнений за замовчуванням, тож ключ має сенс лише як false.

Що зміниться

false = вимкнути thinking на старших моделях (Opus 4.x, Sonnet 4.6). На Opus/Sonnet/Haiku 5.5 і Fable не діє — вони думають завжди, глибину регулює effort.

settings.json
"alwaysThinkingEnabled": false  // лише для старших моделей
fallbackModelarray
Що робить

Упорядкований ланцюжок (до 3 різних дозволених моделей): якщо основна модель перевантажена чи недоступна, Claude Code переключається на наступну до кінця ходу й показує повідомлення. Наступне твоє повідомлення знову спробує основну.

Що зміниться

Сесія не зупиняється з помилкою overloaded. Увесь ланцюжок береться з найвищого файлу, що його задає (без злиття; у managed-settings.d пізніший файл заміщає цілком). --fallback-model сильніший за ключ; "default" розгортається у типову модель. Перехід означає один хід із холодним prompt cache.

settings.json
"fallbackModel": ["claude-sonnet-5-5", "claude-haiku-5-5"]
advisorModelstring
Що робить

Яка модель відповідає, коли Claude викликає серверний advisor-інструмент. Без ключа advisor вимкнений. Значення: "fable", "opus", "sonnet" (поточна версія родини) або повний ID.

Що зміниться

Складні рішення Claude може «віддати на консультацію» сильнішій моделі. Advisor має бути щонайменше таким самим здібним, як основна модель. Зазвичай ключ не правлять руками: його пише /advisor в user settings.

settings.json
"advisorModel": "opus"
--advisor перебиває ключ на сесію; CLAUDE_CODE_DISABLE_ADVISOR_TOOL вимикає advisor, і ключ не може його повернути. Для "fable" спершу прийми згоду на usage credits: /model fable.
⚠ Не діє на Amazon Bedrock і Claude Platform on AWS.
availableModelsMatchstringmanaged only
Що робить

Як зіставляються записи availableModels з ID моделей: "prefix" (default) або "exact".

Що зміниться

З prefix запис "claude-opus-5" дозволяє й пізніші версії (Opus 5.5). З exact кожен ID дозволяє лише названу версію — нова версія лишається заблокованою, доки її не додано. Аліас родини ("opus") і далі дозволяє всю родину; записи best/opusplan/default при exact ігноруються.

managed-settings.json
"availableModels": ["claude-opus-5-5", "claude-sonnet-5-5"],
"availableModelsMatch": "exact"
З v2.1.283. Поза managed ключ ігнорується з попередженням. Заблокувати одну версію без зміни режиму можна через deniedModels.
modelOverridesobject
Що робить

Мапа «ID моделі Anthropic → ID моделі провайдера», напр. ARN inference profile в Bedrock. Кожен пункт пікера викликатиме API провайдера з відображеним значенням.

Що зміниться

Команда на Bedrock бачить звичні назви Opus/Sonnet, а запити йдуть у ваші профілі. При managedSourcesBehavior: "merge" ключ береться з найвищого джерела, окрім випадку, коли вище джерело задає availableModels без modelOverrides — тоді він ігнорується скрізь.

settings.json
"modelOverrides": {
  "claude-opus-4-6": "arn:aws:bedrock:us-east-1:123456789012:inference-profile/example"
}
modelPickerobjectuser / managed
Що робить

Складає список моделей у /model: порядок і підписи ваші. Поле options — масив рядків {model, label?, description?, behavesAs?}; replaceBuiltInOptions (default false) — показати лише ці рядки, Default і поточну модель.

Що зміниться

Пікер показує моделі вашої організації під зрозумілими іменами. model береться дослівно: аліас, ID Anthropic або формат провайдера. Рядок, який неможливо обслужити, відкидається; якщо не лишилось жодного — береться вбудований список. Недоступні зараз рядки сірі й стоять унизу. availableModels діє й на ці рядки.

managed-settings.json
"modelPicker": {
  "options": [
    { "model": "us.anthropic.claude-opus-4-8", "label": "Opus (production)" },
    { "model": "us.anthropic.claude-sonnet-4-6", "label": "Sonnet (production)", "description": "Щоденна робота" }
  ],
  "replaceBuiltInOptions": false
}
З v2.1.242. Ключ читається з managed, --settings і user; у project/local ігнорується, щоб склонований репозиторій не міг перейменувати пікер. Переможе цілий список найвищого з трьох джерел — рядки ніколи не зливаються. behavesAs (v2.1.257+) наказує вважати нову модель відомою, напр. claude-opus-4-8.
modelPricingobjectmanaged only
Що робить

Показувати витрати за вашими тарифами замість публічного прайсу: у /usage, status line, total_cost_usd в SDK, ліміті --max-budget-usd і OTel-метриці вартості.

Що зміниться

Цифри в доларах у розробників збігаються з вашим рахунком. Ставки вводите ви самі — Claude Code не читає контракт і не змінює реальний білінг. Поля: multiplier (>0 і ≤10; >1 — націнка, потребує v2.1.271+) та overrides — мапа «ID моделі → {input, output, cacheRead, cacheWrite}», усі чотири обов’язкові, $ за MTok, 0–10000.

managed-settings.json
"modelPricing": {
  "multiplier": 0.85,
  "overrides": {
    "claude-sonnet-4-6": { "input": 2.4, "output": 12, "cacheRead": 0.24, "cacheWrite": 3 }
  }
}
З v2.1.242. Ключ ігнорується в user/project/local, у --settings і в HKCU. Для server-managed до підтвердження fetch сесія рахує за прайсом. Ряд з overrides використовується як є (без надбавки fast mode чи US-only), multiplier накладається зверху.
promptCacheTtl / subagentPromptCacheTtlenum
Що робить

Як довго prompt cache тримає розмову: "5m" або "1h". promptCacheTtl — головна розмова (інтерактив, -p, SDK та inline-помічники); subagentPromptCacheTtl — усе поза нею: субагенти, workflows, стиснення, назви сесій.

Що зміниться

1h економить на довгих сесіях з паузами, але записи в кеш при цьому тарифікуються дорожче. Пріоритет: FORCE_PROMPT_CACHING_5M > CLAUDE_CODE_PROMPT_CACHE_TTL (для субагентів — CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL) > ключ > ENABLE_PROMPT_CACHING_1H.

settings.json
"promptCacheTtl": "1h",
"subagentPromptCacheTtl": "5m"
З v2.1.242. Діє з будь-якого файлу.
showThinkingSummariesboolean
Що робить

Показувати короткі підсумки extended thinking в інтерактивних сесіях. Default false.

Що зміниться

Без ключа Anthropic API редагує thinking-блоки, і Claude Code показує згорнуту заглушку. Сторонні провайдери блоки не редагують, тож там різниці немає.

settings.json
"showThinkingSummaries": true
switchModelsOnFlagboolean
Що робить

Що робити, коли класифікатор безпеки позначив запит: перейти на запасну модель і продовжити, чи зупинитись і дати вибрати.

Що зміниться

Не задано — перемикається автоматично (в інтерактиві може спитати). false — пауза з вибором; у -p позначений запит завершується помилкою.

settings.json
"switchModelsOnFlag": false
ultracodeboolean
Що робить

Запускати сесії з увімкненим ultracode: Claude сам планує workflow для кожної суттєвої задачі, не чекаючи прохання. Default — вимкнено.

Що зміниться

Працює лише коли динамічні workflows увімкнені й модель підтримує xhigh. Ключ не змінює рівень effort сесії; стеля maxEffortLevel знижує рівень, але ultracode не вимикає. Claude Code ключ лише читає, ніколи не пише.

settings.json
"ultracode": true
На сесію: /effort ultracode / /effort ultracode off; прапор --effort ultracode (v2.1.203+, на рівні xhigh). Поточна поведінка — з v2.1.284: раніше ultracode: true примусово ставив xhigh, а стеля нижче xhigh тримала ultracode вимкненим.
06

hooks

Автоматичні дії на подіях сесії: 5 типів обробників, 33 події. Блокувати можна exit-кодом 2 або JSON-рішенням

#

Що таке хук і як він налаштовується

Хук — це ваш код, який Claude Code виконує детерміновано на певній події життєвого циклу: shell-команда, HTTP-запит, виклик MCP-інструмента, промпт до моделі або міні-агент. На відміну від рядка в CLAUDE.md, це не прохання, а гарантія: формат після кожної правки, заборона на .env, тести перед завершенням відповіді. Конфігурація має три рівні вкладеності: подія → група з matcher → обробники.

settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/format-py.sh",
            "args": [],
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Тут PostToolUse — подія, об’єкт із matcher — група (фільтр за назвою інструмента), внутрішній масив hooks — обробники, що виконуються паралельно. Коментарі й зайві коми в справжньому settings.json не допускаються.

Де визначати хуки

МісцеОхопленняКоментар
~/.claude/settings.jsonусі ваші проєктилокально, не в репозиторії
.claude/settings.jsonодин проєкткомітиться в репозиторій, спільний для команди
.claude/settings.local.jsonодин проєктособистий, gitignored
managed policy settingsвся організаціякерує адміністратор; не вимикається з user/project
плагін hooks/hooks.jsonпоки плагін увімкненийнеобов’язкове верхнє поле description
frontmatter skillрешта сесії після виклику skillєдине місце, де працює once: true
frontmatter субагентапоки субагент працюєStop автоматично стає SubagentStop
Злиття і паралельність

Хуки з різних рівнів додаються, а не перезаписують один одного; однакові обробники з кількох файлів виконуються один раз. Усі хуки, що підійшли під подію, запускаються паралельно. Для PreToolUse при різних рішеннях діє пріоритет deny > defer > ask > allow; якщо кілька хуків повертають updatedInput, перемагає той, що завершився останнім (порядок недетермінований), тож не змінюйте один і той самий інструмент у двох хуках. Меню /hooks лише для читання, а правки файлів підхоплюються автоматично.

Повний довідник

Усі 33 події, поля обробників, семантика matcher та if, exit-коди, JSON-вивід, змінні середовища, безпека й налагодження — у наступному розділі «hooks: довідник» (#hooks-ref). Готові рецепти для Django/Vue/GitLab-команди — наприкінці цього розділу.

hooks.PreToolUsearray
Що робить

Виконується до того, як Claude запускає інструмент (для будь-якого, крім EndConversation; @file-згадки не рахуються). matcher фільтрує за назвою інструмента, а if — за аргументами (синтаксис правил дозволів).

Що зміниться

Єдина подія, де хук може дозволити, заборонити, запитати або відкласти виклик і переписати аргументи. Блокувати можна двома способами: exit 2 (stderr іде Claude як причина) або JSON hookSpecificOutput.permissionDecision = allow | deny | ask | defer. Хук спрацьовує до перевірки режиму дозволів, тож deny діє навіть у bypassPermissions. Prompt-хук з ok:false за замовчуванням завершує хід і показує причину в чаті; з continueOnBlock: true причина повертається Claude як помилка інструмента, і він може виправитися. Таке завершення ходу за замовчуванням — з v2.1.210; раніше причина завжди поверталася Claude як помилка інструмента.

LLM-валідація перед push
settings.json
"PreToolUse": [{
  "matcher": "Bash",                // тільки назва інструмента
  "hooks": [{
    "type": "prompt",               // модель оцінює через Claude
    "if": "Bash(git push *)",       // фільтр за аргументами; збігається і з голим `git push`
    "prompt": "Чи безпечний цей push для main? Дані: $ARGUMENTS",
    "continueOnBlock": true,        // ok:false -> Claude бачить причину і коригується
    "timeout": 30
  }]
}]
$ARGUMENTS = JSON-вхід хука (якщо його немає в промпті, JSON дописується в кінець). Модель відповідає {"ok": true|false, "reason": "...", "impossible": ...}; impossible діє лише на Stop/SubagentStop. Таймаут PreToolUse-хука не блокує виклик: інструмент піде далі звичайним потоком дозволів, тому на «зависання» як на ворота не покладайтеся.
⚠ "matcher": "Bash(git push*)" НЕ працює як фільтр аргументів — це regex по назві інструмента. Аргументи фільтруйте полем "if". Саме if — best-effort: для жорсткої заборони використовуйте permissions.deny.
hooks.PostToolUsearray
Що робить

Виконується після успішного інструмента. Типи обробників: command, http, mcp_tool, prompt, agent (експериментальний). Дані події приходять JSON-ом у stdin.

Що зміниться

Можна автоматично форматувати код, відправляти аудит-лог, запускати лінтер. Інструмент уже виконався, тож скасувати його хук не може, зате може повернути Claude зворотний зв’язок: exit 2 (stderr іде Claude), decision:"block" + reason, additionalContext або підмінити результат через updatedToolOutput. Без хука нічого автоматичного не відбувається.

автоформатування після збереження
settings.json
"PostToolUse": [{
  "matcher": "Edit|Write",
  "hooks": [{
    "type": "command",
    "if": "Edit(*.py)",             // лише Python-файли (правила Edit(...) охоплюють усі вбудовані інструменти редагування)
    "command": "jq -r '.tool_input.file_path' | xargs ruff format",
    "async": true,                  // не блокує Claude (лише command); timeout для async не діє
    "statusMessage": "Форматую код..."
  }]
}]
Змінної $CLAUDE_FILE_PATH немає: шлях беремо зі stdin (jq -r '.tool_input.file_path'), він завжди абсолютний. Змінні середовища для хуків — див. таблицю в розділі «hooks: довідник». З async: true результат (additionalContext, systemMessage) надходить аж на наступному ході, а поля рішень не діють.
hooks.PostToolUse (http аудит-лог)array
Що робить

HTTP-хук надсилає вхід події як POST (Content-Type: application/json) на ваш URL. Заголовки підтримують інтерполяцію $VAR / ${VAR}, але лише для змінних із allowedEnvVars.

Що зміниться

Зручно для централізованого аудиту. HTTP-хук не може заблокувати дію кодом відповіді: блокування — лише 2xx з JSON-рішенням. Не-2xx, невалідне тіло чи збій з’єднання — неблокуюча помилка.

HTTP аудит-лог
settings.json
"PostToolUse": [{
  "matcher": "Bash",
  "hooks": [{
    "type": "http",
    "url": "https://audit.company.com/log",
    "headers": { "Authorization": "Bearer $AUDIT_TOKEN" },
    "allowedEnvVars": ["AUDIT_TOKEN"]
    // ↑ лише ці змінні підставляються в headers; решта стає порожнім рядком
  }]
}]
hooks.TaskCompletedarray
Що робить

Спрацьовує коли задачу зі спільного task list позначають виконаною (agent teams, task-інструменти). Exit 2 = не закривати, stderr іде назад як фідбек.

Що зміниться

Ідеально для pipeline: "перед закриттям — запусти тести". Тести впали → задача не закривається. Без хука — Claude закриває одразу.

авто-тести перед закриттям
settings.json
"TaskCompleted": [{
  "hooks": [{
    "type": "command",
    "command": "cd "$CLAUDE_PROJECT_DIR" && python manage.py test --failfast 1>&2 || exit 2",
    // exit 2 = тести впали = задача не закривається
    "timeout": 120
  }]
}]
⚠ Exit 1 НЕ блокує — лише 2. А pipe у "| tail" замінює код виходу на 0
Також можна завершити роботу тіммейта: JSON {"continue": false, "stopReason": "..."} (ігнорується, якщо подію спричинив виклик TaskUpdate).
hooks.Stop / SessionStart / SessionEndarray
Що робить

Stop — коли головний агент закінчив відповідь (не спрацьовує при перериванні користувачем; при помилці API замість нього спрацьовує StopFailure). SessionStart — при старті/відновленні сесії (matcher: startup, resume, clear, compact, fork); звичайний stdout потрапляє в контекст. SessionEnd — при завершенні сесії.

Що зміниться

Stop + async = сповіщення Telegram/Slack після відповідей. Stop з decision:"block" або exit 2 не дає Claude зупинитись (наприклад, поки не пройдуть тести) — після 8 поспіль таких продовжень Claude Code сам завершує хід (ліміт піднімає CLAUDE_CODE_STOP_HOOK_BLOCK_CAP). SessionStart підтримує лише command і mcp_tool, причому mcp_tool при запуску пропускається (MCP-сервери ще не готові). SessionEnd має спільний бюджет ~1.5 с (піднімається власним timeout хука до 60 с або CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS) — тільки швидкі дії.

Telegram нотифікація
settings.json
"Stop": [{
  "hooks": [{
    "type": "command",
    "command": "python3 ~/.claude/notify.py",
    "async": true,
    "statusMessage": "Відправляю сповіщення..."
  }]
}]
У Stop-хуку є поля stop_hook_active (true, якщо Claude вже продовжує через stop-хук), last_assistant_message (текст останньої відповіді; не читайте transcript_path, він може відставати), background_tasks[] і session_crons[].
hooks.InstructionsLoadedarray
Що робить

Спрацьовує щоразу як завантажується CLAUDE.md або файл з .claude/rules/. Тільки для аудиту — не може блокувати.

Що зміниться

Дозволяє логувати які інструкції завантажуються — виявлення prompt injection атак через підкинуті CLAUDE.md файли.

settings.json
"InstructionsLoaded": [{
  "hooks": [{ "type": "command", "command": "jq -c . >> ~/.claude/audit.log", "async": true }]
}]
всі події та поля хуківobject reference
Що робить

Зараз — 33 події. Детальні таблиці для кожної події — у розділі «hooks: довідник».

Що зміниться

Поле if працює лише на PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied — на інших подіях хук з if взагалі не запуститься. Переглянути активні хуки — /hooks (лише читання).

сесіяSessionStart · Setup · SessionEnd · ConfigChange · CwdChanged · DirectoryAdded · FileChanged
промптUserPromptSubmit · UserPromptExpansion · InstructionsLoaded · MessageDisplay · Notification
інструментиPreToolUse · PermissionRequest · PermissionDenied · PostToolUse · PostToolUseFailure · PostToolBatch
агентиSubagentStart · SubagentStop · TaskCreated · TaskCompleted · TeammateIdle
завершенняStop · StopFailure · PreCompact · PostCompact
іншеPreModelSwitch · PostModelSwitch · WorktreeCreate · WorktreeRemove · Elicitation · ElicitationResult
exit codes0 = успіх (JSON зі stdout читається на будь-якому коді) · 2 = блок (де подія це дозволяє; JSON його не скасує) · інше = неблокуюча помилка, але якщо stdout містить валідний JSON, рішення приймає саме він, а код ігнорується
timeout defaultcommand/http/mcp_tool — 600 с (30 с для UserPromptSubmit, PreModelSwitch, PostModelSwitch; 10 с для MessageDisplay) · prompt — 30 с · agent — 60 с · SessionEnd — спільний бюджет 1.5 с
disableAllHooks / allowManagedHooksOnlyboolean
Що робить

disableAllHooks — вимикає хуки, а також кастомні statusLine і fileSuggestion (і моди плагінів). Діє з будь-якого файлу, але managed-хуки вимикає лише значення з managed settings. allowManagedHooksOnly (лише managed) — залишає тільки managed-хуки, хуки Agent SDK та хуки плагінів, примусово увімкнених у managed enabledPlugins.

Що зміниться

disableAllHooks: true — для troubleshooting; береться значення після злиття пріоритетів, тому false у project-файлі перекриє true у user-файлі. Для одного запуску надійно: --settings '{"disableAllHooks": true}'. allowManagedHooksOnly: true — розробники не можуть додати власні хуки, через які могли б витікати дані.

settings.json
"disableAllHooks": false,          // default - хуки активні
"allowManagedHooksOnly": true      // лише managed settings
allowManagedHooksOnly також: блокує хуки у frontmatter агентів; звужує statusLine, fileSuggestion і subagentStatusLine до managed; вимикає плагіни з джерелом command та headersHelper маркетплейсів (якщо явно не задано disableCommandPluginSources: false); команда /goal при ньому недоступна.
allowedHttpHookUrlsarray
Що робить

Allowlist URL-шаблонів (з *) для HTTP-хуків. Якщо ключ визначено, HTTP-хук виконується лише за збігом з об’єднаним списком; решта блокуються без запуску. Хост порівнюється без урахування регістру.

Що зміниться

Діє на хуки з усіх джерел, включно з managed. Порожній масив [] блокує всі HTTP-хуки. Scope — будь-який файл, масиви зливаються (це не managed-only ключ).

settings.json
"allowedHttpHookUrls": ["https://audit.company.com/*", "http://localhost:*"]
httpHookAllowedEnvVarsarray
Що робить

Зовнішня межа для allowedEnvVars усіх HTTP-хуків. Хук може підставити змінну в заголовок лише якщо її названо і в його власному allowedEnvVars, і в цьому ключі.

Що зміниться

Не дає хуку прочитати секрет, навіть якщо його опис це просить. Не задано — діє лише власний список хука. Scope — будь-який файл, масиви зливаються.

settings.json
"httpHookAllowedEnvVars": ["AUDIT_TOKEN", "HOOK_SECRET"]
Типова пара для команди: allowedHttpHookUrls звужує, куди хуки можуть слати дані, httpHookAllowedEnvVars — які секрети можуть із ними піти. Розкладайте їх у managed settings.

Рецепти для Django + Vue + GitLab

Шість робочих заготовок. Скрипти кладемо в .claude/hooks/, робимо виконуваними (chmod +x) і комітимо разом із .claude/settings.json, щоб вся команда мала однакові правила. Шлях до скрипта — через ${CLAUDE_PROJECT_DIR} і "args": [] (exec form: без shell і без проблем з лапками).

1. ruff + black (і prettier для Vue) після правки

PostToolUse на Edit|Write. Скрипт сам відфільтровує розширення, тож не залежить від тонкощів if. Якщо після автовиправлень лишились порушення ruff, скрипт завершується з кодом 2: stderr побачить Claude (інструмент уже виконано, але зворотний зв’язок він отримає) і виправить решту.

.claude/settings.json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/format.sh",
        "args": [],
        "timeout": 60,
        "statusMessage": "ruff + black / prettier..."
      }]
    }]
  }
}
.claude/hooks/format.sh
#!/bin/bash
f=$(jq -r '.tool_input.file_path // empty')
f="${f//\\//}"                                   # Windows: \ -> /
cd "$CLAUDE_PROJECT_DIR" || exit 0
case "$f" in
  *.py)
    ruff check --fix --quiet "$f"
    black --quiet "$f"
    ruff check "$f" >&2 || exit 2                # залишились помилки -> Claude побачить stderr
    ;;
  *.vue|*.ts|*.js)
    npx prettier --write "$f" >/dev/null 2>&1
    ;;
esac
exit 0

2. Заборона правок .env та вже закомічених міграцій

PreToolUse на Edit|Write, exit 2. «Вже застосована» хук знати не може, тому використовуємо практичне наближення: міграція, що вже є в git, — незмінна; нову міграцію (файл, якого ще немає в індексі) створювати дозволено.

.claude/hooks/protect.sh
#!/bin/bash
f=$(jq -r '.tool_input.file_path // empty')
f="${f//\\//}"

case "$f" in
  */.env|*/.env.*|*/secrets/*)
    echo "Заблоковано: $f - секрети не редагуємо" >&2; exit 2 ;;
esac

if [[ "$f" == */migrations/0*.py ]] && \
   git -C "$CLAUDE_PROJECT_DIR" ls-files --error-unmatch "$f" >/dev/null 2>&1; then
  echo "Міграція $f вже в git. Не правте її - створіть нову через makemigrations" >&2
  exit 2
fi
exit 0
.claude/settings.json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protect.sh",
        "args": []
      }]
    }]
  }
}
Не єдиний бар’єр

Помилка в шляху до скрипта дає неблокуючу помилку (код 127), тобто ворота тихо відкриваються. Для справді критичного додайте дубль у permissions.deny: "Edit(.env)" діє на всі вбудовані інструменти редагування, і до того ж перевіряється самою системою дозволів, а не «best-effort» фільтром.

3. pytest на Stop

Stop-хук запускає тести, лише якщо змінено .py-файли. Якщо тести падають, exit 2 не дає Claude зупинитись, а хвіст виводу pytest іде йому як причина. Після 8 поспіль таких продовжень Claude Code сам завершить хід; ліміт піднімає CLAUDE_CODE_STOP_HOOK_BLOCK_CAP.

.claude/hooks/pytest-on-stop.sh
#!/bin/bash
cd "$CLAUDE_PROJECT_DIR" || exit 0
[ -z "$(git status --porcelain -- '*.py')" ] && exit 0      # Python не чіпали
out=$(python -m pytest -x -q 2>&1) && exit 0
{ echo "pytest не пройшов, виправте перед завершенням:"; echo "$out" | tail -40; } >&2
exit 2
.claude/settings.json
{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/pytest-on-stop.sh",
        "args": [],
        "timeout": 300,
        "statusMessage": "pytest..."
      }]
    }]
  }
}

4. Сповіщення, коли Claude чекає на вас

Подія Notification (matcher permission_prompt|idle_prompt). Варіант для Slack/Mattermost: webhook-URL береться зі змінної середовища, а не з репозиторію. Якщо потрібне лише системне сповіщення, скрипт може повернути terminalSequence (OSC 9/99/777 або BEL; працює тільки в інтерактивній сесії).

.claude/settings.json
{
  "hooks": {
    "Notification": [{
      "matcher": "permission_prompt|idle_prompt",
      "hooks": [{
        "type": "command",
        "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/notify.sh",
        "args": [],
        "async": true
      }]
    }]
  }
}
.claude/hooks/notify.sh
#!/bin/bash
msg=$(jq -r '"Claude Code: " + (.message // "потрібна ваша увага")')
curl -fsS -X POST -H 'Content-Type: application/json' \
  --data "$(jq -nc --arg t "$msg" '{text: $t}')" "$SLACK_WEBHOOK_URL"
.claude/hooks/notify-desktop.sh
#!/bin/bash
# варіант без мережі: OSC 777 (urxvt, Ghostty, Warp); для iTerm2/WezTerm - OSC 9, для Kitty - OSC 99
body=$(jq -r '.message // "Needs your attention"')
seq=$(printf '\033]777;notify;%s;%s\007' "Claude Code" "$body")
jq -nc --arg seq "$seq" '{terminalSequence: $seq}'      # тоді без "async": true

5. Аудит-лог дій Claude

Два варіанти. Локальний JSONL (швидко, нічого не покидає машину) і HTTP-хук на внутрішній сервіс аудиту. Для HTTP обов’язково обмежте URL та змінні середовища на рівні організації. Matcher містить . і *, тому обчислюється як regex, а не як список точних назв.

.claude/settings.json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash|Edit|Write|mcp__.*",
      "hooks": [
        {
          "type": "command",
          "command": "jq -c '{ts: (now|todate), session: .session_id, tool: .tool_name, input: .tool_input}' >> ~/.claude/audit.jsonl",
          "async": true
        },
        {
          "type": "http",
          "url": "https://audit.company.com/claude",
          "headers": { "Authorization": "Bearer $AUDIT_TOKEN" },
          "allowedEnvVars": ["AUDIT_TOKEN"]
        }
      ]
    }]
  }
}
managed-settings.json
{
  "allowedHttpHookUrls": ["https://audit.company.com/*"],
  "httpHookAllowedEnvVars": ["AUDIT_TOKEN"]
}

6. Ворота перед git push: детермінований скрипт + LLM

Спершу дешева детермінована перевірка (force push і push у main/master блокуємо exit 2), далі — prompt-хук, який оцінює решту (наприклад, чи не лишилось налагоджувального коду). Обидва мають if, тож для інших Bash-команд процеси навіть не стартують. Усі хуки групи йдуть паралельно, а при розбіжності діє пріоритет deny.

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "if": "Bash(git push *)",
          "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/push-guard.sh",
          "args": []
        },
        {
          "type": "prompt",
          "if": "Bash(git push *)",
          "prompt": "Ти рев’юер перед push у GitLab. Дані події: $ARGUMENTS. Відхили (ok:false з коротким reason), якщо команда пушить гілку, яка схожа на main/master/release, або явно містить налагоджувальні артефакти. Інакше ok:true.",
          "continueOnBlock": true,
          "timeout": 30
        }
      ]
    }]
  }
}
.claude/hooks/push-guard.sh
#!/bin/bash
cmd=$(jq -r '.tool_input.command')
if grep -Eq -- '--force( |$)|(^| )-f( |$)' <<<"$cmd"; then
  echo "Force push заборонено. Використайте --force-with-lease у feature-гілці" >&2; exit 2
fi
if grep -Eq '(^| |:)(main|master)( |$)' <<<"$cmd"; then
  echo "Push напряму в main/master заборонено - відкрийте Merge Request" >&2; exit 2
fi
exit 0
Обмеження

if для Bash — best-effort: якщо Claude Code не може розібрати команду, хук запускається незалежно від шаблону, а для шаблонів, що уточнюють більше за ім’я команди, — також при $(), зворотних лапках чи $VAR. Захист рівня політики робіть через permissions.deny (наприклад, Bash(git push --force *)) і правила protected branches у GitLab.

07

hooks: довідник

Усі події, типи обробників, matcher та if, exit-коди, JSON-вивід, змінні середовища, безпека, налагодження

#

Повна довідка по хуках: усі події, обробники, matcher, коди завершення, JSON-вивід, змінні середовища, безпека й налагодження. Конфігурація й картки ключів — у попередньому розділі «hooks».

Події: сесія і середовище

ПодіяКоли спрацьовуєБлокує?MatcherКлючові поля inputВихід / рішення
SessionStartстарт або відновлення сесіїніstartup, resume, clear, compact, forksource, model?, agent_type?, session_title?; при resume/fork ще seconds_since_last_response, context_tokens, prompt_cache_likely_expired, estimated_cache_write_usdadditionalContext, initialUserMessage (лише -p), sessionTitle, watchPaths, reloadSkills; звичайний stdout стає контекстом
Setup--init-only, -p --init, -p --maintenanceніinit, maintenancetriggerнемає (JSON відкидається); доступний CLAUDE_ENV_FILE
SessionEndзавершення сесіїніclear, resume, logout, prompt_input_exit, otherreasonнемає; бюджет 1.5 с. (bypass_permissions_disabled прибрано у v2.1.234)
ConfigChangeзмінились файли settings, managed або skillsтак (крім policy_settings)user_settings, project_settings, local_settings, policy_settings, skillssource, file_path?decision:"block"; причина нікому не показується (лише debug-лог)
CwdChangedcd в основній розмовінінемаєold_cwd, new_cwdwatchPaths; доступний CLAUDE_ENV_FILE
DirectoryAdded/add-dir або SDK register_repo_root (не --add-dir)ніslash_command, register_repo_rootdirectory, sourceнемає; працює у фоні
FileChangedфайл зі списку спостереження змінився на дискунілітеральні імена через | (.envrc|.env), вони ж формують watch-listfile_path, event (change/add/unlink)watchPaths; доступний CLAUDE_ENV_FILE

Події: промпт і сповіщення

ПодіяКоли спрацьовуєБлокує?MatcherКлючові поля inputВихід / рішення
InstructionsLoadedзавантажено CLAUDE.md або .claude/rules/*.mdніsession_start, nested_traversal, path_glob_match, include, compactfile_path, memory_type, load_reason, globs?, trigger_file_path?, parent_file_path?; memory_type: User/Project/Local/Managedнемає
UserPromptSubmitкожен промпт, у т.ч. заплановані задачі, звіти фонових субагентів, повідомлення з інших сесійтакнемаєprompt, session_title?decision:"block" + reason (бачить лише користувач), additionalContext, sessionTitle, suppressOriginalPrompt; переписати промпт не можна; звичайний stdout стає контекстом
UserPromptExpansionрозкриття введеної /командитакім’я командиexpansion_type (slash_command/mcp_prompt), command_name, command_args, command_source, promptdecision:"block", reason, additionalContext
MessageDisplayпід час стрімінгу тексту асистентанінемаєturn_id, message_id, index, final, deltadisplayContent (лише відображення; транскрипт і Claude бачать оригінал); типовий таймаут 10 с
Notificationсповіщення Claude Codeніpermission_prompt, idle_prompt, auth_success, elicitation_dialog, elicitation_url_dialog, elicitation_complete, elicitation_response, agent_needs_input, agent_completed, quota_auto_resume_fired, quota_auto_resume_stale, quota_auto_resume_disabledmessage, title?, notification_typeдіє лише terminalSequence. permission_prompt і elicitation-діалоги спрацьовують після ~6 с простою, idle_prompt — після ~60 с

Події: інструменти і дозволи

ПодіяКоли спрацьовуєБлокує?MatcherКлючові поля inputВихід / рішення
PreToolUseперед викликом інструментатакназва інструментаtool_name, tool_input, tool_use_id, mcp_server?hookSpecificOutput.permissionDecision allow/deny/ask/defer, permissionDecisionReason, updatedInput, additionalContext. defer працює лише в -p при одному виклику; AskUserQuestion/ExitPlanMode потребують allow + updatedInput
PermissionRequestось-ось з’явиться запит дозволу (і коли виклик без UI був би авто-відхилений)лише через JSON (exit 2 не діє)назва інструментаtool_name, tool_input, permission_suggestions, mcp_server? (без tool_use_id)decision.behavior allow/deny, updatedInput, updatedPermissions, message, interrupt. Не запускається для мережевих запитів sandbox
PermissionDeniedauto-режим відхилив викликніназва інструментаtool_name, tool_input, tool_use_id, reasonhookSpecificOutput.retry: true (дозволяє моделі повторити)
PostToolUseпісля успішного інструментані, але повертає фідбек Claudeназва інструментаtool_input, tool_response, tool_use_id, duration_ms, mcp_server?; Bash може мати tool_response.bashEditDiff (бета, v2.1.269+)decision:"block" + reason, additionalContext, updatedToolOutput, updatedMCPToolOutput, classifierContext (v2.1.236+, до 2000 символів)
PostToolUseFailureпісля невдалого інструментаніназва інструментаerror, is_interrupt, duration_msadditionalContext; decision:"block"
PostToolBatchпісля паралельного пакета викликів, до наступного запиту до моделітак (зупиняє цикл)немаєtool_calls[] (tool_name, tool_input, tool_use_id, tool_response)additionalContext, decision:"block"

Події: субагенти та задачі

ПодіяКоли спрацьовуєБлокує?MatcherКлючові поля inputВихід / рішення
SubagentStartсубагент запущено або відновлено; також щоразу, коли in-process тіммейт обробляє нове повідомленнянітип агента (плагінні: ^plugin:name$)agent_id, agent_typeadditionalContext (іде в субагента)
SubagentStopсубагент завершив роботутактип агентаstop_hook_active, agent_id, agent_type, agent_transcript_path, last_assistant_message, background_tasks, session_cronsяк у Stop
TaskCreatedвиклик TaskCreateтакнемаєtask_id, task_subject, task_description?, teammate_name?exit 2 або decision:"block" видаляє задачу; continue:false ігнорується
TaskCompletedзадачу позначено виконаною через TaskUpdate, або тіммейт завершується з задачами в роботітакнемаєяк у TaskCreatedexit 2 або continue:false (ігнорується, якщо подію спричинив TaskUpdate)
TeammateIdleтіммейт збирається простоюватитакнемаєteammate_name, team_nameexit 2 або continue:false

Події: завершення і компактування

ПодіяКоли спрацьовуєБлокує?MatcherКлючові поля inputВихід / рішення
Stopголовний агент закінчив відповідьтакнемаєstop_hook_active, last_assistant_message, background_tasks[], session_crons[]decision:"block" + reason (обов’язково), hookSpecificOutput.additionalContext (фідбек без «помилки»)
StopFailureхід закінчився помилкою APIніrate_limit, overloaded, authentication_failed, oauth_org_not_allowed, account_on_hold, billing_error, invalid_request, model_not_found, server_error, max_output_tokens, cloud_credential_error, unknownerror, error_details?, last_assistant_message? (тут це текст помилки API)вивід ігнорується, окрім terminalSequence
PreCompactперед компактуваннямтакmanual, autotrigger, custom_instructionsdecision:"block"
PostCompactпісля компактуванняніmanual, autotrigger, compact_summaryнемає

Події: моделі, worktree, MCP

ПодіяКоли спрацьовуєБлокує?MatcherКлючові поля inputВихід / рішення
PreModelSwitchперед перемиканням моделі користувачем/клієнтом (v2.1.251+)так; таймаут теж блокуєканонічна назва моделі (claude-opus-5, .*opus.*)from_model, to_model, requested_model, source (command/picker/sdk), context_tokens, prompt_cache_warm, cache_ttl, estimated_cache_write_usd, pricingpermissionDecision allow/deny/ask (без defer) або decision:"block". Типи: command/http/mcp_tool
PostModelSwitchпісля будь-якої зміни моделініканонічна назва моделіяк у PreModelSwitch, source також auto|resumeadditionalContext; звичайний stdout стає контекстом
WorktreeCreate--worktree, isolation:"worktree" або фонова сесіятак (будь-який ненульовий код = помилка)немаєnamecommand: шлях — останній непорожній рядок stdout; HTTP: hookSpecificOutput.worktreePath. Замінює git; .worktreeinclude пропускається
WorktreeRemoveвидалення worktree, створеного хукомтак (ненульовий код, якщо каталог ще існує)немаєworktree_pathнемає
ElicitationMCP-сервер просить ввід у користувачатак (відхиляє)ім’я MCP-сервераmcp_server_name, message, mode (form/url), url?, elicitation_id?, requested_schema?hookSpecificOutput.action accept/decline/cancel + content, або decision:"block"
ElicitationResultкористувач відповів на elicitationтак (стає decline)ім’я MCP-сервераmcp_server_name, action, mode?, elicitation_id?, content?action + content (підміна або decline)

Типи обробників

Є п’ять типів. Спільні поля:

ПолеОбов’язковеОпис
typeтакcommand, http, mcp_tool, prompt або agent
ifніодне правило дозволів, напр. Bash(git *) або Edit(*.py); лише на PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied (на інших подіях хук з if ніколи не запуститься)
timeoutнісекунди до скасування; значення за замовчуванням — у таблиці нижче
statusMessageнітекст спінера, поки хук працює
onceніtrue — прибрати хук після першого успішного запуску; працює лише у frontmatter skill (у settings і в агентах ігнорується)

Специфічні поля:

ТипОбов’язкові поляДодаткові поля та поведінка
commandcommand (обов’язково)args — exec form: без shell, кожен елемент — один аргумент (рекомендовано зі шляхами-плейсхолдерами); async; asyncRewake — у фоні, а при exit 2 будить Claude (stderr іде як system reminder); shell = bash | powershell (ігнорується з args). Без args — shell form: sh -c, Git Bash або PowerShell на Windows
httpurl (обов’язково)headers (підтримують $VAR / ${VAR}), allowedEnvVars (без нього інтерполяція не працює, а невказані змінні стають порожніми). Тіло — POST із JSON-входом події. 2xx з порожнім тілом = успіх; 2xx з JSON = розбирається; інше (не-2xx, текст, збій) = неблокуюча помилка
mcp_toolserver, tool (обов’язкові)input з підстановками ${tool_input.file_path}. Для плагінного сервера server = plugin:<plugin>:<server>. Текст результату читається як stdout команди; isError: true = неблокуюча помилка. OAuth не запускає; на SessionStart при запуску та Setup пропускається
promptprompt (обов’язково)model (типово — «фонова» модель), timeout (30), continueOnBlock. $ARGUMENTS — JSON-вхід (\$ екранує); без нього JSON дописується в кінець. Відповідь: {"ok", "reason", "impossible"}
agent (експериментальний)prompt (обов’язково)як prompt, але timeout 60, до 50 ходів, може читати через Read/Grep/Glob; без continueOnBlock та impossible (ok:false обробляється як continueOnBlock: true)

Які типи підтримує подія

ГрупаПодії
Усі п’ять типівPermissionDenied, PostToolBatch, PostToolUse, PostToolUseFailure, PreToolUse, Stop, SubagentStop, TaskCreated, TaskCompleted, TeammateIdle, UserPromptExpansion, UserPromptSubmit
Без agentPermissionRequest
Лише command / http / mcp_toolConfigChange, CwdChanged, DirectoryAdded, Elicitation, ElicitationResult, FileChanged, InstructionsLoaded, MessageDisplay, Notification, PostCompact, PostModelSwitch, PreCompact, PreModelSwitch, SessionEnd, StopFailure, SubagentStart, WorktreeCreate, WorktreeRemove
Лише command / mcp_toolSessionStart, Setup (mcp_tool на SessionStart при запуску й на Setup завжди пропускається)

Таймаути за замовчуванням

Тип / подіяТаймаут
command, http, mcp_tool600 с
prompt30 с
agent60 с
command/http/mcp_tool на UserPromptSubmit, PreModelSwitch, PostModelSwitch30 с
command/http/mcp_tool на MessageDisplay10 с
SessionEnd (усі типи)спільний бюджет 1.5 с; власний timeout піднімає його до 60 с; CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS задає явно
async: trueтаймаут не діє (для asyncRewake діє)
Що буде при таймауті

Хук скасовується, а його вивід відкидається. На PreToolUse таймаут command/http/mcp_tool не блокує виклик (піде звичайний потік дозволів), на PreModelSwitch — блокує перемикання.

Фонові хуки: async і asyncRewake

ПараметрПоведінка
"async": trueлише command; Claude не чекає. Після завершення additionalContext і systemMessage з JSON надходять Claude на наступному ході (користувачу не показуються); поля рішень не діють. Якщо сесія бездіяльна — чекають наступної взаємодії. У -p усі ще запущені async-хуки вбиваються при завершенні
"asyncRewake": trueу фоні; при exit 2 будить Claude одразу, навіть у бездіяльній сесії; stderr (або stdout, якщо stderr порожній) показується як system reminder. Таймаут діє
Сповіщення про завершенняза замовчуванням приховані; Ctrl+O або --verbose

Matcher: як рахується збіг

Значення matcherІнтерпретаціяПриклад
"*", "" або поле відсутнєусеспрацьовує на кожну появу події
лише літери, цифри, _, -, пробіли, ,, |точний рядок або список точних рядківBash — лише Bash; Edit|Write і Edit, Write — або-або
будь-який інший символJavaScript-regex без якорів^Notebook; Edit.* збігається і з NotebookEdit — пишіть ^Edit$
FileChanged, StopFailureвужчий точний набір: літери, цифри, _, |дефіс, пробіл чи кома переводять на regex; розділювач лише |
MCP-інструментиформат mcp__<server>__<tool>mcp__memory не збігається ні з чим — потрібно mcp__memory__.*; плагінний сервер: mcp__plugin_<plugin>_<server>__.*

Matcher чутливий до регістру. Що саме він фільтрує — див. колонку «Matcher» в таблицях подій. Для подій без підтримки matcher (UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, MessageDisplay, CwdChanged) поле тихо ігнорується.

Поле if: фільтр за аргументами

if — рівно одне правило в синтаксисі дозволів, без &&, || і списків; для кількох умов робіть окремі обробники. Обчислюється лише на tool-подіях (див. вище). Для файлових інструментів Edit(src/**) збігається лише з <cwd>/src (з v2.1.214); каталог src на довільній глибині — Edit(**/src/**). Правила Edit(...) в системі дозволів охоплюють усі вбудовані інструменти редагування файлів.

ifBash-командаХук запуститься?Чому
Bash(git *)FOO=bar git pushтакпочаткові присвоєння VAR= відкидаються
Bash(git *)npm test && git pushтакперевіряється кожна підкоманда
Bash(rm *)echo $(rm -rf /)таквміст $() і зворотних лапок перевіряється
Bash(rm *)echo $(date)ніжодна підкоманда не збігається
Bash(git push *)echo $(date)такшаблони, що уточнюють більше за ім’я команди, запускають хук на $(), зворотні лапки й $VAR
if — не механізм безпеки

Якщо Claude Code не може визначити, які команди містить Bash-вхід, він запускає хук незалежно від шаблону. Для жорсткого allow/deny користуйтеся системою дозволів, а не хуком із if.

Вхід (stdin / тіло POST)

Кожна подія додає до спільних полів свої (див. таблиці подій). Для command-хуків це JSON у stdin, для HTTP — тіло запиту. Моделі в спільних полях немає: змінної $CLAUDE_MODEL не існує, а поле model може прийти лише в SessionStart; для відстеження використовуйте PostModelSwitch.

ПолеОпис
session_idідентифікатор сесії
prompt_idUUID поточного промпта (збігається з prompt.id у OpenTelemetry); відсутній до першого вводу
transcript_pathшлях до JSON розмови; файл пишеться асинхронно й може відставати — останній текст беріть з last_assistant_message
cwdпоточний каталог на момент виклику (слідує за cd і за входом у worktree)
scratchpad_dirтека scratchpad сесії (v2.1.257+); може бути відсутня
permission_modedefault, plan, acceptEdits, auto, dontAsk, bypassPermissions; режим Manual приходить як default
effort.levellow / medium / high / xhigh / max; для подій у контексті інструмента; також як $CLAUDE_EFFORT
hook_event_nameназва події
agent_id, agent_typeлише всередині субагента або з --agent
tool_name, tool_input, tool_use_idподії інструментів; для MCP додається mcp_server {name, source} (v2.1.274+). file_path завжди абсолютний (на Windows із зворотними слешами)

Коди завершення

КодЩо означає
0успіх. Stdout розбирається як JSON, лише якщо починається з { і закінчується }. Звичайний текст стає контекстом лише для UserPromptSubmit, UserPromptExpansion, SessionStart, PostModelSwitch; на решті подій іде в debug-лог. Stderr при коді 0 — тільки в debug-лог
2блокуюча помилка (де подія це дозволяє, див. таблицю нижче). Не скасовується JSON-ом: навіть permissionDecision:"allow" не допоможе. Причина — з JSON-рішення, інакше зі stderr. Якщо разом із кодом 2 виведено JSON, що не проходить схему, блок усе одно діє (з v2.1.214)
інші (1, 127...)неблокуюча помилка: дія виконується, у транскрипті з’являється hook error з першим рядком stderr. Виняток: якщо stdout містить валідний JSON, код ігнорується, і рішення приймає лише JSON
невалідний JSONstdout схожий на JSON, але не парситься або не проходить схему — неблокуюча помилка на будь-якому коді, крім 2

Що робить exit 2 на кожній події

РезультатПодії
Блокує діюPreToolUse (виклик), UserPromptSubmit (промпт; stderr бачить користувач), UserPromptExpansion, Stop, SubagentStop, TeammateIdle, TaskCreated, TaskCompleted, PostToolBatch (зупиняє цикл), PreCompact, PreModelSwitch, Elicitation, ElicitationResult (decline), ConfigChange (крім policy_settings)
Будь-який ненульовий код = помилкаWorktreeCreate (створення падає), WorktreeRemove (падає, якщо каталог ще існує)
Не блокує, stderr бачить ClaudePostToolUse, PostToolUseFailure (інструмент уже відпрацював)
Не блокує, stderr бачить лише користувачSessionStart, SubagentStart, SessionEnd, CwdChanged, FileChanged, PostCompact, PostModelSwitch
Exit 2 не дієPermissionRequest (відхиляйте через JSON decision.behavior)
Усе ігноруєтьсяNotification, Setup, StopFailure (крім terminalSequence), PermissionDenied, InstructionsLoaded, MessageDisplay; DirectoryAdded — stderr у debug-лог
Для політик — лише exit 2 або JSON

Код 1 (звичний «збій» в Unix) не блокує, якщо немає валідного JSON. Конвеєр на кшталт cmd | tail повертає код останньої команди, тобто 0. Обирайте одне: або лише коди, або exit 0 + JSON; при змішуванні exit 2 зберігає блокувальну дію.

JSON-вивід

Stdout повинен містити лише JSON-об’єкт. Універсальні поля приймає кожна подія (деякі їх відкидають):

ПолеТиповоОпис
continuetruefalse повністю зупиняє Claude після хука; має пріоритет над рішеннями події
stopReason-повідомлення користувачу при continue:false (залишається в розмові)
suppressOutputfalseприймається, але не має жодного ефекту
systemMessage-попередження користувачу; деякі події його відкидають
terminalSequence-escape-послідовність для терміналу: лише OSC 0/1/2/9/99/777 і BEL; замінює недоступний /dev/tty; тільки в інтерактивній сесії
decision / reason-верхньорівневе рішення для подій, що його використовують (єдине значення — "block")
hookSpecificOutput-вкладений об’єкт; обов’язково містить hookEventName
Схема рішенняПодії
Верхньорівневий decision:"block" + reasonUserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, SubagentStop, ConfigChange, PreCompact
Exit 2 або continue:falseTeammateIdle, TaskCompleted; TaskCreated: exit 2 або decision:"block"
hookSpecificOutput.permissionDecisionPreToolUse (allow/deny/ask/defer); PreModelSwitch (allow/deny/ask)
hookSpecificOutput.decision.behaviorPermissionRequest (allow/deny)
hookSpecificOutput.retryPermissionDenied
hookSpecificOutput.action + contentElicitation, ElicitationResult (або decision:"block")
displayContentMessageDisplay
Лише контекст (additionalContext)SessionStart, SubagentStart, PostModelSwitch
Немає керуванняSetup, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, DirectoryAdded, FileChanged

Переписування та контекст

ПолеДеНотатки
updatedInputPreToolUse (в hookSpecificOutput), PermissionRequest (в decision)замінює весь об’єкт аргументів, тож повертайте й незмінені поля; права й авто-фон Bash оцінюються вже за новим входом
updatedToolOutputPostToolUseзамінює результат інструмента; форма має збігатися з виходом інструмента (для MCP — updatedMCPToolOutput)
updatedPermissionsPermissionRequestмасив записів addRules/replaceRules/removeRules/setMode/addDirectories/removeDirectories; призначення: session, localSettings, projectSettings, userSettings
additionalContextбільшість подій з контекстомтекст обгортається в system reminder; кілька хуків — усі значення; ліміт 10 000 символів (решта у файлі + прев’ю 2000)

Для PreToolUse верхньорівневі decision/reason застарілі (approve/block відображаються на allow/deny). Рядки additionalContext, systemMessage, initialUserMessage і звичайний stdout обмежені 10 000 символами кожен, а надлишок іде у файл із прев’ю 2000 символів. Пишіть контекст як факти («цільове середовище — production»), а не як імперативні «системні» команди: так він сприймається як дані проєкту й не провокує захист від prompt injection.

PreToolUse: заборонити з поясненням для Claude
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Міграції правити не можна: створіть нову"
  }
}
PreToolUse: дозволити й підмінити команду
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "updatedInput": { "command": "pytest -x -q" }
  }
}
Stop: не відпускати, поки не виконано умову
{ "decision": "block", "reason": "Запустіть pytest і виправте помилки" }
Зупинити Claude повністю
{ "continue": false, "stopReason": "Збірка впала, виправте помилки" }

Змінні середовища хуків

Хук успадковує середовище батьківського процесу, окрім змінних OTEL_* (і тих, що вилучає CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1). Плейсхолдери ${CLAUDE_PROJECT_DIR}, ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA} підставляються в command і args і водночас експортуються як змінні. У shell-form обгортайте їх у лапки; у exec form (args) лапки не потрібні. Змінних $CLAUDE_FILE_PATH і $CLAUDE_MODEL немає.

ЗміннаЗначення
CLAUDE_PROJECT_DIRкорінь проєкту, де стартувала сесія; не змінюється і в worktree (поточний каталог — поле cwd у вході)
CLAUDE_PLUGIN_ROOTкаталог встановленого плагіна
CLAUDE_PLUGIN_DATAпостійний каталог даних плагіна (переживає оновлення)
CLAUDE_PLUGIN_OPTION_<KEY>опції плагіна для shell-form хуків (напр. CLAUDE_PLUGIN_OPTION_WEBHOOK_URL)
CLAUDE_ENV_FILEлише SessionStart, Setup, CwdChanged, FileChanged: допишіть рядки export VAR=..., і вони діятимуть у наступних Bash-командах
CLAUDE_EFFORTпоточний рівень effort
CLAUDE_CODE_REMOTE"true" у віддалених (web) середовищах
CLAUDE_CODE_BRIDGE_SESSION_IDID сесії Remote Control, поки з’єднання активне (v2.1.199+)
CLAUDE_CODE_STOP_HOOK_BLOCK_CAPпіднімає ліміт 8 поспіль блокувань Stop
CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MSбюджет SessionEnd; також стає таймаутом хуків без власного timeout (з v2.1.268)
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB1 — з середовища підпроцесів вилучаються чутливі змінні
CLAUDE_CODE_DEBUG_LOG_LEVELverbose — деталі збігу matcher у debug-лозі
CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS1 — вимикає Notification permission_prompt у сесіях із canUseTool (Claude Desktop, VS Code)

Хуки в skills, субагентах і плагінах

ДеКоли діютьОсобливості
frontmatter skillз виклику skill до кінця сесіїформат той самий, що в settings; once: true працює лише тут
frontmatter субагентапоки субагент працюєStop перетворюється на SubagentStop; для проєктного субагента потрібна довіра до теки (workspace trust, з v2.1.218); блокуються під allowManagedHooksOnly
плагін hooks/hooks.jsonпоки плагін увімкненийоб’єднуються з user/project; шляхи через ${CLAUDE_PLUGIN_ROOT}; MCP-сервер у mcp_tool — plugin:<plugin>:<server>
settings / managed / плагіни — в субагентахзавждиtool-події у субагентах запускають ті самі хуки, а вхід містить agent_id та agent_type
.claude/skills/deploy/SKILL.md
---
name: deploy-staging
description: Деплой на staging з перевіркою
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "${CLAUDE_PROJECT_DIR}/.claude/hooks/deploy-guard.sh"
          args: []
          once: true
---
Деплой виконуй лише після зеленого pipeline.

Безпека

Хуки виконуються з вашими повними правами

Command-хук може змінювати, видаляти й читати будь-що, до чого має доступ ваш обліковий запис. Перевіряйте й тестуйте кожну команду перед додаванням.

ТемаЩо знати
Workspace trustв інтерактивній сесії хуки з усіх settings-файлів (навіть ~/.claude/settings.json) чекають, поки ви приймете діалог довіри до теки. У -p/SDK діалогу немає, тека вважається довіреною, тож хуки з репозиторію .claude/settings.json запускаються
Чужий репозиторій у CI/скриптіперегляньте .claude/; запускайте з --bare або --settings '{"disableAllHooks": true}'. Лише user-файла замало: project-налаштування мають вищий пріоритет
Frontmatter-хукипроєктні skills реєструються і в непідтвердженій теці при -p; хуки проєктного субагента — лише після довіри (v2.1.218+)
Політика організаціїallowManagedHooksOnly, allowedHttpHookUrls, httpHookAllowedEnvVars; PreToolUse-deny діє навіть у bypassPermissions, а allow хука не обходить deny-правила
✓
Цитуйте змінні: "$VAR", а не $VAR; шляхи до скриптів — абсолютні або через ${CLAUDE_PROJECT_DIR} з args
✓
Перевіряйте вхід: відхиляйте шляхи з .., нормалізуйте зворотні слеші Windows
✓
Обходьте чутливе: .env, .git/, ключі
✓
JSON збирайте через jq -n --arg, а не конкатенацією рядків
✗
Не покладайтеся на exit 1 як на блокування і на таймаут як на ворота
✗
Не вважайте if захистом: це best-effort фільтр
✗
Не кладіть секрети в сам хук: токени передавайте через allowedEnvVars

Налагодження

ЩоЯк
Лог виконанняclaude --debug-file /tmp/claude.log і tail -f; або /debug посеред сесії; --debug пише в ~/.claude/debug/<session-id>.txt, а не в термінал. Деталі збігів — CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose
Результат запускуCtrl+O (транскрипт): успішний хук мовчить, блок показує причину, неблокуюча помилка — hook error + перший рядок stderr
Ручна перевіркаecho '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./hook.sh; echo $?
Хук не спрацьовує/hooks — чи є він під потрібною подією; matcher чутливий до регістру; чи не стоїть if на події без підтримки; чи виконуваний файл (chmod +x); чи JSON валідний (без коментарів і зайвих ком)
JSON «не діє»зайвий вивід перед { (echo у ~/.zshrc — обгорніть у [[ $- == *i* ]]); поле не на тому рівні (permissionDecision має бути в hookSpecificOutput); у debug-лозі шукайте Hook JSON output had unrecognized keys. JSON краще збирати через jq -n --arg
Stop не відпускаєперевіряйте stop_hook_active; ліміт — 8 поспіль без викликів інструментів між ними
Тихо «відкриті ворота»помилка у шляху (код 127) — неблокуюча; перевірте першу появу хука в транскрипті
08

sandbox

Ізоляція bash-команд від файлової системи і мережі

#

Що саме ізолює sandbox

Sandbox — межа на рівні ОС навколо shell-команд (Bash, PowerShell і Monitor) та їхніх дочірніх процесів. Вона вимкнена за замовчуванням: вмикається через /sandbox або sandbox.enabled. Побудований на відкритому пакеті @anthropic-ai/sandbox-runtime.

РесурсТипово для команди в sandboxЧим змінити
ЗаписРобоча тека, тека тимчасових файлів користувача (для неї виставляється $TMPDIR) і додані директорії. Protected paths завжди під забороною записуfilesystem.allowWrite, filesystem.denyWrite
ЧитанняМайже вся машина, включно з ~/.ssh та ~/.aws/credentialsfilesystem.denyRead / allowRead, credentials, permissions.blockReadsOutsideWorkingDirectories
МережаПрямого виходу немає — лише проксі на вашій машині, який звіряє хост зі списком. Дозволені домени спочатку порожніnetwork.allowedDomains, deniedDomains
Змінні середовищаУспадковуються від Claude Code, включно з секретамиcredentials.envVars, CLAUDE_CODE_SUBPROCESS_ENV_SCRUB
Що працює поза sandbox

Вбудовані Read, Edit, Write, WebFetch, WebSearch керуються правилами дозволів, а не sandbox: denyRead не зупиняє інструмент Read, а allowedDomains не обмежує WebFetch. Поза межею також: хуки, локальні MCP-сервери, LSP, плагінні монітори, statusLine, apiKeyHelper, команди, які ви вводите через !, команди з excludedCommands та повтори поза sandbox. Щоб обгорнути все одним кордоном, запускайте весь Claude Code в контейнері/VM або в sandbox runtime.

Платформи

ПлатформаМеханізмПримітки
macOSSeatbelt (вбудований)Окремо нічого ставити не треба
Linuxbubblewrap + socatsudo apt-get install bubblewrap socat (Ubuntu/Debian) або sudo dnf install bubblewrap socat (Fedora). Необов’язковий seccomp-фільтр додає блокування Unix-сокетів: npm install -g @anthropic-ai/sandbox-runtime. На Ubuntu 24.04+ потрібен AppArmor-профіль для bwrap (перевірка: sysctl kernel.apparmor_restrict_unprivileged_userns)
WSL2bubblewrap + socatТе саме, що Linux. WSL1 не підтримується («Sandboxing requires WSL2»)
Нативний WindowsнемаєКоманди виконуються без sandbox; запускайте Claude Code в WSL2

Якщо sandbox не може стартувати (бракує залежності, непідтримувана платформа), Claude Code типово запускає команди без sandbox; щоб натомість завершувати запуск з помилкою — failIfUnavailable: true. У контейнері без привілеїв bubblewrap не змонтує /proc: див. enableWeakerNestedSandbox.

Режими sandbox і взаємодія з дозволами

РежимЩо відбуваєтьсяНалаштування
auto-allowКоманда, яка виконується всередині sandbox, схвалюється без запиту (навіть у Manual). Deny-правила, content-scoped ask-правила (Bash(git push *)) і rm/rmdir по критичних шляхах усе одно діють; голе Bash в ask для команд у sandbox пропускається, але не в plan-режиміautoAllowBashIfSandboxed: true (default)
regular permissionsУсі команди проходять звичайні запити, навіть у sandbox: більше контролю, більше підтвердженьautoAllowBashIfSandboxed: false

Auto-allow у sandbox і режим auto (класифікатор) — різні речі; вони незалежні й комбінуються. Правила дозволів та sandbox доповнюють одне одного: шляхи з Edit-allow, Read/Edit-deny та домени з WebFetch(domain:) зливаються в підсумкову конфігурацію sandbox.

Мережа: що з хостами поза allowedDomains

Команда лишається в sandbox і чекає рішення; воно залежить від режиму дозволів:

РежимЩо станеться зі з’єднанням
bypassPermissions (і plan, якщо bypass доступний)Дозволено без запиту
Manual, acceptEdits, planЗапит
autoВідхилено, якщо команда не вказала хост у своєму списку (v2.1.271+) і класифікатор його не схвалив
dontAskВідхилено

З strictAllowlist або allowManagedDomainsOnly проксі відхиляє з’єднання в усіх режимах; deniedDomains — теж. «Yes» дозволяє хост до кінця сесії, «Yes, and don’t ask again» зберігає правило WebFetch(domain:…) у локальні налаштування.

  • Інструменти без підтримки проксі (ssh, більшість драйверів БД, UDP, QUIC, ping) не підключаться навіть до дозволеного хоста — їх виносять в excludedCommands.
  • Хости, що резолвляться в loopback/link-local (169.254.169.254), відхиляються; localhost дозволений. Корпоративний проксі задають через HTTPS_PROXY в env.
  • IPv6 пишіть у дужках: "[::1]", "[::1]:443" (v2.1.229+). Запис без порту дозволяє всі порти хоста.
  • Проксі вирішує за іменем хоста і за замовчуванням не розшифровує TLS, тож можливий domain fronting; не дозволяйте надто широкі домени на кшталт github.com, якщо важливий ризик витоку.

Вихід із sandbox (escape hatch)

Коли команда не працює в sandbox, Claude може повторити її з параметром dangerouslyDisableSandbox. Хто це схвалює — залежить від режиму:

РежимПовтор поза sandbox
bypassPermissionsБез запиту
Manual, acceptEditsЗапит «Bash command (unsandboxed)»
autoОкремий класифікатор оцінює команду
dontAskВідхилено
  • Збіжне allow-правило (наприклад Bash(curl *)) схвалює й повтор поза sandbox без запиту.
  • Ask-правило Bash(dangerouslyDisableSandbox:true) змушує питати завжди (навіть в auto і bypass) і має пріоритет над allow.
  • allowUnsandboxedCommands: false («strict sandbox mode») — параметр ігнорується, повтору немає. false з user/managed/--settings утримується навіть проти true з проєктного файлу (з v2.1.285).
  • Команди, які ви вводите вручну через !, у більшості сесій ідуть поза sandbox.
Protected paths у sandbox

Навіть у записуваних теках sandbox забороняє запис у файли, з яких Claude Code бере конфігурацію й код: .claude (settings, skills, agents, commands, hooks), .mcp.json, shell-rc файли (.bashrc, .zshrc), .gitconfig, .vscode, .idea, .git/hooks і .git/config, файли, що перетворили б теку на bare-репозиторій, а також більшу частину ~/.claude, ~/.claude.json і .credentials.json. Виняток зробити не можна — ні allowWrite, ні Edit-allow; лише filesystem.disabled знімає захист (разом з усією ізоляцією файлів).

sandbox.enabledboolean
Що робить

Вмикає ізольоване середовище (Seatbelt на macOS, bubblewrap на Linux/WSL) для bash-команд з обмеженим доступом до файлів і мережі. Default — false.

Що зміниться

true = bash команди виконуються в обмеженому просторі. З autoAllowBashIfSandboxed (default true) команди в пісочниці не потребують підтвердження — менше промптів без втрати безпеки.

settings.json
"sandbox": {
  "enabled": true,
  "autoAllowBashIfSandboxed": true,   // default; false = regular permissions
  "allowUnsandboxedCommands": false,  // strict sandbox mode: ігнорувати dangerouslyDisableSandbox
  "failIfUnavailable": true           // не стартувати без sandbox
}
Слеш-команда /sandbox відкриває панель: Mode (auto-allow або regular), Overrides (allowUnsandboxedCommands), Config (результуючі налаштування); вибір пишеться в .claude/settings.local.json. Для всіх проєктів ставте enabled у ~/.claude/settings.json. Перевірка, що sandbox працює: попросіть Claude виконати touch ~/sandbox-probe — має бути «Operation not permitted» / «Read-only file system».
⚠ Без failIfUnavailable при збої запуску sandbox (немає bubblewrap/socat, WSL1, нативний Windows) Claude Code мовчки запускає команди без ізоляції.
sandbox.filesystemobject
Що робить

allowWrite — куди можна писати. denyWrite — заборона запису. denyRead / allowRead — читання з bash-команд (allowRead повторно відкриває частину області під denyRead; перемагає вужчий шлях). Масиви зливаються з усіх рівнів.

Що зміниться

Це керує лише shell-командами та їхніми процесами: denyRead не зупиняє інструмент Read — для нього потрібні deny-правила Read(...) (вони, навпаки, автоматично потрапляють у denyRead). Запис поза дозволеними теками заблокований на рівні ОС. Типово можна писати в робочу теку, тимчасову теку й додані директорії, а читати — майже все, включно з ~/.ssh.

settings.json
"filesystem": {
  "allowWrite": ["~/.cache/pip", "~/.npm"],   // робоча тека і так записувана
  "denyWrite": ["./config/prod.json"],
  "denyRead": ["~/.ssh", "~/.aws"]
}
Префікси тут інші, ніж у permissions: /x — абсолютний, //x — теж абсолютний, ~/ — home, ./x або без префікса — від кореня проєкту у project settings і від ~/.claude у user settings. Кінцеві / та /** прибираються
⚠ На Linux/WSL запис із *, ?, [ (після зняття кінцевого /**) в allowWrite/denyWrite пропускається й не діє — вказуй конкретні каталоги (це стосується й Edit-правил, які додаються до цих списків). У denyRead/allowRead wildcard-и працюють на всіх платформах. Захищені шляхи (.claude, .git/hooks, shell-rc…) не відкриваються жодним allowWrite.
sandbox.networkobject
Що робить

Allowlist / denylist доменів для мережевих запитів з bash-команд. Запис — домен, wildcard (*.example.com), IP, з необов’язковим :port; без порту — усі порти. Масиви зливаються між рівнями, а ще сюди додаються домени з правил WebFetch(domain:…).

Що зміниться

Прямого виходу з sandbox немає, лише через проксі. Дозволені домени спочатку порожні, а що буде з іншими хостами — вирішує режим дозволів (запит у Manual/acceptEdits/plan, відмова в dontAsk, дозвіл у bypassPermissions; таблиця вище). Жорстка заборона — лише з strictAllowlist чи allowManagedDomainsOnly. deniedDomains блокує навіть усередині ширшого wildcard-а й діє в усіх режимах. allowLocalBinding і allowUnixSockets працюють лише на macOS; на Linux для сокетів — allowAllUnixSockets.

settings.json
"network": {
  "allowedDomains": ["*.github.com", "registry.npmjs.org", "pypi.org"],
  "deniedDomains": ["uploads.github.com"],
  "allowLocalBinding": true,             // localhost:8000 — ok (macOS)
  "allowUnixSockets": ["/var/run/docker.sock"]  // docker (macOS)
}
Managed: allowManagedDomainsOnly — враховувати лише домени з managed (див. картку нижче). strictAllowlist (user/managed, v2.1.219+) — відхиляти хости поза allowlist замість запиту.
⚠ allowedDomains не обмежує інструмент WebFetch. Дозвіл на /var/run/docker.sock через allowUnixSockets фактично віддає хост-систему. Широкі домени (github.com) лишають шляхи для витоку даних.
sandbox.excludedCommandsarray
Що робить

Команди, які виконуються поза sandbox — без файлових обмежень і без проксі (але зі звичайною перевіркою дозволів). Записи мають синтаксис правил Bash(...): шаблон без wildcard — точний збіг, тож docker збігається лише з голим docker без аргументів, а docker * — з викликом з аргументами чи без.

Що зміниться

Для інструментів, несумісних з ізоляцією (docker, клієнти БД без проксі). Якщо інструменту потрібна ще одна тека чи хост — краще allowWrite/allowedDomains, що лишають його в sandbox. Виключена команда має повний доступ: ширший шаблон (docker *) охоплює все, що вміє інструмент.

settings.json
"excludedCommands": ["docker compose *", "python manage.py migrate *"]
Виклик виходить із sandbox лише якщо кожна команда в ньому збігається: npm ci && docker compose build лишається в sandbox, поки не покритий і npm ci. Збіг іде за текстом виклику: скрипт, що всередині викликає docker, і /usr/local/bin/docker не збігаються.
В sandbox лишаються виклики з: cd/pushd/popd, $() чи підоболонкою, if/for, перенаправленням у файл, sudo/eval/xargs на початку, іменем команди зі змінної, а також git clone/init/worktree add із шляхом, що абсолютний, починається з ~ або містить ... У bypassPermissions виключена команда виконується без запиту, якщо не збігається ask-правило.
⚠ Це зручність, а не межа безпеки. Під admin-required sandbox записи з .claude/settings.json і settings.local.json ігноруються — клонований репозиторій не виведе команди з sandbox.
sandbox.credentialsobject
Що робить

Захищає файли з секретами та змінні середовища від команд у пісочниці: deny — приховати, mask — показати плейсхолдер, а справжнє значення підставить sandbox-проксі у вихідних запитах (для файлів mask — з v2.1.221).

Що зміниться

Навіть якщо Claude запустить env чи cat ~/.aws/credentials — секрет не потрапить у контекст. Вбудованого списку немає: захищається лише те, що перелічено (типово секрети читаються, зокрема ~/.aws/credentials). mask, allowPlaintextInject, awsPairs, sigv4 діють лише з user, managed і --settings; з проєктних файлів mask-записи відкидаються. mask потребує network.tlsTerminate (або allowPlaintextInject для HTTP).

settings.json
"credentials": {
  "files":   [{ "path": "~/.aws/credentials", "mode": "deny" }],
  "envVars": [{ "name": "GITHUB_TOKEN", "mode": "deny" }]
}
Приклад mask для змінної: { "name": "GITHUB_TOKEN", "mode": "mask", "injectHosts": ["api.github.com"] } — команда бачить заповнювач, а справжнє значення підставляється лише в запитах до api.github.com (без injectHosts — до всіх хостів з allowedDomains).
extractРегулярний вираз з групою захоплення: маскується лише група 1 (напр. пароль у DATABASE_URL)
decode: "jwt"Підміняє JWT структурно коректною підробкою; з maskClaims маскує лише названі claims (v2.1.224+; не поєднується з extract для змінних)
onExtractNoMatchwarn (default) · deny · error — що робити, коли нічого маскувати
injectHostsХости, де проксі підставляє справжнє значення (мають бути також у allowedDomains)
maskDuplicatesЛише для файлів: маскувати також дослівні копії значення в тому самому файлі
⚠ На macOS файловий mask застосовується як deny; для каталогів, glob-ів, файлів понад 8 MiB і не-UTF-8 — теж fallback на deny. Файловий deny не діє, якщо вимкнено ізоляцію файлів (filesystem.disabled); захист змінних працює і тоді.
sandbox.autoAllowBashIfSandboxedboolean
Що робить

Чи виконувати команди, що працюють усередині sandbox, без запиту підтвердження.

Що зміниться

Default true — auto-allow режим: менше запитів без втрати безпеки (межу тримає ОС). false — «regular permissions»: команди в sandbox проходять звичайні allow/ask правила і режим дозволів. CLAUDE_CODE_SUBPROCESS_ENV_SCRUB вимикає auto-allow.

settings.json
"sandbox": {
  "enabled": true,
  "autoAllowBashIfSandboxed": false   // хочу бачити запити навіть у sandbox
}
Deny-правила, content-scoped ask-правила та rm по критичних шляхах діють і в auto-allow. Поза sandbox (виключені команди, повтори) команда йде звичайним шляхом дозволів.
sandbox.allowUnsandboxedCommandsboolean
Що робить

Чи може Claude повторити заблоковану в sandbox команду поза нею з параметром dangerouslyDisableSandbox.

Що зміниться

Default true. З false параметр ігнорується, і доки sandbox працює, усі команди Claude виконуються в ньому (крім збігів з excludedCommands) — «strict sandbox mode» у вкладці Overrides /sandbox. false з managed чи --settings робить sandbox «admin-required».

settings.json
"sandbox": {
  "enabled": true,
  "allowUnsandboxedCommands": false,
  "failIfUnavailable": true
}
Для суворого режиму додайте failIfUnavailable, інакше при збої sandbox команди підуть без нього. Хто схвалює повтор у кожному режимі — у таблиці вище.
sandbox.failIfUnavailableboolean
Що робить

Завершувати запуск з помилкою, якщо sandbox.enabled: true, але sandbox не стартує (немає залежності чи платформа не підтримується).

Що зміниться

Default false: без ключа Claude Code мовчки виконує команди без sandbox. На непідтримуваній платформі (нативний Windows) з цим ключем Claude Code не стартує. Рекомендовано для managed-розгортань, де sandbox є вимогою безпеки.

settings.json
"sandbox": { "enabled": true, "failIfUnavailable": true }
sandbox.filesystem.allowReadarray
Що робить

Повторно відкриває читання для шляхів усередині області, яку закрив denyRead. Коли правила перетинаються, перемагає вужчий шлях.

Що зміниться

denyRead: ["~/"] + allowRead: ["."] дає читання лише проєкту. Точний або wildcard denyRead лишається заблокованим усередині ширшого allowRead (напр. ~/**/.env), тож широкий allow не відкриє секрет випадково.

settings.json
"sandbox": {
  "filesystem": {
    "denyRead": ["~/"],
    "allowRead": ["."]    // у project settings "." = корінь проєкту
  }
}
У ~/.claude/settings.json той самий "." означає ~/.claude, а не проєкт — файли проєкту лишилися б заблокованими. Простіший шлях закрити читання поза проєктом — permissions.blockReadsOutsideWorkingDirectories.
sandbox.filesystem.disabledbooleanuser / managed
Що робить

Вимикає ізоляцію файлової системи, залишаючи мережеву. Команди отримують необмежені читання й запис на хості, а вихід у мережу лишається в межах allowedDomains. Потребує v2.1.216+.

Що зміниться

Для сценаріїв, де важливо контролювати куди з’єднуються команди, а не що вони пишуть. denyRead і credentials.files (deny) тоді не діють, а credentials.envVars та застосовані mask — працюють. autoAllowBashIfSandboxed за замовчуванням лишається true — поставте false, щоб бачити запити.

settings.json
"sandbox": {
  "enabled": true,
  "filesystem": { "disabled": true },
  "network": { "allowedDomains": ["github.com", "*.npmjs.org"] }
}
Якщо managed налаштовує sandbox.filesystem або credentials.files з режимом deny, ключ може встановити лише managed. Без ізоляції файлів уже не діє й захист protected paths.
sandbox.filesystem.allowManagedReadPathsOnlybooleanmanaged only
Що робить

Враховувати лише ті allowRead, що прийшли з managed-налаштувань, щоб розробники не могли знову відкрити читання шляхів, які закрила організація.

Що зміниться

denyRead усе одно зливається з усіх рівнів — розробник завжди може лише додати заборони.

managed-settings.json
"sandbox": {
  "filesystem": {
    "denyRead": ["~/"],
    "allowRead": ["~/work"],
    "allowManagedReadPathsOnly": true
  }
}
sandbox.network.strictAllowlistbooleanuser / managed
Що робить

Відхиляти хости поза allowlist замість запиту. Allowlist = allowedDomains + домени з allow-правил WebFetch(domain:…) (або лише managed, якщо задано allowManagedDomainsOnly). Потребує v2.1.219+.

Що зміниться

Перетворює «запит залежно від режиму» на жорстку заборону в усіх режимах, включно з bypassPermissions. Стосується лише команд у sandbox: WebFetch далі підкоряється своїм правилам. Репозиторій увімкнути/вимкнути його не може.

settings.json
"sandbox": {
  "network": {
    "allowedDomains": ["pypi.org", "registry.npmjs.org"],
    "strictAllowlist": true
  }
}
sandbox.network.allowManagedDomainsOnlybooleanmanaged only
Що робить

Фіксує мережевий allowlist на тому, що задано в managed: враховуються лише allowedDomains і allow-правила WebFetch(domain:) з managed-налаштувань, інші джерела ігноруються, а непрописані домени блокуються без запиту.

Що зміниться

Робить sandbox «admin-required»: репозиторні ключі, що послаблюють sandbox (excludedCommands, allowedDomains, allowWrite, WebFetch-allow), ігноруються (v2.1.285+), а порт власного проксі може задати лише managed. deniedDomains усе одно зливаються з усіх рівнів.

managed-settings.json
"sandbox": {
  "network": {
    "allowManagedDomainsOnly": true,
    "allowedDomains": ["github.com", "*.npmjs.org", "pypi.org"]
  }
}
sandbox.network.allowAllUnixSocketsboolean
Що робить

Дозволяє командам у sandbox підключатися до будь-яких Unix-сокетів. На Linux і WSL2 це єдиний спосіб дозволити Unix-сокети (seccomp-фільтр інакше блокує socket(AF_UNIX, …)).

Що зміниться

Default false. На WSL2 true також відкриває interop-сокет, що запускає Windows-бінарники (cmd.exe, powershell.exe). Якщо seccomp-фільтра немає, Unix-сокети й так не блокуються.

settings.json
"sandbox": { "network": { "allowAllUnixSockets": true } }
Доступ до сокета типу /var/run/docker.sock фактично віддає хост. Для macOS є вужчий allowUnixSockets, який у картці sandbox.network вище.
sandbox.network.allowMachLookuparray
Що робить

Додаткові імена XPC/Mach-сервісів, які macOS-sandbox може шукати. Потрібно інструментам на XPC: iOS Simulator, Playwright.

Що зміниться

Один кінцевий * — префікс; лише "*" — усі сервіси. Без ключа список порожній. Лише macOS.

settings.json
"sandbox": { "network": { "allowMachLookup": ["com.apple.coresimulator.*"] } }
sandbox.network.httpProxyPortnumber
Що робить

Спрямовує HTTP-трафік sandbox на ваш проксі (локальний TCP-порт) замість вбудованого — щоб інспектувати HTTPS, застосовувати власну фільтрацію чи логувати.

Що зміниться

Ваш проксі бере фільтрацію на себе: Claude Code припиняє застосовувати свої списки доменів і мережеві запити до цього трафіку. Якщо задано лише один із двох портів, для іншого протоколу лишається вбудований проксі. Під allowManagedDomainsOnly порт може задати лише managed.

settings.json
"sandbox": { "network": { "httpProxyPort": 8080 } }
Go-інструменти (gh, gcloud, terraform) за MITM-проксі на macOS потребують ще й enableWeakerNetworkIsolation.
sandbox.network.socksProxyPortnumber
Що робить

Те саме, що httpProxyPort, але для SOCKS5-проксі.

Що зміниться

Власний SOCKS-проксі бере фільтрацію на себе; для HTTP лишається вбудований, якщо не задано й httpProxyPort.

settings.json
"sandbox": { "network": { "socksProxyPort": 8081 } }
sandbox.network.tlsTerminateobjectuser / managed
Що робить

Експериментально. Змушує проксі sandbox термінувати TLS, щоб бачити вміст HTTPS-запитів. Потрібно для підстановки mask-облікових даних.

Що зміниться

{} створює тимчасовий центр сертифікації на сесію; або вкажіть свої caCertPath і caKeyPath. Без ключа TLS не інспектується. З кількох джерел береться значення з найвищим пріоритетом: managed → --settings → user.

settings.json
"sandbox": {
  "network": {
    "tlsTerminate": {}      // або { "caCertPath": "...", "caKeyPath": "..." }
  }
}
Репозиторій не може його увімкнути чи підсунути свій CA.
sandbox.credentials.allowPlaintextInjectbooleanuser / managed
Що робить

Дозволяє підстановку mask також для звичайних HTTP-запитів, а не лише для HTTPS з термінацією TLS.

Що зміниться

На plain HTTP особа сервера не перевіряється, а секрет іде відкритим текстом — залишайте false поза довіреними тестовими мережами.

settings.json
"sandbox": { "credentials": { "allowPlaintextInject": true } }
sandbox.credentials.awsPairsarrayuser / managed
Що робить

Групує замасковані змінні середовища, що утворюють одні AWS-облікові дані, для перепідпису запитів SigV4, коли змінні мають нестандартні імена. Потребує v2.1.224+.

Що зміниться

Стандартна трійка AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN зв’язується автоматично, якщо їх замасковано цілком. Кожна названа змінна має бути mask-записом у credentials.envVars (без extract/decode) і займати лише один слот. Згадка стандартних імен у парі вимикає автозв’язування.

settings.json
"sandbox": {
  "credentials": {
    "awsPairs": [
      { "accessKeyIdVar": "MY_KEY_ID", "secretAccessKeyVar": "MY_SECRET_KEY" }
    ]
  }
}
sandbox.credentials.sigv4objectuser / managed
Що робить

Що робить проксі з формами AWS-запитів, які він не може перепідписати: streaming (aws-chunked), presigned (presigned URL), sigv4a (асиметричний підпис). Потребує v2.1.224+.

Що зміниться

Кожне поле: "deny" — проксі відхиляє запит (типово для всіх), "passthrough" — пересилає з підписом від замаскованого заповнювача, тож AWS поверне власну відмову. Стосується запитів, підписаних заповнювачем замаскованої пари.

settings.json
"sandbox": { "credentials": { "sigv4": { "streaming": "passthrough" } } }
sandbox.ignoreViolationsobject
Що робить

Приглушує звіти про порушення sandbox для шляхів, які команда очікувано пробує і їй відмовляють (наприклад, перевірка /etc/hosts на старті). Блокування лишається; зникає лише сповіщення.

Що зміниться

Ключ — підрядок команди ("*" — будь-яка), значення — масив підрядків порушення (зазвичай шляхи). Зменшує шум у виводі, який бачить Claude.

settings.json
"sandbox": {
  "ignoreViolations": {
    "*": ["/etc/hosts"],
    "npm": ["~/.npmrc"]
  }
}
sandbox.enableWeakerNestedSandboxboolean
Що робить

Linux/WSL2: запуск sandbox усередині непривілейованого Docker-контейнера, де bubblewrap не може змонтувати свіжий /proc. Внутрішній sandbox тоді монтує наявний /proc контейнера.

Що зміниться

Знижує безпеку (відкриває інформацію про процеси). Вмикайте лише коли зовнішній контейнер сам дає потрібну ізоляцію; типова помилка без нього — Can't mount proc on /newroot/proc: Operation not permitted.

settings.json
"sandbox": { "enabled": true, "enableWeakerNestedSandbox": true }
Приклад: CI-образ з Claude Code. Ізоляцію забезпечує сам контейнер без доступу до продакшн-мережі, а не цей ключ.
sandbox.enableWeakerNetworkIsolationboolean
Що робить

macOS: дозволяє командам у sandbox звертатися до системного сервісу довіри TLS com.apple.trustd.agent.

Що зміниться

Go-інструменти (gh, gcloud, terraform) потребують його для перевірки сертифікатів при httpProxyPort з MITM-проксі та власним CA. Знижує безпеку (потенційний канал витоку). Без MITM-проксі краще винести такі інструменти в excludedCommands.

settings.json
"sandbox": { "enabled": true, "enableWeakerNetworkIsolation": true }
sandbox.allowAppleEventsbooleanuser / managed
Що робить

macOS: дозволяє командам у sandbox надсилати Apple Events — без цього open, osascript та інструменти, що відкривають URL у браузері, падають з помилкою -600.

Що зміниться

Прибирає ізоляцію виконання коду: команда зможе без запиту запускати інші програми поза sandbox і слати AppleScript до запущених програм (за згодою TCC). Задається лише в user, managed чи CLI; проєктний файл не може. Безпечніше винести одну потрібну команду в excludedCommands.

settings.json
"sandbox": { "enabled": true, "allowAppleEvents": true }
sandbox.ripgrepobjectuser / managed
Що робить

Вказує sandbox власний бінарник ripgrep замість того, що використовує сам Claude Code.

Що зміниться

Поля: command — шлях до rg, необов’язковий args — масив аргументів, що додаються попереду. Без ключа використовується вбудований ripgrep (якщо не USE_BUILTIN_RIPGREP=0).

settings.json
"sandbox": {
  "ripgrep": { "command": "/usr/local/bin/rg", "args": ["--no-config"] }
}
sandbox.bwrapPathstringmanaged only
Що робить

Linux/WSL2: шлях до бінарника bubblewrap, встановленого поза PATH (наприклад, вендорська копія на ізольованому хості). Використовується і для перевірки залежностей, і для обгортання кожної команди.

Що зміниться

Лише абсолютний шлях (відносний відкидається, і береться bwrap з PATH). Читається лише з managed, щоб user/project файл не міг підмінити бінарник.

managed-settings.json
"sandbox": { "enabled": true, "bwrapPath": "/opt/admin/bwrap" }
sandbox.socatPathstringmanaged only
Що робить

Linux/WSL2: шлях до бінарника socat поза PATH для мережевого проксі sandbox.

Що зміниться

Абсолютний шлях; відносний відкидається. Лише managed.

managed-settings.json
"sandbox": { "enabled": true, "socatPath": "/opt/admin/socat" }

Реальний приклад sandbox для Django + Vue

Проєктні налаштування для команди: Python і npm встановлюють пакети лише з реєстрів та внутрішнього GitLab, секрети домашньої теки закриті, dev-сервери (Django :8000, Vite :5173) працюють на macOS. Команди, що ходять у PostgreSQL (драйвер не користується проксі), виносимо в excludedCommands з ask-правилом.

.claude/settings.json
{
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,     // без 'dangerouslyDisableSandbox'
    "excludedCommands": [
      "docker compose *",                  // docker несумісний із sandbox
      "python manage.py migrate *"         // psycopg не бачить проксі
    ],
    "filesystem": {
      "allowWrite": ["~/.cache/pip", "~/.npm"],
      "denyWrite": ["./.env", "./.env.production"],
      "denyRead": ["~/.ssh", "~/.aws"]
    },
    "network": {
      "allowedDomains": [
        "pypi.org", "files.pythonhosted.org",
        "registry.npmjs.org", "*.npmjs.org",
        "github.com", "gitlab.example.com"
      ],
      "allowLocalBinding": true            // macOS: runserver і vite dev
    },
    "credentials": {
      "files": [{ "path": "~/.aws/credentials", "mode": "deny" }],
      "envVars": [{ "name": "NPM_TOKEN", "mode": "deny" }]
    }
  },
  "permissions": {
    "ask": ["Bash(python manage.py migrate *)", "Bash(docker compose *)"]
  }
}
  • Пакети pip/npm ставляться через проксі, тож pypi.org та registry.npmjs.org мають бути в allowedDomains; strictAllowlist (лише user/managed) зробить список жорстким.
  • Виключена команда має повний доступ, а Claude може змінити скрипт у робочій теці й запустити його поза sandbox — тримайте шаблони вузькими (python manage.py migrate *, а не python *) і залишайте ask-правило.
  • На Linux/WSL2 allowLocalBinding не діє: у кожної команди свій loopback; щоб дістатися сервера на хості (БД у контейнері), виносьте команду в excludedCommands.
  • jest: watchman несумісний із sandbox — запускайте jest --no-watchman. Go-CLI (gh, terraform) на macOS можуть не пройти перевірку TLS — винесіть їх в excludedCommands (enableWeakerNetworkIsolation — лише для MITM-проксі з власним CA). git через SSH на macOS у sandbox не працює — переведіть remote на HTTPS.
09

MCP servers

Управління підключенням до зовнішніх сервісів через MCP протокол

#

MCP-сервер — це локальний процес або віддалений ендпоінт, який дає Claude додаткові інструменти, ресурси та промпти (GitLab, база даних, Sentry тощо). Нижче: де зберігається конфігурація, як додати сервер, як налаштувати авторизацію, як організація обмежує доступ і які ключі settings за це відповідають.

Області (scopes) та файли конфігурації

ОбластьДе завантажуєтьсяСпільна з командоюДе зберігається
local (за замовчуванням)лише поточний проєктні~/.claude.json, у projects["<шлях>"].mcpServers
projectлише поточний проєкттак, через git.mcp.json у корені проєкту
userусі ваші проєктині~/.claude.json, верхній рівень mcpServers
Managed: managed-mcp.jsonусі користувачі машини (ексклюзивний контроль)розгортає адмінсистемний шлях (таблиця нижче)
Managed: managedMcpServersусі користувачі, поверх власних серверіврозгортає адмінmanaged settings (див. картку нижче)
Не плутати

«Local scope» для MCP — це не .claude/settings.local.json. MCP-сервери локальної області лежать у ~/.claude.json (у домашній теці), а загальні локальні settings — у .claude/settings.local.json проєкту.

Пріоритет, коли один сервер визначено в кількох місцях: managedMcpServers > local > project > user > сервери плагінів > конектори claude.ai. Claude Code підключається один раз, використовуючи визначення з найвищого джерела; запис береться цілком, поля між областями не зливаються. Області дедуплікуються за іменем, плагіни та конектори — за ендпоінтом (той самий URL або команда). Якщо одне ім’я має різні ендпоінти в кількох областях, claude mcp list і /mcp покажуть попередження (OAuth-вхід зберігається окремо для кожного ендпоінта).

ПлатформаШлях до managed-mcp.json
macOS/Library/Application Support/ClaudeCode/managed-mcp.json
Linux / WSL/etc/claude-code/managed-mcp.json
WindowsC:\Program Files\ClaudeCode\managed-mcp.json

Файл має той самий формат, що й .mcp.json. Його не можна доставити через server-managed settings — лише як файл на диску (Jamf, Intune, GPO тощо). Не клади ключі й паролі в env такого файлу: його читає будь-який користувач машини; використовуй ${VAR}, OAuth або headersHelper.

Транспорти

ТранспортtypeЯк додатиНотатки
HTTPhttp (синонім streamable-http)claude mcp add --transport http <name> <url>Рекомендований для віддалених серверів. Підтримує OAuth і заголовки.
SSEsseclaude mcp add --transport sse <name> <url>Застарілий. З v2.1.265 --transport http сам перемикається на SSE, якщо сервер не приймає HTTP.
stdiostdioclaude mcp add [опції] <name> -- <команда> [args]Локальний процес. -- відділяє власні прапорці Claude (--transport, --env, --scope) від команди сервера. Сервер отримує змінну CLAUDE_PROJECT_DIR; на roots/list Claude Code відповідає робочими директоріями сесії.
WebSocketwsлише через .mcp.json або claude mcp add-jsonПостійне двостороннє з’єднання. Автентифікація тільки заголовками (статичний токен або headersHelper), OAuth немає. Прапорець --transport значення ws не приймає.
SDKsdk—Реєструється лише SDK-хостом (Agent SDK, desktop). У .mcp.json пропускається з повідомленням.
Типова помилка

JSON-запис із url, але без type вважається stdio-сервером і дає помилку конфігурації (сервер пропускається). Завжди пиши "type": "http" (або sse / ws).

Ім’я сервера в командах claude mcp — лише літери, цифри, - та _. Зарезервовані імена: workspace, claude-in-chrome, computer-use, Claude Preview, Claude Browser (сервер із таким іменем пропускається, claude mcp add відхиляє ім’я).

Команди claude mcp add та керування

shell
# Віддалений HTTP-сервер (область за замовчуванням — local, лише для вас у цьому проєкті)
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

# Спільний для команди сервер: запис потрапляє у .mcp.json (комітиться в git)
# УВАГА: адреса GitLab MCP — плейсхолдер; точний шлях ендпоінта звір із документацією свого GitLab
claude mcp add-json --scope project gitlab \
  '{"type":"http","url":"https://gitlab.acme.example/api/v4/mcp","headers":{"Authorization":"Bearer ${GITLAB_TOKEN}"}}'

# Локальний stdio-сервер для PostgreSQL (--scope user = усі ваші проєкти). Після -- іде команда сервера
claude mcp add --transport stdio --scope user db \
  -- npx -y @bytebase/dbhub --dsn "postgresql://readonly:PASSWORD@db.acme.example:5432/analytics"

# Секрет у змінній середовища сервера (між --env і іменем має бути інша опція, напр. --transport)
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable -- npx -y airtable-mcp-server

# Керування
claude mcp list                         # статус: Connected / Needs authentication / Failed / Pending approval
claude mcp get sentry                   # деталі одного сервера
claude mcp remove sentry --scope local  # також видаляє OAuth-токени та реєстрацію клієнта
claude mcp login sentry [--no-browser]  # OAuth з терміналу
claude mcp logout sentry
claude mcp reset-project-choices        # скинути схвалення серверів з .mcp.json
claude mcp add-from-claude-desktop      # імпорт із Claude Desktop (macOS і WSL)
claude mcp serve                        # запустити сам Claude Code як stdio MCP-сервер

У сесії: /mcp — панель статусів, авторизація, вмикання/вимикання серверів, список інструментів. Промпти MCP-сервера з’являються як команди /server:prompt (MCP) (також працює /mcp__server__prompt).

Реалістичний .mcp.json: GitLab + PostgreSQL + Sentry

Файл комітиться в репозиторій. Секрети не пишемо у файл — тільки посилання ${VAR}, кожен розробник задає змінні у своєму середовищі. Шлях /api/v4/mcp для GitLab — плейсхолдер: точну адресу MCP-ендпоінта звір із документацією свого інстансу GitLab; хости acme.example і адреса БД — теж приклади.

.mcp.json
{
  "mcpServers": {
    "gitlab": {
      "type": "http",
      "url": "${GITLAB_URL:-https://gitlab.acme.example}/api/v4/mcp",
      "headers": {
        "Authorization": "Bearer ${GITLAB_TOKEN}"
      }
    },
    "db": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL_READONLY}"],
      "env": {
        "PGCONNECT_TIMEOUT": "10"
      },
      "timeout": 60000
    },
    "sentry": {
      "type": "http",
      "url": "https://mcp.sentry.dev/mcp"
    }
  }
}

Для БД бери користувача лише з правом читання. Sentry без заголовків авторизується через OAuth: /mcp або claude mcp login sentry.

Підстановка змінних середовища у .mcp.json

  • Синтаксис: ${VAR} та ${VAR:-значення за замовчуванням}.
  • Підставляється в полях command, args, env, url, headers.
  • Якщо змінна не задана й немає :-default, конфіг усе одно завантажується: Claude Code показує попередження у виводі claude mcp list і лишає текст ${VAR} як є.
  • У claude mcp list, claude mcp get і деталях /mcp (v2.1.268+) посилання показуються за іменем, а не розкритим значенням.
  • CLAUDE_PROJECT_DIR виставляється в оточенні сервера, а не Claude Code, тому в command/args поза плагінами пиши ${CLAUDE_PROJECT_DIR:-.}. У плагінах ${CLAUDE_PROJECT_DIR} підставляється напряму.
Облікові змінні читаються порожніми

У url і headers віддалених серверів Claude Code читає облікові змінні як порожні: ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, AWS_BEARER_TOKEN_BEDROCK, HTTPS_PROXY, NPM_TOKEN тощо — навіть якщо вони задані, а :-default для них ігнорується. Так репозиторій або плагін не можуть вислати ваші облікові дані на чужий сервер. Результат — Bearer без токена та 401. Лайфхак: скопіюй значення у змінну зі своїм іменем (наприклад GITLAB_TOKEN) і посилайся на неї. Ім’я поза списком (API_KEY) підставляється як звичайно.

Поля запису сервера

ПолеДляЩо робить
typeусіhttp | sse | stdio | ws
command, args, envstdioкоманда запуску, її аргументи, змінні оточення процесу
urlhttp / sse / wsадреса ендпоінта (для remote обов’язково)
headershttp / sse / wsстатичні HTTP-заголовки
headersHelperhttp / sse / wsкоманда, що друкує JSON-об’єкт заголовків (див. нижче)
timeoutусітайм-аут інструментів цього сервера в мс; перекриває MCP_TOOL_TIMEOUT
alwaysLoadусіtrue — інструменти завжди в контексті (без tool search); false — завжди відкладені (v2.1.287+)
oauthhttp / sseоб’єкт clientId, callbackPort, authServerMetadataUrl, scopes

Схвалення project-серверів та довіра до папки

  • Сервери з .mcp.json в інтерактивній сесії потребують схвалення (діалог). Скинути вибір — claude mcp reset-project-choices.
  • У claude -p, Agent SDK та cloud-сесіях діалогу немає, тому project-сервери завантажуються без запиту. Щоб тримати їх осторонь: disabledMcpjsonServers (працює в усіх режимах), --setting-sources без project, або --strict-mcp-config (тільки сервери з --mcp-config).
  • Клонований репозиторій не може схвалити сам себе: enableAllProjectMcpServers/enabledMcpjsonServers
  • з закоміченого .claude/settings.json ігноруються, доки ти не прийняв діалог довіри до папки (діє й для claude mcp list / get з v2.1.196). Схвалення з user settings, managed та --settings працюють і в недовіреній папці.
  • /mcp-перемикачі «вимкнути сервер» пишуть per-project у ~/.claude.json списки disabledMcpServers (вимкнути звичайний сервер, плагінний, claude.ai-конектор) і enabledMcpServers (увімкнути вбудований сервер, вимкнений за замовчуванням, напр. computer-use). Це не ті самі ключі, що *Mcpjson*.

Авторизація віддалених серверів

  • OAuth 2.0 для HTTP/SSE: відповідь 401/403 позначає сервер у /mcp як такий, що потребує входу. Увійти — /mcp або claude mcp login <name> [--no-browser]. Токени зберігаються безпечно й оновлюються автоматично; «Clear authentication» у /mcp відкликає доступ.
  • Якщо ти сам задав заголовок Authorization (у headers чи через headersHelper) і сервер його відхилив, Claude Code повідомить про помилку з’єднання й не перейде на OAuth.
  • --callback-port фіксує redirect URI http://localhost:PORT/callback (також змінна MCP_OAUTH_CALLBACK_PORT).
  • Немає Dynamic Client Registration — передай --client-id і --client-secret (маскований запит або змінна MCP_CLIENT_SECRET). Секрет можна задати лише при додаванні сервера; зберігається в keychain (macOS) або credentials-файлі. Підтримується також CIMD.
  • oauth.authServerMetadataUrl (лише https://) перекриває стандартне виявлення метаданих; oauth.scopes — рядок scope через пробіл, що фіксує потрібний набір (спосіб обмежити сервер підмножиною прав, схваленою службою безпеки).
  • У claude -p сам OAuth пройти не можна: потрібен попередній вхід через /mcp чи claude mcp login.
.mcp.json
{
  "mcpServers": {
    "internal-api": {
      "type": "http",
      "url": "https://mcp.internal.acme.example",
      "headersHelper": "/opt/bin/get-mcp-auth-headers.sh"
    },
    "slack": {
      "type": "http",
      "url": "https://mcp.slack.com/mcp",
      "oauth": { "scopes": "channels:read chat:write search:read" }
    }
  }
}

headersHelper — команда, яка друкує у stdout JSON-об’єкт рядкових заголовків. Запускається через shell, тайм-аут 10 с, на кожне підключення/перепідключення та після 401/403; результат не кешується. Динамічні заголовки перекривають статичні. Змінні середовища для скрипта: CLAUDE_CODE_MCP_SERVER_NAME, CLAUDE_CODE_MCP_SERVER_URL, CLAUDE_PLUGIN_ROOT (лише для серверів плагіна). Для серверів із project .mcp.json та плагінів змінні з «обліковими» іменами (TOKEN, SECRET, KEY, AUTH …) з оточення прибираються; для project/local-серверів скрипт виконується лише після діалогу довіри до папки.

Конектори claude.ai

  • Якщо ти увійшов через підписку claude.ai, конектори з claude.ai/customize/connectors автоматично доступні в Claude Code й у /mcp.
  • Вони не завантажуються, якщо активні ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN чи apiKeyHelper, сторонній провайдер (Bedrock, Vertex …) або токен із claude setup-token.
  • Сервер, доданий у Claude Code, має пріоритет над конектором з тим самим URL. Вимкнути всі — disableClaudeAiConnectors або ENABLE_CLAUDEAI_MCP_SERVERS=false; поодинці — deniedMcpServers або перемикач у /mcp.
  • Організація може задати для інструментів конектора режими ask (запит на кожен виклик, навіть в bypassPermissions; у dontAsk — відмова) та blocked (інструмент для Claude прихований).

Settings-ключі MCP

Ці ключі діють у файлах settings (settings.json); конфігурація самих серверів — у .mcp.json / ~/.claude.json / managed-mcp.json.

allowedMcpServersarrayдіє з managed
Що робить

Whitelist MCP серверів. Кожен запис — об’єкт з одним ключем: serverName, serverUrl (з * wildcard) або serverCommand (точний масив). Denylist має пріоритет.

Що зміниться

Не задано = дозволені всі сервери. Порожній [] = не дозволено жоден, крім серверів, що пропускають allowlist (managedMcpServers, записи managed-mcp.json без ${VAR}, вбудовані: Claude in Chrome, ide). Без allowManagedMcpServersOnly allowlist-и з усіх рівнів зливаються, тож користувач може розширити ваш список власним.

settings.json
"allowedMcpServers": [
  { "serverName": "github" },
  { "serverName": "trello" },
  { "serverUrl": "https://*.company.com/*" },
  { "serverCommand": ["npx", "-y", "@company/mcp-server"] }
]
⚠ Щойно є хоч один serverUrl/serverCommand — serverName більше не пропускає сервери цього типу
⚠ serverName — не засіб безпеки: це просто мітка, яку користувач дає серверу, і будь-який сервер можна назвати github. У allowlist serverName — лише літери, цифри, - та _. Для реального контролю використовуй serverUrl / serverCommand.
serverUrl: * — wildcard, можна навіть замість схеми; регістр хоста не важливий, шлях чутливий до регістру. Хост, записаний повністю й без порту, збігається лише з портом за замовчуванням (443/80); хост із * — з будь-яким портом; :* — будь-який порт. serverCommand — точний масив: кожен аргумент по порядку; env не порівнюється. У serverUrl / serverCommand розкриваються ${VAR} з «закріпленого» оточення (v2.1.219+), тому для enforcement краще писати літеральні значення.
Порядок перевірки: злити списки з усіх областей, потім denylist (завжди перемагає), потім allowlist. Віддалений сервер проходить лише за serverUrl (serverName рахується, тільки якщо в списку немає жодного serverUrl); stdio — за serverCommand. Allowlist не поширюється на managed-mcp.json (з 2.1.259), крім записів із ${VAR}. Обидва списки фільтрують і сервери з --mcp-config (крім type: "sdk").
deniedMcpServersarray
Що робить

Blacklist — має пріоритет над allowedMcpServers. Зливається з усіх рівнів. У serverName можна вказати і назву claude.ai-конектора.

Що зміниться

Блокує потенційно небезпечні MCP сервери з доступом до файлів або інтернету що можуть витікати дані з проєкту.

settings.json
"deniedMcpServers": [
  { "serverName": "filesystem" },
  { "serverUrl": "https://untrusted-mcp.io/*" },
  { "serverName": "claude.ai Slack" }
]
У denylist serverName — будь-який непорожній рядок без пробілів на краях, зокрема з пробілами: так блокується конектор claude.ai за назвою ("claude.ai Slack"). Назва конектора може змінитися або отримати суфікс (N), тому надійніше — serverUrl.
Denylist застосовується до всіх серверів, включно з managed-mcp.json, managedMcpServers і --mcp-config; власний denylist користувача зливається з вашим — він може заблокувати managed-сервер лише для себе. Ніщо не перекриває збіг із denylist.
enabledMcpjsonServers / disabledMcpjsonServersarray
Що робить

Керує схваленням серверів з .mcp.json проєкту — дозволяє або забороняє без зміни самого файлу репо. enableAllProjectMcpServers схвалює всі одразу (за замовчуванням не задано — питати про кожен). При конфлікті виграє заборона.

Що зміниться

Якщо .mcp.json містить сервери що не потрібні всій команді — вибірково увімкни тільки потрібні без редагування файлу.

settings.json
"enabledMcpjsonServers": ["github", "trello"],
"disabledMcpjsonServers": ["filesystem"],
"enableAllProjectMcpServers": false
// false = не авто-схвалювати всі MCP з .mcp.json
// у недовіреній папці true діє з user, managed та --settings (не з project-файлу)
Діалог схвалення сам пише ці ключі в .claude/settings.local.json. Закомічені в репозиторій enableAllProjectMcpServers/enabledMcpjsonServers ігноруються, доки папка не стала довіреною — клонований репо не може схвалити власні сервери. disabledMcpjsonServers з будь-якого файлу працює завжди й виграє над обома.
⚠ У claude -p, SDK та cloud-сесіях діалогу схвалення немає — project-сервери завантажуються без запиту, якщо їх не відхилено через disabledMcpjsonServers.
allowManagedMcpServersOnly / managedMcpServersboolean / objectmanaged only
Що робить

allowManagedMcpServersOnly: true робить allowlist авторитетним: враховується лише allowedMcpServers із managed-джерела (потрібен саме там; з v2.1.273 замок і список читаються з усіх адмін-джерел). Не плутати з allowManagedPermissionRulesOnly — той блокує лише permission rules. managedMcpServers (v2.1.259+) — об’єкт «ім’я сервера → запис»: роздати віддалені HTTP/SSE сервери всім користувачам, не забираючи в них власні.

Що зміниться

true = розробники можуть підключити лише те, що дозволяє managed allowlist. Denylist при цьому все одно зливається з усіх рівнів. Записи managedMcpServers не потребують allowlist, мають пріоритет над серверами local/project/user, плагінів і конекторів (при збігу імені з managed-mcp.json виграє файл), їх не можна видалити (лише вимкнути для себе в /mcp, розділ Managed MCPs) і вони лишаються при strictPluginOnlyCustomization.

settings.json
"allowManagedMcpServersOnly": true,
"allowedMcpServers": [
  { "serverUrl": "https://mcp.sentry.dev/*" },
  { "serverCommand": ["npx", "-y", "@bytebase/dbhub", "--dsn", "postgresql://readonly@db.acme.example:5432/analytics"] }
],
"managedMcpServers": {
  "gitlab": {
    "type": "http",
    "url": "https://gitlab.acme.example/api/v4/mcp"  // плейсхолдер — підстав свій ендпоінт
  }
}
Запис managedMcpServers завантажується, лише якщо: type = http/sse; url — https:// (навіть localhost по http:// не можна); немає command, args, env, headersHelper; ніде немає ${VAR} (змінні не розкриваються); ім’я містить лише літери, цифри, -, _. Інакше запис відкидається, а причину видно в /status.
⚠ Усі, хто читає managed settings, бачать значення headers — клади туди лише облікові дані, видані всій аудиторії, або дай кожному користувачу увійти через OAuth. Ключ читається лише з managed-джерел (з user/project/local відкидається з попередженням). Desktop-ключ з такою самою назвою має інший формат (масив) — не копіюй.
disableClaudeAiConnectorsboolean
Що робить

Вимикає конектори claude.ai, які Claude Code підтягує сам (сервери, додані у claude.ai/customize/connectors).

Що зміниться

Конектори не з’являються в /mcp і не підключаються. Семантика «будь-яке джерело true»: true у будь-якому файлі (user, managed, навіть project) перемагає; false у project не поверне те, що вимкнув user чи політика. Не зачіпає сервери з --mcp-config.

settings.json
"disableClaudeAiConnectors": true
Змінна середовища ENABLE_CLAUDEAI_MCP_SERVERS=false робить те саме на одну сесію; якщо хоч одне з двох вимикає конектори, інше не може їх увімкнути. Діє лише для конекторів, які Claude Code отримує сам (термінал, VS Code, JetBrains, Agent SDK), але не для cloud-сесій і desktop-сесій — там конектори приходять інакше.
allowAllClaudeAiMcpsbooleanmanaged only
Що робить

Дозволяє завантажувати конектори claude.ai поруч із розгорнутим managed-mcp.json. За замовчуванням false.

Що зміниться

Без цього ключа managed-mcp.json бере ексклюзивний контроль і приховує конектори claude.ai. З true вони завантажуються як без файлу (allow/deny-списки до них усе одно застосовуються; сервери плагінів лишаються заблокованими).

settings.json
"allowAllClaudeAiMcps": true
Читається лише з адмін-джерел (server-managed, MDM plist / HKLM, системний managed-settings.json); у user/project не діє.
allowClaudeInChromeWithManagedMcpbooleanmanaged only
Що робить

Дозволяє вбудованому серверу Claude in Chrome працювати поруч із розгорнутим managed-mcp.json (v2.1.282+).

Що зміниться

За замовчуванням при managed-mcp.json Claude Code блокує Claude in Chrome у терміналі, а claude --chrome завершується з помилкою, що називає цей ключ. З true розширення працює. Запис deniedMcpServers для claude-in-chrome усе одно блокує.

settings.json
"allowClaudeInChromeWithManagedMcp": true
⚠ Читається лише з файлів/реєстру самого пристрою (plist, HKLM, системний файл), а не з server-managed settings і не з HKCU.
disabledMcpServers / enabledMcpServersarray
Що робить

Per-project списки, які Claude Code сам веде у ~/.claude.json, коли ти вмикаєш/вимикаєш сервер перемикачем у /mcp. disabledMcpServers — opt-out для звичайних серверів, плагінних, managed-серверів, конекторів claude.ai (за display-іменем, напр. "claude.ai Slack") та вбудованих серверів, увімкнених за замовчуванням. enabledMcpServers — opt-in для вбудованих серверів, вимкнених за замовчуванням (напр. computer-use).

Що зміниться

Сервер із disabledMcpServers не підключається, але лишається в конфігурації й у /mcp (позначений вимкненим). Для кожного сервера діє рівно один список: звичайний сервер у enabledMcpServers або default-off вбудований у disabledMcpServers ігноруються.

~/.claude.json
"projects": {
  "/Users/me/work/shop": {
    "disabledMcpServers": ["sentry", "claude.ai Slack"],
    "enabledMcpServers": ["computer-use"]
  }
}
Це не ключі settings.json і не пов’язані з enabledMcpjsonServers / disabledMcpjsonServers (вони керують лише схваленням серверів з .mcp.json).

Шаблони керування MCP в організації

МетаЩо налаштувати
Вимкнути MCP повністюmanaged-mcp.json з {"mcpServers": {}}. claude mcp add тоді падає з помилкою політики. Не задавай managedMcpServers та allowAllClaudeAiMcps: сервери з них продовжать завантажуватися навіть при порожньому наборі.
Фіксований набір серверівmanaged-mcp.json із потрібними серверами: користувачі не можуть додавати/міняти інші, у тому числі плагінні й --mcp-config (з ним Claude Code на робочій станції завершується з помилкою).
Видати сервери всім, але не забирати власніmanagedMcpServers у managed settings (v2.1.259+).
Затверджений каталогallowedMcpServers + allowManagedMcpServersOnly: true. Вбудованого реєстру серверів у Claude Code немає — розповсюджуй команди claude mcp add у wiki або видавай сервери плагінами через корпоративний marketplace.
Лише сервери з плагінівstrictPluginOnlyCustomization зі значенням "mcp" у масиві: ~/.claude.json та .mcp.json ігноруються, плагінні й managed-сервери лишаються.
М’який allowlistallowedMcpServers без allowManagedMcpServersOnly: користувачі можуть його розширити.
Тільки чорний списокdeniedMcpServers.

Перевірка на керованій машині: claude mcp list показує лише сервери з managed-mcp.json (плюс managedMcpServers); claude mcp add --transport http test https://example.com/mcp має впасти з «enterprise MCP configuration is active …».

Важлива зміна v2.1.259

До v2.1.259 кожен сервер з managed-mcp.json мав проходити allowlist. Тепер allowlist до них не застосовується (крім записів з ${VAR}), тож сервери, які ти раніше «відсікав» allowlist-ом, почнуть завантажуватися без повідомлення — додай для них записи в deniedMcpServers.

Ліміти виводу MCP та змінні середовища

ПараметрЗначенняЩо робить
Попередження10 000 токенівClaude Code показує попередження, якщо вивід інструмента перевищив поріг.
MAX_MCP_OUTPUT_TOKENSза замовчуванням 25 000Максимум токенів у відповіді MCP-інструмента. Успішний результат (без зображень) понад ліміт зберігається у файл у теці tool-results сесії (під ~/.claude/projects/), а в розмову потрапляє шлях до файлу. Зображення цим лімітом обмежуються завжди.
Ліміт символів тексту50 000 символівУспішний текстовий результат довший за це зберігається у файл незалежно від токенів і від MAX_MCP_OUTPUT_TOKENS. Автор сервера може підняти ліміт для свого інструмента через _meta["anthropic/maxResultSizeChars"] (стеля 500 000).
Відповідь HTTP/SSE16 МБClaude Code перестає читати відповідь (чи подію потоку) після 16 МБ після розпакування; запит завершується помилкою.
Текст помилки≈ 11 000 символівДовший текст обрізається посередині: лишаються перші й останні 5 000 символів.
MCP_TIMEOUTза замовчуванням 30 000 мсТайм-аут запуску сервера.
MCP_TOOL_TIMEOUTза замовчуванням 100 000 000 мс (≈ 28 год)Тайм-аут виконання інструмента; для HTTP/SSE кожен запит окремо обмежений 60 с, поки значення (або timeout сервера) не більше 60 000. Поле timeout у конфігу сервера перекриває змінну.
CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUTмс; 0 = вимкнутиСкасувати виклик, якщо сервер не відповідає і не шле progress. Типові значення: 300 000 (мережеві) і 1 800 000 (stdio).
CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSза замовчуванням 120 000Виклик MCP-інструмента в основній розмові, що триває довше, стає фоновою задачею (v2.1.212+); 0 вимикає.
MCP_CONNECTION_NONBLOCKING0 = чекатиЗа замовчуванням запуск не чекає на підключення серверів; 0 змушує чекати перед першим запитом. Сервери з alwaysLoad: true чекають завжди.
MCP_CONNECT_TIMEOUT_MSза замовчуванням 5 000Скільки блокуючий старт чекає на пачку підключень.
MCP_SERVER_CONNECTION_BATCH_SIZE / MCP_REMOTE_SERVER_CONNECTION_BATCH_SIZE3 / 20Скільки локальних (stdio) / віддалених серверів підключати паралельно на старті.
MCP_DISCOVERY_CACHE1 / 0Кеш списку інструментів віддалених серверів (статус «cached», підключення при першому виклику). Типово вимкнений, якщо його не вмикає поступовий rollout.
MCP_SDK_GENERATIONv1 | v2Обрати MCP-клієнт: на TypeScript SDK 1.x чи 2.0.
MCP_PROTOCOL_NEGOTIATIONauto | legacyЛише для v2: чи пробувати протокол 2026-07-28.
MCP_CLIENT_SECRETрядокOAuth client secret без інтерактивного запиту при claude mcp add --client-secret.
MCP_OAUTH_CALLBACK_PORTпортФіксований порт OAuth-callback (альтернатива --callback-port).
ENABLE_CLAUDEAI_MCP_SERVERSfalseНе підтягувати конектори claude.ai.
CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTHза замовчуванням 2 048 символівОбмеження довжини опису кожного інструмента й інструкцій кожного сервера (v2.1.280+).
CLAUDE_CODE_MCP_ALLOWLIST_ENV1stdio-сервери запускаються лише з безпечним базовим оточенням + власним env, а не з усім середовищем оболонки.

Змінні можна задати в оболонці або в блоці env settings. Приклад: export MAX_MCP_OUTPUT_TOKENS=50000 перед запуском claude.

Tool search: відкладене завантаження інструментів

За замовчуванням визначення MCP-інструментів відкладаються: на старті в контекст потрапляють лише назви інструментів та інструкції серверів, повні схеми підтягуються за потреби (інструмент ToolSearch). Тому додавання серверів майже не з’їдає контекст. Потрібна модель з підтримкою tool_reference (Sonnet/Haiku/Opus 4.5 і новіші).

ENABLE_TOOL_SEARCHПоведінка
не заданоУсі MCP-інструменти відкладені. Автоматично вимикається (усе вантажиться наперед) при нестандартному ANTHROPIC_BASE_URL, на моделях раніше 4.5 у Google Cloud Agent Platform та на Foundry, розміщеному в Azure.
trueЗавжди відкладати (і слати beta-заголовок через проксі; на проксі без підтримки tool_reference запити падатимуть).
autoПоріг 10% контексту: поки визначення займають менше — вантажаться наперед, від 10% — відкладаються.
auto:NТе саме з власним порогом у відсотках (0–100), напр. auto:5.
falseУсі інструменти завантажуються наперед.
  • Інструмент можна вимкнути політикою: permissions.deny: ["ToolSearch"].
  • CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS тримає tool search вимкненим, і перекрити це змінною ENABLE_TOOL_SEARCH неможливо; організація може залишити його ввімкненим через managed settings (v2.1.227+).
  • На сервер: "alwaysLoad": true — інструменти завжди в контексті (старт чекає на сервер до 5 с); "alwaysLoad": false — завжди відкладені, навіть якщо автор позначив інструмент _meta["anthropic/alwaysLoad"] (v2.1.287+). На рівні інструмента автор сервера може виставити _meta["anthropic/alwaysLoad"].

Імена інструментів та дозволи

  • Інструмент: mcp__<server>__<tool>; для плагінного сервера — mcp__plugin_<plugin>_<server>__<tool>. Правила permissions приймають і mcp__server, і mcp__server__*.
  • Правила з параметрами (дужки) для MCP-інструментів працюють лише через --disallowedTools; settings-файли пропускають такі правила.
  • У matcher хуків потрібно .*: mcp__memory нічого не збігається, а mcp__memory__.* — так.
  • Сервер може вимагати підтвердження кожного виклику: _meta["anthropic/requiresUserInteraction"]: true у tools/list — запит показується в будь-якому режимі (навіть bypassPermissions, а у dontAsk виклик відхиляється).
  • Сервер може запитувати введення у користувача посеред задачі (elicitation): діалог у режимі форми або URL; автовідповідь — хук Elicitation.
10

plugins

Розширення Claude Code через систему плагінів і маркетплейси

#

Плагін — це тека з компонентами, які Claude Code вантажує разом: скіли, агенти, хуки, MCP- та LSP-сервери, теми, монітори. Плагіни поширюються через marketplace — каталог (marketplace.json) у git-репозиторії, за URL або в локальній теці. Нижче — будова плагіна та marketplace, ключі settings, команди CLI і готовий рецепт для команди.

Що може містити плагін та структура теки

КомпонентТипове розташуванняНотатки
Маніфест.claude-plugin/plugin.jsonНеобов’язковий. Без нього компоненти беруться зі стандартних місць, ім’я — з marketplace або з назви теки.
Скілиskills/<name>/SKILL.mdОсновний спосіб додавати команди. Плагін із SKILL.md у корені (без skills/) завантажується як один скіл.
Командиcommands/*.mdПлоскі Markdown-файли; для нового краще використовувати скіли.
Агентиagents/*.mdПідтеки входять до імені агента.
Хукиhooks/hooks.jsonФормат як у hooks у settings.
MCP-сервери.mcp.jsonАбо вбудовано в mcpServers у plugin.json. Зареєстроване ім’я сервера: plugin:<plugin>:<server>.
LSP-сервери.lsp.jsonПідсвітка/діагностика коду.
Стилі виводуoutput-styles/—
Workflowworkflows/JS-файли воркфлоу.
Темиthemes/JSON-файли тем.
Моніториmonitors/monitors.jsonПрацюють лише в інтерактивних сесіях і не на Bedrock / Vertex / Foundry.
Виконувані файлиbin/Додаються в PATH Bash-інструмента, поки плагін увімкнений.
Settings плагінаsettings.jsonДіють лише ключі agent та subagentStatusLine.
структура
deploy-tools/
├── .claude-plugin/
│   └── plugin.json
├── skills/
│   └── deploy/
│       └── SKILL.md
├── agents/
│   └── reviewer.md
├── hooks/
│   └── hooks.json
├── bin/
│   └── deploy-tool
├── scripts/
│   └── format.sh
├── settings.json
├── .mcp.json
└── .lsp.json
Правила

Усі компоненти лежать у корені плагіна, а не всередині .claude-plugin/ (там лише plugin.json). CLAUDE.md у корені плагіна не завантажується в контекст (валідатор попереджає) — інструкції кладіть у скіл. Компоненти мають простір імен за іменем плагіна: скіл /my-plugin:review, агент my-plugin:reviewer.

plugin.json: приклад

.claude-plugin/plugin.json
{
  "name": "django-review",
  "displayName": "Django Review",
  "version": "1.2.0",
  "description": "Рев’ю Django-коду: міграції, ORM-запити, DRF-серіалізатори",
  "author": { "name": "Acme Platform Team", "email": "platform@acme.example" },
  "license": "MIT",
  "keywords": ["django", "review"],
  "mcpServers": {
    "gitlab": {
      "type": "http",
      "url": "${user_config.gitlab_url}/api/v4/mcp",
      "headers": { "Authorization": "Bearer ${user_config.gitlab_token}" }
    }
  },
  "userConfig": {
    "gitlab_url": {
      "type": "string",
      "title": "GitLab URL",
      "description": "Адреса інстансу GitLab",
      "default": "https://gitlab.acme.example"
    },
    "gitlab_token": {
      "type": "string",
      "title": "GitLab token",
      "description": "Personal access token з правом read_api",
      "sensitive": true,
      "required": true
    }
  }
}

Адреса ${user_config.gitlab_url}/api/v4/mcp — плейсхолдер для GitLab MCP-ендпоінта; підстав реальний шлях свого інстансу.

Перевірка: claude plugin validate ./django-review (з --strict попередження стають помилками — зручно для CI). Невідомий ключ верхнього рівня відкидається з попередженням; невідомий ключ усередині userConfig / channels / lspServers / monitors — помилка, і плагін не завантажується.

Поля plugin.json

ПолеТипЩо робить
namestring, обов’язковеІдентифікатор у kebab-case, без пробілів, @ та :. Усі компоненти отримують його як префікс. Імена з префіксами claude-, anthropic-, anthropics-, cc-plugin- — помилка claude plugin validate (і відмова init/tag).
displayNamestringНазва в UI замість name; не використовується для простору імен і пошуку. displayName запису marketplace має пріоритет.
versionstringФіксує версію: користувачі лишаються на ній, доки не змінити. Не перевіряється як semver.
description, author, homepage, repository, license, keywordsstring / object / arrayМетадані для UI та marketplace; author = {name, email, url}, license — SPDX-ідентифікатор. homepage має бути валідним URL, інакше плагін не завантажиться.
metadataobjectДовільні ваші дані; Claude Code не читає (v2.1.222+).
icon, documentationUrl, supportUrl, privacyPolicyUrl, termsOfServiceUrlstringДля лістингу в каталозі Anthropic; Claude Code ігнорує. Задаються лише в plugin.json.
defaultEnabledboolean (true)Чи вмикається плагін, якщо користувач не задав у enabledPlugins. Значення в запису marketplace перекриває.
dependenciesarrayПлагіни, які мають бути ввімкнені: "name", "name@marketplace" або об’єкт {name, marketplace, version}.
settingsobjectSettings при увімкненому плагіні; діють лише agent і subagentStatusLine. settings.json у корені має пріоритет.
userConfigobjectЗначення, які Claude Code запитує при вмиканні (див. нижче).
channelsarrayКанали повідомлень, кожен прив’язаний до MCP-сервера плагіна.
typespath.d.ts для «модів» (плагінів із обробниками подій).
skillspath | arrayДодаткові теки скілів — додаються до стандартного skills/. "." = корінь плагіна.
commandspath | array | objectЗамінює стандартну commands/. Об’єкт: ключ — ім’я команди, значення — source або content (+ description, argumentHint, model, allowedTools).
agentspath | arrayФайли .md (теки не приймаються); замінює agents/.
hookspath | object | arrayШлях до .json або inline-конфіг; зливається з hooks/hooks.json.
mcpServerspath | object | array.json, пакети .mcpb/.dxt або inline-сервери; зливається з .mcp.json (пізніше ім’я замінює раніше).
lspServerspath | object | arrayЯк mcpServers, для .lsp.json.
outputStyles, workflowspath | arrayЗамінюють стандартні output-styles/ і workflows/.
experimental.themes, experimental.monitors, experimental.evalspath | arrayТеми й монітори (замінюють стандартні themes/ і monitors/monitors.json) та тека eval-кейсів (за замовчуванням evals/).

Усі шляхи компонентів відносні до кореня плагіна, починаються з ./, не виходять за корінь (без ..) і мають існувати. Якщо ключ замінює стандартну теку, а тека існує, claude plugin list покаже попередження «Default … folder is ignored».

userConfig та змінні середовища плагіна

Поле userConfigОбов’язковеОпис
typeтакstring, number, boolean, directory, file
title, descriptionтакПідпис і підказка в діалозі конфігурації
required, defaultніНе приймати порожнє значення / значення за замовчуванням
optionsніДля string: фіксований список (вибір у /config; v2.1.271+; якщо оголошено, старіші клієнти плагін не завантажать)
multiple, sensitive, min/maxніМасив рядків; маскування й зберігання в сховищі секретів; межі для number
  • Значення посилаються як ${user_config.KEY} (у конфігах MCP/LSP, exec-form хуках, змісті скілів і агентів — секретні там стають плейсхолдером) та як змінна CLAUDE_PLUGIN_OPTION_<KEY> у процесах хуків. Не дозволено в shell-form хуках, командах моніторів і headersHelper (там — помилка).
  • Несекретні значення зберігаються в pluginConfigs (user/managed), секретні — у системному keychain (або ~/.claude/.credentials.json).
  • ${CLAUDE_PLUGIN_ROOT} — абсолютний шлях встановленої версії плагіна (змінюється при оновленні, стан тут не зберігай).
  • ${CLAUDE_PLUGIN_DATA} — ~/.claude/plugins/data/<id>/: зберігається між оновленнями (node_modules, кеші); видаляється при видаленні останньої інсталяції, якщо не --keep-data.
  • ${CLAUDE_PROJECT_DIR} — корінь проєкту. Ці змінні не експортуються в команди, які Claude виконує через Bash-інструмент.

marketplace.json

Файл лежить у .claude-plugin/marketplace.json кореня каталогу; відносні шляхи плагінів рахуються від цього кореня (не від .claude-plugin/). Якщо файл лежить деінде, користувачі мають оголосити marketplace в extraKnownMarketplaces із path у джерелі.

.claude-plugin/marketplace.json
{
  "name": "acme-plugins",
  "owner": { "name": "Acme Platform Team", "email": "platform@acme.example" },
  "description": "Плагіни команди Django + Vue",
  "metadata": { "pluginRoot": "./plugins" },
  "plugins": [
    {
      "name": "django-review",
      "source": "django-review",
      "description": "Рев’ю Django-коду",
      "version": "1.2.0",
      "category": "code-review",
      "tags": ["django", "python"]
    },
    {
      "name": "vue-tools",
      "source": {
        "source": "git-subdir",
        "url": "https://gitlab.acme.example/platform/claude-tools.git",
        "path": "plugins/vue-tools",
        "ref": "v0.4.0"
      }
    },
    {
      "name": "deploy-helper",
      "source": {
        "source": "url",
        "url": "https://gitlab.acme.example/platform/deploy-helper.git",
        "ref": "main"
      }
    }
  ]
}

Тут "source": "django-review" — «голе» ім’я, що розкривається в ./plugins/django-review завдяки metadata.pluginRoot (v2.1.239+).

Поле верхнього рівняОпис
nameобов’язкове. Літери, цифри, ., _, -; користувачі пишуть його після @ (django-review@acme-plugins). Один користувач — один marketplace з цим іменем.
ownerобов’язкове: name, необов’язково email, url
pluginsобов’язкове: масив записів; кожен запис валідується окремо
description, version, $schemaметадані; metadata.description/metadata.version — альтернатива
metadata.pluginRootтека, в якій розкриваються «голі» імена джерел
forceRemoveDeletedPluginstrue — плагін, видалений зі списку, видаляється й на машинах користувачів
allowCrossMarketplaceDependenciesOnімена marketplace, плагіни яких можуть бути залежностями
renamesмапа «старе ім’я → нове» (або null для видаленого плагіна)
Зарезервовані імена marketplace

Не можна називати marketplace так, як офіційні: claude-plugins-official, claude-code-plugins, anthropic-plugins, claude-community тощо (резерв знімається лише для репозиторіїв під github.com/anthropics/), іменами-імітаціями, префіксом claudeai- (marketplace на claude.ai) та системними inline, builtin, skills-dir, synced, npm, github тощо.

Запис плагіна у marketplace: поля та джерела

Поле записуОпис
name, sourceобов’язкові. name — те, що вводять до @ при встановленні.
description, version, category, tagsкаталог і пошук. Якщо version є й у plugin.json — виграє plugin.json (валідатор попереджає).
stricttrue за замовчуванням: plugin.json — авторитет, компоненти запису (commands, agents, skills, hooks, outputStyles, themes) додаються до нього (hooks — замінюють по подіях). false + компоненти і в plugin.json, і в записі = конфлікт, плагін не завантажиться.
relevance, dependencies, defaultEnabled, displayName, metadataпідказки для рекомендацій, залежності, увімкнення за замовчуванням (запис перекриває plugin.json), назва в UI
headers, headersHelperзаголовки для завантаження архіву (v2.1.238+); headersHelper вимагає "strict": false
будь-яке поле plugin.jsonкрім полів лістингу каталогу. Якщо в плагіна немає власного plugin.json — запис і є маніфест.
Тип джерела плагінаПоляНотатки
Відносний шлях"./plugins/x"Тека всередині marketplace. Лише для джерел github / git / file / directory; для marketplace типу url шляхи не розкриваються.
githubrepo, ref, shaРепозиторій owner/repo.
urlurl, ref, shaБудь-який git-репозиторій за повним URL (GitLab, Azure DevOps …); скорочення owner/repo не підтримується.
git-subdirurl, path, ref, shaОдна тека монорепо (sparse checkout, partial clone).
npmpackage, version, registryПакет npm; скрипти встановлення не виконуються.
archiveurl, sha256zip за HTTPS (v2.1.224+); якщо задано sha256 — розбіжність відхиляється.
commandcommand, timeout, modeКаталог, який друкує команда на машині користувача (v2.1.229+). Користувач бачить команду і підтверджує її. Блокується disableCommandPluginSources.

ref — гілка чи тег; sha — повний 40-символьний SHA коміту (якщо задано обидва, береться sha). Для production-плагінів зі стороннього джерела фіксуй sha.

Джерела marketplace (куди вказує extraKnownMarketplaces)

ТипПоляЩо вводиш у marketplace add
githubrepo, ref, path, sparsePathsowner/repo, owner/repo@ref або owner/repo#ref
giturl, ref, path, sparsePathsuser@host:path або https-URL, що закінчується на .git / містить /_git/ / веде на github.com чи gitlab.com
urlurl, headers, headersHelperбудь-який інший http(s)-URL — це пряме посилання на marketplace.json (завантажується лише він)
file / directorypathшлях до .json-файлу / теки
settingsname, plugins, ownerinline-каталог просто в settings; лише об’єктні джерела плагінів; name має збігатися з ключем

Лише в політиках (strictKnownMarketplaces / blockedMarketplaces): hostPattern, pathPattern, skills-dir та owner/* у github.repo. Джерело npm для marketplace не реалізоване (завантаження падає з «NPM marketplace sources not yet implemented»).

Settings-ключі плагінів

Спочатку ключі, що реєструють marketplace і вмикають плагіни, потім політики адміністратора.

enabledPluginsobject
Що робить

Вмикає (true) або вимикає (false) плагіни у форматі "plugin@marketplace". Плагіни додають скіли, агентів, хуки, MCP/LSP-сервери. Без запису плагін береться зі свого defaultEnabled. Ключ пишуть для вас /plugin і claude plugin enable.

Що зміниться

Автоматично на всіх машинах плагін з’являється лише з managed enabledPlugins + managed extraKnownMarketplaces. Запис у .claude/settings.json репозиторію для плагіна із зовнішнім джерелом (GitHub, npm) нікому нічого не встановлює: кожен бачить «is enabled in project settings but isn’t installed», доки не виконає claude plugin install <name>@<marketplace> --scope project. Автоматично вантажаться лише плагіни з відносним шляхом у marketplace, зареєстрованому репозиторієм. false у managed блокує плагін на всіх рівнях і ховає його.

settings.json
"enabledPlugins": {
  "code-review@claude-plugins-official": true,
  "deploy-tools@acme-plugins": true,
  "experimental-ui@personal": false
}
Пріоритет областей: local > project > user; managed перекриває всі. Щоб вимкнути для себе плагін, увімкнений у проєкті, постав false у .claude/settings.local.json (false у ~/.claude/settings.json не допоможе). Один синхронізований із claude.ai плагін вимикається записом "<name>@synced": false.
extraKnownMarketplacesobject
Що робить

Реєструє маркетплейси за ім’ям, щоб люди, які відкрили репозиторій (або всі, до кого доходять managed settings), могли ставити плагіни. Джерела (source.source): github, git, url, file, directory, settings (inline-каталог). Необов’язкове поле autoUpdate (boolean): для claude-plugins-official і більшості офіційних маркетплейсів Anthropic за замовчуванням true, для сторонніх false. Alias — additionalMarketplaces (v2.1.232+).

Що зміниться

Новий учасник команди відкриває репозиторій — і після довіри до папки маркетплейс уже підключений (в недовіреній папці запис мовчки ігнорується, і в -p теж). Плагіни з enabledPlugins підхоплюються самі лише якщо вони в цьому маркетплейсі вказані відносним шляхом; плагін із зовнішнім джерелом кожен ставить сам (claude plugin install … --scope project). Запис з тим самим ім’ям із файлу вищого пріоритету замінює нижчий цілком — поля не зливаються (з v2.1.228).

settings.json
"extraKnownMarketplaces": {
  "acme-plugins": {
    "source": { "source": "github", "repo": "acme-corp/claude-plugins" },
    "autoUpdate": true
  },
  "gitlab-plugins": {
    "source": { "source": "git", "url": "https://gitlab.acme.example/platform/claude-plugins.git", "ref": "main" }
  }
}
Поля джерел: github — repo, ref, path, sparsePaths; git — url, ref, path, sparsePaths; url — прямий лінк на marketplace.json з headers і headersHelper (v2.1.238+); file/directory — path; settings — name (= ключ), plugins, owner. Джерело npm не реалізоване (завантаження падає). headersHelper з .claude/settings*.json теки, доданої через --add-dir, ігнорується.
⚠ Для приватного репозиторію клонування виконує git на машині користувача з наявними credential helper / SSH-ключами без запитів — доступ на читання потрібен кожному. Хости, чиї clone-URL не мають суфікса .git (наприклад AWS CodeCommit), додавай записом git у цьому ключі, а не командою marketplace add.
strictKnownMarketplacesarraymanaged only
Що робить

Allowlist джерел маркетплейсів, з яких можна встановлювати плагіни (не плагінів усередині них). [] = повне блокування, включно з офіційним маркетплейсом. Джерела: github, git, url, file, directory, hostPattern, pathPattern, settings (збіг за ім’ям і ідентичними plugins) та skills-dir. Alias — allowedMarketplaces (v2.1.232+).

Що зміниться

Розробники зможуть встановлювати плагіни тільки з корпоративного GitHub чи внутрішнього git-хоста. Співставлення точне, включно з ref і path.

settings.json
"strictKnownMarketplaces": [
  { "source": "github", "repo": "acme-corp/approved-plugins" },
  { "source": "github", "repo": "acme-corp/*" },
  { "source": "hostPattern", "hostPattern": "^git\\.acme\\.com$" },
  { "source": "skills-dir" }
]
⚠ Якщо задано будь-який allowlist (навіть порожній), плагіни зі скіл-теки (~/.claude/skills/, .claude/skills/ з .claude-plugin/plugin.json) перестають вантажитися, доки не додано { "source": "skills-dir" }. Звичайні скіли (просто SKILL.md) не страждають.
Зіставлення: для github/git мусять збігатися repo або url, ref та path (або бути відсутніми з обох боків). Запис без ref не покриває джерело з ref: "main"; запис github не покриває той самий репозиторій як git-URL; суфікс .git, слеш у кінці чи ssh:// замість https:// — інше значення. github з "repo": "acme-corp/*" — wildcard на власника (v2.1.223+; лише * замість усієї назви репо). hostPattern/pathPattern — регулярні вирази, що збігаються будь-де, тож прив’язуй їх ^…$. У JSON зворотний слеш подвоюється: "^git\\.acme\\.com$".
pluginTrustMessagestringmanaged only
Що робить

Кастомне повідомлення що додається до попередження безпеки при встановленні плагінів.

Що зміниться

Розробники бачитимуть твій текст при кожній спробі встановити плагін. Корисно для посилання на internal policy або контакт для схвалення.

settings.json
"pluginTrustMessage": "Схвалюйте тільки з корпоративного реєстру. Питання: security@company.com"
strictPluginOnlyCustomization / blockedMarketplacesboolean / arraymanaged only
Що робить

Managed-ключі. Перший: true (усі чотири типи) або масив із "skills" / "agents" / "hooks" / "mcp" — відповідні кастомізації дозволені лише з плагінів, managed-налаштувань та вбудованих (не з .claude/ і не з ~/.claude.json / .mcp.json). Другий — blocklist джерел маркетплейсів; перевіряється раніше за allowlist, тому джерело в обох списках блокується; збіг ширший, ніж в allowlist (канонізація git-URL, github блокує й еквівалентний git).

Що зміниться

Кастомізація Claude Code проходить через перевірені плагіни — не можна просто покласти скіл у ~/.claude/skills. MCP-сервери з managedMcpServers і managed-mcp.json продовжують працювати. Ключ не обмежує, які саме плагіни ставлять — поєднуй зі strictKnownMarketplaces.

settings.json
"strictPluginOnlyCustomization": ["hooks", "mcp"],
"blockedMarketplaces": [{ "source": "github", "repo": "random/plugins" }]
disableCommandPluginSourcesbooleanmanaged only
Що робить

Забороняє плагіни з джерелом типу command — коли каталог плагіна генерується командою, що виконується на машині користувача.

Що зміниться

Такі плагіни не встановлюються, не оновлюються й не завантажуються. Якщо ключ не задано, береться значення allowManagedHooksOnly. На інші типи джерел не впливає. (v2.1.229+)

settings.json
"disableCommandPluginSources": true
pluginSuggestionMarketplacesarraymanaged only
Що робить

Імена маркетплейсів, плагіни яких можуть з’являтися як контекстні підказки встановлення (у spinner-підказках та закріплені вгорі вкладки Discover в /plugin).

Що зміниться

Підказка з’являється лише якщо маркетплейс зареєстрований на машині, його ім’я є в цьому списку, а його джерело оголошене в тій самій політиці (запис extraKnownMarketplaces або allowlist). Для офіційного маркетплейсу достатньо імені. Збіг із проєктом задають через relevance у записі marketplace.

settings.json
"pluginSuggestionMarketplaces": ["acme-plugins"]
syncClaudeAiPluginsbooleanuser / local / managed
Що робить

Керує завантаженням плагінів, увімкнених для твого акаунта claude.ai, у ~/.claude/plugins/synced/; вантажаться як <name>@synced. Має сенс лише значення false (v2.1.273+).

Що зміниться

false зупиняє завантаження і припиняє вантажити вже синхронізовані (у user/managed вони ще й переміщуються в .trash). true = не задано. Один синхронізований плагін вимикають записом "<name>@synced": false в enabledPlugins. Блокування всіх джерел через strictKnownMarketplaces: [] синхронізовані плагіни не зачіпає — їх вимикає саме цей ключ.

settings.json
"syncClaudeAiPlugins": false
Діє в user, local, managed і --settings; репозиторій не може вимкнути синхронізацію за користувача. Для скілів є аналог syncClaudeAiSkills (тека ~/.claude/skills/synced/).
syncClaudeAiSkillsbooleanuser / local / managed
Що робить

Керує завантаженням скілів, увімкнених для акаунта claude.ai, у ~/.claude/skills/synced/. Має сенс лише false.

Що зміниться

false зупиняє синхронізацію й припиняє вантажити вже синхронізовані скіли (у user/managed — ще й переміщує їх у .trash). true = не задано.

settings.json
"syncClaudeAiSkills": false
Діє в user, local, managed і --settings; репозиторій вимкнути не може.
pluginConfigsobjectuser / managed
Що робить

Зберігає несекретні відповіді з діалогу userConfig плагіна, ключ — ID плагіна (name@marketplace). Claude Code пише його сам, коли заповнюєш діалог.

Що зміниться

Значення підставляються у конфіги хуків, MCP та LSP плагіна. Секретні опції сюди не потрапляють — вони йдуть у keychain macOS (або ~/.claude/.credentials.json). Проєктні та локальні записи ігноруються (репозиторій не повинен підсовувати такі значення), читається лише з user та managed.

settings.json
"pluginConfigs": {
  "deployer@acme-plugins": {
    "options": { "api_endpoint": "https://api.acme.example" }
  }
}
Вбудовані плагіни зберігають опції під суфіксом @builtin. Опцію можна задати й командою claude plugin install … --config api_endpoint=… або claude plugin configure.
disableSkillShellExecutionboolean
Що робить

Вимикає виконання inline-shell у блоках !`…` та ```! у скілах і custom-командах із user, project, plugin та additional-directory джерел.

Що зміниться

Замість виводу команди підставляється [shell command execution disabled by policy]. true у managed не можна перекрити. Вбудовані скіли та скіли з managed settings не зачіпаються.

settings.json
"disableSkillShellExecution": true
disableBundledSkillsboolean
Що робить

Вимикає скіли та workflow, що йдуть у комплекті з Claude Code. Також змінна CLAUDE_CODE_DISABLE_BUNDLED_SKILLS.

Що зміниться

Вбудовані команди на кшталт /init можна набрати, але модель їх не бачить.

settings.json
"disableBundledSkills": true
skillOverridesobject
Що робить

Ховає чи згортає скіл без редагування його SKILL.md: ключ — ім’я скіла, значення — "on", "name-only", "user-invocable-only" або "off".

Що зміниться

name-only — Claude бачить лише ім’я без опису; user-invocable-only — Claude скіл не бачить, але /name працює; off — не бачить ні Claude, ні автодоповнення. Меню /skills пише сюди в .claude/settings.local.json.

settings.json
"skillOverrides": {
  "legacy-context": "name-only",
  "deploy": "off"
}
⚠ Не діє на скіли плагінів — ними керують через /plugin.
prependPlugins / appendPluginsarrayuser / managed
Що робить

Списки plugin@marketplace керованих плагінів, чиї «моди» (обробники подій у коді плагіна) запускаються до / після усіх модів, які встановив користувач, у вказаному порядку. У managed додай sec-default@builtin, щоб зберегти вбудований захист.

Що зміниться

Ідентифікатор, указаний в обох списках, виконується як prepend. У managed пропускаються id, чий плагін не належить організації. Читається з managed, а з user — лише на машині без managed settings і без входу через Team/Enterprise; у project, local і --settings ігнорується.

settings.json
"enabledPlugins": { "acme-guard@acme-tools": true, "acme-audit@acme-tools": true },
"prependPlugins": ["acme-guard@acme-tools", "sec-default@builtin"],
"appendPlugins": ["acme-audit@acme-tools"]
channelsEnabled / allowedChannelPluginsboolean / arraymanaged only
Що робить

channelsEnabled дозволяє «канали» (плагіни, що можуть пушити повідомлення в сесію). allowedChannelPlugins замінює типовий список дозволених канальних плагінів: масив {marketplace, plugin} або рядків "plugin@marketplace" (рядкова форма — v2.1.267+, старіші версії відхиляють усе значення).

Що зміниться

Без channelsEnabled канали заблоковані на Team/Enterprise і на Console-акаунтах з managed settings; на Pro/Max і Console без managed — дозволені. allowedChannelPlugins працює лише при channelsEnabled: true.

settings.json
"channelsEnabled": true,
"allowedChannelPlugins": [
  { "marketplace": "claude-plugins-official", "plugin": "telegram" }
]

Як працюють enabledPlugins та extraKnownMarketplaces разом

  • Область: пріоритет local > project > user, а managed перекриває все. Щоб вимкнути для себе плагін, увімкнений у проєкті, постав false у .claude/settings.local.json: false у user-файлі не допоможе.
  • Managed false блокує плагін у всіх областях і ховає його з marketplace.
  • Автоматично встановлюються лише плагіни, ввімкнені в managed enabledPlugins разом із managed extraKnownMarketplaces. У репозиторії (.claude/settings.json) плагін із відносним шляхом у marketplace, зареєстрованому цим репозиторієм, завантажується сам, але плагін із зовнішнім джерелом (GitHub, npm …) ні — кожен користувач бачить «Plugin "<name>" is enabled in project settings but isn’t installed», доки не виконає claude plugin install <name>@<marketplace> --scope project.
  • extraKnownMarketplaces у файлах репозиторію враховується лише після діалогу довіри до папки (у недовіреній — тихо ігнорується, у тому числі в -p).
  • Запис із тим самим іменем marketplace з файлу вищого пріоритету замінює нижчий цілком, без злиття полів (з v2.1.228).
  • Офіційний claude-plugins-official реєструється сам при першій інтерактивній сесії; у скриптах спершу claude plugin marketplace add anthropics/claude-plugins-official. Вимкнути авто-реєстрацію — CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1.

Матриця політик плагінів

КлючЩо забезпечуєЧого не робить
strictKnownMarketplacesallowlist джерел marketplace; [] блокує все, навіть офіційнийне реєструє marketplace, не обмежує плагіни всередині дозволеного, не блокує --plugin-dir
blockedMarketplacesblocklist, перевіряється до allowlistне відключає marketplace, уже зареєстрований із джерела, що не збігається
enabledPluginstrue — примусове вмикання, false — блок у всіх областяхне встановить плагін із незареєстрованого/недозволеного marketplace
disableSideloadFlagsвідхиляє --plugin-dir, --plugin-url, --agents, plugins в SDK, не-SDK --mcp-config, CLAUDE_CODE_PLUGIN_DIRS (v2.1.193+)не обмежує .mcp.json, claude mcp add — поєднуй з allowedMcpServers
strictPluginOnlyCustomizationскіли/агенти/хуки/MCP лише з плагінів, managed і вбудованихне обмежує, які саме плагіни ставлять
pluginTrustMessageдодає ваш текст до попередження довіри в /pluginне змінює саме попередження
Обидва списки перевіряються двічі

Allow/block-списки застосовуються перед завантаженням (додавання, встановлення, оновлення, auto-update) і ще раз на старті сесії: уже встановлений плагін, чий marketplace більше не підходить, не завантажується, а /plugin показує «is not in the allowed marketplace list» або «is blocked by enterprise policy». Поки діє будь-який allowlist, плагін із marketplace, якого Claude Code не знайшов, теж не вантажиться.

Змінні середовища для плагінів

ЗміннаЩо робить
CLAUDE_CODE_PLUGIN_CACHE_DIRКоренева тека плагінів (за замовчуванням ~/.claude/plugins) — marketplace та кеш лежать у піддиректоріях. Корисна для побудови seed.
CLAUDE_CODE_PLUGIN_SEED_DIRТека(и) з уже готовими marketplace та кешем плагінів, лише для читання (розділювач : або ; на Windows). Для образів контейнерів і CI. Плагіни зі seed потрібно ще ввімкнути в enabledPlugins.
CLAUDE_CODE_SYNC_PLUGIN_INSTALL1: у -p чекати завершення встановлення плагінів до першого запиту (інакше вони ставляться у фоні). Тайм-аут — CLAUDE_CODE_SYNC_PLUGIN_INSTALL_TIMEOUT_MS.
CLAUDE_CODE_PLUGIN_DIRSТеки плагінів на сесію (як --plugin-dir), абсолютні шляхи або з ~ (v2.1.280+).
CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MSТайм-аут клонування/оновлення marketplace (за замовчуванням 120 000 мс).
CLAUDE_CODE_PLUGIN_PREFER_HTTPS1: клонувати скорочення owner/repo по HTTPS, а не SSH (CI, контейнери).
CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE1: не переклоновувати marketplace, якщо оновлення не може дістатися до remote (офлайн / airgap).
DISABLE_AUTOUPDATER / FORCE_AUTOUPDATE_PLUGINSВимкнути auto-update (разом із оновленнями самого Claude Code) / залишити авто-оновлення плагінів попри це.

Команди керування плагінами

У сесії: /plugin (вкладки Discover, Installed, Marketplaces та Errors) і /reload-plugins (підхопити зміни без перезапуску). З оболонки — claude plugin (псевдонім claude plugins). Код виходу: 0 — успіх, 1 — помилка; у validate 2 — збій самого валідатора.

КомандаЩо робить
claude plugin install <plugin>[@marketplace] [-s user|project|local] [--config k=v] [-y] [--json] [--marketplace <source>]Встановити плагін (псевдонім i). Область за замовчуванням — user (~/.claude/settings.json); project — .claude/settings.json (кожен колега все одно ставить сам); local — .claude/settings.local.json. --config задає userConfig
claude plugin uninstall <plugin> [-s …] [--keep-data] [--prune]Видалити (remove / rm). Дані ${CLAUDE_PLUGIN_DATA} видаляються з останньою інсталяцією, якщо не --keep-data.
claude plugin enable|disable <plugin> [-s …], disable --allУвімкнути/вимкнути; область визначається автоматично (local, project, user). Синхронізований з claude.ai плагін — <name>@synced.
claude plugin update <plugin> [-s user|project|local|managed]Оновити до версії з marketplace; застосується в наступній сесії або після /reload-plugins.
claude plugin list [--json], claude plugin details <name>Список встановлених із версіями/областями/статусом; склад плагіна та проєктована вартість токенів.
claude plugin configure <plugin@marketplace> [--values-stdin] [--json]Показати або зберегти значення userConfig (JSON зі stdin); v2.1.285+.
claude plugin pruneПрибрати автовстановлені залежності, які більше нікому не потрібні.
claude plugin init <name> [--with skills hooks …]Створити каркас у ~/.claude/skills/<name>/ (завантажується як <name>@skills-dir).
claude plugin validate <path> [--strict] [--json]Перевірити plugin.json, marketplace.json або компоненти в теці; для CI.
claude plugin tag [path] [--push] [--dry-run]Створити git-тег <name>--v<version> (перед цим звіряє версії в plugin.json і marketplace).
claude plugin eval [target] [--threshold 0..1] [--runs n] [--json], eval initПрогнати eval-кейси плагіна з оцінкою (v2.1.269+); порівнює з/без плагіна; коди виходу 0/1/2.
claude plugin marketplace add <source> [--scope …] [--sparse …] [--claudeai]Додати marketplace і оголосити його в settings. Джерело: owner/repo[@ref], git-URL, URL на marketplace.json, локальний шлях.
claude plugin marketplace list|remove|updateСписок / видалення (видаляє й його плагіни та дані) / оновлення каталогу.
claude --plugin-dir <path|.zip>, claude --plugin-url <url>Завантажити плагін лише на цю сесію (з’являється як <name>@inline). Блокується disableSideloadFlags.

Рецепт: роздати плагіни команді Django + Vue на GitLab

  1. Репозиторій marketplace. Створи в GitLab репо platform/claude-plugins з .claude-plugin/marketplace.json і теками плагінів у plugins/. Для кожного плагіна — .claude-plugin/plugin.json із version.
  2. Перевір і познач реліз: claude plugin validate . --strict у CI, потім claude plugin tag plugins/django-review --push. Для зовнішніх джерел фіксуй ref і sha.
  3. Підключи в проєкті. У репозиторії застосунку закоміть .claude/settings.json (нижче). У нашому прикладі django-review (відносний шлях) підхопиться після довіри до папки, а vue-tools (git-subdir, зовнішнє джерело) кожен колега ставить командою claude plugin install vue-tools@acme-plugins --scope project.
  4. Приватний репозиторій. Клонування йде через git на машині користувача (credential helper / SSH-ключі, без запитів). Для CI налаштуй git credential helper з токеном із правом читання репозиторію (у документації — приклад для GitHub Actions: GH_TOKEN + gh auth setup-git), або зроби seed-образ: CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin marketplace add … на збірці, CLAUDE_CODE_PLUGIN_SEED_DIR=/opt/claude-seed у рантаймі.
  5. Жорстка політика на рівні компанії. У managed settings (див. другий приклад): те саме extraKnownMarketplaces + enabledPlugins — і плагіни ставляться самі на кожній машині, плюс strictKnownMarketplaces лише з вашого GitLab-хоста та disableSideloadFlags.
  6. Перевір. /plugin показує marketplace і плагіни; у CI — claude -p --output-format stream-json --verbose: подія init містить масив plugins. У -p додай CLAUDE_CODE_SYNC_PLUGIN_INSTALL=1, щоб плагін був доступний уже на першому ході.
.claude/settings.json (у репозиторії застосунку)
{
  "extraKnownMarketplaces": {
    "acme-plugins": {
      "source": {
        "source": "git",
        "url": "https://gitlab.acme.example/platform/claude-plugins.git",
        "ref": "main"
      },
      "autoUpdate": true
    }
  },
  "enabledPlugins": {
    "django-review@acme-plugins": true,
    "vue-tools@acme-plugins": true
  }
}
managed-settings.json (політика на всі машини)
{
  "extraKnownMarketplaces": {
    "acme-plugins": {
      "source": {
        "source": "git",
        "url": "https://gitlab.acme.example/platform/claude-plugins.git"
      },
      "autoUpdate": true
    }
  },
  "enabledPlugins": {
    "django-review@acme-plugins": true,
    "vue-tools@acme-plugins": true
  },
  "strictKnownMarketplaces": [
    { "source": "hostPattern", "hostPattern": "^gitlab\\.acme\\.example$" },
    { "source": "skills-dir" }
  ],
  "disableSideloadFlags": true,
  "pluginTrustMessage": "Плагіни лише з acme-plugins. Питання: security@acme.example"
}
Деталі, які часто ламають розгортання
  • Офіційний marketplace при allowlist із вашого хоста не працюватиме — додай його в strictKnownMarketplaces (anthropics/claude-plugins-official) і в extraKnownMarketplaces, якщо він потрібен.
  • Записи extraKnownMarketplaces мають самі проходити allowlist, інакше Claude Code відмовиться їх реєструвати.
  • autoUpdate: для claude-plugins-official і більшості офіційних marketplace Anthropic за замовчуванням true, для сторонніх false. Якщо managed-запис задає поле, користувач не може його перемкнути в /plugin.
  • Фіксований реліз: у plugin.json поле version «приколює» плагін до цієї версії, доки ти його не змінив; без version версію обчислює сам Claude Code.
11

enterprise / managed

Розміщення managed settings, пріоритети, авторизація, політики

#
managed-settings.json — де лежитьlocation
Що робить

Джерела managed за пріоритетом: server-managed (консоль claude.ai або self-hosted Claude apps gateway) → MDM (plist / HKLM) → файл + drop-in каталог managed-settings.d/*.json → резервний HKCU (Windows; user-writable, тому не вважається admin-джерелом).

Що зміниться

Різні команди безпеки можуть класти свої фрагменти в managed-settings.d/ — файли зливаються за алфавітом. За замовчуванням ("first-wins") діє лише найвище джерело з ключем політики — плюс невеликий набір ключів, які читаються з усіх admin-джерел. managedSourcesBehavior: "merge" (v2.1.242+) поєднує всі. Деталі — у розділі файли і пріоритети.

macOS /Library/Application Support/ClaudeCode/ (managed-settings.json, managed-settings.d/, managed-mcp.json)
Linux / WSL /etc/claude-code/ (ті самі файли)
Windows C:\Program Files\ClaudeCode\ (ті самі файли; стара C:\ProgramData\ClaudeCode\managed-settings.json не читається)
macOS MDM plist-домен com.anthropic.claudecode
Windows MDM HKLM\SOFTWARE\Policies\ClaudeCode → Settings (REG_SZ або REG_EXPAND_SZ); перевірка кожні 30 хв
Windows HKCU HKCU\SOFTWARE\Policies\ClaudeCode → Settings: user-writable, тому застосовується лише коли вище немає жодного admin-документа
пріоритет налаштуваньprecedence
Що робить

Від найвищого: managed → --settings → .claude/settings.local.json → .claude/settings.json → ~/.claude/settings.json.

Що зміниться

Масиви (allow, deny...) зливаються між файлами, скаляри — перевизначаються; hooks зливаються, а managed-hooks видалити не можна. Змінні середовища не є рівнем стека — пріоритет вирішується для кожної пари окремо. settings.local.json з v2.1.211 читається з кореня git-репозиторію і додається в global git excludes.

1 · managed не перевизначається нічим
2 · --settings файл або JSON у CLI
3 · local .claude/settings.local.json — особисте, не комітиться
4 · project .claude/settings.json — спільне для команди
5 · user ~/.claude/settings.json
Виняток: для ключів-обмежень «суворіше» значення з нижчого рівня виграє навіть над managed: disableClaudeAiConnectors (true з будь-якого рівня), enableArtifact / disableArtifact (false / true з будь-якого, v2.1.242+), isolatePeerMachines (true), permissions.blockReadsOutsideWorkingDirectories (true, v2.1.257+), autoMode.classifyAllShell (true з user чи --settings), remoteControlAtStartup (false з project/local), crossSessionInbound (суворіше значення з project/local), useAutoModeDuringPlan, syncClaudeAiSkills, syncClaudeAiPlugins (false з managed, --settings, user чи local), maxEffortLevel (найнижча стеля, v2.1.267+). Повна таблиця — у розділі файли і пріоритети.
forceLoginMethod / forceLoginOrgUUIDenum / stringдіє з managed
Що робить

Обмежує, яким акаунтом можна логінитись: "claudeai", "console" або "gateway" (хмарний gateway замість першопартійного входу). forceLoginOrgUUID — один UUID або масив UUID організацій.

Що зміниться

"claudeai" = через підписки Claude Pro/Max/Team/Enterprise. "console" = через Anthropic Console API — командний billing. forceLoginMethod "claudeai"/"console" обмежує вхід з будь-якого файлу налаштувань (діє у VS Code, SDK, claude setup-token, /install-github-app); єдиний виняток — інтерактивний екран входу в терміналі (/login або онбординг першого запуску), який лише попередньо обирає метод (до v2.1.212 застосовувався лише у терміналі). "gateway" береться лише з managed-джерела на машині (файл, plist, HKLM, policyHelper) — не з server-managed, HKCU чи user-файлів. forceLoginOrgUUID примусово діє лише з managed; в інших файлах один UUID лише попередньо обирає організацію, масив — нічого. Порожній масив або нерозбірливе managed-значення блокує усі входи.

settings.json
"forceLoginMethod": "console",
"forceLoginOrgUUID": ["xxxx-xxxx-xxxx-xxxx"]
// UUID організації (можна кілька)
apiKeyHelperstring
Що робить

Shell-команда (будь-який командний рядок: /bin/sh на macOS/Linux, cmd на Windows), що динамічно віддає облікові дані. Вивід іде як X-Api-Key і Authorization: Bearer. Кеш — 5 хв за замовчуванням; команда перезапускається також при 401/403 та (з v2.1.246) коли кешований вивід — JWT, що вже прострочився.

Що зміниться

Без нього — ключ статичний. З ним — інтегрується HashiCorp Vault, AWS IAM, або будь-яка ротація токенів. Ключ ніколи не зберігається на диску розробника. Останні два випадки перезапуску діють лише коли вивід — це справжній credential і не задано ANTHROPIC_AUTH_TOKEN. В інтерактивних сесіях хелпер із project/local settings не виконується, доки не прийнято діалог довіри до робочої теки. У managed-merge ключ читається лише з найвищого джерела.

settings.json
"apiKeyHelper": "/opt/company/get-claude-key.sh"
// Команда виводить ключ в stdout; йде як X-Api-Key і Bearer
// TTL кешу — CLAUDE_CODE_API_KEY_HELPER_TTL_MS
companyAnnouncementsarray
Що робить

Масив рядків — одне рандомно показується при старті кожної сесії (при першому запуску — перше). Власний "message of the day" для команди.

Що зміниться

Розробники бачитимуть оголошення щоразу при запуску. Корисно для нагадувань про security policy, нові інструменти, планові роботи.

settings.json
"companyAnnouncements": [
  "🔒 Нагадування: секрети — тільки у Vault!",
  "📋 Новий MCP для Jira — деталі в Confluence",
  "🚀 Оновлено managed settings v2.4 — changelog"
]
cleanupPeriodDaysinteger
Що робить

Скільки днів зберігати локальні транскрипти сесій (~/.claude/projects/). Після — автоматично видаляються. Мінімум 1, default 30.

Що зміниться

Менше — швидше видалення, менше місця, краща приватність. Важливо для compliance вимог (GDPR, SOC2). Для довгого зберігання — велике значення.

settings.json
"cleanupPeriodDays": 7     // тиждень — для compliance
"cleanupPeriodDays": 30    // default
"cleanupPeriodDays": 3650  // ≈ ніколи не видаляти
⚠ Значення 0 тепер не проходить валідацію (раніше вимикало очищення)
requiredMinimumVersion / requiredMaximumVersionstringmanaged only
Що робить

Managed-ключі (з v2.1.163). Claude Code виходить на старті, якщо його версія нижча (requiredMinimumVersion) або вища (requiredMaximumVersion) за дозволену. Перевірка лише на старті — уже запущені сесії працюють далі; claude update, claude install і claude doctor лишаються доступними для відновлення. Невалідне значення ігнорується.

Що зміниться

Гарантує, що в команді немає старих CLI з відомими вразливостями, і що ніхто не обганяє перевірену версію. minimumVersion — інше: він не блокує запуск, а лише не дає автооновленню та claude update встановити версію нижче (корисно при переході на канал stable).

settings.json
"requiredMinimumVersion": "2.1.280",   // потрібна для Opus 5.5
"requiredMaximumVersion": "2.1.295"
otelHeadersHelperstring
Що робить

Скрипт що виводить OpenTelemetry headers. Прокидає телеметрію Claude Code в корпоративну observability систему.

Що зміниться

Метрики й події Claude Code потрапляють у Datadog/Grafana поряд з іншими сервісами компанії. Частоту оновлення задає CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS.

settings.json
"otelHeadersHelper": "/opt/company/otel-headers.sh"
allowedProvidersarraymanaged only
Що робить

Список сервісів, через які машина може ходити до Claude. Сесія на провайдері поза списком відхиляється на старті, при логіні й при наступному зверненні до API — перемкнутись посеред сесії теж не вийде.

Що зміниться

Гарантує, що код не піде в непередбачений хмарний сервіс. Server-managed список може лише звузити перелік машини, ніколи не розширити. Невідомі записи відкидаються з повідомленням; порожній список або такий, де всі записи нерозпізнані, забороняє всіх провайдерів — Claude Code не запуститься.

managed-settings.json
"allowedProviders": ["anthropic", "bedrock"]
anthropicAnthropic API на власному хості (вхід claude.ai/Console або ключ); для обмеження входу додай forceLoginMethod / forceLoginOrgUUID
bedrock / mantleAmazon Bedrock / його Mantle endpoint (для сесії, що використовує обидва, вкажи обидва)
vertex / foundry / anthropicAwsGoogle Cloud Agent Platform / Microsoft Foundry / Claude Platform on AWS
customEndpointAPI Anthropic або хмарного провайдера на інший хост (LLM gateway через ANTHROPIC_BASE_URL тощо); допускається лише для точного значення, закріпленого в managed env
gatewayвхід через Cloud gateway
З v2.1.285.
awsAuthRefreshstring
Що робить

Власна команда (напр. aws sso login), що оновлює облікові дані в каталозі .aws, коли ті, що має Claude Code для Amazon Bedrock, перестали працювати.

Що зміниться

Команда запускається лише після того, як перевірка через STS не пройшла; потім Claude Code перечитує .aws. Якщо кілька процесів (термінали, вікна IDE) впали одночасно, команду запускає один, інші чекають; той, хто чекає 60 с, запускає сам. Блокування вимикає CLAUDE_CODE_DISABLE_AUTH_REFRESH_LOCK=1.

settings.json
"awsAuthRefresh": "aws sso login --profile myprofile"
Якщо потік оновлення не пише в .aws, а друкує креди — використовуй awsCredentialExport.
awsCredentialExportstring
Що робить

Команда, що друкує AWS-креди у JSON (формат виводу aws sts або плаский aws configure export-credentials), коли вони не лежать в .aws.

Що зміниться

Креди обмежені власним Bedrock-клієнтом Claude Code: shell-команди, які запускає Claude, бачать твої звичайні змінні. На відміну від awsAuthRefresh, команда виконується завжди, коли задана, без попередньої перевірки.

settings.json
"awsCredentialExport": "/bin/generate_aws_grant.sh"
gcpAuthRefreshstring
Що робить

Команда, що оновлює Google Cloud Application Default Credentials, коли вони прострочені або не завантажуються.

Що зміниться

Запити до Google Cloud Agent Platform продовжують працювати без ручного перелогіну. Без ключа помилка просто підказує виконати gcloud auth application-default login. Спільне блокування як у awsAuthRefresh.

settings.json
"gcpAuthRefresh": "gcloud auth application-default login"
forceLoginGatewayUrlstringmanaged (на машині)
Що робить

URL, до якого підключається екран /login → Cloud gateway. Повна адреса зі схемою.

Що зміниться

Люди потрапляють на ваш gateway, не вводячи адреси. Без ключа екран просить звернутись до IT. Цей ключ або forceLoginMethod: "gateway" робить машину gateway-only (крім сесій з CLAUDE_CODE_USE_*); задай обидва, щоб екран підключався, а не показував помилку.

managed-settings.json
"forceLoginGatewayUrl": "https://claude-gateway.example.com"
Читається лише з managed-файлу, plist, HKLM і policyHelper; у server-managed та HKCU ігнорується. Невалідний URL — помилка на екрані входу, решта файлу діє.
gatewayInternalNetworksarraymanaged (на машині)
Що робить

Публічні IPv4-блоки, з яких організація нумерує внутрішню мережу, щоб /login приймав cloud gateway і там.

Що зміниться

Без ключа /login підключається лише до gateway на приватних адресах. З ключем приймає ще й gateway усередині вказаного блоку, лише прямим з’єднанням, і адреса самої машини має бути в тому ж блоці. До 4 CIDR (/8–/32), без перетину між собою та з приватним простором. Невалідний запис блокує усі нові gateway-входи на машині, доки не виправиш.

managed-settings.json
"gatewayInternalNetworks": ["203.0.113.0/24"]
З v2.1.268. Приклад — документаційний діапазон: заміни своїм блоком (документаційні, VPN/NAT64 та multicast-діапазони Claude Code відкидає).
disableSideloadFlagsbooleanmanaged only
Що робить

Відхиляє прапори --plugin-dir, --plugin-url, --agents і --mcp-config на старті. Default false.

Що зміниться

Закриває обхід strictKnownMarketplaces через підвантаження плагінів, агентів чи MCP з командного рядка. У cloud-сесіях замість відмови відкидаються server-delivered записи --mcp-config.

managed-settings.json
"disableSideloadFlags": true
З v2.1.193 (поведінка в cloud-сесіях — v2.1.239/268/280).
forceRemoteSettingsRefreshbooleanmanaged only
Що робить

Блокує старт CLI, доки свіжо не отримано server-managed settings. Якщо fetch не вдався — Claude Code завершується. Default false.

Що зміниться

Політика не «застаріє» з кешу. Значення true береться з будь-якого admin-джерела; перевірка йде до запуску policyHelper. Зміна діє з наступного запуску сесії.

managed-settings.json
"forceRemoteSettingsRefresh": true
parentSettingsBehaviorenummanaged only
Що робить

Чи застосовувати managed-налаштування від процесу-хоста (Agent SDK, розширення IDE, Claude Desktop), коли на машині є і admin-managed рівень: "first-wins" (default) або "merge".

Що зміниться

first-wins відкидає налаштування хоста. merge застосовує їх під admin-рівнем через фільтр «лише обмеження» — хост може передати власні обмеження сесіям, які запускає (наприклад, egress allowlist gateway). Читається з найвищого admin-джерела.

managed-settings.json
"parentSettingsBehavior": "merge"
policyHelperobjectmanaged only
Що робить

Виконуваний файл, який ви розгортаєте і який обчислює managed-налаштування на старті — з позиції пристрою, ідентичності чи віддаленого сервісу — замість статичного файлу. Запускається до першого промпту, його вивід стає managed-налаштуваннями сесії.

Що зміниться

Політику можна рахувати динамічно. Хелпер без аргументів друкує у stdout один JSON-об’єкт (до 1 МіБ) з ключем managedSettings — «голий» об’єкт без цього ключа не застосує нічого й не дасть помилки. У середовищі є CLAUDE_CODE_VERSION. Якщо видано managedSettings, це єдине managed-джерело сесії: MDM, файл і HKCU ігноруються.

managed-settings.json
"policyHelper": {
  "path": "/usr/local/bin/claude-policy",
  "timeoutMs": 5000,
  "refreshIntervalMs": 300000
}
pathобов’язковий; абсолютний нормалізований шлях без ./..; у Windows — диск або UNC, кінчається .exe
timeoutMsціле, мінімум 1000, default 10000. Таймаут на старті = Claude Code відмовляється запускатися
refreshIntervalMs0 = вимкнено, інакше ≥60000; без ключа хелпер запускається один раз. Збій фонового оновлення залишає останню успішну політику, /status показує причину
⚠ Читається з plist, HKLM або managed-файлу, коли саме те джерело — найвище з ключем політики; у server-managed, HKCU і parent settings ігнорується (server-managed на старті перекриває хелпер). Збій на старті — відмова запуску: хелперу, якому потрібна стійкість до збоїв, слід віддавати власний кеш і завершуватись з кодом 0. Новий або змінений запис діє з наступного запуску.
wslInheritsWindowsSettingsbooleanmanaged only
Що робить

Змушує Claude Code у WSL читати managed-налаштування з ланцюга політик Windows: HKLM і Windows-файл мають пріоритет над /etc/claude-code та HKCU. Default false (WSL читає лише /etc/claude-code).

Що зміниться

Одна політика Windows діє і на сесії WSL тієї ж машини. Поки ланцюг увімкнено, /etc/claude-code читається лише якщо у HKLM чи в C:\Program Files\ClaudeCode\ немає admin-документа. Визнається лише з HKLM або з файлу/drop-in у C:\Program Files\ClaudeCode\; на нативному Windows не діє.

managed-settings.json
"wslInheritsWindowsSettings": true
З v2.1.282. Джерело, що містить лише цей ключ, не вважається джерелом політики. HKCU долучається на WSL, лише якщо й там true.
desktopSessionCleanupPeriodDaysinteger
Що робить

Віковий ліміт (дні, ≥0) для транскриптів сесій, які ти починав або востаннє продовжував у Claude Desktop чи Cowork. Default 0 — без ліміту.

Що зміниться

Транскрипт видаляється лише коли він старший і за цей ключ, і за cleanupPeriodDays. Корисно для окремої політики зберігання десктопних сесій.

settings.json
"desktopSessionCleanupPeriodDays": 90
З v2.1.248. User або managed (і --settings).
feedbackDraftsenum
Що робить

Керує чернетками відгуків, які пише Claude: "notify" (default), "quiet" або "off".

Що зміниться

Визначає, чи може Claude ставити чернетки відгуків у чергу для твого перегляду і чи показує Claude Code картку. "off" прибирає інструмент SendFeedback; те саме дає CLAUDE_CODE_SEND_FEEDBACK=0.

settings.json
"feedbackDrafts": "quiet"
User або managed.
feedbackSurveyRatenumber
Що робить

Імовірність (0–1) показати опитування якості сесії, коли сесія до нього придатна. 0 — не показувати ніколи.

Що зміниться

Без ключа діє віддалена частота (або 0.005 на Bedrock/Vertex/Foundry). Повністю вимкнути опитування можна й змінною CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1.

settings.json
"feedbackSurveyRate": 0
skipWebFetchPreflightboolean
Що робить

Пропускає перевірку безпеки домену перед WebFetch, яка надсилає запитану назву хоста на api.anthropic.com.

Що зміниться

Для середовищ, що блокують трафік до Anthropic: Bedrock, Google Cloud Agent Platform чи Foundry з обмеженим egress. Без ключа перевірка виконується перед першим запитом до кожного хоста в сесії.

settings.json
"skipWebFetchPreflight": true
⚠ Без перевірки WebFetch пробує будь-який URL, не звіряючись із blocklist, — обмежуй домени правилами WebFetch у permissions.
12

загальні

Мова, оновлення, пам’ять, стиль відповідей

#
languagestring
Що робить

Встановлює мову відповідей Claude незалежно від мови запиту. Також мову голосової диктовки та назв сесій.

Що зміниться

"ukrainian" = Claude відповідатиме українською навіть якщо запит англійською. Корисно для стандартизації мови в команді.

settings.json
"language": "ukrainian"
autoMemoryEnabled / autoMemoryDirectoryboolean / string
Що робить

Claude автоматично зберігає корисний контекст у ~/.claude/projects/<проєкт>/memory/ (індекс MEMORY.md) — рішення, патерни, уподобання. Default true.

Що зміниться

true = Claude "навчається" від сесії до сесії. false = кожна сесія ізольована, нічого не пишеться. Для compliance (GDPR) — false. autoMemoryDirectory — перенести пам’ять в інше місце.

settings.json
"autoMemoryEnabled": true   // зберігає контекст між сесіями
"autoMemoryEnabled": false  // кожна сесія з нуля
"autoMemoryDirectory": "~/work/claude-memory"
autoUpdatesChannel / minimumVersionenum
Що робить

З якого каналу отримувати автооновлення Claude Code CLI: "latest" (default) або "stable". Homebrew-інсталяції ігнорують.

Що зміниться

"stable" відстає від latest і містить перевірені збірки (зараз 2.1.286 проти 2.1.295). Для команд краще "stable" — менше сюрпризів.

settings.json
"autoUpdatesChannel": "stable"  // ✓ рекомендовано для команд
"minimumVersion": "2.1.280"
outputStylestring
Що робить

Задає стиль відповідей Claude. Вбудовані: Default, Proactive, Concise, Explanatory, Learning, або власний з .claude/output-styles/.

Що зміниться

"Explanatory" = пояснює рішення. "Learning" = залишає частину коду тобі. "Concise" = мінімум тексту. Зміна діє з наступного повідомлення.

settings.json
"outputStyle": "Explanatory"  // onboarding junior розробників
plansDirectorystring
Що робить

Де зберігати план-файли що Claude Code створює в режимі планування. Шлях відносно кореня проєкту.

Що зміниться

Default ~/.claude/plans. Перемістивши в ./plans/ — плани в репозиторії, доступні всій команді через git і code review. Шлях поза проєктом ігнорується.

settings.json
"plansDirectory": "./plans"  // в репо поряд з CLAUDE.md
autoCompactWindow / bashOutputMaxCharsinteger
Що робить

Нові ключі. autoCompactWindow (100000–1000000) — розмір вікна, після якого стискається контекст; значення обмежене вікном моделі. bashOutputMaxChars (4000–128000, default 30000) — скільки виводу успішної Bash/PowerShell-команди Claude отримує одразу; понад ліміт вивід зберігається у файл, Claude бачить прев’ю і шлях.

Що зміниться

Менше вікно = дешевші запити на 1M-моделях, але частіше стиснення. Менший bash-вивід = економія токенів на шумних тестах і білдах. bashOutputMaxChars потребує v2.1.261+ і має пріоритет над BASH_MAX_OUTPUT_LENGTH: якщо ключ задано, змінна ігнорується. Пріоритет autoCompactWindow: CLAUDE_CODE_AUTO_COMPACT_WINDOW > --autocompact > ключ; modelSettings.<модель>.autoCompactWindow (його пише /autocompact) у тому ж файлі сильніший за ключ.

settings.json
"autoCompactWindow": 400000,
"bashOutputMaxChars": 15000
autoCompactEnabledboolean
Що робить

Чи стискати розмову автоматично, коли контекст наближається до межі. Default true.

Що зміниться

false — контекст не стискається сам, лишається ручний /compact. Змінна DISABLE_AUTO_COMPACT теж вимикає авто-стиснення, і жоден із двох способів не може повернути те, що вимкнув інший.

settings.json
"autoCompactEnabled": false
claudeMdstringmanaged only
Що робить

Вставляє інструкції у стилі CLAUDE.md як організаційну managed-пам’ять без розгортання окремого файлу. Це текст Markdown, переноси — \n.

Що зміниться

Завантажується раніше за user- і project-CLAUDE.md, тож базові правила інженерії діють у кожному проєкті. Підходить для політик, які мають бути в контексті завжди.

managed-settings.json
"claudeMd": "# Engineering rules\n\n- Перед комітом запускай make lint.\n- Міграції Django — лише через makemigrations."
claudeMdExcludesarray
Що робить

Glob-шаблони або абсолютні шляхи CLAUDE.md-файлів, які треба пропустити під час завантаження пам’яті. Шаблони зіставляються з абсолютними шляхами.

Що зміниться

Корисно в монорепо: чужі CLAUDE.md сусідніх команд або вендорні каталоги не засмічують контекст.

settings.json
"claudeMdExcludes": ["**/vendor/**/CLAUDE.md", "**/node_modules/**/CLAUDE.md"]
fileCheckpointingEnabledboolean
Що робить

Робити знімок файлів перед кожною правкою, щоб /rewind міг відновити їх. Default true; у /config — «Rewind code (checkpoints)».

Що зміниться

false — знімків немає, /rewind не поверне код. CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING=1 вимикає те саме на сесію; що вимкнуло — те й лишається вимкненим.

settings.json
"fileCheckpointingEnabled": false
У -p та Agent SDK ключ ігнорується: SDK вмикає опцією enableFileCheckpointing, а «голий» -p потребує CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true.
skillListingBudgetFractionnumber
Що робить

Частка вікна контексту (0 < x ≤ 1, default 0.01), яку може займати щоходовий перелік скілів.

Що зміниться

Понад ліміт Claude Code «скидає описи найменш вживаних скілів». Піднімай, якщо скілів багато і Claude перестає їх помічати.

settings.json
"skillListingBudgetFraction": 0.02
skillListingMaxDescCharsinteger
Що робить

Скільки символів тексту (description + when_to_use) показувати на один скіл у переліку. Default 1536.

Що зміниться

Довші описи обрізаються. Збільшуй, якщо критичні умови запуску скіла стоять наприкінці опису.

settings.json
"skillListingMaxDescChars": 2048

Застарілі ключі

Ці ключі вже не мають ефекту або замінені новими. Старі файли з ними не ламаються, але прибери їх під час наступної ревізії.

КлючСтатусЩо робити
taskOutputMaxCharsвидалено у v2.1.277 разом з інструментом TaskOutput; не дієПрибрати.
permissionExplainerEnabledвидалено у v2.1.257 (разом з поясненням Ctrl+E); не дієПрибрати.
teammateDefaultModelвидалено у v2.1.234; не дієПрибрати.
keybindingFlavordeprecated з v2.1.261; не діє — клавіші редагування слів завжди за readlineПрибрати.
voiceEnableddeprecated з v2.1.92, ще читаєтьсяЗамінити на voice.enabled.
disableArtifactdeprecated, ще читається: true = enableArtifact: false, false ігноруєтьсяЗамінити на enableArtifact: false.
includeCoAuthoredBydeprecated з v2.0.62, ще читається (див. розділ git)Замінити на attribution.
13

git / attribution

Підпис Claude в комітах і PR

#
attributionobject | false
Що робить

Кастомізує текст атрибуції що Claude додає до git комітів як co-author trailer та в описи Pull Request. Нове поле sessionUrl — посилання на сесію.

Що зміниться

"" = прибрати конкретний підпис. false (v2.1.281+) = сховати всю атрибуцію. Корисно якщо internal policy не дозволяє AI-атрибуцію в комітах.

settings.json
"attribution": { "commit": "", "pr": "", "sessionUrl": false }
// або все одразу:
"attribution": false
// або кастомний текст:
"attribution": { "commit": "Co-authored-by: AI Dev <ai@company.com>" }
includeCoAuthoredBy — deprecated, використовуй attribution
includeGitInstructionsboolean
Що робить

Вмикає/вимикає вбудовані git-інструкції та знімок git status у system prompt Claude. Default true.

Що зміниться

false = Claude не використовує стандартні git інструкції. Корисно якщо є власний CLAUDE.md з кастомними git конвенціями — уникнення конфлікту інструкцій. Env-аналог: CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS.

settings.json
"includeGitInstructions": false  // є свій CLAUDE.md з git правилами
prUrlTemplate / worktreestring / object
Що робить

Нові ключі. prUrlTemplate — шаблон посилання на PR для не-GitHub хостингів. worktree — об’єкт з підключами baseRef, symlinkDirectories, sparsePaths, bgIsolation: як Claude створює git worktree для --worktree, EnterWorktree, ізольованих субагентів і фонових сесій.

Що зміниться

Посилання на PR ведуть у твій внутрішній code-review інструмент. baseRef: "fresh" (default) — від origin/<default-branch>, "head" — від поточного HEAD з незапушеними комітами.

settings.json
"prUrlTemplate": "https://reviews.company.com/{owner}/{repo}/pull/{number}",
"worktree": { "baseRef": "head" }
worktree.symlinkDirectoriesarray
Що робить

Каталоги (шляхи від кореня репозиторію), які символічно лінкуються з основного репо в кожен worktree.

Що зміниться

Не дублюєш на диску важкі каталоги: у Django + Vue проєкті — node_modules або кеші. Без ключа нічого не лінкується.

settings.json
"worktree": {
  "symlinkDirectories": ["node_modules", ".cache"]
}
Щоб скопіювати в нові worktree gitignored-файли на кшталт .env, поклади в корінь проєкту файл .worktreeinclude — окремого ключа для цього немає.
worktree.sparsePathsarray
Що робить

Каталоги від кореня репо, які git sparse-checkout вивантажує в кожен worktree. На диск записуються лише вони та файли з кореня.

Що зміниться

Швидше у великих монорепо: у worktree з’являється лише потрібна частина дерева. Без ключа береться все дерево.

settings.json
"worktree": {
  "sparsePaths": ["packages/my-app", "shared/utils"]
}
Поки існує sparse-worktree, git вмикає extensions.worktreeConfig у спільному .git/config.
worktree.bgIsolationenum
Що робить

Як фонові сесії ізолюють правки файлів: "worktree" (default) або "none".

Що зміниться

З "worktree" Claude Code блокує Edit і Write в основному checkout, доки сесія не викличе EnterWorktree. З "none" фонові завдання правлять робочу копію напряму — для репо, де worktree незручні. Сесія, яку ти сам перевів у фон (← чи /background), редагує на місці за будь-якого значення.

settings.json
"worktree": {
  "bgIsolation": "none"
}
Поза git невдалий hook WorktreeCreate знімає блокування, і сесія редагує каталог на місці (з v2.1.203).
14

UI / spinner

Кастомізація інтерфейсу терміналу

#

Ключі нижче лежать у settings.json, якщо не сказано інше. Бейдж біля ключа показує, звідки він діє: без бейджа ключ читається з будь-якого файла (user, project, local, managed); «user або managed» означає, що project і local ігноруються (репозиторій не може вмикати такі речі за тебе). Деякі ключі (theme, verbose, terminalProgressBarEnabled, respectGitignore, teammateMode, ключі сповіщень) за відсутності в settings читаються ще й з ~/.claude.json, куди їх писали старіші версії.

Рядок статусу, спінер і файли

statusLine / subagentStatusLineobject
Що робить

Кастомний рядок статусу внизу терміналу. Скрипт читає JSON зі stdin (модель, контекст, cost, git) і виводить рядок. subagentStatusLine — окремий рядок для субагентів.

Що зміниться

Без цього — стандартний статус. З скриптом — показуй що завгодно: git branch, витрачені токени, час сесії. padding — горизонтальний відступ у символах. refreshInterval — оновлення за таймером, у секундах, мінімум 1. hideVimModeIndicator: true ховає вбудований індикатор vim-режиму, коли скрипт сам малює vim.mode. Якщо ввімкнено allowManagedHooksOnly (або disableAllHooks стоїть поза managed), працює лише значення з managed.

settings.json
"statusLine": {
  "type": "command",
  "command": "~/.claude/statusline.sh",
  "padding": 2,            // відступ, символів
  "refreshInterval": 5,   // кожні 5 с (мінімум 1)
  "hideVimModeIndicator": true
}
spinnerVerbs / spinnerTipsEnabled / showTurnDuration / prefersReducedMotionmixed
Що робить

Кастомізує анімований спінер: текст дій (append або replace), підказки, тривалість ходу, анімації. Чисто косметично.

Що зміниться

spinnerTipsEnabled false = без підказок (або свої через spinnerTipsOverride). showTurnDuration false = не показувати "Cooked for 1m 6s". prefersReducedMotion true = вимкнути анімацію (accessibility).

settings.json
"spinnerVerbs": { "mode": "replace", "verbs": ["Думаю...", "Пишу..."] },
"spinnerTipsEnabled": false,
"showTurnDuration": true,
"prefersReducedMotion": false
fileSuggestionobject
Що робить

Власний скрипт для автокомпліту файлів при наборі "@filename". Отримує {"query": "..."} у stdin, виводить до 15 шляхів. Таймаут 5 с.

Що зміниться

Дозволяє інтегрувати fd, ripgrep, або кастомний індекс великого монорепо. Без цього — стандартний пошук по директорії.

settings.json
"fileSuggestion": { "type": "command", "command": "~/.claude/file-suggest.sh" }
// file-suggest.sh: q=$(jq -r .query); fd --type f | fzf --filter "$q" | head -15
tui / timeFormat / timeZone / maxProseWidthstring
Що робить

Нові ключі інтерфейсу: рендерер tui ("fullscreen" — без мерехтіння, або "default"), формат часу та часовий пояс (v2.1.257), а також ширина тексту maxProseWidth (з v2.1.282, число колонок, мінімум 40; інші значення ігноруються). Параграфи, заголовки, списки й цитати переносяться в межах цієї ширини, а таблиці та блоки коду лишаються на всю ширину терміналу. Без tui Claude Code сам обирає рендерер; /tui fullscreen або /tui default записують ключ за тебе.

Що зміниться

Однаковий вигляд терміналу в команді, коректний час у статусах для розподілених команд.

settings.json
"tui": "fullscreen",
"timeFormat": "24-hour",
"timeZone": "Europe/Kyiv",
"maxProseWidth": 80

Термінал і відображення

themeenum
Що робить

Колірна тема інтерфейсу. Зазвичай її міняють через /theme або /config, але ключ дозволяє зафіксувати тему у файлі.

Що зміниться

Без ключа діє "dark". "auto" слідує за темою терміналу; daltonized-теми — для дальтонізму; ansi-теми використовують лише 16 кольорів терміналу.

settings.json
{
  "theme": "light-daltonized"
}
"auto"за темою терміналу
"dark" / "light"стандартні (default — dark)
"dark-daltonized" / "light-daltonized"для дальтонізму
"dark-ansi" / "light-ansi"лише ANSI-кольори терміналу
"custom:<slug>", "custom:<plugin>:<slug>"власна тема або тема з плагіна
viewModeenum
Що робить

У якому вигляді транскрипту стартує Claude Code: default (звичайний, вивід інструментів скорочено), verbose (повний вивід інструментів) або focus (лише твій останній промпт, однорядкове зведення викликів інструментів і фінальна відповідь).

Що зміниться

Якщо ключ заданий, він перекриває і запам’ятований вибір /focus, і ключ verbose. Режим focus працює лише з fullscreen-рендерером (tui). Без ключа діють ключ verbose і твій останній вибір /focus. Прапорець --verbose перекриває ключ на одну сесію.

settings.json
{
  "viewMode": "focus"
}
verboseboolean
Що робить

Показувати повний вхід і вихід кожного виклику інструмента просто в розмові, у міру того як він відбувається. Типово false.

Що зміниться

Корисно, коли треба дебажити, що саме запускає Claude (повні аргументи Bash, вміст читаних файлів). Прапорець --verbose перекриває ключ на одну сесію. Шумно для щоденної роботи.

settings.json
{
  "verbose": true
}
syntaxHighlightingDisabledboolean
Що робить

Вимикає підсвічування синтаксису: diff-и, блоки коду й прев’ю показуються простим текстом. Типово false.

Що зміниться

Корисно в терміналах із поганою передачею кольору або коли підсвічування заважає читати diff. Функціональних наслідків немає.

settings.json
{
  "syntaxHighlightingDisabled": true
}
autoScrollEnabledboolean
Що робить

У fullscreen-рендерінгу вікно слідує за новим виводом до низу розмови. Типово true.

Що зміниться

З false позиція прокрутки залишається там, де ти її лишив, і нові рядки не відкидають тебе вниз. Зручно, коли перечитуєш довгу відповідь, поки Claude ще пише.

settings.json
{
  "autoScrollEnabled": false
}
wheelScrollAccelerationEnabledboolean
Що робить

У fullscreen-рендерінгу прискорює прокрутку колесом миші під час швидкого скролу. Типово true.

Що зміниться

З false швидкість скролу постійна: передбачувано на трекпадах і в мишах із власною акселерацією.

settings.json
{
  "wheelScrollAccelerationEnabled": false
}
terminalProgressBarEnabledboolean
Що робить

Повідомляє терміналу про стан «виконується», якщо той уміє показувати індикатор прогресу на вкладці чи в панелі завдань. Типово true.

Що зміниться

З false індикатор у вкладці не з’являється. Якщо ключа немає в settings, береться значення з ~/.claude.json.

settings.json
{
  "terminalProgressBarEnabled": false
}
terminalTitleFromRenameboolean
Що робить

Керує тим, чи заголовок вкладки терміналу оновлюється, коли ти перейменовуєш сесію. Типово true.

Що зміниться

З false на вкладці лишається згенерований заголовок навіть після того, як ти дав сесії ім’я.

settings.json
{
  "terminalTitleFromRename": false
}
footerLinksRegexesarrayuser або managed
Що робить

Додаткові клікабельні бейджі у футері під полем вводу: коли regex збігається з виводом ходу (результати інструментів, відповіді Claude), з’являється посилання. Іменовані capture-групи підставляються в {name} у url і label.

Що зміниться

Ідентифікатори задач чи MR, які друкують CLI проєкту, перетворюються на посилання в один клік. Без ключа бейджів немає.

номери задач → Jira / GitLab
settings.json
{
  "footerLinksRegexes": [
    {
      "type": "regex",
      "pattern": "\\b(?<key>SHOP-\\d+)\\b",
      "url": "https://jira.example.com/browse/{key}",
      "label": "{key}"
    }
  ]
}
Кожен елемент: type: "regex", pattern, url, необов’язковий label. Приклад: коли в результаті інструмента або відповіді з’являється SHOP-1234, у футері виникає бейдж із посиланням на цю задачу.

Ввід і взаємодія

editorModeenum
Що робить

Режим клавіш у полі вводу: "normal" (за замовчуванням) або "vim".

Що зміниться

З "vim" поле вводу працює як vim (INSERT / NORMAL). Разом із vimInsertModeRemaps можна повісити вихід з INSERT на jj.

settings.json
{
  "editorMode": "vim"
}
vimInsertModeRemapsobjectuser або managed
Що робить

У vim-режимі перетворює двосимвольні послідовності в INSERT на Escape. Єдине допустиме значення — "<Esc>". Потребує v2.1.208+.

Що зміниться

Без ключа вихід з INSERT лише справжнім Esc. Працює тільки при editorMode: "vim".

settings.json
{
  "editorMode": "vim",
  "vimInsertModeRemaps": { "jj": "<Esc>" }
}
spellcheckobjectuser або managed
Що робить

Підкреслює слова з помилками у полі вводу під час набору через spell checker, який ти встановив сам (aspell, hunspell, ispell). Перевіряється лише текст у полі вводу. Потребує v2.1.235+.

Що зміниться

Типово вимкнено. Поля: enabled, checker ("aspell", "hunspell", "ispell" або "auto" — перший знайдений у PATH), language (назва словника для checker) і color (ім’я кольору, #rrggbb, rgb(r,g,b), ansi256(n), ansi:<name>; типово колір помилки з теми).

settings.json
{
  "spellcheck": {
    "enabled": true,
    "checker": "hunspell",
    "language": "uk_UA"
  }
}
Блок береться цілим з найвищого рівня, який його задає: поля з різних файлів не зливаються.
voiceobject
Що робить

Голосова диктовка: вмикає її та задає поведінку клавіші диктовки. Поля: enabled, mode — "hold" (тримаєш клавішу, відпускаєш — стоп) або "tap" (тап — старт, тап — відправити), autoSubmit (відправити промпт при відпусканні, лише в hold).

Що зміниться

Без ключа диктовка вимкнена; якщо enabled: true, а mode не задано, використовується "hold". Ключ пише за тебе команда /voice. Потрібен акаунт claude.ai.

settings.json
{
  "voice": {
    "enabled": true,
    "mode": "tap"
  }
}
emojiCompletionEnabledboolean
Що робить

Показує підказки емодзі після : і замінює шорткоди на кшталт :heart: на символи. Типово true. Потребує v2.1.217+.

Що зміниться

З false двокрапка у промпті не викликає підказок: зручно, якщо часто пишеш : у коді чи YAML.

settings.json
{
  "emojiCompletionEnabled": false
}
promptSuggestionEnabledboolean
Що робить

Показує або ховає підказки промпту: сірі передбачення, що з’являються у полі вводу. Типово true.

Що зміниться

З false поле вводу залишається порожнім, поки ти не почнеш писати. Змінна оточення CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION робить те саме.

settings.json
{
  "promptSuggestionEnabled": false
}
respectGitignoreboolean
Що робить

Чи пропускає файловий вибір @ файли, що збігаються з патернами .gitignore. Типово true.

Що зміниться

З false у списку @ з’являються й ігноровані файли (node_modules, dist, .env). Якщо ключа немає в settings, береться значення з ~/.claude.json.

settings.json
{
  "respectGitignore": false
}
defaultShellenum
Що робить

Який шел виконує команди, які ти вводиш через префікс !: "bash" або "powershell".

Що зміниться

Типово "bash" (або "powershell" на Windows без Bash). Команди, що їх запускає сам Claude, цим ключем не змінюються.

settings.json
{
  "defaultShell": "powershell"
}
respondToBashCommandsboolean
Що робить

Чи відповідає Claude на команду, введену через !. Типово true.

Що зміниться

З false вивід команди просто додається в контекст без відповіді Claude: економить токени, коли ти збираєш дані для наступного промпту.

settings.json
{
  "respondToBashCommands": false
}
bashEditDiffEnabledbooleanuser або managed
Що робить

Чи записує Claude Code, які файли в Git-репозиторії змінила Bash-команда, поки вона виконувалась. Показує diff і передає його у PostToolUse-хуки на Bash. Потребує v2.1.269+.

Що зміниться

Без ключа запис ведеться лише в режимах auto і bypassPermissions. true рахується тільки з user, --settings чи managed. Змінна оточення: CLAUDE_CODE_BASH_EDIT_DIFF.

settings.json
{
  "bashEditDiffEnabled": true
}
showClearContextOnPlanAcceptboolean
Що робить

Додає першим пунктом у меню схвалення плану варіант «Yes, clear context and …». Типово false.

Що зміниться

З true схвалити план можна одразу з очищенням контексту: корисно, коли дослідження забило вікно, а виконанню потрібен чистий старт.

settings.json
{
  "showClearContextOnPlanAccept": true
}

Діалоги, таймаути й сповіщення

askUserQuestionTimeoutenumuser або managed
Що робить

Дозволяє діалогу AskUserQuestion, на який ніхто не відповів, автоматично продовжити після періоду бездіяльності: Claude Code відправляє варіанти, які ти вже встиг вибрати.

Що зміниться

Значення: "60s", "5m", "10m", "never" (типово). Корисно для довгих сесій, які ти залишаєш без нагляду. Змінна CLAUDE_AFK_TIMEOUT_MS перекриває ключ.

settings.json
{
  "askUserQuestionTimeout": "5m"
}
dialogExpiryenumuser або managed
Що робить

Дедлайн для діалогів, які Claude Code пересилає віддаленому клієнту: Remote Control або хосту SDK. Потребує v2.1.224+.

Що зміниться

Значення: "60s", "5m" (типово), "10m", "never". Змінна оточення: CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS.

settings.json
{
  "dialogExpiry": "10m"
}
autoContinueAtUsageLimitbooleanuser або managed
Що робить

Коли ліміт використання claude.ai зупиняє сесію, Claude Code чекає в цій самій відкритій сесії й сам продовжує задачу після скидання ліміту. Типово true. Потребує v2.1.234+.

Що зміниться

З false сесія просто зупиняється, і продовжувати треба вручну. Значення з project чи local може лише вимкнути функцію, і то лише якщо не задано значення в user, --settings чи managed.

settings.json
{
  "autoContinueAtUsageLimit": false
}

Доступність

axScreenReaderboolean
Що робить

Режим для скрінрідерів: плоский текст без декоративних рамок і анімацій. Працює на класичному рендерері, тому ключ tui під час його дії ігнорується.

Що зміниться

Типово вимкнено. Пріоритет: прапорець --ax-screen-reader, потім змінна CLAUDE_AX_SCREEN_READER, потім ключ. Разом із prefersReducedMotion (див. вище) дає мінімально рухливий інтерфейс.

settings.json
{
  "axScreenReader": true,
  "prefersReducedMotion": true
}

Застарілі ключі

Ці ключі не потрібно додавати в нові конфіги.

КлючСтанЩо робити
voiceEnabledзастарілий з v2.1.92, ще читаєтьсяЗаміни на voice.enabled (див. картку voice вище)
keybindingFlavorзастарілий з v2.1.261, не має ефектуВидали. Клавіші редагування слів завжди працюють за readline
15

Агенти, сесії й workflows

Ключі для головного агента, фонових сесій, agent teams і динамічних workflows

#

Ключі, що вирішують, ким працює головний потік, як сесії спілкуються між собою і чи доступні динамічні workflows. Самі поняття — субагенти, agent teams, workflows — пояснені на сторінці Команди та агенти; тут лише налаштування. Усі ключі читаються з будь-якого файла, якщо не вказано інакше.

Головний потік і фонові агенти

agentstring
Що робить

Запускає головний потік як іменований субагент: Claude Code застосовує до сесії системний промпт, обмеження інструментів і модель цього субагента (вбудованого чи власного). Також задає типове значення для диспетчеризації через claude agents.

Що зміниться

Без ключа працює звичайна сесія. Прапорець --agent перекриває ключ. Зручно закріпити за репозиторієм, скажімо, рев’юера чи агента міграцій Django.

settings.json
{
  "agent": "code-reviewer"
}
disableAgentViewboolean
Що робить

Вимикає фонових агентів і agent view: claude agents, --bg, /background і супервізор на вимогу.

Що зміниться

Для середовищ, де фонові процеси заборонені політикою. Змінна оточення: CLAUDE_CODE_DISABLE_AGENT_VIEW.

settings.json
{
  "disableAgentView": true
}
processWrapperstringuser або managed
Що робить

На macOS і Linux ставить корпоративний launcher перед фоновими процесами, які запускає Claude Code. Значення — префікс argv; launcher мусить виконати exec у Claude Code. Потребує v2.1.210+.

Що зміниться

Дозволяє пропускати фонові процеси через аудит чи профілювання. Змінна оточення: CLAUDE_CODE_PROCESS_WRAPPER (з project і local settings її задати не можна).

settings.json
{
  "processWrapper": "/opt/corp/launcher --profile claude"
}
teammateModeenum
Що робить

Де Claude Code показує teammates з agent teams: у твоїй основній панелі терміналу чи в окремих split-панелях.

Що зміниться

Значення: "in-process" (типово), "auto", "tmux", "iterm2". Прапорець --teammate-mode перекриває ключ на одну сесію.

settings.json
{
  "teammateMode": "auto"
}

Зв’язок між сесіями

crossSessionInboundenum
Що робить

Що ця сесія робить із повідомленнями, які надходять від твоїх інших сесій Claude Code. Потребує v2.1.224+.

Що зміниться

Значення: "accept", "hold" (показати сповіщення, не доставляючи повідомлення), "refuse". Без ключа рішення приймається для кожного повідомлення окремо. Значення з project чи local застосовується лише якщо воно суворіше.

settings.json
{
  "crossSessionInbound": "hold"
}
isolatePeerMachinesboolean
Що робить

Вимагає твого явного схвалення, перш ніж SendMessage від Claude дійде до сесії поза цією машиною. Потребує v2.1.224+.

Що зміниться

Захист від того, щоб агент розсилав повідомлення між твоїми машинами без відома. true з будь-якого рівня застосовується.

settings.json
{
  "isolatePeerMachines": true
}

Динамічні workflows

enableWorkflowsboolean
Що робить

Вмикає або вимикає динамічні workflows для тебе особисто.

Що зміниться

Без ключа workflows увімкнені, крім плану Pro, де вони вимкнені типово. Для вимкнення для всіх, кого зачіпають settings, дивись disableWorkflows.

settings.json
{
  "enableWorkflows": true
}
disableWorkflowsboolean
Що робить

Вимикає динамічні workflows і вбудовані команди workflows для всіх, кого досягають ці settings. Типово false.

Що зміниться

Власнику репозиторію чи адміну достатньо виставити true у спільному файлі. Змінна оточення: CLAUDE_CODE_DISABLE_WORKFLOWS.

settings.json
{
  "disableWorkflows": true
}
workflowKeywordTriggerEnabledboolean
Що робить

Чи запускає динамічний workflow слово ultracode, набране у промпті. Типово true.

Що зміниться

З false слово у промпті лишається звичайним текстом і workflow не запускає; режим ultracode все одно вмикається ключем ultracode чи /effort ultracode.

settings.json
{
  "workflowKeywordTriggerEnabled": false
}
workflowSizeGuidelineenum
Що робить

Орієнтир для кількості агентів у динамічних workflows, які пише Claude. Це порада, а не жорсткий ліміт. Потребує v2.1.219+.

Що зміниться

Типово "medium", на плані Pro — "small" (з v2.1.271).

settings.json
{
  "workflowSizeGuideline": "small"
}
"small"менше 5 агентів
"medium"менше 10 агентів (типово)
"large"менше 50 агентів
"unrestricted"без орієнтира
16

Remote, Desktop і сповіщення

Remote Control, хмарні сесії, Desktop-застосунок, push-сповіщення, Artifact

#

Remote Control, хмарні сесії, desktop-застосунок, сповіщення та Artifact. Багато ключів тут для адміністраторів: вони читаються лише з managed settings (файл, MDM, server-managed) і ігноруються в user, project та local. Для managed-ключів приклади показано у managed-settings.json.

Сповіщення

preferredNotifChannelenum
Що робить

Як Claude Code повідомляє тебе, що задача завершена або чекає дозволу.

Що зміниться

Типово "auto".

settings.json
{
  "preferredNotifChannel": "terminal_bell"
}
"auto"десктоп-сповіщення в iTerm2, Ghostty і Kitty; у Terminal.app дзвінок, лише якщо його звуковий дзвінок вимкнено; в інших терміналах нічого (типово)
"terminal_bell"символ дзвінка в будь-якому терміналі
"iterm2", "iterm2_with_bell"сповіщення iTerm2 (з дзвінком чи без)
"kitty", "ghostty"нативні сповіщення цих терміналів
"notifications_disabled"без сповіщень
inputNeededNotifEnabledboolean
Що робить

Push-сповіщення на телефон, коли permission-запит або питання чекає на твою відповідь. Типово false.

Що зміниться

Дозволяє піти від терміналу й повернутися лише тоді, коли Claude справді застряг. Потрібне підключення Remote Control.

settings.json
{
  "inputNeededNotifEnabled": true
}
agentPushNotifEnabledboolean
Що робить

Дозволяє Claude самому надсилати push на телефон, коли він вважає, що це варто зробити. Типово false.

Що зміниться

Відрізняється від inputNeededNotifEnabled: тут рішення приймає модель (наприклад, довгий прогін завершився). Потребує підключеного Remote Control.

settings.json
{
  "agentPushNotifEnabled": true
}
awaySummaryEnabledboolean
Що робить

Однорядковий підсумок сесії, коли ти повертаєшся до терміналу після кількох хвилин відсутності.

Що зміниться

Без ключа підсумок показується. З false вимикається. Змінна оточення: CLAUDE_CODE_ENABLE_AWAY_SUMMARY.

settings.json
{
  "awaySummaryEnabled": false
}

Remote Control і хмарні сесії

remoteControlAtStartupboolean
Що робить

Автоматично підключає Remote Control на старті кожної інтерактивної сесії.

Що зміниться

Без ключа діє адмінський дефолт організації, якщо він є; інакше Remote Control вмикається вручну (/remote-control, --remote-control). Значення false з project чи local перекриває навіть true з managed, а true з project чи local ігнорується: репозиторій може відмовитися від автопідключення, але не ввімкнути його.

settings.json
{
  "remoteControlAtStartup": true
}
disableRemoteControlboolean
Що робить

Повністю вимикає Remote Control: Claude Code відмовляється від claude remote-control, прапорця --remote-control, автозапуску й перемикача в сесії. Типово false.

Що зміниться

Ключ читається з будь-якого файла; щоб примусово заборонити Remote Control в організації, клади його в managed settings (наприклад, через MDM).

settings.json
{
  "disableRemoteControl": true
}
remote.defaultEnvironmentIdstring
Що робить

Типове хмарне середовище для сесій, які ти створюєш з CLI, наприклад через claude --cloud. Значення виду env_… або ccpool_…. Ключ пише команда /remote-env.

Що зміниться

Без ключа береться середовище, яке хостить Anthropic (якщо воно є у твоєму списку), інакше перше середовище, що не є bridge-середовищем Remote Control. Прапорець --environment перекриває ключ для однієї сесії. ID self-hosted середовищ (ccpool_…) приймаються лише з user, managed або --settings.

settings.json
{
  "remote": {
    "defaultEnvironmentId": "env_0123abcd"
  }
}
disableDeepLinkRegistrationstring
Що робить

Забороняє Claude Code реєструвати в операційній системі обробник протоколу claude-cli://. Єдине значення — "disable".

Що зміниться

Після цього посилання claude-cli:// не відкриватимуть Claude Code.

settings.json
{
  "disableDeepLinkRegistration": "disable"
}

Artifact

enableArtifactboolean
Що робить

Керує інструментом Artifact, що публікує вивід сесії як приватну веб-сторінку на claude.ai. Практично має сенс лише false: це вимикає інструмент. Потребує v2.1.196+.

Що зміниться

false з будь-якого файла перемагає, і жодним іншим значенням його вже не ввімкнути. Для середовищ, де вивід сесії не можна публікувати назовні.

settings.json
{
  "enableArtifact": false
}

Desktop-застосунок: SSH, браузер, симулятор

sshConfigsarrayuser або managed
Що робить

Додає SSH-підключення у випадаючий список середовищ Desktop. Кожен елемент: id, name, sshHost, необов’язково sshPort та sshIdentityFile.

Що зміниться

Розробники одразу бачать dev-машини команди. Записи з managed доступні лише для читання.

dev-VM для команди
settings.json
{
  "sshConfigs": [
    {
      "id": "dev-vm",
      "name": "Dev VM (Django)",
      "sshHost": "deploy@dev.example.com",
      "sshPort": 22
    }
  ]
}
sshHostAllowlistarraymanaged only
Що робить

Обмежує хости, до яких Desktop може підключитися по SSH. Шаблони без урахування регістру: точне ім’я, * або на кшталт *.example.com (сам домен і всі піддомени). Порожній масив вимикає SSH-сесії. Читає лише Desktop-застосунок (Claude Desktop v2.26454.0+).

Що зміниться

Без ключа дозволені будь-які хости.

managed-settings.json
{
  "sshHostAllowlist": ["*.devboxes.example.com"]
}
disableDesktopLocalSessionsbooleanmanaged only
Що робить

Вимикає Code-сесії, що виконуються на самому пристрої в Desktop. Для розгортань, де розробники мають працювати на віддалених машинах по SSH. Враховується лише JSON true. Claude Desktop v1.37937.0+.

Що зміниться

Локальні сесії в Desktop недоступні; лишаються SSH і хмарні.

managed-settings.json
{
  "disableDesktopLocalSessions": true
}
browserExternalPageToolsstringmanaged only
Що робить

Забороняє Claude використовувати свої інструменти, щоб читати чи керувати зовнішніми сторінками в панелі Browser Desktop-застосунку. Значення — "disabled" (також приймається "disable"). CLI ключ ігнорує.

Що зміниться

Claude не читає зовнішні сторінки й не діє на них у панелі Browser.

managed-settings.json
{
  "browserExternalPageTools": "disabled"
}
disableBrowserExternalNavigationbooleanmanaged only
Що робить

Вимикає зовнішній браузинг у панелі Browser Desktop-застосунку для людини й для Claude разом. Прев’ю localhost dev-серверів працюють. Враховується лише true.

Що зміниться

Жорсткіша версія browserExternalPageTools: обмежує і самого користувача.

managed-settings.json
{
  "disableBrowserExternalNavigation": true
}
disableMobileSimulatorToolsbooleanmanaged only
Що робить

Блокує інструменти Claude для панелі iOS Simulator у Desktop-застосунку. Враховується лише true.

Що зміниться

Claude не отримує інструментів для керування iOS Simulator.

managed-settings.json
{
  "disableMobileSimulatorTools": true
}

Застарілі ключі

КлючСтанЩо робити
disableArtifactзастарілий, замінений на enableArtifacttrue дорівнює enableArtifact: false, а false ігнорується. Використовуй enableArtifact: false
17

Глобальний конфіг: ~/.claude.json

Ключі, які працюють лише в ~/.claude.json, а не в settings.json

#

Окрім settings.json, Claude Code веде файл ~/.claude.json. Він його пише сам: там лежать сесія входу, конфігурації MCP-серверів, стан по проєктах (наприклад, рішення про довіру до папки) і «глобальні» ключі, які змінює /config. Ключі нижче працюють лише в ~/.claude.json; в будь-якому з settings-файлів Claude Code їх ігнорує.

settings.json~/.claude.json
Хто пишети (або команда через /config, /model тощо)Claude Code; можна й вручну
Рівніuser, project, local, managedодин файл у домашній директорії
Що тамpermissions, hooks, env, sandbox, модель, UIвхід, MCP-сервери, довіра до проєктів, ключі нижче
У gitproject / local можна комітити чи ігноруватиніколи не комітиться
Помилка в файлі

Якщо ~/.claude.json не парситься, Claude Code копіює зламаний файл у ~/.claude/backups/.claude.json.corrupted.<timestamp> і питає, вийти й виправити руками чи скинути конфіг. Перед кожним записом зберігаються резервні копії; відновити стан можна з однієї з п’яти останніх .claude.json.backup.<timestamp> у ~/.claude/backups/.

IDE

autoConnectIdebooleanлише ~/.claude.json
Що робить

Автоматично підключається до запущеної IDE (VS Code чи JetBrains), коли ти стартуєш Claude Code із зовнішнього терміналу. Типово false.

Що зміниться

У /config з’являється, лише якщо ти працюєш поза терміналом VS Code чи JetBrains. Змінна CLAUDE_CODE_AUTO_CONNECT_IDE має вищий пріоритет.

~/.claude.json
{
  "autoConnectIde": true
}
autoInstallIdeExtensionbooleanлише ~/.claude.json
Що робить

Автоматично встановлює розширення Claude Code для IDE, коли ти запускаєш його з терміналу VS Code. Типово true.

Що зміниться

З false розширення не ставиться саме. Змінна оточення: CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL.

~/.claude.json
{
  "autoInstallIdeExtension": false
}
diffToolenumлише ~/.claude.json
Що робить

Де показувати diff для змін від Edit або Write, коли підключено IDE VS Code чи JetBrains: у diff-в’ювері IDE ("auto", типово) чи в терміналі ("terminal").

Що зміниться

З "terminal" схвалюєш правки, не переключаючись у IDE.

~/.claude.json
{
  "diffTool": "terminal"
}
claudeInChromeDefaultEnabledbooleanлише ~/.claude.json
Що робить

Стартує кожну інтерактивну CLI-сесію з увімкненою інтеграцією з Chrome, без прапорця --chrome. Підтримка в розширенні VS Code з v2.1.287.

Що зміниться

Без ключа інтеграція вимкнена, поки не передати --chrome.

~/.claude.json
{
  "claudeInChromeDefaultEnabled": true
}

Редагування й буфер обміну

copyFullResponsebooleanлише ~/.claude.json
Що робить

Змушує /copy щоразу копіювати всю відповідь, без вибору блоку коду. Типово false.

Що зміниться

Без ключа /copy показує вибір (відповідь чи окремий блок коду).

~/.claude.json
{
  "copyFullResponse": true
}
copyOnSelectbooleanлише ~/.claude.json
Що робить

Копіює виділений мишею текст у буфер обміну одразу після виділення, у fullscreen-рендерінгу та agent view. Типово true.

Що зміниться

З false копіювати треба вручну.

~/.claude.json
{
  "copyOnSelect": false
}
externalEditorContextbooleanлише ~/.claude.json
Що робить

Коли Ctrl+G відкриває зовнішній редактор, буфер починається з попередньої відповіді Claude у вигляді рядків-коментарів із #. Типово false.

Що зміниться

Зручно, коли пишеш довгу відповідь у $EDITOR і хочеш бачити, на що відповідаєш.

~/.claude.json
{
  "externalEditorContext": true
}

Agent view і pull request

defaultToAgentsViewbooleanлише ~/.claude.json
Що робить

Команда claude без аргументів відкриває agent view замість нової розмови. Типово false.

Що зміниться

Підходить, якщо ти працюєш переважно з фоновими агентами. Про agent view — на сторінці агентів.

~/.claude.json
{
  "defaultToAgentsView": true
}
leftArrowOpensAgentsbooleanлише ~/.claude.json
Що робить

Стрілка ← на порожньому промпті переводить сесію у фон і відкриває agent view. Типово true.

Що зміниться

З false комбінація вимкнена: корисно, якщо випадково тиснеш ← у порожньому полі.

~/.claude.json
{
  "leftArrowOpensAgents": false
}
prStatusFooterEnabledbooleanлише ~/.claude.json
Що робить

Показує у футері бейдж відкритого pull request чи merge request для поточної гілки та перевірку, що за ним стоїть. Типово true.

Що зміниться

З false бейдж і відповідні запити зникають.

~/.claude.json
{
  "prStatusFooterEnabled": false
}

Видалені ключі

КлючВидаленоПримітка
permissionExplainerEnabledv2.1.257Разом із поясненням команди по Ctrl+E на shell-запитах дозволу. Ефекту немає
teammateDefaultModelv2.1.234Ефекту немає. Як Claude Code обирає модель teammate, див. розділ про agent teams

Приклад фрагмента ~/.claude.json (решта файла — вхід, MCP, проєкти — лишається як є):

~/.claude.json (фрагмент)
{
  "autoConnectIde": true,
  "diffTool": "terminal",
  "copyOnSelect": false,
  "prStatusFooterEnabled": true
}
18

повний приклад

Готовий managed-settings.json для Django/Vue команди

#
managed-settings.json — логістична компанія
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  // схема може відставати від найновіших ключів CLI

  // Модель і рівень thinking
  "model": "sonnet",
  "availableModels": ["sonnet", "opus", "haiku"],
  "effortLevel": "high",
  "maxEffortLevel": "xhigh",
  "fallbackModel": ["claude-haiku-5-5"],
  "fastModePerSessionOptIn": true,

  // Мова відповідей
  "language": "ukrainian",

  // Дозволи
  "permissions": {
    "defaultMode": "default",
    "disableBypassPermissionsMode": "disable",
    "allow": [
      "Bash(git status)", "Bash(git diff *)", "Bash(git log *)",
      "Bash(git add *)",
      "Bash(python manage.py showmigrations)",
      "Bash(npm run lint)", "Bash(npm run test:unit)",
      "Bash(docker compose ps)", "Bash(docker compose logs *)"
    ],
    "ask": [
      "Bash(git commit *)", "Bash(git push *)",
      "Bash(python manage.py migrate)",
      "Bash(docker compose up *)", "Bash(docker compose down *)"
    ],
    "deny": [
      "Read(**/.env)", "Read(**/.env.*)",
      "Read(~/.ssh/**)", "Read(~/.aws/**)",
      "Bash(sudo *)", "Bash(su *)",
      "Bash(rm -rf /)", "Bash(dd *)"
    ]
  },

  // Змінні середовища
  "env": {
    "DISABLE_TELEMETRY": "1",
    "BASH_DEFAULT_TIMEOUT_MS": "300000"
  },

  // Хуки
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{ "type": "command", "command": "~/.claude/format.sh", "async": true }]
    }],
    "TaskCompleted": [{
      "hooks": [{ "type": "command", "command": "cd "$CLAUDE_PROJECT_DIR" && python manage.py test --failfast 1>&2 || exit 2", "timeout": 120 }]
    }],
    "Stop": [{
      "hooks": [{ "type": "command", "command": "python3 ~/.claude/notify-telegram.py", "async": true }]
    }]
  },

  // Enterprise
  "forceLoginMethod": "console",
  "autoUpdatesChannel": "stable",
  "requiredMinimumVersion": "2.1.280",
  "cleanupPeriodDays": 14,
  "allowManagedPermissionRulesOnly": true,
  "allowManagedHooksOnly": true,
  "companyAnnouncements": ["🔒 Секрети — тільки у Vault, не в .env!"],

  // Git
  "attribution": { "commit": "", "pr": "" },
  "includeGitInstructions": false
}