---
title: How to stop agents from running destructive MCP tools
description: Deny the destructive MCP tools an agent never needs, make the rest ask first, and give the server a credential that can’t delete. Then make writes undoable.
canonical: https://mcp1.com/blog/stop-destructive-mcp-tools
last-updated: 2026-11-12
---

# How to stop agents from running destructive MCP tools

Deny the destructive MCP tools an agent never needs, make the rest ask first, and give the server a credential that can’t delete. Then make writes undoable.

![](https://avatars.githubusercontent.com/u/1297371?s=96&v=4)Eldad FuxFounder and CEO, Appwrite

 Destructive tools

- `github__get_file_contents`Allowed
- `github__merge_pull_request`Ask first
- `supabase__execute_sql`Ask first
- `github__delete_file`Admin only

 Destructive tools

- `github__get_file_contents`Allowed
- `github__merge_pull_request`Ask first
- `supabase__execute_sql`Ask first
- `github__delete_file`Admin only

To stop an agent from running destructive MCP tools, turn off the ones it never needs, make the rest ask a person before every call, and connect the server with a credential that can’t do the damage in the first place. Tool annotations tell you which tools a server considers destructive, but a tool without them could be anything, so match on tool names as well.

## What counts as a destructive MCP tool?

A tool is destructive when its server sets the `destructiveHint` annotation, meaning a call may delete or overwrite something rather than only add to it. The MCP spec defines four annotations, all of them hints:

AnnotationMeaning, and the default when it’s missing

`readOnlyHint`

The tool doesn’t change anything. Defaults to false.

`destructiveHint`

A call may destroy or overwrite data. Only meaningful when readOnlyHint is false. Defaults to true.

`idempotentHint`

Calling it twice with the same arguments does no more than once. Defaults to false.

`openWorldHint`

It reaches outside systems, like the web. Defaults to true.

By the spec’s defaults, a tool with no annotations is a possibly destructive write. In practice the list to worry about is short and easy to read from the names: tools that delete, merge, push, reset, cancel, refund or run arbitrary SQL. On GitHub’s server that’s `delete_file`, `push_files` and `merge_pull_request`. On Supabase’s it’s `execute_sql`, `apply_migration` and `delete_branch`. A single `execute_sql` can drop a table, so treat any tool that takes free-form code or queries as destructive, whatever its annotation says.

## How do I block destructive tools in Claude Code?

Add `deny` rules for tools the agent should never call and `ask` rules for tools it may call with your approval, in `.claude/settings.json` for a project or `~/.claude/settings.json` for yourself:

.claude/settings.json

```
{
  "permissions": {
    "deny": [
      "mcp__github__delete_file",
      "mcp__supabase__delete_branch"
    ],
    "ask": [
      "mcp__github__merge_pull_request",
      "mcp__github__push_files",
      "mcp__supabase__apply_migration",
      "mcp__supabase__execute_sql"
    ]
  }
}
```

A deny rule wins over every allow rule and takes the tool away from the agent. An ask rule stops each call for confirmation, even in a session where you’ve allowed other tools on the same server. Name each tool in full. `mcp__github__*` covers a whole server, which is right for a deny and too broad for an ask.

For a whole team

Rules in a project’s settings file can be changed by anyone who edits the file, and personal settings by their owner. To enforce rules across a company, put them in Claude Code’s managed settings, which sit above every other settings file and can’t be overridden by users.

## What about Codex, Cursor and VS Code?

Codex takes a list of tools to leave out, per server, in `config.toml`. A disabled tool is never offered to the model:

\~/.codex/config.toml

```
[mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
bearer_token_env_var = "GITHUB_TOKEN"
disabled_tools = ["delete_file", "merge_pull_request"]
```

Cursor and VS Code ask before running an MCP tool unless you’ve approved it for good or turned on auto-run. Keep destructive tools off those allowlists, and switch off the ones you never need in the server’s tool list in settings, so the agent doesn’t see them at all.

## Why aren’t client rules enough?

Client rules are worth setting, but each one protects one person on one machine, and they share three weaknesses:

- They live with the user. Anyone can edit their own settings, approve a tool for good, or use the same token from a script or another client that has no rules.
- Confirmations wear thin. After the twentieth prompt in a day, people approve without reading, and an approval dialog only helps if the person understands the arguments.
- The agent’s input isn’t trusted. An issue body, web page or log line can ask the agent to call a tool. Asking first is what catches that, so the tools that matter most should never be auto-approved.

The control that holds regardless of the client is the credential. A token that can’t delete can’t be talked into deleting. For how to scope one, see [how to make an MCP server read-only](https://mcp1.com/blog/read-only-mcp-server).

## How do I limit the damage when a destructive call goes through?

Assume one eventually will, and set up the services so it can be undone:

1. 1Protect the main branch. With branch protection or a ruleset, an agent’s token can open pull requests but can’t push to or merge into main.
2. 2Give database agents a branch or a copy. Supabase and Neon both create database branches, so migrations and SQL run somewhere you can throw away.
3. 3Turn on backups and point-in-time recovery before you connect an agent, not after.
4. 4Give the agent its own credential, so its writes are attributed to it and you can revoke it without locking out a person.
5. 5Record every call with its arguments, so you know exactly what to restore.

## Stopping destructive tools in MCP1

MCP1 applies these rules in the gateway, so they hold for every client and every person in the workspace, and nobody can edit them from their own machine:

- **Destructive tools need admin.** A workspace guardrail, on by default: tools their server marks as destructive can only be called by admins.
- **Confirm destructive calls.** When it’s on, a destructive call asks the person to confirm it in their client first, over MCP elicitation, where the client supports it.
- **Rules by name.** Patterns like `*__delete_*` or `github__merge_pull_request` can block tools, set a minimum role, limit them to some groups, or ask first. An Ask first rule refuses clients that can’t ask, and covers matching tools installed later.
- **Read-only access.** Groups can get a gateway read-only, and a server can hold a second, read-only token for them, so the service refuses their writes.
- **The audit log** records every call, including refused ones as **Blocked**.

MCP1 treats a tool as destructive only when its server says so explicitly, so cover unannotated tools with a rule by name. Each server’s page, like [GitHub](https://mcp1.com/servers/github) or [Supabase](https://mcp1.com/servers/supabase), marks every tool as read-only, destructive or may write, which shows where you need one. The [docs](https://mcp1.com/docs#policies) list every rule and the order calls are checked in.

## Common questions

### What is destructiveHint in MCP?

A tool annotation that says a call may delete or overwrite data. It only applies when readOnlyHint is false, defaults to true, and is a hint from the server, not something the protocol enforces.

### Can I stop Claude Code from deleting files through an MCP server?

Yes. Add a deny rule with the tool’s full name, like mcp\_\_github\_\_delete\_file, to your settings. Deny rules win over allow rules, and managed settings can enforce them for a whole company.

### Is asking for confirmation enough to stop prompt injection?

It helps, because a person sees the call before it runs, but only if they read the arguments. Pair it with a credential that can’t do the damage.

### How do I let an agent run migrations safely?

Run them against a database branch or a copy, not production, with backups and point-in-time recovery on, and keep the migration tool behind an ask rule.

Give your team one URL

Create a workspace, install your servers and share a gateway with a group. Free for individuals.

[Start with MCP1](https://mcp1.com/signup)[Read the docs](https://mcp1.com/docs)

## More from the blog

[What is an MCP gateway?An MCP gateway is one endpoint between MCP clients and many MCP servers. It signs people in, filters their tools, holds server credentials and logs every call.![](https://avatars.githubusercontent.com/u/1297371?s=96&v=4)Eldad FuxFounder and CEO, Appwrite](https://mcp1.com/blog/what-is-an-mcp-gateway)[ Terminal$ claude mcp add --transport http linear mcp.linear.app/mcplinearConnectedHow to connect Linear MCP to Claude CodeRun claude mcp add with Linear’s hosted URL and authenticate with /mcp. How to share it with a team, make it read-only, use an API key and fix errors.![](https://avatars.githubusercontent.com/u/1297371?s=96&v=4)Eldad FuxFounder and CEO, Appwrite](https://mcp1.com/blog/linear-mcp-claude-code)

---

This is the markdown copy of https://mcp1.com/blog/stop-destructive-mcp-tools. Site index for agents: https://mcp1.com/llms.txt
