Tripwire
Injeção de contexto para agentes de IA via MCP. Defina políticas baseadas em caminhos em YAML — quando um agente lê um arquivo correspondente, o conhecimento relevante é injetado automaticamente. Previne erros antes que aconteçam. Funciona com Claude Code, Cursor e qualquer cliente MCP.
Documentação
Tripwire
Injeção de contexto para agentes de IA, acionada pelo próprio código.
Tripwire é um servidor MCP local que injeta automaticamente contexto relevante quando um agente lê arquivos no seu projeto. Defina tripwires em caminhos — quando um agente aciona um, ele recebe o conhecimento necessário antes de causar danos.
Agentes não sabem o que não sabem. Tripwire resolve isso.
Modelo mental: Tripwires são políticas baseadas em caminhos. Eles injetam contexto em leituras de arquivos. São determinísticos e nativos do repositório. A aplicação depende do suporte do cliente (hooks) ou do modo proxy.
Agent opens payments/stripe.py
→ Tripwire fires
→ Context injected: "All secrets from vault. Never hardcode keys. See docs/security/secrets.md"
→ Agent proceeds with the right context, without having to ask
Como Funciona
- Tripwires vivem no seu repositório como pequenos arquivos YAML em
.tripwires/ - O servidor MCP lida com chamadas de ferramentas de leitura de arquivos e faz correspondência glob contra os gatilhos dos tripwires
- O contexto correspondente é prefixado ao conteúdo do arquivo — automático para o agente, inspecionável via
tripwire explain - Agentes criam novos tripwires quando cometem erros e são corrigidos
- Tudo sincroniza via git — tripwires viajam com o código, são revisados em PRs e se propagam pela equipe
Sem serviços externos. Sem bancos de dados. Sem configuração além de iniciar o servidor.
Modelo de ameaça: Tripwires são um canal de instruções privilegiado — um tripwire malicioso pode direcionar agentes a introduzir vulnerabilidades. Tripwire é injeção de orientação/política, não um sistema de permissões. Proteja
.tripwires/com CODEOWNERS, exija revisão de CI para todas as alterações e rejeite tripwirescriticalcriados por agentes sem aprovação humana. Consulte SECURITY.md para o modelo de ameaça completo e receitas de CI.
Instalação
Requer Node.js >= 18.
Teste rápido (sem instalação)
Adicione ao .mcp.json e pronto:
{
"mcpServers": {
"tripwire": {
"command": "npx",
"args": ["-y", "@tripwire-mcp/tripwire", "serve", "--project", "."]
}
}
}
Para Cursor, use .cursor/mcp.json com a mesma configuração.
Configuração de equipe (recomendado)
Fixar como dependência de desenvolvimento para que todos recebam a mesma versão:
npm install --save-dev @tripwire-mcp/tripwire
Adicione scripts ao package.json:
{
"scripts": {
"tripwire": "tripwire",
"tripwire:lint": "tripwire lint --strict",
"tripwire:doctor": "tripwire doctor"
}
}
Aponte .mcp.json para a instalação local (sem necessidade de -y):
{
"mcpServers": {
"tripwire": {
"command": "npx",
"args": ["tripwire", "serve", "--project", "."]
}
}
}
Alternativa: instalação global
npm install -g @tripwire-mcp/tripwire
Qualquer cliente compatível com MCP
Tripwire fala MCP padrão via stdio. Para uma configuração completa e funcional, consulte examples/hello-tripwire/.
Início Rápido
Inicialize no seu projeto
cd your-project
tripwire init
Cria um diretório .tripwires/ com um exemplo inicial.
Defina seu primeiro tripwire
# .tripwires/no-hardcoded-secrets.yml
triggers:
- "payments/**"
- "billing/**"
- "**/stripe*.py"
context: |
CRITICAL: Never hardcode API keys or secrets in this module.
All credentials must be loaded from the vault service.
See docs/security/secrets-policy.md for the approved pattern.
severity: critical
created_by: human
Pronto. Qualquer agente lendo arquivos que correspondam a esses globs agora recebe este contexto automaticamente.
Deixe os agentes aprenderem
Quando um agente comete um erro e você o corrige, o agente pode criar um tripwire para prevenir o mesmo erro em sessões futuras:
# .tripwires/api-v1-versioning.yml
triggers:
- "src/api/v1/**"
context: |
This is a frozen API version. Do not modify existing endpoint
signatures or response shapes. Add new functionality to v2 only.
Breaking changes here will fail the contract test suite.
severity: high
created_by: agent:claude-code
learned_from: "Changed a v1 response field, broke 3 downstream consumers"
Formato do Tripwire
Cada arquivo .yml em .tripwires/ define um tripwire:
# Required
triggers: # Glob patterns matched against file paths (relative to repo root)
- "src/auth/**"
- "middleware/auth*.ts"
context: | # Free-text context injected when triggered (markdown supported)
The auth module uses session-based auth, NOT JWT.
See ADR-012 for the migration rationale.
created_by: human # Who authored this (required — see format below)
# Optional
severity: info | warning | high | critical # Default: warning (affects ordering only)
learned_from: "..." # Required if created_by starts with agent:
tags: # For filtering and organization
- security
- architecture
expires: 2026-06-01 # Auto-remove after this date
depends_on: # Other tripwires that must also fire
- no-hardcoded-secrets
Padrões glob
Tripwire usa sintaxe glob padrão:
| Padrão | Correspondência |
|---|---|
src/auth/** | Qualquer arquivo sob src/auth/, em qualquer profundidade |
*.sql | Arquivos SQL na raiz |
**/*.sql | Arquivos SQL em qualquer lugar |
src/api/v{1,2}/** | Arquivos nos diretórios de API v1 ou v2 |
!**/*.test.ts | Excluir arquivos de teste (prefixo com !) |
Convenções de nomenclatura
Nomes de tripwires são derivados do nome do arquivo YAML e normalizados para a-z, 0-9 e hífens. Espaços e sublinhados tornam-se hífens. Nomes não diferenciam maiúsculas de minúsculas — No_Raw_SQL.yml torna-se no-raw-sql. tripwire lint verifica nomes duplicados.
created_by é obrigatório. tripwire lint gera erro se ausente. Valores canônicos:
| Valor | Significado |
|---|---|
human | Escrito à mão por um desenvolvedor |
agent:<client> | Criado via ferramenta MCP (ex.: agent:mcp, agent:claude-code) |
tool:<name> | Criado por automação (ex.: tool:ci-generate) |
lint --strict gera erro em formato inválido (agent ou tool sem nome de cliente é inválido). A ferramenta MCP create_tripwire define created_by: agent:mcp automaticamente.
Tags são um array de strings YAML. Nomes de tags devem corresponder a /^[a-z0-9][a-z0-9-]{0,31}$/ (alfanumérico minúsculo + hífens, máx. 32 caracteres). tripwire lint gera erro em tags inválidas. Em cabeçalhos de injeção, tags são renderizadas como uma string separada por vírgulas sem escape: tags="security,architecture". A regex estrita torna o escape desnecessário.
Especificação de Comportamento
Esta seção documenta a semântica exata de tempo de execução. Útil para depuração, escrita de testes ou construção de clientes alternativos. Se este documento conflitar com a implementação, a implementação é a fonte da verdade até a próxima revisão da especificação.
Correspondência de caminhos
Tripwire usa micromatch para correspondência glob. Suporta expansão de chaves ({a,b}) e negação (!).
Sensibilidade a maiúsculas/minúsculas: A correspondência diferencia maiúsculas de minúsculas por padrão (match_case: true). Quando match_case: false, a correspondência não diferencia maiúsculas de minúsculas (definido como: tanto o caminho normalizado quanto os padrões de gatilho são comparados sem considerar maiúsculas/minúsculas). Em sistemas de arquivos sem distinção de maiúsculas/minúsculas (macOS, Windows), a capitalização de caminhos relatada pelas ferramentas pode não corresponder à capitalização dos gatilhos — defina match_case: false em .tripwirerc.yml para evitar incompatibilidades.
Normalização: Antes da correspondência, os caminhos são normalizados: barras invertidas tornam-se barras normais, ./ inicial é removido. A correspondência usa dot: true (arquivos ocultos correspondem a **).
Ordem de avaliação: A configuração exclude_paths é verificada primeiro. Se um caminho for excluído, nenhuma avaliação de tripwire ocorre — mesmo que os gatilhos de um tripwire correspondam. Dentro de um tripwire, padrões de negação (!) aplicam-se após padrões positivos.
Padrões positivos vs. negação:
- Padrões positivos (ex.:
src/auth/**) correspondem a arquivos para inclusão. - Padrões de negação começam com
!(ex.:!**/*.test.ts) e excluem arquivos que de outra forma corresponderiam. - Um caminho corresponde se corresponde a pelo menos um padrão positivo E zero padrões de negação.
- Se todos os padrões forem de negação, um padrão positivo implícito
**é adicionado (ou seja, "corresponder a tudo exceto...").
Ordenação
Quando múltiplos tripwires correspondem a um caminho, eles são ordenados deterministicamente:
- Severidade decrescente: crítica (0) > alta (1) > aviso (2) > informativa (3)
- Nome crescente (alfabético) dentro da mesma severidade
Esta ordem determina a ordem de avaliação e emissão dos grupos de tripwires raiz. Um grupo consiste no tripwire raiz mais suas dependências resolvidas (consulte Dependências). Dependências não participam da ordenação global por severidade/nome; elas são emitidas como parte do seu grupo raiz.
A severidade afeta a ordenação e a prioridade de truncamento. Ela não impõe bloqueio rígido ou controle de escrita. Todos os grupos correspondentes são injetados quando o orçamento permite — maior severidade sobrevive ao truncamento primeiro. O nível também sinaliza ao agente quão seriamente tratar o contexto.
Truncamento
Quando max_context_length > 0, Tripwire aplica um orçamento de caracteres ao contexto injetado (não tokens — clientes diferentes podem truncar independentemente). O separador e o conteúdo do arquivo não fazem parte do orçamento.
O que conta para o orçamento: a string de injeção totalmente renderizada — o cabeçalho de cada bloco (<<<TRIPWIRE ...>>>), corpo do contexto, rodapé (<<<END_TRIPWIRE>>>) e nova linha final. O bloco de supressão em si não é contado.
- Granularidade de tripwire inteiro — um bloco de tripwire é totalmente incluído ou totalmente omitido. O contexto nunca é cortado no meio do bloco.
- Orçamento inclui dependências — blocos de dependência contam para o mesmo orçamento.
- Melhor esforço na ordem de classificação — grupos são tentados na ordem classificada (severidade raiz DESC, nome raiz ASC). Grupos de maior severidade são tentados primeiro, mas não há garantia rígida de que caberão. Se um único grupo exceder o orçamento, ele é suprimido — mesmo que seja crítico. Recomendado: mantenha
max_context_length: 0(ilimitado, o padrão) para repositórios críticos de segurança onde todo tripwire deve disparar. - Bloco suprimido — quando grupos são omitidos, um bloco
<<<TRIPWIRE_SUPPRESSED count="N" reason="context_budget">>>lista o nome do tripwire raiz e a severidade para cada grupo suprimido. Dependências suprimidas como parte de um grupo atômico não são listadas individualmente — o nome raiz identifica o grupo. Formato da entrada suprimida: uma linha por grupo raiz suprimido:<severity> <name>(ex.:critical billing-freeze). O bloco termina com<<<END_TRIPWIRE_SUPPRESSED>>>.
Dependências
Tripwires podem declarar depends_on: [name1, name2] para puxar o contexto de outros tripwires quando disparam.
- Resolução transitiva — dependências são resolvidas transitivamente até
max_dependency_depth(padrão: 5). - Detecção de ciclos — um conjunto de visitados rastreia a caminhada. Se um ciclo for detectado, um aviso é emitido e a aresta do ciclo é ignorada.
- Dependências ausentes — se uma dependência nomeada não existir, um aviso é emitido e a resolução continua.
- Deduplicação global — cada bloco de dependência aparece no máximo uma vez por resposta. Uma dependência é considerada "já emitida" se seu bloco
<<<TRIPWIRE ...>>> ... <<<END_TRIPWIRE>>>completo foi incluído na injeção renderizada (supressão não conta como emissão). Se múltiplos grupos raiz referenciam a mesma dependência, ela é emitida uma vez com o grupo raiz mais antigo na ordem de classificação; seu atributooriginator="<rootName>"reflete o tripwire raiz cujo grupo primeiro causou a emissão dessa dependência. - Construção de grupo — para cada tripwire raiz correspondido, um grupo é construído: o fechamento de dependências (DFS, percorrido na ordem da lista
depends_on) seguido pela raiz. Grupos são ordenados por severidade raiz DESC, depois nome raiz ASC. Dentro de um grupo, dependências aparecem na ordem de travessia DFS (estável: ordem dos irmãos corresponde à ordem de declaraçãodepends_on). - Truncamento atômico — quando
max_context_length > 0, o grupo inteiro (dependências + raiz) deve caber no orçamento restante. Se o grupo não couber, tudo é suprimido — a raiz nunca é emitida sem suas dependências. O tamanho do grupo é calculado após a deduplicação global: dependências já emitidas por um grupo anterior não são recontadas e não são necessárias para o ajuste do grupo. Isso é seguro porque dependências são sempre emitidas com o grupo raiz mais antigo na ordem de classificação, então qualquer raiz posterior que referencie essa dependência pode omiti-la — o bloco de dependência aparecerá antes na mesma resposta. - Renderização — dependências são renderizadas com atributos
origin="dependency" originator="<rootName>".originatoré o tripwire raiz cujo grupo primeiro causou a emissão dessa dependência. Onamesempre corresponde ao nome do arquivo do tripwire (ex.:name="depName"), nunca a um composto sintético.
Conflitos
Tripwire não tenta resolver conflitos entre contextos. Se dois tripwires correspondem ao mesmo caminho e dão instruções contraditórias, ambos são injetados e o agente vê ambos.
Verificações tripwire lint (sempre):
- Campo
created_byausente (erro) - Tripwire criado por agente (
created_by: agent:*) semlearned_fromquandorequire_learned_fromé verdadeiro (erro) - Tripwire criado por agente (
created_by: agent:*) semexpiresquandoauto_expire_days > 0(erro) — impede que entradasagent:*escritas à mão contornem a expiração automática - Nomes de tags inválidos — devem corresponder a
/^[a-z0-9][a-z0-9-]{0,31}$/(erro)tripwire lint --strictadiciona: - Conjuntos de gatilhos idênticos (aviso) — dois tripwires cujos arrays de gatilhos ordenados são iguais (insensível à ordem). Correspondência exata, não detecção de sobreposição.
- Sobreposição crítica (aviso) — enumera arquivos do projeto (glob
**, apenas arquivos, filtrados porexclude_paths, ordenados lexicograficamente, limitados a 5000)..gitignorenão é respeitado para manter resultados de lint estáveis entre ambientes; useexclude_pathspara controlar o escopo da varredura. Avisa se qualquer arquivo corresponder a >1 tripwirecritical. Relata os nomes específicos dos tripwires. - Formato
created_by(erro) — deve serhuman,agent:<client>outool:<name>.agentoutoolsem um nome de cliente/ferramenta é inválido. - Contexto individual > 4 KB (aviso) — sugere dividir.
- Contexto agregado > 16 KB (aviso) — total em todos os tripwires.
- Tripwire crítico excede
max_context_length(aviso) — será suprimido em tempo de execução.
tripwire explain <path> exibe todos os tripwires correspondentes para um determinado caminho, tornando os conflitos visíveis antes que causem problemas.
Ferramentas MCP
O servidor expõe estas ferramentas aos agentes conectados:
read_file
Substituto direto para leitura padrão de arquivos. Verifica tripwires e antepõe o contexto correspondente.
Agent calls: read_file("src/auth/login.ts")
Returns:
<<<TRIPWIRE severity="high" name="auth-session-based" tags="security">>>
The auth module uses session-based auth, NOT JWT.
See ADR-012 for the migration rationale.
<<<END_TRIPWIRE>>>
<<<TRIPWIRE_FILE_CONTENT>>>
<actual file contents>
Formato do delimitador:
<<<TRIPWIRE severity="<level>" name="<name>" [origin="dependency" originator="<rootName>"] [tags="<csv>"]>>>
<context text>
<<<END_TRIPWIRE>>>
| Atributo | Sempre presente | Valores |
|---|---|---|
severity | sim | info, warning, high, critical |
name | sim | nome do arquivo tripwire sem .yml |
origin | apenas em dependências | dependency |
originator | apenas em dependências | tripwire raiz cujo grupo primeiro causou a emissão desta dependência |
tags | apenas se não vazio | separados por vírgula, sem escape (vírgulas não permitidas em nomes de tags) |
O conteúdo do arquivo segue após um sentinela <<<TRIPWIRE_FILE_CONTENT>>> (escolhido para ser improvável em código real; se precisar de separação inequívoca, use inject_mode: metadata). Quando tripwires são suprimidos, um bloco <<<TRIPWIRE_SUPPRESSED count="N" reason="context_budget">>> lista grupos raiz suprimidos como linhas <severity> <name> e termina com <<<END_TRIPWIRE_SUPPRESSED>>>.
Modos de injeção:
prepend(padrão) — contexto + sentinela + conteúdo do arquivo em uma única resposta. Compatibilidade universal; funciona mesmo quando clientes achatam saídas de ferramentas de múltiplos blocos.metadata— contexto e conteúdo do arquivo retornados como blocos de resposta separados. Separação mais limpa, mas depende do cliente preservar os limites dos blocos.
create_tripwire
Permite que agentes criem novos tripwires. Cria um arquivo .yml em .tripwires/.
{
"name": "db-migration-checklist",
"triggers": ["migrations/**"],
"context": "Always run migrations against a copy of prod data first...",
"severity": "high",
"learned_from": "Migration #47 corrupted the users table in staging",
"force": false
}
Comportamento:
- O
nameé normalizado para um nome de arquivo canônico (a-z,0-9, apenas hífens).Db_Migration Checklisttorna-sedb-migration-checklist.yml. - Se um tripwire com o mesmo nome normalizado já existir, a chamada falha (sem sobrescritas silenciosas). Passe
force: truepara sobrescrever, ou exclua/desative o tripwire existente primeiro. - A ferramenta MCP define
created_by: "agent:mcp"automaticamente. YAML escrito à mão deve incluircreated_byexplicitamente — não há padrão;tripwire lintgera erro se ausente. - A sobrescrita é atômica (escreve em arquivo temporário, depois renomeia).
- Se
created_bynão for"human"eauto_expire_days > 0, uma dataexpiresé adicionada automaticamente. - Se
require_learned_fromfortrue(padrão) ecreated_bycomeçar comagent:,learned_fromé obrigatório.tripwire lintimpõe isso.
list_tripwires
Retorna todos os tripwires ativos, opcionalmente filtrados por caminho, tag ou severidade.
check_tripwires
Dado um caminho de arquivo, retorna quais tripwires seriam acionados — útil para agentes visualizarem antes de ler.
explain
Dado um caminho de arquivo, retorna uma análise estruturada do que seria injetado e por quê: tripwires correspondentes com seus globs, dependências resolvidas, entradas suprimidas, configuração ativa e a injeção renderizada completa. Útil para depuração.
deactivate_tripwire
Desativa suavemente um tripwire sem excluir o arquivo. Adiciona active: false ao YAML.
CLI
tripwire serve [--project <path>] # Start MCP server (stdio by default)
tripwire init [--force] # Initialize .tripwires/ in current directory
tripwire check <filepath> # Show which tripwires match a file
tripwire list [--tag <tag>] [--severity <level>] # List all tripwires
tripwire lint [--strict] [--prune] # Validate all tripwire YAML files
tripwire stats [--json] # Show tripwire coverage and statistics
tripwire doctor [--json] # Check enforcement setup
tripwire explain <filepath> [--json] # Show what would be injected and why
Integração com Git
Tripwires são arquivos simples em .tripwires/. Eles fazem diff, merge e revisão como código.
Fluxo de trabalho recomendado
- Agente cria um tripwire após uma correção → aparece em
git diff - Desenvolvedor revisa no PR — aceita, edita ou rejeita o tripwire
- Tripwires mesclados propagam para toda a equipe no próximo pull
- Tripwires expirados são limpos com
tripwire lint --prune
Nota de segurança: Tripwires influenciam o comportamento do agente. Trate-os como código — revise-os em PRs, não faça auto-merge de tripwires criados por agentes, e tenha cuidado especial com a severidade critical, pois ela molda como agentes interagem com módulos sensíveis. Veja SECURITY.md para o modelo de ameaças completo, configuração de CODEOWNERS e receitas de CI.
.gitattributes (avançado, opcional)
.tripwires/*.yml merge=union
Ressalva: merge=union faz auto-merge mantendo ambos os lados linha por linha. Isso funciona bem quando dois ramos adicionam arquivos de tripwire diferentes, mas pode duplicar silenciosamente chaves YAML se dois ramos editarem o mesmo tripwire. O padrão mais seguro é merges normais com tripwire lint --strict no CI para detectar qualquer quebra. Use merge=union apenas se sua equipe entender a compensação.
Política de CI recomendada
- CODEOWNERS — proteja
.tripwires/**para que alterações exijam revisão - CI executa
tripwire lint --strict— detectacreated_byausentes, violações de formato, sobreposições críticas - Bloquear críticos criados por agentes — falhe o CI se um diff tocar um arquivo com ambos
created_by: agent:*eseverity: critical. A aprovação do CODEOWNER é aplicada separadamente via proteção de ramo do GitHub ("Exigir revisão dos Code Owners"):BASE=$(git merge-base origin/main HEAD) FILES=$(git diff --name-only --diff-filter=ACMRT "$BASE"...HEAD -- .tripwires/ || true) [ -z "$FILES" ] && exit 0 echo "$FILES" | while read -r f; do [ -f "$f" ] || continue grep -q '^severity:\s*critical\b' "$f" || continue grep -q '^created_by:\s*agent:' "$f" || continue echo "FAIL: $f is agent-authored critical (block by policy)" exit 1 done
Hook de pré-commit (opcional)
tripwire lint --strict
Valida todos os arquivos de tripwire antes do commit — detecta YAML malformado, violações de formato e sobreposições críticas.
Configuração
.tripwirerc.yml opcional na raiz do projeto:
# Injection behavior
inject_mode: prepend # prepend | metadata (metadata = structured, not inline)
separator: "\n<<<TRIPWIRE_FILE_CONTENT>>>\n" # Sentinel between context and file content
max_context_length: 2000 # Truncate injected context beyond this (chars)
# Agent authoring
allow_agent_create: true # Let agents create tripwires via MCP
require_learned_from: true # Agents must explain what mistake prompted the tripwire
auto_expire_days: 90 # Default expiry for agent-authored tripwires
# Enforcement (Claude Code hooks)
enforcement_mode: strict # strict = deny raw reads | advisory = allow with warning
# Filtering
exclude_paths: # Never check tripwires for these paths
- "node_modules/**"
- "dist/**"
- ".git/**"
Padrões de configuração
| Chave | Tipo | Padrão | Notas |
|---|---|---|---|
inject_mode | "prepend" | "metadata" | "prepend" | metadata retorna contexto e conteúdo como blocos separados |
separator | string | \n<<<TRIPWIRE_FILE_CONTENT>>>\n | sentinela entre contexto e conteúdo do arquivo — improvável em código normal, mas pode aparecer em heredocs, templates ou fixtures de teste que referenciam o próprio Tripwire |
max_context_length | number | 0 (ilimitado) | orçamento de caracteres (não tokens) — truncamento de tripwire inteiro, nunca corta no meio do bloco |
allow_agent_create | boolean | true | defina false para bloquear tripwires criados por agentes |
require_learned_from | boolean | true | agentes devem explicar o erro |
auto_expire_days | number | 90 | 0 = sem expiração automática |
enforcement_mode | "strict" | "advisory" | "strict" | advisory permite leituras brutas com um aviso |
exclude_paths | string[] | ["node_modules/**", "dist/**", ".git/**"] | nunca verifique tripwires para estes |
tripwires_dir | string | ".tripwires" | diretório contendo arquivos YAML |
max_dependency_depth | number | 5 | profundidade máxima para resolução de cadeia depends_on |
match_case | boolean | true | defina false para correspondência sem diferenciar maiúsculas/minúsculas (recomendado em macOS/Windows) |
Chaves desconhecidas são silenciosamente ignoradas. Use tripwire lint --strict para detectar problemas de configuração.
Aplicação (Hooks do Claude Code)
Sem aplicação, um agente pode contornar o Tripwire usando a ferramenta embutida Read em vez de mcp__tripwire__read_file. Um hook PreToolUse fecha essa lacuna bloqueando leituras brutas e redirecionando-as através do Tripwire.
Compatibilidade: Hooks de aplicação são atualmente específicos do Claude Code. Cursor e outros clientes MCP precisarão de seu próprio mecanismo para redirecionar leituras. O servidor MCP em si é universal — apenas a camada de aplicação é específica do editor.
Configuração
O Tripwire vem com um hook pronto. Copie ambos os arquivos para o seu projeto:
.claude/
settings.json # Hook config: intercepts Read calls
hooks/
enforce-tripwire-read.mjs # Denies raw reads, suggests tripwire read_file
Nenhuma dependência externa necessária — o hook é Node.js puro.
Como funciona
- Agente chama
Read(oumcp__filesystem__read_file) para um arquivo do projeto - Hook resolve o caminho real via
realpath(previne bypass por symlink/traversal) - Hook verifica se
.tripwires/existe e se.mcp.jsontem um servidor"tripwire"configurado - Se ambas as condições forem atendidas e o arquivo não estiver em um diretório excluído, o hook nega a leitura
- A mensagem de negação informa ao agente o nome exato da ferramenta e a forma do argumento a usar em vez disso
- Agente tenta novamente com
mcp__tripwire__read_file— o contexto é injetado automaticamente
Válvulas de segurança:
- Se
.tripwires/não existir, o hook não faz nada (não é um projeto Tripwire) - Se
.mcp.jsonnão tiver um servidor"tripwire", o hook permite a leitura (agente não tem alternativa — previne loops) - Se a mensagem de negação incluir: "Se o Tripwire MCP não estiver disponível, execute:
tripwire doctor"
Diretórios excluídos (sempre permitidos via Read): .git/, node_modules/, dist/, .tripwires/, .claude/.
Modos de aplicação
Definido em .tripwirerc.yml:
| Modo | Comportamento | Caso de uso |
|---|---|---|
strict (padrão) | Negar leituras brutas, forçar Tripwire | Produção, equipes estabelecidas |
advisory | Permitir leituras brutas com um aviso | Adoção progressiva, avaliação |
Verificar
tripwire doctor
Verifica todos os componentes e imprime ENFORCEMENT: ON, PARTIAL ou OFF com instruções de correção acionáveis.
Notas importantes
- A chave do servidor MCP em
.mcp.jsondeve ser"tripwire"para que o nome da ferramenta resolva paramcp__tripwire__read_file - A aplicação é opcional, mas fortemente recomendada — sem ela, o Tripwire depende do agente escolher a ferramenta certa
Princípios de Design
O codebase é a fonte da verdade, não a memória do agente. O Tripwire externaliza conhecimento para o repositório para que sobreviva entre sessões, agentes e membros da equipe.
O conhecimento encontra o agente. Agentes não precisam saber o que procurar. O contexto certo chega no momento certo, acionado pelo que eles estão realmente fazendo.
Git é a camada de sincronização. Sem armazenamento proprietário, sem dependência de nuvem. Tripwires viajam com o código e passam pelo mesmo processo de revisão.
Humanos curadores, agentes acumuladores. Agentes criam tripwires a partir de erros. Humanos revisam e podam. O sistema fica mais inteligente ao longo do tempo sem manutenção manual.
Arquivos simples em vez de abstrações inteligentes. Qualquer pessoa pode abrir um arquivo YAML e entender o que um tripwire faz. Sem bancos de dados, sem embeddings, sem linguagens de consulta.
Exemplos
Prevenir erros comuns
# .tripwires/no-orm-raw-sql.yml
triggers:
- "src/models/**"
context: |
Use the ORM for all queries. Raw SQL is not allowed in model files
due to SQL injection risk. If you need a complex query, add it to
src/queries/ with parameterized statements.
severity: high
created_by: human
Aplicar decisões arquiteturais
# .tripwires/event-driven-orders.yml
triggers:
- "src/orders/**"
- "src/inventory/**"
context: |
Orders and Inventory communicate via events only (see src/events/).
Never import directly between these modules.
ADR-007 has the full rationale.
severity: critical
created_by: human
tags: [architecture]
Preservar conhecimento tribal
# .tripwires/csv-export-encoding.yml
triggers:
- "src/export/**"
context: |
Japanese customers require Shift-JIS encoding for CSV exports.
UTF-8 with BOM also works but some older Excel versions on
Windows JP break. Always test with the fixtures in test/fixtures/jp/.
severity: warning
created_by: agent:claude-code
learned_from: "Generated UTF-8 CSVs that showed garbled text for JP users"
Proteções temporárias
# .tripwires/frozen-for-audit.yml
triggers:
- "src/billing/**"
- "src/compliance/**"
context: |
These modules are frozen during the Q1 audit (ends 2026-03-15).
Do not modify without explicit approval from @finance-team.
severity: critical
created_by: human
expires: 2026-03-15
tags: [temporary, compliance]
Solução de problemas
Execute tripwire doctor primeiro — ele verifica todos os componentes e informa exatamente o que está errado.
| Sintoma | Causa provável | Correção |
|---|---|---|
| Nenhum contexto injetado | Agente usou Read em vez de mcp__tripwire__read_file | Ative hooks de aplicação (veja Aplicação) |
| Contexto injetado, mas hook não bloqueando | .claude/settings.json ausente ou matcher errado | Execute tripwire doctor, verifique a configuração do hook |
| Agente preso em loop de negação | Servidor MCP do Tripwire não carregado | Verifique se .mcp.json tem a chave "tripwire", reinicie a sessão |
tripwire doctor mostra FAIL no MCP | .mcp.json ausente ou chave de servidor errada | A chave do servidor deve ser "tripwire" (não "tw", não "tripwire-mcp") |
| Hook não disparando de forma alguma | Arquivo de configurações não carregado | Reinicie a sessão do Claude Code após criar .claude/settings.json |
| Funciona no Claude Code, não no Cursor | Cursor não tem hooks PreToolUse | Veja Estratégia para Cursor |
Modo Proxy de Sistema de Arquivos
O Tripwire inclui 4 ferramentas de sistema de arquivos para que possa servir como o único provedor de FS para clientes MCP. Apenas read_file injeta contexto — as outras 3 são passagens diretas simples:
| Ferramenta | Comportamento |
|---|---|
read_file | Verifica tripwires, injeta contexto, retorna conteúdo do arquivo |
list_directory | Lista entradas em um diretório (passagem direta) |
file_stat | Retorna tipo, tamanho, modificado, criado (passagem direta) |
search_files | Pesquisa glob por arquivos (passagem direta) |
Configure o Tripwire como o único servidor de sistema de arquivos. Os agentes descobrem as ferramentas disponíveis no momento da conexão via tools/list do MCP — se nenhum outro servidor fornecer ferramentas de sistema de arquivos, os agentes devem usar as versões do Tripwire e todas as leituras recebem injeção de contexto automaticamente.
Limitação rígida: O modo proxy só funciona se o cliente não tiver acesso a arquivos não-MCP habilitado. Se o cliente fornecer um comando nativo Read, os agentes podem contornar o Tripwire usando esse comando.
Como fechar a lacuna por cliente:
- Claude Code — tem uma ferramenta nativa
Readque contorna o MCP. Use hooks de aplicação (PreToolUse) para negar leituras brutas. O modo proxy sozinho não é suficiente. - Cursor — o modo proxy cobre leituras que passam por ferramentas MCP. Se o Tripwire for o único servidor que fornece ferramentas de sistema de arquivos, isso é suficiente. Se o Cursor tiver outros caminhos de leitura (dependendo da versão), o Tripwire não pode interceptá-los. Desative outros servidores de FS, se presentes.
- Outros clientes MCP — verifique se o cliente tem acesso a arquivos integrado. Se tiver e não houver mecanismo de hook, o modo proxy não pode garantir a cobertura. Ainda não sabemos quais clientes suportam desabilitar FS nativo — se o seu suporta, nos avise.
Quando usar modo proxy vs. hooks
| Abordagem | Melhor para | Limitação |
|---|---|---|
| Hooks de aplicação | Claude Code (suporta PreToolUse) | Específico do cliente |
| Modo proxy | Cursor, qualquer cliente MCP | Deve ser o único servidor de FS |
| Ambos | Cobertura máxima | Mais configuração |
Estratégia para Cursor
O servidor MCP do Tripwire funciona no Cursor — os agentes podem chamar read_file, list_tripwires, etc. A diferença é a aplicação: o Cursor não suporta hooks PreToolUse, então não há como bloquear leituras brutas de sistema de arquivos.
Recomendado: Use o modo proxy de sistema de arquivos — configure o Tripwire como o único servidor MCP com capacidade de sistema de arquivos. Com read_file, list_directory, file_stat e search_files disponíveis, os agentes têm acesso completo a FS através do Tripwire. Se nenhum outro servidor fornecer ferramentas de sistema de arquivos, os agentes devem usar as versões do Tripwire, e todas as leituras recebem injeção de contexto automaticamente.
Roadmap
- Modo proxy de sistema de arquivos — servir ferramentas de leitura/lista/status/busca para que o Tripwire seja o único provedor de FS
- Detecção de obsolescência — sinalizar tripwires cujos arquivos acionados mudaram significativamente desde a criação
- Análises de disparo — rastrear quais tripwires disparam mais, quais nunca disparam (candidatos para remoção)
- Correspondência semântica — corresponder por conteúdo/intenção do arquivo, não apenas por globs de caminho
- Integração com editor — mostrar indicadores de tripwire na margem do VS Code
-
tripwire suggest— analisar git blame e comentários de PR para propor tripwires automaticamente
Licença
MIT