TripWire — Project Story
The safety layer AI coding agents don't have yet.
Inspiration
I was inspired to build TripWire based on the occurrences during the second half of 2025 and into 2026, four separate AI coding agents, built by four separate companies, caused real, unrecoverable damage not just in theory, but in production. For instance, Replit's agent deleted a live database of over 1,200 executives and companies during a declared code freeze, then fabricated data to cover it up. Cursor ran a command despite the user typing "DO NOT RUN ANYTHING" in capital letters. Google's Antigravity, in "Turbo mode," ran rmdir on an entire drive instead of the intended project folder, permanently destroying years' worth of files. These incidents have aggrieved developers, analysts, and engineers alike, causing a sense of dread about whether they can trust these AI or agentic systems that were meant to ease productivity and achieve more in less time. For the no-code developers/enthusiasts, vibe coders, and the non-technical users, the effects of these problems happen too late for them to diagnose what their AI agents or systems are currently doing.
These are different vendors that were affected by the same underlying failure in the space of five months. At this juncture, one conclusion can be made: nothing was watching the action itself.
What made this feel solvable rather than just alarming was a line in the Model Context Protocol's own specification, which is the standard nearly all of these agents run on. MCP explicitly states that tool behavior should be treated as untrusted, and that a host must get explicit user consent before invoking a tool. But the protocol has no mechanism to enforce that. The people who designed the standard already flagged the exact gap. TripWire is a direct answer to a limitation its own creators acknowledged.
The second half of the inspiration came from a different direction entirely: watching the industry realize, in real time, that agentic AI can cost more than the people it's meant to replace. A safety layer that's too expensive to run on every single action isn't a safety layer. Rather, it's a safety layer for the actions you remembered to worry about. That constraint shaped the architecture as much as the incidents did.
What it does
TripWire is an MCP server that sits between an AI coding agent and the shell, filesystem, or database it's about to act on. Every proposed command is classified into one of four states:
- Safe commands execute instantly, at zero model cost.
- Policy violation commands i.e., indirect environment-variable expansion (
$HOME,~, command substitution) that could resolve somewhere unexpected, are rejected outright, before any resolution is even attempted. - Destructive commands, including a destructive operation paired with what looks like a production resource despite a "test" or "cleanup" label, are blocked immediately.
- Ambiguous commands: for the genuinely unclear cases, a snapshot is taken, gets escalated to GPT-5.6 for real reasoning, and waits for a human to approve or deny through a dashboard. Only the exact, original, canonicalized command that was actually approved ever executes. In this manner, the cases of destruction or incidents would be lower, policing safe commands, never something the model merely claims it approved.
Every decision writes to a tamper-evident, hash-chained audit log. A verdict cache remembers previously-approved patterns, scoped narrowly enough by path and command shape that trust never silently generalizes to a different target, so the same repo gets cheaper to run over time without a cached "safe" verdict ever skipping the underlying destructive check. Because the interception point is the open MCP standard rather than any single vendor's platform, the same server integrates with Codex, Cursor/VS Code, Antigravity, and Replit.
How we built it
TripWire was built with Codex from the ground up, on Python and FastAPI, with an MCP stdio server exposing a safe_exec tool, SQLite for local state, and Docker for packaging. The core architectural decision was tiering: a fast, free, deterministic local classifier handles the overwhelming majority of commands, and GPT-5.6's reasoning, the only paid step in the whole pipeline, is reserved for the fraction that's genuinely ambiguous, running a real tool-calling loop that pulls context, snapshots state, reaches a verdict, executes or rolls back, logs the incident, and caches the outcome.
A few deliberate security choices shaped the build: every file path operand is resolved to a canonical absolute path and checked for containment, rather than trusting a string prefix; approval tokens are HMAC-signed and bound to an exact command-and-snapshot pair, with expiry and single-use enforcement that holds even across the process boundary between the MCP server and the dashboard; and credential redaction is applied consistently everywhere sensitive data could otherwise leak.
Challenges we ran into
The hardest challenge was making strong safety claims without overstating what the product can enforce. MCP protects commands that are deliberately routed through TripWire’s safe_exec path; it cannot silently intercept an IDE’s unrestricted raw terminal. We kept that boundary explicit and focused the demo on a reliable local protected path: VS Code launches the Docker environment, while the authenticated dashboard handles review and recovery. The most valuable challenge was an adversarial audit of our own early implementation. It exposed two genuine security gaps: path traversal was being checked as a string-prefix problem instead of resolving every declared file operand against the sandbox root, and commands such as test runners were initially treated as safe even though a workspace-controlled test suite can execute arbitrary code. We reclassified executable tools as review-required, added command-aware path validation and symlink checks, then re-tested the full flow. Deployment hardening also took real iteration. Docker Desktop’s Bake backend was unreliable in our Windows environment, so we built a repeatable VS Code launch task that disables Bake for the local demo. We also found that the dashboard logo existed in the repository but was excluded from the packaged Python static assets—an example of why fresh-container testing matters even for seemingly small UI details. This made creation of VSIX files very difficult and if created, very difficult to test them.
Accomplishments that we're proud of
- The full classify → snapshot → approve → execute → rollback loop, built and tested end to end,
- Finding two real, exploitable bugs through our own adversarial self-audit before anyone else did — and proving the fixes held through re-testing rather than assuming they did.
- Approval tokens that are cryptographically bound to a specific command and snapshot expire and remain single-use even across the MCP-server/dashboard process boundary — closing a replay-and-substitution gap that's easy to overlook entirely.
- Multi-platform support (Cursor/VS Code, Antigravity, Replit) that maps directly onto the platforms where the real incidents happened, not generic breadth for its own sake.
- An architecture where the overwhelming majority of commands never touch a paid model call at all, and the ones that do only cost anything once per distinct pattern in a given repo.
What we learned
- The MCP specification already names the exact trust gap this project fills: tool behavior should be treated as untrusted, and enforcement is left entirely to whoever implements the host, with no protocol-level guarantee.
- Safety guarantees here come entirely from application logic, not the operating system.
- The most dangerous mistakes are rarely the ones you were actively worried about. Both bugs we found were classic, well-documented vulnerability classes hiding in code that looked reasonable at a glance.
- Cost discipline is a requirement. A safety layer too expensive to run on every action doesn't get run on every action, which defeats the point of building it.
What's next for TripWire MCP Server Tool
Expand adversarial validation. Run larger fuzz, concurrency, prompt-injection, rollback-failure, and dashboard-disconnect suites so every failure mode continues to fail closed.
Measure live GPT‑5.6 behavior. Use a dedicated, revocable API key to collect latency, tool-call, error, and cost data for representative ambiguous commands, while retaining the credential-free deterministic demo mode for judges. Strengthen production isolation. The current local Docker path uses Landlock and resource limits. A hosted production version should add stronger worker isolation, restricted network egress, and eventually gVisor or microVM-based execution. Mature IDE and remote integrations. The included VSIX remains an experimental protected-terminal prototype. The next integration milestone is a reliable, clearly non-bypassable IDE execution hook. Remote gateways for platforms such as Replit and n8n remain advisory until those platforms expose a supported enforcement point.
Built With
- code
- codex
- cursor
- docker
- docker-compose
- fastapi
- gpt-5.6-terra
- html
- landlock
- model-context-protocol-(mcp)
- openai-responses-api
- python
- sqlite
- typescript
- vs
Log in or sign up for Devpost to join the conversation.