ClawMart AI
← All issuesClaw Mart Daily
Issue #245July 31, 2026

MCP servers run with root-level trust. Most shouldn't.

MCP servers are everywhere now. GitHub integration, file system access, browser automation, API connectors — the ecosystem exploded overnight. But here's what nobody talks about: most of these servers can do anything they want to your system.

I learned this the hard way when a "harmless" file browser MCP server started making network requests. Then I found another one that could execute arbitrary shell commands through a "file preview" feature. The MCP protocol doesn't enforce boundaries — it trusts servers completely.

Here's the security model that actually works:

Assumption: Every MCP server is potentially malicious. Even the ones you trust.

The fix is a security sandbox that wraps every MCP server call. Here's the pattern:

# mcp_sandbox.py
import subprocess
import tempfile
import os
from pathlib import Path

class MCPSandbox:
    def __init__(self, allowed_paths=None, network_allowed=False):
        self.allowed_paths = allowed_paths or []
        self.network_allowed = network_allowed
        self.temp_dir = tempfile.mkdtemp(prefix="mcp_sandbox_")
    
    def execute_server(self, server_path, args):
        # Create isolated environment
        env = os.environ.copy()
        env['HOME'] = self.temp_dir
        env['TMPDIR'] = self.temp_dir
        
        # Network isolation
        if not self.network_allowed:
            # Use unshare or docker for network isolation
            cmd = ['unshare', '--net', server_path] + args
        else:
            cmd = [server_path] + args
            
        # File system restrictions via chroot/jail
        return subprocess.run(cmd, env=env, cwd=self.temp_dir)

But subprocess sandboxing is complex. The simpler approach is permission-based filtering:

# mcp_filter.py
class MCPSecurityFilter:
    def __init__(self):
        self.allowed_operations = {
            'files': ['read'],  # No write, no execute
            'network': [],      # No network by default
            'system': []        # No system calls
        }
    
    def validate_request(self, tool_name, args):
        if tool_name.startswith('file_'):
            if 'write' in tool_name or 'delete' in tool_name:
                return False, "Write operations not allowed"
        
        if tool_name.startswith('shell_') or tool_name.startswith('exec_'):
            return False, "Execution not allowed"
            
        if 'network' in args or 'http' in str(args):
            return False, "Network access not allowed"
            
        return True, "OK"

The key insight: least privilege by default. Every MCP server starts with zero permissions. You explicitly grant what it needs:

# claude_desktop_config.json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["@modelcontextprotocol/server-filesystem", "/safe/path"],
      "permissions": {
        "file_read": true,
        "file_write": false,
        "network": false,
        "system": false
      }
    }
  }
}

I run a permission audit every week now. Three questions for every MCP server:

  • What's the minimum it needs to function? File read vs write vs execute
  • Does it need network access? Most don't, despite claiming they do
  • Can it escalate privileges? Shell access, system calls, environment variables

The MCP ecosystem moves fast. Security practices don't. Sandbox first, trust later.

I caught two "legitimate" MCP servers trying to write to my home directory last month. The permission model saved me from debugging a corrupted config for hours.

Your agent needs access to be useful. But it needs boundaries to be safe. The MCP security sandbox gives you both.

Paste into your agent's workspace

Claw Mart Daily

Get tips like this every morning

One actionable AI agent tip, delivered free to your inbox every day.