← All posts
aimcpsecurityllm

Is your MCP server safe? One line in mcp.json, and your agent recovers from its own DROP TABLE

If you run an AI agent through MCP (Claude Code, Cursor, or any MCP client), your tool calls now flow through MCP servers: a filesystem server, a database server, a shell. That standardization is great. It also means a single hallucinated or prompt-injected tool call can do real, irreversible damage, and the model does not know a destructive call from a safe one until it is already making it.

So people ask: is this MCP server safe?

Here is the better question. Your agent will, eventually, send an MCP server something destructive. The question is not only whether you block it. It is whether the run survives the block.

Block it with one line. No code, no key.

Wrap any MCP server with agentx-mcp. It is a small stdio proxy: it spawns the real server, relays the MCP protocol untouched, and screens every tools/call before it runs. One line in your mcp.json:

{
  "mcpServers": {
    "database": {
      "command": "agentx-mcp",
      "args": ["npx", "-y", "your-real-mcp-server", "..."]
    }
  }
}
pip install agentx-security-sdk   # this ships the agentx-mcp command

Now every tool call the agent makes is checked by a deterministic floor first. A DROP TABLE, an unscoped DELETE, a secret-store read, an SSRF to 169.254.169.254, an rm -rf: all blocked before they reach the server. No API key, nothing leaves your machine, no LLM in the hot path for the block. It works with any MCP-speaking stack, because it screens the protocol, not your code.

That is the part you can verify in two minutes without trusting me.

A block that kills the run is still a broken agent

Most "is it safe" answers stop here: the dangerous call is blocked, the tool returns an error, and your agent gives up. A hard 403 in the middle of an autonomous run is its own kind of failure. The task does not get done. You just traded one broken outcome for another.

So the block does not end the run

agentx-mcp blocks the dangerous call and hands your agent what it needs to get back on track, so the run finishes instead of dying on the block. Same one-line wrap, no extra key.

Here it is end to end, on a real MCP server. The agent's task is "report the user count," and its query hides an injection: SELECT name FROM users; DROP TABLE users;

agentx-mcp blocks a stacked DROP TABLE at the proxy before it reaches the database, and the run still finishes with the user count, the table intact

The DROP TABLE is blocked at the proxy and never reaches the database. The run keeps going and still returns the right answer: three users, table intact, task done. The catch is table stakes. Finishing the job anyway is the point.

What it catches today, and how

The floor is deterministic, so the block is a rule, not a vibe:

  • destructive SQL: DROP TABLE, TRUNCATE, unscoped DELETE
  • secret and API-key bulk reads
  • SSRF and cloud-metadata fetches (169.254.169.254)
  • shell and filesystem teardown: rm -rf, curl | sh, path traversal
  • runaway tool-call loops

No model inference for the floor, which is why it runs with no key and adds negligible latency. It is the blatant-catastrophic floor on purpose: the things you never want an agent to do, blocked deterministically, every time.

Try it, and tell me what it caught

I am looking for people running MCP servers against something real (a database, a filesystem, cloud, internal APIs) to wrap one and tell me two things:

  • What did it catch that would have bitten you?

  • What dangerous tool call did it miss? Try to stump it.

  • Watch the catch-and-recover live, and try it: Playground

  • Tell me what broke or what it missed: Discord

If your agent never touches anything irreversible, ignore me. If it does, wrapping one MCP server is one line, and DROP TABLE is a bad way to learn this the hard way.

See it catch and recover, live

Paste a tool call you are worried about and watch AgentX block it, coach the agent, and let the run finish. No install, no key.

Open the playground