The destructive flagone bit changes everything READ TOOLS destructive=false auto-callable no confirmation compose freely safe by construction green light WRITE TOOLS destructive=true explicit consent dry-run mode audit log scoped credentials red light agents do not need permission to read

The destructive flag that stopped an agent from wiping prod

1 de junio de 2026·Patterns

Un boolean por tool. Eso es todo lo que separó una sesión rutinaria de un incidente con CEO en el loop. Te cuento qué hizo destructive: true cuando el agente alcanzó la call equivocada.

La escena

Un agente con acceso al MCP de Atalaya estaba iterando sobre una limpieza de pipeline runs viejos. Tarea acotada, prompt razonable, contexto suficiente. Llegó a delete_pipeline_runs con un filtro más amplio del que yo había imaginado — había drift entre lo que le pedí y lo que él entendió por "viejos".

No había nada raro en el log hasta ese punto. El plan se veía sensato leído en abstracto. El problema es que "sensato en abstracto" y "correcto en este entorno" no son lo mismo cuando la llamada es irreversible.

El runtime intercepta la ejecución porque la tool declara destructive: true en su schema. En vez de ejecutar, pide confirmación humana, muestra el filtro resuelto y los IDs afectados. Confirmé que no, ese alcance no era el que yo quería, y rearmamos la query. Tiempo perdido: cinco minutos. Tiempo ganado: el que hubiera tomado restaurar de backup explicándole al CEO por qué un dashboard quedó vacío.

Por qué un boolean en el schema gana al permission system

La pregunta natural es: ¿por qué no resolver esto con permisos del lado del servicio? La respuesta corta es que los permission systems viven afuera del modelo. El agente los descubre cuando ya falló — la llamada se rechaza, el agente reintenta con otro approach, eventualmente encuentra una manera de hacer el daño que el permission no anticipó.

destructive: true vive adentro del schema que el agente lee al planear. No es un guardrail post-hoc, es metadata semántica. Cambia el plan, no solo la ejecución. Cuando el modelo ve que una tool es destructiva, asigna más "cuidado" en su razonamiento — agrupa la llamada con un check previo, busca confirmación, propone dry-run primero.

Esa diferencia (planear vs. ejecutar) es la que importa. Un sistema de permisos es la última línea de defensa. El flag en el schema es la primera línea — y la barata.

Qué cuenta como destructive en mi rúbrica

Me pasó que el equipo se enredó debatiendo grises, así que escribí una rúbrica concreta. Destructive es cualquier write que no es trivialmente reversible: DELETE, DROP, override de estado financiero, cambios que invalidan auditoría.

También destructive: sends a producción que llegan a terceros. Notificaciones outbound, webhooks salientes, transacciones de pago, emails al cliente final. La irreversibilidad acá no es técnica — es social. Una vez que el cliente recibió el mail, no lo "des-enviás".

También destructive: cambios de configuración con efecto en runtime de otros servicios. Cambiar un feature flag en producción, modificar un rate limit, alterar un routing rule. La consola no se rompe, pero el blast radius es real.

No destructive: reads, queries, dry-runs, generación de artefactos en sandbox, escrituras en bases efímeras de testing. Si el peor escenario es perder cinco minutos de cómputo, no hay flag.

El costo de adoptarlo retroactivamente

Inventariar las 19 tools que teníamos vivas en AgentGuard y declarar el flag en cada una tomó una tarde. Eso es lo barato. La parte cara fue otra: decidir los casos grises tomó tres días de debate de equipo.

Update_metadata, por ejemplo. ¿Es destructive? Depende — si la metadata participa en cálculos posteriores, sí. Si es decorativa, no. Tuvimos que mirar uso real, no nombre. Esa conversación nunca habíamos tenido tiempo de tenerla, y resultó que tres tools que decíamos hacer "lo mismo" hacían cosas distintas en el camino caliente.

Ese debate fue el verdadero valor. El flag fue la excusa para nombrar qué hace cada tool. Sin el flag forzando la decisión binaria, hubiéramos seguido posponiendo la conversación indefinidamente.

La lección que me llevo: los buenos defaults técnicos a veces valen menos por lo que controlan en runtime y más por las decisiones que obligan a tomar al ponerlos. Este es uno de esos.

¿Tus MCP tools declaran si son destructive? Curioso por el porcentaje honesto en tu stack.

#MCP #AI #AgentGuard #Safety

Escríbenos por WhatsApp