Configuração do Claude Code em time: o que versionar no repositório e o que fica só na sua máquina

A configuração do Claude Code em time se divide em duas caixas: o que vale para qualquer pessoa que abre o projeto vai pro Git (o CLAUDE.md, o .claude/settings.json, o .claude/agents/, o .claude/skills/ e o .mcp.json com chave via ${VAR}), e o que é gosto seu, muda de máquina ou toca em credencial fica local (.claude/settings.local.json, CLAUDE.local.md e a memória automática no home). Aprovação com "Yes, don’t ask again" vira regra sua, não do time. E quando duas configurações brigam, o /permissions mostra de qual arquivo de settings cada regra veio
Fala aí, beleza? Tem um momento clássico na vida de todo time que adota o Claude Code junto: o repositório começa a receber arquivo de configuração de todo mundo, sem ninguém ter combinado nada
Aí surge a pergunta chata no code review: isso aqui é regra do projeto ou é gosto seu?
Existe uma linha no meio disso, e ela é bem clara. De um lado, o que vale para qualquer pessoa que abre o projeto e por isso merece viver no Git. Do outro, o que é preferência sua, muda de máquina pra máquina ou toca em credencial, e por isso não deveria sair do seu computador
Este post é sobre essa linha, ou seja, é sobre convivência e limite
O foco aqui é onde cada arquivo mora e para quem ele passa a valer 🙂
O que você precisa ter antes de organizar isso no time
Não tem mistério aqui, mas pular esses três pontos costuma dar dor de cabeça depois
- um repositório git com o time trabalhando no mesmo checkout
- Claude Code instalado na máquina de cada pessoa
- um acordo mínimo sobre quem revisa mudança em arquivo de configuração compartilhada
Esse último é o que mais gente ignora
Hooks e servidores MCP não são "ajustinho", eles entram em PR como código entra, com alguém olhando do outro lado
E por quê tanto rigor? Porque o Claude Code lê instruções, settings, skills, subagents e memória do diretório do projeto E do ~/.claude no seu home, e faz isso em toda sessão
Ou seja: no momento em que você commita um arquivo do .claude do projeto, ele passa a valer na máquina alheia também. Isso está na documentação do diretório .claude, e é justamente o desenho da coisa: arquivo de projeto existe pra ser compartilhado
Se você conhece a lógica de dependência de projeto versus pacote global instalado na sua máquina, é bem parecido: um todo mundo herda, o outro é só seu
Como montar a configuração compartilhada do projeto passo a passo
A ideia deste bloco é simples: tudo aqui é coisa que o time inteiro deveria receber ao clonar o repositório
Domine o Claude Code do básico ao avançado
Você vai aprender a criar sistemas completos com Claude Code, sem precisar ser programador. Inscreva-se para ter acesso a um desconto de lançamento e bônus especiais!
- Comece pelo
CLAUDE.mdna raiz, com as instruções persistentes do projeto. Ele é lido no início de cada sessão, então é o lugar certo pra convenção que vale pra todo mundo
projeto/
CLAUDE.md
.mcp.json
.claude/
settings.json
agents/
skills/A documentação de memória recomenda mirar menos de 200 linhas por arquivo CLAUDE.md, porque arquivo longo come contexto e derruba a aderência
É o mesmo raciocínio do prompt que ele verifica sozinho antes de dizer que terminou: quanto menos texto disputando espaço, melhor
O erro comum deste passo: achar que quebrar tudo em imports @path reduz contexto. Não reduz, os arquivos importados carregam no lançamento da sessão do mesmo jeito. Import organiza, não economiza
- Use o
.claude/settings.jsoncomo o arquivo de settings do projeto. Ele é exatamente o arquivo pensado pra ser checado no controle de versão e compartilhado com o time
O erro comum deste passo: jogar preferência pessoal aqui dentro. Se é gosto seu, tem outro arquivo pra isso (chego lá no próximo bloco)
- Versione
.claude/agents/e.claude/skills/. Subagents de projeto ficam em.claude/agents/e a documentação de subagents recomenda explicitamente versioná-los pro time usar e melhorar em conjunto. Skills de projeto seguem a mesma pasta lógica, em.claude/skills/
E os comandos customizados? Foram fundidos em skills
Segundo a documentação de comandos, um arquivo em .claude/commands/ e uma skill em .claude/skills/<nome>/SKILL.md criam o mesmo /nome e funcionam igual, e a recomendação pra coisa nova é usar skill, que ainda ganha um diretório pra arquivos de apoio
O erro comum deste passo: criar tudo em ~/.claude/agents/ e ~/.claude/skills/ no seu home. Funciona lindamente na sua máquina, e ninguém do time vê nada
- Coloque servidor MCP de escopo de projeto no
.mcp.jsonda raiz. Esse arquivo pode ir pro controle de versão numa boa
São três escopos possíveis: local (só na sua máquina), projeto (compartilhado pelo .mcp.json no repo) e usuário (global, em todos os seus projetos)
Tome cuidado com uma coisa: chave de API NÃO se escreve no bloco env do arquivo, porque qualquer usuário da máquina consegue ler aquilo
O jeito certo é expansão de variável, que lê do ambiente de cada pessoa:
"headers": {
"Authorization": "Bearer ${API_TOKEN}"
}A sintaxe suportada é ${VAR}, que expande pro valor da variável de ambiente, e ${VAR:-default}, que usa um padrão quando a variável não está definida. Funciona em campos como URLs e headers
O erro comum deste passo: esquecer de avisar o time que, na primeira vez, o Claude Code pede aprovação do servidor de escopo de projeto antes de rodar. Quem clona não sai usando direto, tem um prompt no caminho (e ainda bem, né?)
- Pré-registre o marketplace de plugins do time no settings versionado. Dá pra deixar isso pronto no
.claude/settings.jsondo projeto:
{
"extraKnownMarketplaces": {
"my-team-tools": {
"source": {
"source": "github",
"repo": "your-org/claude-plugins"
}
}
},
"enabledPlugins": {
"plugin-name@marketplace-name": true
}
}Quando a pessoa confia na pasta do repositório, o Claude Code oferece instalar
O erro comum deste passo: confundir habilitar com instalar. Como está na documentação de plugins, a partir da versão 2.1.195 do Claude Code adicionar o marketplace não instala plugins de fonte externa, e um plugin habilitado só pelo .claude/settings.json do projeto, vindo de fonte externa como repositório GitHub ou pacote npm, NÃO carrega até o membro do time instalar
- Trate hooks com respeito. Hooks são comandos de shell definidos por você, declarados nos arquivos JSON de settings, e a própria documentação de hooks pede revisão antes de colocá-los em ambiente compartilhado ou de produção
Faz todo sentido: você está commitando comando de shell que vai rodar na máquina dos outros
O erro comum deste passo: mandar hook novo direto na main "porque é rapidinho". Esse é o tipo de linha que merece um par de olhos, sempre
O que fica só na sua máquina (e como garantir que não vaze pro Git)
Agora o outro lado da linha: preferência, experimentação e qualquer coisa que cheire a segredo
- Use o
.claude/settings.local.jsonpra preferência pessoal e experimentação. Esse arquivo existe justamente pra não ser commitado
E tem um detalhe que confunde MUITA gente: quando o próprio Claude Code salva uma configuração ali, num repositório que ainda não ignora o arquivo, ele adiciona o padrão **/.claude/settings.local.json ao arquivo de excludes GLOBAL do git, não ao .gitignore do projeto
A documentação de settings detalha como esse global é resolvido: sai do core.excludesFile do git config global quando é caminho absoluto ou com ~, senão $XDG_CONFIG_HOME/git/ignore, senão ~/.config/git/ignore
O erro comum deste passo: criar o arquivo na mão (ou pedir pro Claude escrever com a ferramenta Write) e assumir que ele já está protegido. Nesse caminho o ignore não é automático, você mesmo precisa colocar no gitignore:
.claude/settings.local.json
CLAUDE.local.md- Saiba onde a aprovação vai parar. Quando você aprova algo com "Yes, don’t ask again" e a regra é salva em definitivo, ela vai pro
settings.local.jsonda raiz do repositório git
Isso significa que ela é regra SUA, não do time
Pela documentação de permissões, a leitura e a escrita acontecem na raiz do repo git, resolvidas via worktrees pro checkout principal, então um arquivo só cobre sessões iniciadas em qualquer subpasta ou worktree
O erro comum deste passo: liberar um comando na sua máquina e jurar que "já está liberado pra todo mundo". Não está
- Deixe preferência pessoal por projeto no
CLAUDE.local.md. Ele fica na raiz do projeto e precisa entrar no.gitignore
Tem um caminho documentado na página de memória do Claude Code pra isso acontecer sozinho:
CLAUDE_CODE_NEW_INIT=1Com essa variável definida, rodar /init e escolher a opção pessoal adiciona o CLAUDE.local.md ao .gitignore automaticamente
O erro comum deste passo: criar o arquivo na correria, sem gitignore, e commitar suas manias pro time inteiro herdar
- Aceite que a memória automática não é compartilhável. A auto memory que o Claude escreve sozinho vive em
~/.claude/projects/<project>/memory/
O caminho <project> é derivado do repositório git, então todos os worktrees e subpastas do mesmo repo compartilham um diretório de auto memory
Agora, entre máquinas ou com ambientes cloud, nada disso sincroniza
O erro comum deste passo: contar com a memória automática como se fosse documentação do time. Se a informação é importante pra todo mundo, o lugar dela é o CLAUDE.md versionado
- Segredo é capítulo à parte. Pra credencial dinâmica ou rotativa existe o
apiKeyHelper, um script cuja saída vira a chave, em vez de chave estática dormindo num arquivo de configuração
Por padrão ele é chamado depois de 5 minutos ou em resposta a um HTTP 401, e o intervalo de refresh é configurável pela variável CLAUDE_CODE_API_KEY_HELPER_TTL_MS
E se liga nisso, que é o ponto que quase ninguém pensa: segredo vaza pelo transcript, não só pelo arquivo de config
Se uma ferramenta lê um .env ou um comando imprime uma credencial, aquele valor é gravado no arquivo de sessão, em projects/<project>/<session>.jsonl
Dá pra reduzir a exposição baixando o cleanupPeriodDays, que encurta a retenção dos transcripts, ou definindo a variável CLAUDE_CODE_SKIP_PROMPT_HISTORY, que pula a gravação de transcripts e do histórico de prompt em qualquer modo
O erro comum deste passo: proteger o arquivo de configuração e deixar o comando que cospe a chave rodando alegremente no terminal
Quando duas configurações brigam: quem vence e como descobrir
Essa é a parte que aparece depois de algumas semanas de uso em time, quando os arquivos começam a se cruzar
Sintoma: funciona na sua máquina e não na do colega
A causa quase sempre é merge entre escopos. As configurações são mescladas: valor escalar do escopo de maior prioridade sobrescreve, e array concatena (com exceções descritas na página de precedência)
Então você pode estar com um array somando as suas regras às do projeto, enquanto o colega tem só as do projeto
Sintoma: uma regra não muda por nada que você faça
Aqui a causa costuma ser configuração gerenciada (managed) pela organização
Managed é o nível mais alto e não é sobrescrito por outros escopos (com exceções documentadas na própria página), e é entregue via server delivery, perfis de configuração MDM, políticas de registro ou arquivos de managed settings
Se é isso, não adianta brigar no seu settings.local.json, o papo é com quem administra
Sintoma: um deny está bloqueando algo que um allow específico deveria liberar
As regras de permissão têm três tipos, allow (libera sem aprovação manual), ask (pede confirmação) e deny (bloqueia)
Segundo a documentação de permissões, a ordem de avaliação é deny, depois ask, depois allow, o primeiro match decide e especificidade não muda nada
Na prática: um deny amplo como Bash(aws *) bloqueia até o que casa com um allow mais específico como Bash(aws s3 ls)
Ou seja, deny não comporta exceção. Se você precisa de exceção, o deny está largo demais
Sintoma: um settings.local.json antigo continua mandando
Se existir um settings.local.json deixado por versão anterior, ele ainda é lido
Em conflito de mesma chave vale o valor do arquivo da raiz do repositório, mas as regras de permissão dos dois continuam em efeito
Traduzindo: você acha que apagou o comportamento, e ele volta
Sintoma: skill e subagent com o mesmo nome se comportam diferente
Porque a ordem de prioridade não é a mesma pros dois
Skills: managed > user > project
Subagents: managed > flag de CLI > project > user > plugin
Repare que em skills o seu arquivo pessoal ganha do projeto, e em subagents o projeto ganha do pessoal. É o tipo de detalhe que gera discussão longa no Slack sem necessidade
A solução (e como prevenir)
O atalho pra sair do achismo é o comando /permissions
Ele lista todas as regras de permissão e mostra de qual arquivo settings.json cada regra veio
/permissionsPra prevenir, duas combinações simples: nada de preferência pessoal no arquivo compartilhado, e mudança em hook, MCP ou permissão do projeto passa por PR igual código
O que aprendi instalando um pacote de configuração no meu próprio repositório
No vídeo abaixo eu instalo o GSD no Claude Code e, sem querer, o processo virou uma aula sobre exatamente esse tema: o que entra no repositório e o que fica na minha máquina
Primeira surpresa: a instalação acontece fora do Claude Code, por um comando npx, no terminal mesmo. Eu esperava um fluxo de plugin dentro da ferramenta e não é assim que funciona
Na instalação o assistente pergunta pra qual ferramenta de IA você quer instalar, e dava pra marcar mais de uma. Naquele momento escolhi só o Claude Code
Escolhi também a instalação global em vez da local, com o argumento de que os comandos só são ativados quando eu peço. Repare que essa decisão é a mesma régua do post: o pacote ficou na MINHA máquina, não no repositório
Pra confirmar que deu certo, digitei o comando de barra dentro do Claude Code e vi os comandos aparecerem na lista. Simples assim
Um detalhe de fluxo: iniciei o Claude Code pulando a confirmação de permissões, porque a fase de planejamento gera muitos arquivos e aprovar tudo na mão deixa o processo bem lento. Dá pra usar sem isso, e em repositório de time eu pensaria duas vezes antes de fazer o mesmo
A pergunta que mais casou com este post veio na entrevista de configuração: os documentos de planejamento devem ser versionados no git?
Respondi que sim
É o mesmo raciocínio de quando avalio versionar o vault no Git antes de deixar a IA editar minhas notas: se o artefato serve pra qualquer pessoa que abre o projeto, ele merece histórico
No resto da entrevista escolhi poucas fases (algo entre três e cinco) com um a três planos por fase, porque mais fases significa mais subdivisão de tarefa e mais tempo de desenvolvimento. Optei por rodar os planos em paralelo em vez de sequencial
Liguei a pesquisa antes de planejar em cada fase, ciente de que gasta mais token e mais tempo, por avaliar que melhora a qualidade do código. Também liguei a verificação de que os planos atingem os objetivos e a verificação do trabalho contra os requisitos ao fim de cada fase
Nos modelos, fiquei num perfil equilibrado pros agentes de planejamento. Vale dizer: essas perguntas todas mexem em consumo de tokens e em quais modelos vão ser usados, não são decoração
Aí veio a parte que me fez pensar em configuração compartilhada
Além dos documentos de planejamento, o assistente gerou um arquivo de configuração refletindo exatamente as respostas que eu dei na entrevista. Ou seja, minhas escolhas viraram arquivo, e arquivo é a coisa que o Git carrega pra máquina dos outros
Dois detalhes bonitinhos: a ferramenta percebeu que eu escrevia em português e seguiu a conversa em português, e a pasta de planejamento nasceu com as informações que escolhi, porém escritas de forma bem mais detalhada do que eu havia respondido
E o conselho que eu repito: leia a documentação oficial do projeto antes de sair usando, foi de lá que tirei o comando de instalação
A fase de planejamento é rigorosa e às vezes sofrida, mas vale a pena. Ela força o detalhamento, e na minha avaliação isso é especialmente útil pra quem não vem da área técnica, porque garante um software melhor guiado pela IA
Três situações de time que mudam a sua decisão
A régua geral é boa, mas tem três cenários que mudam a resposta na prática
1. Você trabalha com vários git worktrees do mesmo repositório
Aqui o CLAUDE.local.md te trai
Como ele é gitignored, ele existe só no worktree onde foi criado. Você configura tudo bonitinho, troca de worktree e cadê suas preferências?
A alternativa documentada é importar um arquivo do seu home dentro do CLAUDE.md:
@~/.claude/my-project-instructions.mdAssim a preferência vive num lugar só, e todo worktree enxerga
2. Onboarding de gente nova no time
Esse é o cenário em que versionar compensa mais
A pessoa clona o repositório e já recebe instrução do projeto, subagents e o servidor MCP declarado. Bem melhor do que um documento no Notion dizendo "agora configure isso na mão"
Só não prometa mágica total: servidor MCP de escopo de projeto pede aprovação na primeira vez, e plugin de fonte externa habilitado pelo settings do projeto ainda depende da pessoa instalar
Coloque esses dois passos no seu checklist de primeiro dia e acabou o problema
3. Projeto com dado sensível
Repare numa proteção que já vem pensada pra isso: na primeira vez que o Claude Code encontra imports externos num projeto, ele mostra um diálogo de aprovação listando os arquivos
Esse diálogo existe justamente pra te proteger de arquivos que outras pessoas commitaram no projeto compartilhado
E quando o time precisa de variável de ambiente valendo pra todo mundo, ela pode ser declarada na chave env de um settings.json, que o Claude Code lê direto do arquivo, valendo independentemente de como o claude foi iniciado:
{
"env": {
"MINHA_VARIAVEL": "valor"
}
}Só lembra da regra de ouro do bloco anterior: variável de configuração pode, credencial estática não
Fechando: a regra de bolso para decidir onde cada arquivo mora
A régua cabe em uma frase
Se a regra vale pra qualquer pessoa que abre o projeto, versiona. Se é gosto seu, se muda entre máquinas ou se toca em credencial, fica local
Na prática, fica assim:
| Arquivo ou pasta | Vai pro Git? | Pra que serve |
|---|---|---|
CLAUDE.md | Sim | Instruções persistentes do projeto, lidas no início de cada sessão |
.claude/settings.json | Sim | Settings do projeto, compartilhadas com o time |
.claude/agents/ | Sim | Subagents do projeto, pro time usar e melhorar junto |
.claude/skills/ | Sim | Skills do projeto (comandos foram fundidos em skills) |
.mcp.json | Sim | Servidor MCP de escopo de projeto, com chave via ${VAR} |
.claude/settings.local.json | Não | Preferência pessoal e experimentação |
CLAUDE.local.md | Não | Preferência pessoal por projeto, no .gitignore |
~/.claude/projects/<project>/memory/ | Não | Memória automática, só na sua máquina |
~/.claude/agents/, ~/.claude/skills/, ~/.claude/commands/ | Não | Seu setup pessoal, em todos os seus projetos |
O próximo passo prático é bem direto: roda /permissions no seu repositório hoje e olha de qual arquivo veio cada regra que está ativa aí
Depois disso, dá uma varrida no que está commitado sem precisar estar. Aposto que tem preferência pessoal de alguém morando no arquivo compartilhado 😀
Configuração compartilhada boa é aquela que ninguém precisa explicar no onboarding, ela só funciona quando a pessoa clona
até o próximo post!
Perguntas frequentes
Qual a diferença entre .claude/settings.json e .claude/settings.local.json no Claude Code?
O .claude/settings.json é pensado para ir pro controle de versão e valer pro time inteiro. Já o .claude/settings.local.json guarda preferência pessoal e experimentação, e não é commitado. Se sobrar um settings.local.json antigo deixado por versão anterior, ele ainda é lido: em conflito na mesma chave vale o valor do arquivo da raiz do repositório, mas as regras de permissão dos dois continuam em efeito.
Onde entra a configuração pessoal do Claude Code que não deve ir pro Git?
Ela mora em ~/.claude, no home de cada pessoa, e vale em todos os projetos da máquina, não só no repositório atual. Dentro do projeto, o equivalente pessoal é o .claude/settings.local.json, que fica de fora do controle de versão. Se você criar esse arquivo na mão ou pedir pro Claude escrever com a ferramenta Write, o ignore não é automático, você mesmo precisa colocar no gitignore.
O CLAUDE.local.md funciona em múltiplos git worktrees do mesmo repositório?
Não direto: como ele é gitignored, o arquivo existe só no worktree onde foi criado. A alternativa documentada é importar um arquivo do home dentro do CLAUDE.md, por exemplo @~/.claude/my-project-instructions.md. Assim toda sessão, em qualquer worktree, carrega a mesma instrução pessoal.
Como funciona a ordem entre allow, ask e deny nas permissões do Claude Code?
As regras são avaliadas nessa ordem: deny primeiro, depois ask, depois allow, e o primeiro match decide. Isso vale mesmo quando o allow é mais específico: um deny amplo como Bash(aws *) bloqueia até uma permissão específica como Bash(aws s3 ls). Pra ver de qual settings.json cada regra veio, o comando /permissions lista tudo com a origem.
Dá para o /init adicionar o CLAUDE.local.md ao gitignore automaticamente?
Existe um caminho documentado na página de memória do Claude Code, mas ele depende de uma variável de ambiente ligada antes. Com CLAUDE_CODE_NEW_INIT=1 definida, rodar /init e escolher a opção pessoal adiciona o CLAUDE.local.md ao .gitignore automaticamente. Sem essa variável, o comportamento não é garantido.
A memória automática (auto memory) do Claude Code é compartilhada com o time?
Não. Ela fica em ~/.claude/projects/<project>/memory, por projeto, mas dentro do home de cada pessoa. Os arquivos não são compartilhados entre máquinas nem com ambientes cloud, então cada integrante do time acumula a própria memória separada.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares

As diferenças de var, let e const

Como fazer redirecionamento com PHP
Neste artigo você vai aprender a como fazer redirecionamento com PHP, utilizaremos abordagens fáceis de entender e de aplicar Fala programador(a), beleza? Bora aprender mais […]

ChatGPT: o que é, como usar, dicas e como acessar login
ChatGPT é uma ferramenta de processamento de linguagem natural (NLP) baseada na arquitetura GPT-3.5, desenvolvida pela OpenAI. Sua criação representa um marco significativo no campo […]
