How to Safely Run MCP Tool Servers
To safely run MCP tool servers, add SafeClaw action-level gating. Install with npx @authensor/safeclaw and define a deny-by-default policy that evaluates every tool call before it reaches the MCP server. The Model Context Protocol (MCP) is an open standard for connecting AI models to external tools and data sources. MCP servers expose capabilities — file operations, database queries, API calls, shell commands — that any MCP-compatible agent can invoke. Every MCP tool call is an action that needs policy enforcement.
What MCP Tool Servers Can Do (And Why That's Risky)
MCP servers are middleware between AI agents and system capabilities. The protocol itself provides no authorization layer:
- Filesystem servers — MCP filesystem servers expose
read_file,write_file,list_directory,create_directory,move_file, anddelete_filetools. The agent decides which paths to pass as arguments. - Database servers — MCP database servers (PostgreSQL, SQLite, etc.) expose
querytools. The agent generates SQL and the server executes it. There is no query validation in the protocol. - Shell/command servers — some MCP servers expose
run_commandorexecutetools. The agent provides the command string. The server runs it. - API integration servers — MCP servers for GitHub, Slack, Jira, and other services expose tools that create issues, send messages, merge pull requests, and modify resources. The agent controls the parameters.
- Web fetch servers —
fetchtools retrieve arbitrary URLs. Content returned to the agent can include prompt injections. - Tool composition — an agent with access to multiple MCP servers can chain tools across servers. Read a file from the filesystem server, extract data, send it via the Slack server, then delete the file.
Step-by-Step Setup
Step 1: Install SafeClaw
npx @authensor/safeclaw
Select MCP Proxy as the integration type. SafeClaw acts as a proxy between the MCP client and your MCP tool servers, evaluating every tool call in transit.
Step 2: Get Your API Key
Visit safeclaw.onrender.com. Free-tier keys renew every 7 days, no credit card required.
Step 3: Configure SafeClaw as an MCP Proxy
Instead of connecting your agent directly to MCP servers, connect it to SafeClaw, which proxies to the actual servers:
Before (direct connection):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/path/to/allowed"]
}
}
}
After (SafeClaw proxy):
{
"mcpServers": {
"safeclaw": {
"command": "npx",
"args": ["@authensor/safeclaw", "serve", "--mode", "mcp-proxy"],
"env": {
"SAFECLAW_API_KEY": "your-key-here",
"SAFECLAW_UPSTREAM_SERVERS": "./mcp-servers.json"
}
}
}
}
Where mcp-servers.json lists your actual MCP servers:
{
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/path/to/allowed"]
},
"postgres": {
"command": "npx",
"args": ["@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
}
}
Step 4: Define Your Policy
version: 1
default: deny
rules:
# Filesystem server rules
- action: file_read
path: "${PROJECT_DIR}/**"
effect: allow
- action: file_read
path: "*/.env"
effect: deny
- action: file_write
path: "${PROJECT_DIR}/src/**"
effect: allow
- action: file_write
path: "${PROJECT_DIR}/tests/**"
effect: allow
- action: file_write
path: "${PROJECT_DIR}/config/**"
effect: deny
# Database server rules
- action: shell_exec
command: "SELECT*"
effect: allow
- action: shell_exec
command: "DROP*"
effect: deny
- action: shell_exec
command: "DELETE*"
effect: deny
- action: shell_exec
command: "ALTER*"
effect: deny
- action: shell_exec
command: "INSERT*"
effect: allow
- action: shell_exec
command: "UPDATE*"
effect: allow
# Network/API rules
- action: network
host: "api.github.com"
effect: allow
- action: network
host: "*.slack.com"
effect: deny
- action: network
host: "*"
effect: deny
Step 5: Test in Simulation Mode
npx @authensor/safeclaw simulate --policy safeclaw.policy.yaml --mode mcp-proxy
Route test traffic through the proxy. Review verdicts. Adjust. Then enforce.
What Gets Blocked, What Gets Through
ALLOWED — Agent reads source file through filesystem server:
{ "server": "filesystem", "tool": "read_file", "action": "file_read", "path": "/project/src/app.ts", "verdict": "ALLOW" }
DENIED — Agent writes to config directory:
{ "server": "filesystem", "tool": "write_file", "action": "file_write", "path": "/project/config/database.yaml", "verdict": "DENY", "reason": "path matches config/** deny rule" }
ALLOWED — Agent runs SELECT query through database server:
{ "server": "postgres", "tool": "query", "action": "shell_exec", "command": "SELECT * FROM users WHERE active = true", "verdict": "ALLOW" }
DENIED — Agent runs DROP TABLE through database server:
{ "server": "postgres", "tool": "query", "action": "shell_exec", "command": "DROP TABLE users", "verdict": "DENY", "reason": "DROP* matches deny rule" }
DENIED — Agent tries to send Slack message through API server:
{ "server": "slack", "tool": "send_message", "action": "network", "host": "hooks.slack.com", "verdict": "DENY", "reason": "*.slack.com matches deny rule" }
Without SafeClaw vs With SafeClaw
| Scenario | Without SafeClaw | With SafeClaw |
|---|---|---|
| Agent calls filesystem server delete_file on config | File deleted, configuration lost | Blocked — config/** is denied for writes |
| Agent sends DROP TABLE to database server | Table dropped, data lost | Blocked — DROP* matches explicit deny rule |
| Agent chains: read credentials file, send via Slack server | Credentials exfiltrated to Slack channel | Both blocked — .env read denied, .slack.com network denied |
| Agent reads source files for context | Files read normally | Allowed — src/ and tests/ in read allowlist |
| Agent inserts records through database server | INSERT executed | Allowed — INSERT* matches allow rule |
SafeClaw proxies MCP tool calls with sub-millisecond policy evaluation and zero third-party dependencies. Every tool call verdict is logged to a tamper-proof SHA-256 hash chain audit trail. The control plane receives only action metadata — never your database credentials, file contents, or API tokens. SafeClaw is validated by 446 tests under TypeScript strict mode. The client is 100% open source, MIT licensed.
Cross-References
- What is SafeClaw? — Deny-by-default action gating fundamentals
- How to Safely Use Claude Code — Claude Code uses MCP for tool integration
- How to Safely Use Cursor Agent Mode — Cursor uses MCP servers for agent tools
- How to Safely Use GitHub Copilot Agent Mode — Copilot extensions use similar tool patterns
- SafeClaw Policy Reference — Full policy syntax for MCP tool gating
Try SafeClaw
Action-level gating for AI agents. Set it up in your browser in 60 seconds.
$ npx @authensor/safeclaw