Tudo na Nabucodonosor passa por aquele painel de monitores. Tudo no Claude passa pelo settings.json.
O que é o settings.json?
Quatro características que fazem desse arquivo o painel único de controle de tudo que o Claude Code pode ou não pode fazer.
Centraliza tudo
Permissões, hooks, ambiente, modelo, statusline. Uma única tela, todas as decisões.
Hierárquico
Três níveis, do local ao global. O mais específico sempre vence quem é mais genérico.
JSON declarativo
Sem script, sem mágica. Você descreve o estado desejado; o Claude obedece a configuração.
Compartilhável
Vai pro Git com o projeto. Time inteiro com o mesmo painel, sem improviso de cada dev.
Três níveis, uma só verdade
O Claude lê os três e faz merge. O mais específico vence o mais genérico. Quem está mais perto do seu código manda.
Overrides locais
Seu PC, sua máquina. Fora do Git.
Projeto
Vai pro Git, vale para o time.
Usuário
Vale em todo projeto da sua máquina.
# Nivel 1: overrides locais (fora do git) .claude/settings.local.json ↳ no .gitignore por padrao ↳ so vale na sua maquina ↳ vence os outros dois # Nivel 2: configuracao do projeto (vai pro git) .claude/settings.json ↳ compartilhado com o time ↳ vence o global do usuario ↳ define a "lei" do repositorio # Nivel 3: configuracao global do usuario ~/.claude/settings.json ↳ vale em todos os projetos ↳ seu padrao pessoal ↳ base quando nao ha override
Regra de ouro: precedência é por chave. Se você define permissions nos três, vale o nível 1. Se só o nível 3 tem env, ele permanece.
Settings · CLAUDE.md · Memory
Três peças que parecem fazer a mesma coisa, mas cobrem aspectos diferentes. Saber quando usar cada uma evita conflito de regras.
Em resumo: settings.json diz o que pode acontecer; CLAUDE.md diz como o código deve ser; Memory lembra o que já foi decidido.
Como o Claude resolve
O merge dos três níveis
O Claude lê os três settings em ordem, do mais genérico ao mais específico, e produz uma configuração efetiva única. Quem está em cima, manda.
Um settings.json de verdade
Permissões, hooks, env, modelo. Tudo num só arquivo. Esse é o painel inteiro de um projeto sério.
{
"model": "claude-sonnet-4-6",
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(git status)",
"Read(./src/**)"
],
"deny": [
"Read(./.env)",
"Read(./secrets/**)",
"Bash(rm -rf:*)"
],
"ask": [
"Bash(git push:*)",
"WebFetch(domain:*)"
]
},
"hooks": {
"PreToolUse": [
{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "./scripts/audit.sh" }] }
],
"PostToolUse": [
{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "npm run lint" }] }
]
},
"env": {
"ANTHROPIC_LOG_LEVEL": "info",
"PROJECT_ENV": "dev"
},
"includeCoAuthoredBy": true,
"cleanupPeriodDays": 30
}
permissions
Allow, deny, ask
hooks
Eventos do ciclo
env
Variáveis injetadas
model
Modelo default
Anatomia: permissions
Três listas controlam o que o agente pode fazer sem perguntar, o que está proibido e o que precisa confirmar.
allow
Pode sem perguntar
"allow": [ "Bash(npm test:*)", "Bash(git status)", "Bash(git log:*)", "Read(./src/**)", "Edit" ]
O agente executa direto. Bom para comandos repetitivos e seguros do dia a dia.
deny
Bloqueio absoluto
"deny": [ "Read(./.env)", "Read(./secrets/**)", "Bash(rm -rf:*)", "Bash(curl:*)" ]
Nem com confirmação. Use para tudo que jamais pode acontecer: segredos, comandos destrutivos.
ask
Pergunta antes
"ask": [ "Bash(git push:*)", "Bash(npm publish)", "WebFetch(domain:*)", "Bash(docker:*)" ]
Ações sensíveis mas legítimas. O agente pede um "sim" antes de executar.
Sintaxe de matcher
Bash(npm test)
Match exato. Só esse comando, nada mais.
Bash(npm test:*)
Wildcard. Qualquer coisa que começa com "npm test".
Read(./src/**)
Glob. Qualquer arquivo recursivo dentro de src.
WebFetch(domain:example.com)
Modificador. Restringe ao domínio indicado.
Anatomia: hooks
Comandos shell que rodam automaticamente em eventos do ciclo de vida do agente. Vigilância contínua, sem você precisar lembrar.
"hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "./scripts/audit.sh" } ] } ], "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "npm run lint" } ] } ] }
Por que vive no settings.json: hooks são gatilhos do sistema; precisam ser declarativos, versionados e aplicados antes do agente decidir. Não dá pra deixar isso para o prompt.
Ambiente injetado
Variáveis que aparecem em todos os comandos shell e hooks do projeto. Sem precisar exportar no terminal, sem depender do dotfile do dev.
Padrão de log do projeto
Feature flags por ambiente
Chaves de API públicas (nunca segredos)
{
"env": {
"ANTHROPIC_LOG_LEVEL": "debug",
"NODE_ENV": "development",
"PROJECT_NAME": "engenharia-software",
"FEATURE_NEW_PARSER": "on"
}
}
Nunca coloque segredos no settings.json do projeto. Esse arquivo vai pro Git. Para chaves de API use apiKeyHelper ou um settings.local.json com a chave fora do versionamento.
Seu primeiro settings.json
Um arquivo, três blocos, um painel inteiro funcionando. Sem instalar nada, sem mexer no código.
{
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(git status)"
],
"deny": [
"Read(./.env)"
]
},
"env": {
"PROJECT_ENV": "dev"
},
"includeCoAuthoredBy": true
}
Três blocos: permissions protege o que importa, env injeta contexto, includeCoAuthoredBy assina os commits.
O Claude leu o settings antes de qualquer ação. Cada ferramenta passou pelo painel; o painel decidiu se libera, bloqueia ou pergunta.
Crie a pasta
.claude/ na raiz do projeto.
Salve o JSON
.claude/settings.json com o conteúdo acima.
Reinicie a sessão
O Claude relê os settings no início e aplica imediatamente.
Quando você não quer abrir o JSON
Dois slash commands abrem o painel sem você precisar mexer no arquivo na mão.
Slash command
/permissions
Editor visual para a seção de permissões. Adiciona, remove, muda entre allow, deny e ask sem você abrir o JSON.
Slash command
/config
Painel geral de configuração. Modelo, tema, statusline, includeCoAuthoredBy, tudo num menu.
Sacada: os dois comandos escrevem no mesmo arquivo. UI bonita por cima, JSON honesto por baixo. Quando o time precisa revisar, o diff sai limpo.
Cinco settings que valem o setup
Configurações que viram músculo do seu projeto. Escreve uma vez, vale para sempre.
Setting 1 · allowlist
Bash sem fricção
Comandos triviais e repetitivos não precisam de confirmação a cada turno. Coloque tudo que é seguro no allow e libere o ritmo do agente.
{
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(npm run lint)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git branch:*)",
"Bash(ls:*)",
"Bash(pwd)"
]
}
}
na linha 42. Vou olhar.
Ganho prático: zero "permite?" para tarefas óbvias. O agente roda, observa, decide o próximo passo sem você precisar babá-lo.
Setting 2 · denylist
Segredos intocáveis
Nada de "ah, ele não vai ler o .env". Bloqueie no painel e durma tranquilo. O agente nem cogita acessar.
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(./**/*.pem)",
"Read(./**/*credentials*)",
"Bash(rm -rf:*)",
"Bash(curl:*)",
"Bash(sudo:*)"
]
}
}
Se a chave precisa estar
disponível, configure via
apiKeyHelper no settings.
Ganho prático: defesa em profundidade. Mesmo se o prompt induzir o agente ao erro, o painel impede o vazamento.
Setting 3 · hook UserPromptSubmit
Auditoria de prompts
Toda vez que você manda um prompt, um script registra. Útil para compliance, retroativa de erros, ou para entender quanto tempo gasta em cada tipo de tarefa.
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "./scripts/audit-prompt.sh"
}
]
}
]
}
}
#!/bin/bash # Le o prompt do stdin (JSON do Claude) PROMPT=$(jq -r .prompt) DATE=$(date --iso-8601=seconds) echo "$DATE | $USER | $PROMPT" \ >> .claude/audit.log
Ganho prático: rastro auditável de tudo que foi pedido ao agente. Em ambiente regulado, isso vale ouro. Em ambiente normal, vira métrica de produtividade.
Setting 4 · env
Debug ligado por padrão
Quando algo não funciona, você precisa de log. Ative o nível debug no settings.local.json e o Claude passa a contar tudo que faz, sem você lembrar de exportar variável.
{
"env": {
"ANTHROPIC_LOG_LEVEL": "debug",
"CLAUDE_TRACE": "1",
"DEBUG": "claude:*"
}
}
Use o settings.local.json: debug é seu, não do time. Não suja o painel compartilhado.
quebra, você sabe onde.
Ganho prático: debug não fica esquecido. O painel local já liga. Quando precisar desligar, é uma linha.
Setting 5 · statusLine
Linha de status vivente
A linha de status é o painel embaixo do prompt. Por padrão mostra modelo e diretório. Com statusLine ela passa a mostrar branch, status do Git e qualquer coisa que você quiser.
{
"statusLine": {
"type": "command",
"command": "./scripts/statusline.sh"
}
}
#!/bin/bash BRANCH=$(git branch --show-current) DIRTY=$(git status --porcelain | wc -l) MODEL=$(jq -r .model) echo "⎇ $BRANCH" \ "·" \ "$DIRTY arquivos sujos" \ "·" \ "$MODEL"
de validação JWT.
Ganho prático: contexto perene à vista. Você nunca esquece em qual branch está nem quanto trabalho não comitado tem na fila.
Os cinco settings lado a lado
Resumo das configurações práticas que você acabou de ver.
| Chave | O que resolve | Ganho | |
|---|---|---|---|
| permissions.allow | Libera Bash repetitivo (test, lint, status, log) | Zero fricção | |
| permissions.deny | Bloqueia .env, segredos e comandos destrutivos | Defesa absoluta | |
| hooks.UserPromptSubmit | Registra cada prompt enviado em um log local | Auditoria contínua | |
| env.ANTHROPIC_LOG_LEVEL | Liga debug detalhado sem variável manual | Diagnóstico fácil | |
| statusLine | Mostra branch, sujeira do Git e modelo o tempo todo | Contexto perene |
Cinco chaves dentro de um único arquivo. Você cola, ajusta os caminhos e seu projeto inteiro passa a se comportar como um produto sério.
Quer dominar cada peça?
O livro Engenharia de Software para Agentes Inteligentes destrincha settings, commands, hooks, skills, MCP, subagents e tudo que faz o agente trabalhar a seu favor.
·
@canalsandeco
Quem pode, quando dispara, em qual mundo. Tudo num só painel, e a Nabucodonosor faz o resto.
Sem settings, o agente improvisa. Com settings, o projeto tem lei. Esse arquivo conecta hooks, permissions, env e o restante do ecossistema num único ponto de verdade.