Squidbrake
The server provides controlled access to core business functions, allowing AI agents to perform tasks like financial transactions and CRM updates while ensuring every step is recorded and meets governance requirements.
Manage email interactions by listing, reading, and sending support emails.
Execute CRM operations, including searching for customers, adding notes, and updating subscription plans.
Handle financial processes such as listing card charges, issuing refunds, and performing wire transfers.
Utilize governance tools to pause actions for human approval, check past decisions, or request clarification from a human team member.
Provides push notifications for approval requests via ntfy, allowing approvers to be notified on their phone.
Sends approval notifications to Slack, with a link to the event, when a risky action needs human approval.
Provides tools to list tables, describe tables, query, and execute SQL on a SQLite database (data/shop.db), with reads running immediately and writes waiting for approval; destructive operations like DROP/TRUNCATE are blocked.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Squidbrake can you hold refunds over $100 for my approval?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Squidbrake
Change control for AI agents. Agents propose. People approve.
5,000+ PyPI downloads.
Your AI agents run commands, edit code, call MCP tools, send emails, issue refunds and change databases. Squidbrake sits between the agents and those actions:
routine work runs on its own, and is recorded
risky changes wait for a person who isn't the one who asked
catastrophic ones are blocked
Every decision goes into a tamper-evident record that someone outside engineering can read.
One policy covers every agent your company runs: Claude Code, Cursor, Codex, Gemini CLI, VS Code Copilot,
Antigravity, Qwen Code, Factory Droid, Kiro, and any MCP tool. Open source (Apache 2.0) and free for one person; more than one person, phone approvals, Slack/Teams/email and the audit export are part of the Team plan (squidbrake license). Runs on your laptop or your own server.

Why
Agents are good at each step and blind to the whole. Often every step is allowed, and the combination isn't:
An agent turns off a database's backups. Later, in another conversation or from another agent, it deletes the database.
An agent reads a web page, an issue or a support ticket that names an address. It then sends your data there.
A person rejects a force push, and the agent retries it with a different spelling.
Built-in agent permissions judge one tool call at a time, inside one agent. Squidbrake judges each action against what came before it, across conversations and agents. A person signs off on what matters, with the reason and the steps that led to it.
Related MCP server: AgentGuard MCP Server
How it works
agent (Claude Code, Cursor, Codex, MCP client, your own code)
│ every action, before it runs (hook, MCP proxy or HTTP)
▼
Squidbrake gateway ── rules.yaml + what came before ──► allow · hold for a person · block
│ │
└──────────── tamper-evident record ◄──────────────────────┘
dashboard · phone · Slack · Teams · email · SIEMDeterministic. No LLM decides anything. Rules and checks are in
rules.yaml, hot-reloaded on save.Reads what a command really does before it runs:
ls && rm -rf ~/,bash -c "...",curl ... | shMakefile targets and
package.jsonscriptscommands sent over
ssh,docker execandkubectl exec
Shows the approver the blast radius, measured on the developer's machine:
"removes 3 commits from origin/main"
"deletes 4,312 rows of 10,240 in orders"
"destroys 12 resources, including aws_db_instance.main"

Quick start
1. Install. One line installs it, runs it in the background, connects every agent on this computer, and opens the dashboard:
curl -fsSL https://pilots.squidbrake.com/install.sh | SQUIDBRAKE_REF=github sh # macOS / Linux$env:SQUIDBRAKE_REF="github"; irm https://pilots.squidbrake.com/install.ps1 | iex # WindowsOr with pip: pip install squidbrake && squidbrake setup.
2. Start in observe mode. Nothing is blocked or held; Squidbrake records what it would have done:
squidbrake connect all --mode observe
squidbrake doctor # every agent connected, and what each one's hook does and doesn't check3. Review after a week:
squidbrake report --week # held, blocked, would-have, false-positive rate, decision time, chains caughtMark any hold that shouldn't have happened with "This was legit" in the dashboard, or
squidbrake feedback EVENT_ID legit. The report counts the false-positive rate per rule.
4. Enforce. Set mode: enforce in ~/.squidbrake/rules.yaml. You can also enforce rule by rule (mode: on a
single rule) and observe the rest.
Even in observe mode, three things are always enforced:
catastrophic commands (
rm -rf ~/, wiping a drive)an emergency stop
an agent reaching for Squidbrake's own approval path
No install? Open the live demo in your browser: a sandbox company's support agent works its inbox while you watch.
More ways to install: docs/install.md. First run not right? docs/troubleshooting.md.
What it controls
Control | What it does | Details |
Sign-off by a second person | Risky changes wait in the dashboard, on a phone (one tap, optional Face ID / fingerprint), or in Slack, Teams or email. A key can't approve its own request, and per rule ( | |
Steer a running agent | Send a note an agent gets with its next action. The agent can ask a person instead of guessing ( | |
Command checks | Catastrophic commands are blocked. Every delete (except build output, caches and temp files, which are flagged), irreversible commands ( | |
Chains | An action is judged by what came before it: backups off and then a delete, a retry after a no, a refund loop. This works across conversations and agents, until the earlier step expires ( | |
Prompt injection, without a model | Sending to an address that only outside content mentioned (a web page, an email, an issue), even in an earlier conversation, waits for a person. The approver is told where the address came from | |
Data in public places | A customer's name or personal data in a PR, issue, comment or chat post waits for a person | |
Undo | Before an approved delete, | |
Self-protection | An agent can't approve its own action, read Squidbrake's keys, or switch Squidbrake off without a person. Every minute it checks that its hooks, rules and installed files are unchanged | |
Evidence | A hash-chained record with signed checkpoints that anyone can verify offline ( | |
Spend limits and kill switch | Pause an agent after N tokens or dollars a day. Stop one agent, one conversation, or all of them, from the dashboard or a phone. While stopped, its waiting approvals don't time out |
An example from the shipped rules.yaml:
rules:
- id: approve-money-out
action: review # allow | review (a person decides) | deny
reason: Bank transfers, wires and payouts need finance sign-off
timeout_seconds: 900
approvers: ["role:finance", "role:admin"]
match:
name: ["*transfer*", "*wire*", "*payout*"]
sequences:
- id: runaway-refunds
action: deny
reason: Too many refunds in a short time; the agent may be stuck in a loop
match: { name: ["*refund*"] }
count: { more_than: 10, within_hours: 1, scope: identity } # across all of one person's agentsProof
The incidents and the session benchmark run in CI, so they can't quietly stop being true.
Real incidents: incidents/ replays 12 public AI-agent incidents against the shipped rules.
Examples: Replit's production database, the Railway volume deletion, GitHub MCP, Supabase MCP, CurXecute.
14 of 15 harmful actions are stopped.
Reported bypasses: every way around Squidbrake that someone sent us is a test that must stay stopped on every release (tests/test_reported_bypasses.py): 42 of 42 stopped, and the everyday variants of each still run.
The one not stopped is listed and explained: a malicious MCP server adds a BCC inside itself, after the check.
Whole sessions: in bench/chains/, Squidbrake stops 65 of 66 harmful steps and holds 3 of 41 routine ones. An allowlist stops 53 and holds 10.
Other tools: bench/compare/ runs the same steps through two other tools (dcg and Microsoft's Agent Governance Toolkit), plus everyday coding work. This one is run by hand, not in CI.
Claims audit: AUDIT.md checks every claim on this page against the code. Gaps still open are tests that fail on purpose.
Supported agents
Agent | What's checked |
Claude Code | every tool call: commands, edits, reads, web, MCP (hook, or the Claude Code plugin) |
Cursor | terminal commands, file reads, edits and deletes, MCP tools |
Codex | shell commands, edits, MCP tools. Approve the hook once in Codex with |
Gemini CLI | shell commands, reads, writes and edits, and its MCP servers |
VS Code Copilot | agent-mode commands, reads and edits, and its MCP servers |
Antigravity | terminal commands, reads and writes, and its MCP servers |
Qwen Code | shell commands, reads, writes and edits, and its MCP servers |
Factory Droid | commands, reads, edits and new files, and MCP tools |
Kiro CLI | shell commands, reads and writes; its MCP servers (Kiro IDE: MCP servers only) |
Windsurf, Cline, Claude Desktop | their MCP servers |
Any MCP client, ChatGPT / claude.ai connectors, Devin, n8n | through the MCP proxy, by command or by URL |
Your own agents (OpenAI Agents SDK, LangGraph, CrewAI, ...) |
|
squidbrake doctor lists, for each agent on a computer, what its hook doesn't see.
Details: docs/install.md and docs/integrations.md.
Deployment
One laptop: the quick start above. Data, keys and rules stay in
~/.squidbrake.A team:
Run one gateway on a server:
./install.sh gateway.yourcompany.comfrom a clone sets it up with HTTPS. Or use Docker:docker run -d -p 8080:8080 -v squidbrake-data:/app/data ghcr.io/batrapulkit/squidbrake.Connect each laptop with
squidbrake connect all --url https://gateway.yourcompany.com --key gw_.... Each agent key works for one person.For several replicas, use Postgres (
DATABASE_URL).Settings → Agents across the team lists the agents on each computer that don't go through Squidbrake yet (
squidbrake doctorreports names only;SQUIDBRAKE_NO_INVENTORY=1turns it off).
Company-wide:
squidbrake lockdown --url https://gateway.yourcompany.comwrites the managed-settings files IT pushes to every machine. Each agent must then run Squidbrake's hook, and--dangerously-skip-permissions/--yoloare turned off.Integrations: Slack (approve and reject in the channel), Microsoft Teams, email, phone push (ntfy), and SIEM export (Splunk HEC, Datadog, an OpenTelemetry collector, any HTTP endpoint).
Signed builds: every PyPI file and Docker image carries Sigstore-signed build provenance (how to check).
Security model and limits
Squidbrake is a policy and approval layer for agents that make mistakes or follow instructions they shouldn't. It is not a sandbox against an agent deliberately trying to escape.
It doesn't see code running inside an allowed program or an MCP server, a background process started earlier, a tool that isn't connected, or someone with admin rights on the machine.
When the agent and Squidbrake run as the same OS user, a program the agent was allowed to run can read whatever that user can. Squidbrake finds its keys by real path (symlinks, globs and
cdfollowed). It alerts within seconds if a key file changes, and approvals come only from the dashboard, a phone or Slack. To close the gap fully, run the gateway as another user or on a server, so the agent's computer only ever holds a key that can ask and never approve. Details: THREAT_MODEL.md.It doesn't make an over-privileged agent safe. Use it with least-privilege credentials, and a container or VM for untrusted work.
While the gateway is down (
when_unreachable: block_risky, the default):what the rules already allow (reads, everyday coding work) still runs, unrecorded
anything that would wait for a person, and any command that can't be undone or can't be read, is blocked
AWS IAM reach isn't checked yet. An agent giving itself admin in small steps isn't caught. This is on the roadmap and is an open test in AUDIT.md.
The evidence pack shows which controls exist for SOC 2, ISO/IEC 42001, the EU AI Act, CERT-In and RBI. It doesn't make you compliant.
The full list, per agent and with the test behind each claim, is in THREAT_MODEL.md. To report a vulnerability, see SECURITY.md.
Privacy
What your agents do never leaves your machine or server: commands, files, prompts, tool inputs and outputs, and the audit trail.
Anonymous usage counts are sent to the Squidbrake team:
the command name and version
how many actions were allowed, held and blocked
the decision time
for each hold or block, only the program (like
rm) and the rule
The first run in a terminal says so, and asks, optionally, for your work email and name (Enter skips it; only if you
give an email are it, your name and the names of the coding agents installed here sent). squidbrake telemetry status shows exactly what is sent, and DO_NOT_TRACK=1
turns it off. Details: docs/operations.md.
What is stored
The gateway keeps its record in its database (SQLite on your machine by default, or the Postgres you point it at):
Each action: who asked, the tool, the decision and why, and a redacted copy of the input and output. Redaction removes values under secret-looking names (
password,token,api_key, ...) and strings that look like keys or tokens, and masks emails and card numbers (on by default). It works on names and patterns, so a secret written in free text can survive. Long inputs are cut toMAX_PAYLOAD_CHARS.The audit trail: every decision and change, hash-chained, with fingerprints of each action's input and output.
Chains: what an agent's earlier steps gave it (the
after:capabilities), until they expire.Approvals, notes, snapshots taken before risky changes, usage, and the passkeys used to sign approvals.
With Postgres, whoever runs that database (Supabase, your cloud) holds this data. The keys and signing secrets stay out of the database: docs/postgres-supabase.md says what to back up besides it.
Documentation
install options, connecting each agent, sharing with a team | |
observe mode, command checks, prompt injection, sequences, approvals, undo, spend limits | |
MCP proxy, agents by URL, OAuth apps, Python frameworks, HTTP API | |
dashboard, API, evidence and offline verification, behaviour notes, usage counts | |
how it differs from built-in permissions, what if it's down, can an agent get around it | |
what it stops, what it doesn't, and the test behind each claim | |
the first ten minutes; a five-minute demo with a sandbox company |
Status and roadmap
Squidbrake is early and moves fast: releases are frequent, and the rules format can still change between minor versions. Start in observe mode, and read the release notes before upgrading.
Next:
Reach checks for AWS (#18, design). Before an IAM change runs, work out what the agent can reach afterwards.
Rule packs for chains.
Business email compromise: a vendor's bank details change, then a payment goes to that vendor.
Refunds larger than the order, or sent to a destination changed just before.
An optional risk model that can only escalate (#16): a second opinion that can hold an action, never allow one.
Tell us what you need most with a 👍 or a comment on the issue.
Badge
Using Squidbrake in a repo where agents work? Say so in its README:
[](https://squidbrake.com/go/badge)Contributing, security, license
CONTRIBUTING.md covers a 10-minute setup and good first issues that name the file and function to change. Hacktoberfest pull requests are welcome. Replaying a real agent incident is a good first one.
SECURITY.md explains how to report vulnerabilities privately.
Licensed under the Apache License 2.0.
Available Tools
12 toolsacme_ask_userA
Ask a person on your team a question and wait for their answer, instead of guessing (which environment, which customer, is this safe). They answer in Squidbrake's dashboard or on their phone. If the answer isn't there yet, call this again with the event_id you were given.
Inputs: event_id, question.
acme_check_approvalB
Finish a acme call Squidbrake was holding for human approval (WAITING FOR HUMAN APPROVAL): runs it if approved, reports if rejected, or keeps waiting a little longer.
Inputs: event_id (required).
acme_recent_decisionsA
What people decided about your earlier requests (approved / rejected, by whom, and their notes). Check it before retrying something, and follow the notes.
Inputs: no named parameters.
crm_add_noteC
Add a note to a customer's CRM record.
Inputs: note (required), email (required), justification.
crm_find_customerC
Find customers by email, name or company.
Inputs: query (required), justification. Returns: result
crm_update_planB
Change a customer's plan (free, starter, pro, team) or cancel it (cancelled).
Inputs: plan (required), email (required), justification.
email_sendC
Send an email from support@acme.com.
Inputs: to (required), body (required), subject (required), justification.
inbox_listA
List support emails in the shared inbox (newest first) with a short preview.
Inputs: justification. Returns: result
inbox_readB
Read one support email in full and mark it as read.
Inputs: message_id (required), justification.
payments_list_chargesC
List a customer's card charges, with any refunds already made.
Inputs: customer_email (required), justification. Returns: result
payments_refundC
Refund all or part of a card charge back to the customer.
Inputs: amount (required), reason (required), charge_id (required), justification.
payments_transferC
Send a bank transfer (wire) from Acme's account.
Inputs: memo (required), amount (required), to_account (required), justification.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
Each tool maps to a distinct resource and action: inbox, CRM, payments, and human-in-the-loop functions are cleanly separated by prefix and description. The three acme_* tools are related but clearly differentiated (ask a question, check approval of a held action, review past decisions), so an agent should select correctly.
All names use snake_case with resource prefixes (inbox_, email_, crm_, payments_, acme_), which is largely predictable. Minor inconsistencies exist: email_send breaks the inbox_ email grouping, and acme_recent_decisions is noun-based rather than verb_noun.
12 tools is well within the ideal range and matches the breadth of the support-ops domain without bloat. Each tool appears to earn its place by covering a distinct capability.
Core support workflows—reading/replying to emails, looking up customers, updating plans, issuing refunds/transfers, and human escalation—are covered. Gaps include no email search/archive, no customer creation or general contact update, and no charge creation, but these are minor for the stated support context.
Maintenance
Related MCP Connectors
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
Human-in-the-loop review and approval for AI agents. Audit trail, approval policies, native MCP.
Authorize AI agent tool calls before they run: policy-as-code, human approval, signed receipts.
Runtime permission, approval, and audit layer for AI agent tool execution.
Related MCP Servers
AlicenseNot gradedqualityCmaintenanceEnables AI agents to securely call MCP tools with risk scoring, checkpoints, rollback, and approval workflows.11 npmMIT- FlicenseNot gradedqualityCmaintenanceProvides a secure MCP boundary for AI agents, intercepting and validating tool calls, redacting secrets, and requiring human approval for sensitive actions with a tamper-evident audit trail.-
- FlicenseNot gradedqualityDmaintenanceMCP server that provides a security gateway for AI agents, enforcing allow/confirm/deny policies on tool calls and requiring human approval for risky operations, with full audit logging.-
- AlicenseNot gradedqualityBmaintenanceProvides a governance layer for MCP servers, enforcing policy-based allow/deny/approval rules, requiring human approval for risky calls, and recording an auditable trail of every AI agent tool call.MIT