Permission and Security Boundaries
The permission problem
An MCP server is code running on your machine—or someone else's machine—with access to tools that can read files, execute commands, and make network requests. The protocol itself does not enforce sandboxing, verification, or audit. That responsibility falls to clients and organizations.
Security research from mid-2025 found over 1,800 MCP servers exposed on the public internet without authentication.
The Asana MCP integration leaked data across tenants.
The mcp-remote package with 437,000 downloads was vulnerable to remote code execution (CVE-2025-6514).
This matters because MCP's power is also its risk: servers can do almost anything.
What servers can request
MCP servers expose capabilities through three primitive types: tools, resources, and prompts. Each carries different permission levels and risks.
Tool permissions
Tools are model-controlled actions—the server defines them, but the model decides when to invoke them. A filesystem server might expose:
read_file— Read contents of allowed fileswrite_file— Create or modify fileslist_directory— Enumerate directory contentssearch_files— Find files matching patterns
Each tool can perform operations with real consequences. Claude Code requires explicit user consent before invoking any tool for the first time. After approval, tool usage follows permission rules defined in your configuration.
Resource permissions
Resources are application-controlled context—files, database schemas, or API documentation that servers make available to the model. Resources are read-only by definition, but "read" can still be sensitive.
A database server might expose table schemas as resources. A documentation server might expose internal API specifications. Reading these surfaces information the model incorporates into its context.
Prompt permissions
Prompts are user-controlled templates—pre-defined instructions users can invoke. Since users explicitly trigger them, prompts carry the lowest risk.
Controlling server access
Three layers control what MCP servers can do: Claude Code's permission system, server-specific configuration, and OS-level sandboxing.
Claude Code permission rules
The permission system uses allow, ask, and deny rules evaluated in order:
{
"permissions": {
"deny": [
"mcp__filesystem__write_file",
"mcp__*__delete*"
],
"ask": [
"mcp__github__create_issue",
"mcp__database__execute_query"
],
"allow": [
"mcp__filesystem__read_file",
"mcp__filesystem__list_directory"
]
}
}Rule syntax for MCP tools:
mcp__servername__toolname— Specific server and toolmcp__servername__*— All tools from a servermcp__*__toolname— Specific tool across all serversmcp__*__delete*— Pattern matching with wildcards
Evaluation order:
- Deny rules checked first (highest priority)
- Ask rules checked second (requires confirmation)
- Allow rules checked third (auto-approved)
A tool matching no rules defaults to requiring confirmation.
Wildcards are powerful but dangerous.
mcp__*__* allows all MCP tools from all servers without confirmation.
Be explicit about what you allow.
Server-specific restrictions
Many servers support their own access controls independent of Claude Code.
Filesystem server:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/dev/projects/current",
"/Users/dev/docs"
]
}
}
}Only the specified directories are accessible. Paths outside these directories cannot be read or written regardless of Claude Code permissions.
Database servers: Most production database MCP servers support read-only mode:
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}", "--readonly"]
}
}
}This restricts operations to SELECT queries—no INSERT, UPDATE, DELETE, or DDL.
Network-level controls
For remote MCP servers, network policies add another control layer:
- Firewall rules — Restrict which endpoints MCP servers can reach
- Proxy configuration — Route requests through inspection points
- VPC boundaries — Isolate servers in private networks
Claude Code's sandbox includes network isolation options that restrict outbound connections.
Process isolation
MCP servers run as separate processes, but process boundaries alone don't prevent data access or network activity. Stronger isolation requires explicit configuration.
Transport-based isolation
The transport mechanism determines baseline isolation:
| Transport | Isolation | Risk Profile |
|---|---|---|
| stdio | Process boundary, same user | Access to user files, environment |
| HTTP | Network boundary | Depends on server location |
| Docker | Container boundary | Filesystem and process isolation |
Stdio servers run with your user permissions. They can access anything you can access. HTTP servers run elsewhere, but you trust them with your data during requests.
Session isolation
MCP requires servers to generate cryptographically secure session IDs:
- UUIDs or equivalent entropy (not sequential, not predictable)
- Bound to user context where applicable (
<user_id>:<session_id>) - Rotated periodically to limit exposure window
Session hijacking becomes possible if servers use predictable session identifiers. The Git MCP server vulnerabilities patched in December 2025 included session-related issues.
Multi-server boundaries
Each MCP server runs in its own process with no direct communication channel to other servers. Servers cannot:
- Access another server's memory or state
- Read another server's configuration
- Invoke tools from other servers
The host (Claude Code) mediates all interactions. This isolation-by-default prevents one compromised server from directly attacking others.
Sandboxing options
OS-level sandboxing contains damage when server code misbehaves—whether through bugs or malicious intent.
Claude Code native sandbox
Claude Code includes built-in sandboxing using OS primitives:
| Platform | Technology | Notes |
|---|---|---|
| macOS | Seatbelt | Works automatically |
| Linux | Bubblewrap | Requires apt install bubblewrap socat |
| WSL2 | Bubblewrap | Same as Linux |
Enable sandboxing in settings:
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true
}
}Filesystem restrictions:
- Read/write access to current working directory
- Read-only access elsewhere (except explicitly denied paths)
- No modification outside working directory
Network restrictions:
- Domain restrictions via proxy
- User confirmation for new domains
- Custom proxy rules for advanced filtering
The sandbox applies to commands Claude Code executes, not to MCP servers directly. Sandboxing MCP servers requires container-based approaches.
Container-based isolation
Docker provides stronger isolation for MCP servers:
docker run --rm -i \
--read-only \
--network none \
--user nobody \
--cap-drop ALL \
-v /projects/current:/data:ro \
mcp-server:latestContainer hardening options:
--read-only— Immutable root filesystem--network none— No network access--user nobody— Non-root user--cap-drop ALL— Remove all Linux capabilities-v path:ro— Read-only volume mounts
The Docker MCP Gateway (available since late 2025) provides pre-configured secure containers:
- 1 CPU and 2 GB memory per container
- No host filesystem access by default
- Image signing and attestation
- Centralized policy enforcement
Kernel-level sandboxing
For maximum isolation, gVisor, Kata Containers, or Firecracker provide kernel-level separation:
| Technology | Approach | Overhead | Best For |
|---|---|---|---|
| gVisor | User-space kernel | Low | General workloads |
| Kata Containers | Hardware virtualization | Medium | Full Linux compatibility |
| Firecracker | Minimal MicroVM | ~5 MB per instance | Untrusted code execution |
Firecracker, used by AWS Lambda and Fargate, has the smallest attack surface—only virtio-net, virtio-block, serial console, and keyboard are exposed. It's the gold standard for running untrusted AI-generated code.
These technologies apply primarily to self-hosted MCP infrastructure, not typical development setups.
Enterprise managed policies
Organizations can enforce security policies that users cannot override.
Managed settings hierarchy
Claude Code evaluates settings in priority order:
- Managed (cannot be overridden)
- Command line arguments
- Local (
.claude/*.local.*) - Project (
.claude/) - User (
~/.claude/)
Managed settings files require administrator privileges to modify.
Restricting MCP servers
The allowedMcpServers and deniedMcpServers settings control what users can configure:
{
"allowedMcpServers": [
{ "serverName": "github" },
{ "serverName": "filesystem" },
{ "serverCommand": ["npx", "-y", "@modelcontextprotocol/server-memory"] },
{ "serverUrl": "https://mcp.company.com/*" }
],
"deniedMcpServers": [
{ "serverUrl": "https://*.external.com/*" },
{ "serverCommand": ["*", "mcp-remote", "*"] }
]
}Matching behaviors:
serverName— Matches the configured name exactlyserverCommand— Matches command arrays (wildcards in array elements)serverUrl— Matches URL patterns for HTTP/SSE servers
Lockdown modes:
allowedMcpServers: []— Complete lockdown; no user-added serversdeniedMcpServersonly — Blacklist approach; everything else allowed- Both defined — Allowlist checked first, denylist overrides
Denylists always win. A server matching both lists is blocked.
Exclusive control with managed-mcp.json
For tighter control, managed-mcp.json provides the only MCP servers users can access:
{
"mcpServers": {
"company-approved": {
"type": "http",
"url": "https://mcp.internal.company.com/api",
"headers": {
"Authorization": "Bearer ${COMPANY_TOKEN}"
}
}
}
}When this file exists, users cannot add additional servers. This is the strictest configuration—appropriate for highly regulated environments.
Disabling specific permissions
Managed settings can block entire permission categories:
{
"permissions": {
"deny": [
"Bash(curl:*)",
"Bash(wget:*)",
"Read(.env)",
"Read(./secrets/**)",
"mcp__*__delete*",
"mcp__*__execute*"
]
},
"disableBypassPermissionsMode": "disable"
}The disableBypassPermissionsMode setting prevents users from circumventing permission checks entirely.
Authentication enforcement
Organizations can require specific authentication methods:
{
"forceLoginMethod": "sso",
"forceLoginOrgUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}This ensures users authenticate through corporate SSO rather than personal accounts, enabling proper audit trails and access controls.
Security boundaries in practice
Defense in depth
No single control is sufficient. Effective MCP security combines multiple layers:
- Permission rules — Control which tools can be invoked
- Server restrictions — Limit what each server can access
- Process isolation — Contain server execution
- Network controls — Restrict outbound communication
- Managed policies — Enforce organizational standards
A filesystem server running in a container with read-only mounts, network isolation, and managed allowlist rules is defense in depth working as intended.
Audit and monitoring
Track MCP activity for security review:
- Claude Code logs tool invocations with timestamps
/mcpshows current server states- Server-side logs (where available) capture request details
- Enterprise plans include compliance API access
For security-sensitive environments, route MCP traffic through centralized gateways that provide logging, rate limiting, and policy enforcement.
Incident response
When an MCP server is compromised or misbehaves:
- Remove immediately:
claude mcp remove <name> - Review activity: Check Claude Code logs for tool invocations
- Assess exposure: What data did the server access?
- Reset credentials: Rotate any tokens the server used
- Update policies: Add to denylist, review allowlist
The protocol's session isolation means compromising one server doesn't automatically compromise others. Contain, investigate, remediate.