2025-12-29 · Authensor

Using SafeClaw with MCP Servers: Tool Execution Gating

Scenario

You are developing an MCP (Model Context Protocol) server that exposes tools to AI clients. Your server provides tools like read_file, write_file, run_command, and fetch_url. Any MCP-compatible client (Claude Desktop, Cursor, custom agents) can invoke these tools. You need to ensure that no client can misuse your tools to access unauthorized files, run dangerous commands, or reach restricted network endpoints.

SafeClaw sits between the MCP tool handler and the actual execution layer. When a client calls a tool, the handler evaluates the action against your policy before executing it. The client receives a denial response if the action is blocked.

Threat Model

An MCP server without action-level gating on its tools exposes:

SafeClaw adds a policy enforcement point inside your MCP server so that every tool invocation is gated, regardless of which client calls it.

Recommended Policy

# MCP Server Tool Execution Policy
policy:
  name: "mcp-server-tools"
  default: DENY

rules:
# --- read_file tool ---
- action: file_read
path: "/workspace/**"
decision: ALLOW

- action: file_read
path: "/workspace/.env"
decision: DENY

- action: file_read
path: "/workspace/.env.*"
decision: DENY

- action: file_read
path: "/.ssh/"
decision: DENY

- action: file_read
path: "/etc/**"
decision: DENY

# --- write_file tool ---
- action: file_write
path: "/workspace/output/**"
decision: ALLOW

- action: file_write
path: "/workspace/src/**"
decision: REQUIRE_APPROVAL

- action: file_write
path: "/workspace/.git/**"
decision: DENY

- action: file_write
path: "/workspace/node_modules/**"
decision: DENY

# --- run_command tool ---
- action: shell_exec
command: "ls *"
decision: ALLOW

- action: shell_exec
command: "cat *"
decision: ALLOW

- action: shell_exec
command: "grep *"
decision: ALLOW

- action: shell_exec
command: "npm test*"
decision: ALLOW

- action: shell_exec
command: "npm run build*"
decision: ALLOW

- action: shell_exec
command: "rm *"
decision: DENY

- action: shell_exec
command: "sudo*"
decision: DENY

- action: shell_exec
command: "chmod*"
decision: DENY

- action: shell_exec
command: "curl*"
decision: DENY

# --- fetch_url tool ---
- action: network
domain: "api.github.com"
decision: ALLOW

- action: network
domain: "registry.npmjs.org"
decision: ALLOW

- action: network
domain: "169.254.169.254"
decision: DENY

- action: network
domain: "*.internal"
decision: DENY

- action: network
domain: "*"
decision: DENY

Example Action Requests

1. Client reads a project source file (ALLOW)

{
  "action": "file_read",
  "path": "/workspace/src/index.ts",
  "agent": "mcp-client-claude",
  "tool": "read_file",
  "timestamp": "2026-02-13T11:00:00Z"
}
// Decision: ALLOW — path matches /workspace/**

2. Client reads a .env file (DENY)

{
  "action": "file_read",
  "path": "/workspace/.env",
  "agent": "mcp-client-claude",
  "tool": "read_file",
  "timestamp": "2026-02-13T11:00:30Z"
}
// Decision: DENY — /workspace/.env is explicitly denied

3. Client writes to the output directory (ALLOW)

{
  "action": "file_write",
  "path": "/workspace/output/report.json",
  "content": "{\"status\": \"complete\"}",
  "agent": "mcp-client-cursor",
  "tool": "write_file",
  "timestamp": "2026-02-13T11:01:00Z"
}
// Decision: ALLOW — path matches /workspace/output/**

4. Client modifies source code (REQUIRE_APPROVAL)

{
  "action": "file_write",
  "path": "/workspace/src/utils.ts",
  "content": "export function newHelper() { ... }",
  "agent": "mcp-client-cursor",
  "tool": "write_file",
  "timestamp": "2026-02-13T11:02:00Z"
}
// Decision: REQUIRE_APPROVAL — /workspace/src/** requires human sign-off

5. Client attempts to reach cloud metadata endpoint (DENY)

{
  "action": "network",
  "domain": "169.254.169.254",
  "method": "GET",
  "path": "/latest/meta-data/iam/security-credentials/",
  "agent": "mcp-client-unknown",
  "tool": "fetch_url",
  "timestamp": "2026-02-13T11:03:00Z"
}
// Decision: DENY — cloud metadata IP is explicitly denied

6. Client runs a safe command (ALLOW)

{
  "action": "shell_exec",
  "command": "npm test -- --reporter json",
  "agent": "mcp-client-claude",
  "tool": "run_command",
  "timestamp": "2026-02-13T11:04:00Z"
}
// Decision: ALLOW — matches npm test*

Setup Steps

  1. Install SafeClaw in your MCP server project:
   npx @authensor/safeclaw
The browser-based setup wizard opens. Free tier with 7-day renewable keys, no credit card required.
  1. Select the "MCP Server" template from the wizard. This pre-configures rules for common MCP tool patterns: file read, file write, shell exec, and network fetch.
  1. Integrate SafeClaw into each tool handler. The enforcement point sits between the MCP request handler and the execution function:
   import { evaluate } from "@authensor/safeclaw";

server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;

if (name === "read_file") {
const decision = await evaluate({
action: "file_read",
path: args.path,
agent: request.meta?.clientId || "unknown",
tool: "read_file"
});

if (decision.result !== "ALLOW") {
return { content: [{ type: "text", text: Access denied: ${args.path} }] };
}
return readFile(args.path);
}
// ... repeat for write_file, run_command, fetch_url
});

  1. Block sensitive paths explicitly. Even though deny-by-default catches unknown paths, explicitly deny .env, .ssh, /etc, and cloud metadata IPs for defense in depth.
  1. Use REQUIRE_APPROVAL for source code modifications. This lets connected clients suggest changes that you review in the SafeClaw dashboard before they take effect.
  1. Test with simulation mode. Connect your MCP clients and run typical workflows. The dashboard shows every tool invocation, the evaluated policy rule, and the decision.
  1. Ship with SafeClaw built in. When you distribute your MCP server, SafeClaw is included as part of the execution pipeline. Users can customize the policy through the dashboard without modifying server code.
  1. Monitor the audit trail. The tamper-proof SHA-256 hash chain logs every tool invocation with client identity, tool name, action parameters, and decision. Export for security review or incident response.

Cross-References

Try SafeClaw

Action-level gating for AI agents. Set it up in your browser in 60 seconds.

$ npx @authensor/safeclaw