Tripwire

Inyección de contexto para agentes de IA mediante MCP. Define políticas basadas en rutas en YAML: cuando un agente lee un archivo coincidente, se inyecta automáticamente el conocimiento relevante. Previene errores antes de que ocurran. Funciona con Claude Code, Cursor y cualquier cliente MCP.

Documentación

Tripwire

npm version CI License: MIT Node.js TypeScript

Inyección de contexto para agentes de IA, activada por el propio código base.

Tripwire es un servidor MCP local que inyecta automáticamente contexto relevante cuando un agente lee archivos en tu proyecto. Define tripwires en rutas: cuando un agente activa uno, recibe el conocimiento que necesita antes de poder causar daño.

Los agentes no saben lo que no saben. Tripwire lo soluciona.

Modelo mental: Los tripwires son políticas basadas en rutas. Inyectan contexto en las lecturas de archivos. Son deterministas y nativos del repositorio. La aplicación depende del soporte del cliente (hooks) o del 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

Cómo Funciona

  1. Los tripwires viven en tu repositorio como pequeños archivos YAML en .tripwires/
  2. El servidor MCP gestiona las llamadas de herramientas de lectura de archivos y compara con glob contra los disparadores de tripwire
  3. El contexto coincidente se antepone al contenido del archivo: automático para el agente, inspeccionable mediante tripwire explain
  4. Los agentes crean nuevos tripwires cuando cometen errores y son corregidos
  5. Todo se sincroniza mediante git — los tripwires viajan con el código, se revisan en los PR y se propagan por todo el equipo

Sin servicios externos. Sin bases de datos. Sin configuración más allá de iniciar el servidor.

Modelo de amenazas: Los tripwires son un canal de instrucciones privilegiado: un tripwire malicioso puede dirigir a los agentes hacia la introducción de vulnerabilidades. Tripwire es inyección de guía/políticas, no un sistema de permisos. Protege .tripwires/ con CODEOWNERS, exige revisión de CI para todos los cambios y rechaza tripwires critical creados por agentes sin aprobación humana. Consulta SECURITY.md para el modelo de amenazas completo y las recetas de CI.


Instalación

Requiere Node.js >= 18.

Prueba rápida (sin instalación)

Añade a .mcp.json y listo:

{
  "mcpServers": {
    "tripwire": {
      "command": "npx",
      "args": ["-y", "@tripwire-mcp/tripwire", "serve", "--project", "."]
    }
  }
}

Para Cursor, usa .cursor/mcp.json con la misma configuración.

Configuración de equipo (recomendada)

Fija como dependencia de desarrollo para que todos obtengan la misma versión:

npm install --save-dev @tripwire-mcp/tripwire

Añade scripts a package.json:

{
  "scripts": {
    "tripwire": "tripwire",
    "tripwire:lint": "tripwire lint --strict",
    "tripwire:doctor": "tripwire doctor"
  }
}

Apunta .mcp.json a la instalación local (no se necesita -y):

{
  "mcpServers": {
    "tripwire": {
      "command": "npx",
      "args": ["tripwire", "serve", "--project", "."]
    }
  }
}

Alternativa: instalación global

npm install -g @tripwire-mcp/tripwire

Cualquier cliente compatible con MCP

Tripwire habla MCP estándar sobre stdio. Para una configuración completa y funcional, consulta examples/hello-tripwire/.


Inicio Rápido

Inicializa en tu proyecto

cd your-project
tripwire init

Crea un directorio .tripwires/ con un ejemplo inicial.

Define tu primer 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

Eso es todo. Cualquier agente que lea archivos que coincidan con esos globs recibe ahora este contexto automáticamente.

Deja que los agentes aprendan

Cuando un agente comete un error y lo corriges, el agente puede crear un tripwire para evitar el mismo error en sesiones 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 de Tripwire

Cada archivo .yml en .tripwires/ define un 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

Patrones glob

Tripwire utiliza sintaxis glob estándar:

PatrónCoincide con
src/auth/**Cualquier archivo bajo src/auth/, a cualquier profundidad
*.sqlArchivos SQL en la raíz
**/*.sqlArchivos SQL en cualquier lugar
src/api/v{1,2}/**Archivos en directorios de API v1 o v2
!**/*.test.tsExcluir archivos de prueba (prefijo con !)

Convenciones de nomenclatura

Los nombres de tripwire se derivan del nombre del archivo YAML y se normalizan a a-z, 0-9 y guiones. Los espacios y guiones bajos se convierten en guiones. Los nombres no distinguen entre mayúsculas y minúsculas: No_Raw_SQL.yml se convierte en no-raw-sql. tripwire lint comprueba nombres duplicados.

created_by es obligatorio. tripwire lint da error si falta. Valores canónicos:

ValorSignificado
humanEscrito a mano por un desarrollador
agent:<client>Creado mediante herramienta MCP (p. ej. agent:mcp, agent:claude-code)
tool:<name>Creado por automatización (p. ej. tool:ci-generate)

lint --strict da error en formato no válido (un agent o tool sin nombre de cliente no es válido). La herramienta MCP create_tripwire establece created_by: agent:mcp automáticamente.

Las etiquetas son un array de cadenas YAML. Los nombres de etiqueta deben coincidir con /^[a-z0-9][a-z0-9-]{0,31}$/ (alfanuméricos en minúsculas + guiones, máx. 32 caracteres). tripwire lint da error en etiquetas no válidas. En los encabezados de inyección, las etiquetas se representan como una cadena separada por comas sin escapar: tags="security,architecture". La expresión regular estricta hace innecesario el escape.


Especificación de Comportamiento

Esta sección documenta la semántica exacta de ejecución. Útil para depurar, escribir pruebas o crear clientes alternativos. Si este documento entra en conflicto con la implementación, la implementación es la fuente de verdad hasta la próxima revisión de la especificación.

Coincidencia de rutas

Tripwire utiliza micromatch para la coincidencia de globs. Admite expansión de llaves ({a,b}) y negación (!).

Sensibilidad a mayúsculas: La coincidencia distingue mayúsculas y minúsculas por defecto (match_case: true). Cuando match_case: false, la coincidencia no distingue mayúsculas y minúsculas (definido como: tanto la ruta normalizada como los patrones de disparo se comparan sin tener en cuenta mayúsculas). En sistemas de archivos que no distinguen mayúsculas (macOS, Windows), las mayúsculas de las rutas reportadas por las herramientas pueden no coincidir con las de los disparadores: establece match_case: false en .tripwirerc.yml para evitar discrepancias.

Normalización: Antes de la coincidencia, las rutas se normalizan: las barras invertidas se convierten en barras normales, se elimina el ./ inicial. La coincidencia utiliza dot: true (los archivos ocultos coinciden con **).

Orden de evaluación: La configuración exclude_paths se comprueba primero. Si una ruta está excluida, no se realiza ninguna evaluación de tripwire, incluso si los disparadores de un tripwire coincidirían. Dentro de un tripwire, los patrones de negación (!) se aplican después de los patrones positivos.

Patrones positivos frente a de negación:

  • Los patrones positivos (p. ej. src/auth/**) coinciden con archivos para su inclusión.
  • Los patrones de negación comienzan con ! (p. ej. !**/*.test.ts) y excluyen archivos que de otro modo coincidirían.
  • Una ruta coincide si coincide con al menos un patrón positivo Y cero patrones de negación.
  • Si todos los patrones son de negación, se añade un patrón positivo implícito ** (es decir, «coincide con todo excepto...»).

Ordenación

Cuando varios tripwires coinciden con una ruta, se ordenan de forma determinista:

  1. Gravedad descendente: critical (0) > high (1) > warning (2) > info (3)
  2. Nombre ascendente (alfabético) dentro de la misma gravedad

Este orden determina la evaluación y el orden de emisión de los grupos de tripwire raíz. Un grupo consiste en el tripwire raíz más sus dependencias resueltas (consulta Dependencias). Las dependencias no participan en la ordenación global por gravedad/nombre; se emiten como parte de su grupo raíz.

La gravedad afecta a la ordenación y a la prioridad de truncamiento. No impone bloqueo estricto ni control de escritura. Todos los grupos coincidentes se inyectan cuando el presupuesto lo permite: la gravedad más alta sobrevive primero al truncamiento. El nivel también indica al agente con qué seriedad debe tratar el contexto.

Truncamiento

Cuando max_context_length > 0, Tripwire aplica un presupuesto de caracteres al contexto inyectado (no tokens: distintos clientes pueden truncar de forma independiente). El separador y el contenido del archivo no forman parte del presupuesto.

Qué cuenta para el presupuesto: la cadena de inyección completamente renderizada: el encabezado de cada bloque (<<<TRIPWIRE ...>>>), el cuerpo del contexto, el pie (<<<END_TRIPWIRE>>>) y el salto de línea final. El propio bloque de supresión no se cuenta.

  • Granularidad de tripwire completo — un bloque de tripwire se incluye por completo o se omite por completo. El contexto nunca se corta a mitad de bloque.
  • El presupuesto incluye dependencias — los bloques de dependencias cuentan para el mismo presupuesto.
  • Mejor esfuerzo en orden de clasificación — los grupos se intentan en orden clasificado (gravedad raíz DESC, nombre raíz ASC). Los grupos de mayor gravedad se intentan primero, pero no hay garantía estricta de que quepan. Si un solo grupo supera el presupuesto, se suprime, incluso si es crítico. Recomendado: mantén max_context_length: 0 (ilimitado, el valor predeterminado) para repositorios críticos para la seguridad donde cada tripwire debe activarse.
  • Bloque suprimido — cuando se omiten grupos, un bloque <<<TRIPWIRE_SUPPRESSED count="N" reason="context_budget">>> enumera el nombre del tripwire raíz y la gravedad de cada grupo suprimido. Las dependencias suprimidas como parte de un grupo atómico no se enumeran individualmente: el nombre raíz identifica el grupo. Formato de entrada suprimida: una línea por grupo raíz suprimido: <severity> <name> (p. ej. critical billing-freeze). El bloque termina con <<<END_TRIPWIRE_SUPPRESSED>>>.

Dependencias

Los tripwires pueden declarar depends_on: [name1, name2] para incorporar el contexto de otros tripwires cuando se activan.

  • Resolución transitiva — las dependencias se resuelven transitivamente hasta max_dependency_depth (predeterminado: 5).
  • Detección de ciclos — un conjunto de visitados rastrea el recorrido. Si se detecta un ciclo, se emite una advertencia y se omite el borde del ciclo.
  • Dependencias faltantes — si una dependencia nombrada no existe, se emite una advertencia y la resolución continúa.
  • Desduplicación global — cada bloque de dependencia aparece como máximo una vez por respuesta. Una dependencia se considera «ya emitida» si su bloque <<<TRIPWIRE ...>>> ... <<<END_TRIPWIRE>>> completo se ha incluido en la inyección renderizada (la supresión no cuenta como emisión). Si varios grupos raíz hacen referencia a la misma dependencia, se emite una vez con el grupo raíz más temprano en el orden de clasificación; su atributo originator="<rootName>" refleja el tripwire raíz cuyo grupo provocó primero la emisión de esta dependencia.
  • Construcción de grupos — para cada tripwire raíz coincidente, se construye un grupo: el cierre de dependencias (DFS, recorrido en el orden de la lista depends_on) seguido de la raíz. Los grupos se ordenan por gravedad raíz DESC y luego por nombre raíz ASC. Dentro de un grupo, las dependencias aparecen en orden de recorrido DFS (estable: el orden de hermanos coincide con el orden de declaración depends_on).
  • Truncamiento atómico — cuando max_context_length > 0, todo el grupo (deps + raíz) debe caber dentro del presupuesto restante. Si el grupo no cabe, se suprime por completo: la raíz nunca se emite sin sus dependencias. El tamaño del grupo se calcula después de la desduplicación global: las dependencias ya emitidas por un grupo anterior no se vuelven a contar ni se requieren para que el grupo quepa. Esto es seguro porque las dependencias siempre se emiten con el grupo raíz más temprano en el orden de clasificación, por lo que cualquier raíz posterior que haga referencia a esa dependencia puede omitirla: el bloque de dependencia aparecerá antes en la misma respuesta.
  • Renderizado — las dependencias se renderizan con atributos origin="dependency" originator="<rootName>". originator es el tripwire raíz cuyo grupo provocó primero la emisión de esta dependencia. El name siempre coincide con el nombre del archivo del tripwire (p. ej. name="depName"), nunca con un compuesto sintético.

Conflictos

Tripwire no intenta resolver conflictos entre contextos. Si dos tripwires coinciden con la misma ruta y dan instrucciones contradictorias, ambos se inyectan y el agente ve ambos.

tripwire lint comprueba (siempre):

  • Campo created_by faltante (error)
  • Tripwire creado por agente (created_by: agent:*) sin learned_from cuando require_learned_from es true (error)
  • Tripwire creado por agente (created_by: agent:*) sin expires cuando auto_expire_days > 0 (error): evita que las entradas agent:* escritas a mano omitan la caducidad automática
  • Nombres de etiqueta no válidos: deben coincidir con /^[a-z0-9][a-z0-9-]{0,31}$/ (error) tripwire lint --strict añade:
  • Conjuntos de disparadores idénticos (advertencia) — dos tripwires cuyos arreglos de disparadores ordenados son iguales (insensible al orden). Coincidencia exacta, no detección de solapamiento.
  • Solapamiento crítico (advertencia) — enumera los archivos del proyecto (glob **, solo archivos, filtrados por exclude_paths, ordenados lexicográficamente, con un máximo de 5000). .gitignore no se respeta para mantener los resultados de lint estables entre entornos; use exclude_paths para controlar el alcance del escaneo. Advierte si algún archivo coincide con >1 tripwire critical. Informa los nombres específicos de los tripwires.
  • Formato created_by (error) — debe ser human, agent:<client> o tool:<name>. Un agent o tool sin un nombre de cliente/herramienta es inválido.
  • Contexto individual > 4 KB (advertencia) — sugiere dividirlo.
  • Contexto agregado > 16 KB (advertencia) — total en todos los tripwires.
  • Tripwire crítico excede max_context_length (advertencia) — se suprimirá en tiempo de ejecución.

tripwire explain <path> muestra todos los tripwires coincidentes para una ruta dada, haciendo visibles los conflictos antes de que causen problemas.


Herramientas MCP

El servidor expone estas herramientas a los agentes conectados:

read_file

Reemplazo directo para la lectura estándar de archivos. Verifica los tripwires y antepone el contexto coincidente.

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 del delimitador:

<<<TRIPWIRE severity="<level>" name="<name>" [origin="dependency" originator="<rootName>"] [tags="<csv>"]>>>
<context text>
<<<END_TRIPWIRE>>>
AtributoSiempre presenteValores
severitysíinfo, warning, high, critical
namesínombre del archivo tripwire sin .yml
originsolo en dependenciasdependency
originatorsolo en dependenciastripwire raíz cuyo grupo causó primero que esta dependencia se emitiera
tagssolo si no está vacíoseparados por comas, sin escape (las comas no están permitidas en nombres de etiquetas)

El contenido del archivo sigue después de un centinela <<<TRIPWIRE_FILE_CONTENT>>> (elegido para ser poco probable en código real; si necesita una separación inequívoca, use inject_mode: metadata). Cuando los tripwires están suprimidos, un bloque <<<TRIPWIRE_SUPPRESSED count="N" reason="context_budget">>> lista los grupos raíz suprimidos como líneas <severity> <name> y termina con <<<END_TRIPWIRE_SUPPRESSED>>>.

Modos de inyección:

  • prepend (predeterminado) — contexto + centinela + contenido del archivo en una sola respuesta. Compatibilidad universal; funciona incluso cuando los clientes aplanan las salidas de herramientas de múltiples bloques.
  • metadata — el contexto y el contenido del archivo se devuelven como bloques de respuesta separados. Separación más limpia pero depende de que el cliente preserve los límites de los bloques.

create_tripwire

Permite a los agentes crear nuevos tripwires. Crea un archivo .yml en .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
}

Comportamiento:

  • El name se normaliza a un nombre de archivo canónico (a-z, 0-9, solo guiones). Db_Migration Checklist se convierte en db-migration-checklist.yml.
  • Si ya existe un tripwire con el mismo nombre normalizado, la llamada falla (sin sobrescrituras silenciosas). Pase force: true para sobrescribir, o elimine/desactive el tripwire existente primero.
  • La herramienta MCP establece created_by: "agent:mcp" automáticamente. El YAML escrito a mano debe incluir created_by explícitamente — no hay valor predeterminado; tripwire lint da error si falta.
  • La sobrescritura es atómica (escribir en un archivo temporal, luego renombrar).
  • Si created_by no es "human" y auto_expire_days > 0, se agrega automáticamente una fecha expires.
  • Si require_learned_from es true (predeterminado) y created_by comienza con agent:, se requiere learned_from. tripwire lint lo hace cumplir.

list_tripwires

Devuelve todos los tripwires activos, opcionalmente filtrados por ruta, etiqueta o severidad.

check_tripwires

Dada una ruta de archivo, devuelve qué tripwires se activarían — útil para que los agentes previsualicen antes de leer.

explain

Dada una ruta de archivo, devuelve un desglose estructurado de qué se inyectaría y por qué: tripwires coincidentes con sus globs, dependencias resueltas, entradas suprimidas, configuración activa y la inyección renderizada completa. Útil para depuración.

deactivate_tripwire

Desactiva suavemente un tripwire sin eliminar el archivo. Agrega active: false al 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

Integración con Git

Los tripwires son archivos simples en .tripwires/. Se diferencian, fusionan y revisan como código.

Flujo de trabajo recomendado

  1. El agente crea un tripwire después de una corrección → aparece en git diff
  2. El desarrollador revisa en el PR — acepta, edita o rechaza el tripwire
  3. Los tripwires fusionados se propagan a todo el equipo en el próximo pull
  4. Los tripwires expirados se limpian con tripwire lint --prune

Nota de seguridad: Los tripwires influyen en el comportamiento del agente. Trátelos como código — revíselos en los PR, no auto-fusione tripwires creados por agentes, y tenga especial cuidado con la severidad critical ya que moldea cómo los agentes interactúan con módulos sensibles. Consulte SECURITY.md para el modelo de amenazas completo, la configuración de CODEOWNERS y las recetas de CI.

.gitattributes (avanzado, opcional)

.tripwires/*.yml merge=union

Advertencia: merge=union auto-fusiona manteniendo ambos lados línea por línea. Esto funciona bien cuando dos ramas agregan archivos de tripwire diferentes, pero puede duplicar silenciosamente claves YAML si dos ramas editan el mismo tripwire. El valor predeterminado más seguro son las fusiones normales con tripwire lint --strict en CI para detectar cualquier rotura. Solo use merge=union si su equipo entiende la compensación.

Política de CI recomendada

  1. CODEOWNERS — proteja .tripwires/** para que los cambios requieran revisión
  2. CI ejecuta tripwire lint --strict — detecta created_by faltantes, violaciones de formato, solapamientos críticos
  3. Bloquear críticos creados por agentes — haga fallar el CI si un diff toca un archivo con ambos created_by: agent:* y severity: critical. La aprobación de CODEOWNER se aplica por separado mediante la protección de ramas de GitHub ("Requerir revisión de los propietarios del código"):
    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
    

Gancho de pre-commit (opcional)

tripwire lint --strict

Valida todos los archivos de tripwire antes del commit — detecta YAML malformado, violaciones de formato y solapamientos críticos.


Configuración

Opcional .tripwirerc.yml en la raíz del proyecto:

# 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/**"

Valores predeterminados de configuración

ClaveTipoPredeterminadoNotas
inject_mode"prepend" | "metadata""prepend"los metadatos devuelven contexto y contenido como bloques separados
separatorstring\n<<<TRIPWIRE_FILE_CONTENT>>>\ncentinela entre contexto y contenido del archivo — poco probable en código normal pero podría aparecer en heredocs, plantillas o fixtures de prueba que hagan referencia al propio Tripwire
max_context_lengthnumber0 (ilimitado)presupuesto de caracteres (no tokens) — truncamiento de tripwire completo, nunca corta a mitad de bloque
allow_agent_createbooleantrueestablezca false para bloquear tripwires creados por agentes
require_learned_frombooleantruelos agentes deben explicar el error
auto_expire_daysnumber900 = sin caducidad automática
enforcement_mode"strict" | "advisory""strict"asesoramiento permite lecturas sin procesar con una advertencia
exclude_pathsstring[]["node_modules/**", "dist/**", ".git/**"]nunca verificar tripwires para estos
tripwires_dirstring".tripwires"directorio que contiene archivos YAML
max_dependency_depthnumber5profundidad máxima para la resolución de cadena depends_on
match_casebooleantrueestablezca false para coincidencia sin distinción de mayúsculas (recomendado en macOS/Windows)

Las claves desconocidas se ignoran silenciosamente. Use tripwire lint --strict para detectar problemas de configuración.


Aplicación (Ganchos de Claude Code)

Sin aplicación, un agente puede eludir Tripwire usando la herramienta integrada Read en lugar de mcp__tripwire__read_file. Un gancho PreToolUse cierra esta brecha bloqueando lecturas sin procesar y redirigiéndolas a través de Tripwire.

Compatibilidad: Los ganchos de aplicación son actualmente específicos de Claude Code. Cursor y otros clientes MCP necesitarán su propio mecanismo para redirigir lecturas. El servidor MCP en sí es universal — solo la capa de aplicación es específica del editor.

Configuración

Tripwire incluye un gancho listo para usar. Copie ambos archivos en su proyecto:

.claude/
  settings.json                  # Hook config: intercepts Read calls
  hooks/
    enforce-tripwire-read.mjs    # Denies raw reads, suggests tripwire read_file

No se requieren dependencias externas — el gancho es Node.js puro.

Cómo funciona

  1. El agente llama a Read (o mcp__filesystem__read_file) para un archivo del proyecto
  2. El gancho resuelve la ruta real mediante realpath (previene eludir por symlink/traversal)
  3. El gancho verifica que .tripwires/ exista y que .mcp.json tenga un servidor "tripwire" configurado
  4. Si ambas condiciones se cumplen y el archivo no está en un directorio excluido, el gancho deniega la lectura
  5. El mensaje de denegación le dice al agente el nombre exacto de la herramienta y la forma del argumento a usar en su lugar
  6. El agente reintenta con mcp__tripwire__read_file — el contexto se inyecta automáticamente

Válvulas de seguridad:

  • Si .tripwires/ no existe, el gancho no hace nada (no es un proyecto Tripwire)
  • Si .mcp.json no tiene un servidor "tripwire", el gancho permite la lectura (el agente no tiene alternativa — evita bucles)
  • Si el mensaje de denegación incluye: "Si Tripwire MCP no está disponible, ejecute: tripwire doctor"

Directorios excluidos (siempre permitidos a través de Read): .git/, node_modules/, dist/, .tripwires/, .claude/.

Modos de aplicación

Establecido en .tripwirerc.yml:

ModoComportamientoCaso de uso
strict (predeterminado)Denegar lecturas sin procesar, forzar TripwireProducción, equipos establecidos
advisoryPermitir lecturas sin procesar con advertenciaAdopción progresiva, evaluación

Verificar

tripwire doctor

Verifica todos los componentes e imprime ENFORCEMENT: ON, PARTIAL o OFF con instrucciones de corrección accionables.

Notas importantes

  • La clave del servidor MCP en .mcp.json debe ser "tripwire" para que el nombre de la herramienta se resuelva a mcp__tripwire__read_file
  • La aplicación es opcional pero muy recomendada — sin ella, Tripwire depende de que el agente elija la herramienta correcta

Principios de diseño

El código base es la fuente de verdad, no la memoria del agente. Tripwire externaliza el conocimiento en el repositorio para que sobreviva a través de sesiones, agentes y miembros del equipo.

El conocimiento encuentra al agente. Los agentes no necesitan saber qué buscar. El contexto correcto llega en el momento correcto, activado por lo que realmente están haciendo.

Git es la capa de sincronización. Sin almacenamiento propietario, sin dependencia en la nube. Los tripwires viajan con el código y pasan por el mismo proceso de revisión.

Los humanos curan, los agentes acumulan. Los agentes crean tripwires a partir de errores. Los humanos los revisan y podan. El sistema se vuelve más inteligente con el tiempo sin mantenimiento manual.

Archivos planos sobre abstracciones ingeniosas. Cualquiera puede abrir un archivo YAML y entender qué hace un tripwire. Sin bases de datos, sin embeddings, sin lenguajes de consulta.


Ejemplos

Prevenir errores comunes

# .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 decisiones arquitectónicas

# .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 conocimiento 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"

Barreras temporales

# .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]

Solución de problemas

Ejecute tripwire doctor primero — verifica todos los componentes y le dice exactamente qué está mal.

SíntomaCausa probableSolución
No se inyecta contextoEl agente usó Read en lugar de mcp__tripwire__read_fileHabilite los ganchos de aplicación (consulte Aplicación)
Contexto inyectado pero el gancho no bloquea.claude/settings.json falta o comparador incorrectoEjecute tripwire doctor, verifique la configuración del gancho
Agente atrapado en bucle de denegaciónServidor MCP de Tripwire no cargadoVerifique que .mcp.json tenga la clave "tripwire", reinicie la sesión
tripwire doctor muestra FAIL en MCP.mcp.json falta o clave de servidor incorrectaLa clave del servidor debe ser "tripwire" (no "tw", no "tripwire-mcp")
El gancho no se dispara en absolutoArchivo de configuración no cargadoReinicie la sesión de Claude Code después de crear .claude/settings.json
Funciona en Claude Code, no en CursorCursor no tiene ganchos PreToolUseConsulte Estrategia para Cursor

Modo Proxy de Sistema de Archivos

Tripwire incluye 4 herramientas de sistema de archivos para que pueda servir como el único proveedor de FS para clientes MCP. Solo read_file inyecta contexto — las otras 3 son paso directo:

HerramientaComportamiento
read_fileComprueba tripwires, inyecta contexto, devuelve el contenido del archivo
list_directoryLista entradas en un directorio (paso directo)
file_statDevuelve tipo, tamaño, modificado, creado (paso directo)
search_filesBúsqueda glob de archivos (paso directo)

Configura Tripwire como el único servidor de sistema de archivos. Los agentes descubren las herramientas disponibles al momento de la conexión a través de tools/list de MCP — si ningún otro servidor proporciona herramientas de sistema de archivos, los agentes deben usar las versiones de Tripwire y todas las lecturas reciben inyección de contexto automáticamente.

Limitación dura: El modo proxy solo funciona si el cliente no tiene habilitado acceso a archivos no-MCP. Si el cliente proporciona un comando nativo Read, los agentes pueden omitir Tripwire usando ese en su lugar.

Cómo cerrar la brecha por cliente:

  • Claude Code — tiene una herramienta nativa Read que omite MCP. Usa ganchos de aplicación (PreToolUse) para denegar lecturas sin procesar. El modo proxy por sí solo no es suficiente.
  • Cursor — el modo proxy cubre las lecturas que pasan por herramientas MCP. Si Tripwire es el único servidor que proporciona herramientas de sistema de archivos, esto es suficiente. Si Cursor tiene otras vías de lectura (dependiente de la versión), Tripwire no puede interceptarlas. Desactiva otros servidores FS si están presentes.
  • Otros clientes MCP — verifica si el cliente tiene acceso a archivos integrado. Si lo tiene y no hay mecanismo de ganchos, el modo proxy no puede garantizar la cobertura. Aún no sabemos qué clientes admiten deshabilitar FS nativo — si el tuyo lo hace, avísanos.

Cuándo usar el modo proxy vs. ganchos

EnfoqueMejor paraLimitación
Ganchos de aplicaciónClaude Code (admite PreToolUse)Específico del cliente
Modo proxyCursor, cualquier cliente MCPDebe ser el único servidor FS
AmbosCobertura máximaMás configuración

Estrategia para Cursor

El servidor MCP de Tripwire funciona en Cursor — los agentes pueden llamar a read_file, list_tripwires, etc. La diferencia es aplicación: Cursor no admite ganchos PreToolUse, por lo que no hay forma de bloquear lecturas sin procesar del sistema de archivos.

Recomendado: Usa el modo proxy de sistema de archivos — configura Tripwire como el único servidor MCP con capacidad de sistema de archivos. Con read_file, list_directory, file_stat y search_files disponibles, los agentes tienen acceso completo a FS a través de Tripwire. Si ningún otro servidor proporciona herramientas de sistema de archivos, los agentes deben usar las versiones de Tripwire, y todas las lecturas reciben inyección de contexto automáticamente.


Hoja de ruta

  • Modo proxy de sistema de archivos — sirve herramientas de lectura/listado/estadísticas/búsqueda para que Tripwire sea el único proveedor de FS
  • Detección de obsoletos — marca tripwires cuyos archivos activados han cambiado significativamente desde su creación
  • Analíticas de activación — rastrea qué tripwires se activan más, cuáles nunca se activan (candidatos para eliminación)
  • Coincidencia semántica — coincidir en contenido/intención del archivo, no solo en globs de ruta
  • Integración con editor — mostrar indicadores de tripwire en el margen de VS Code
  • tripwire suggest — analizar git blame y comentarios de PR para proponer tripwires automáticamente

Licencia

MIT