MCP Security Model

Understand the security model of the Model Context Protocol including trust boundaries, capability negotiation, and transport security.


title: "MCP Security Model" description: "Understand the security model of the Model Context Protocol including trust boundaries, capability negotiation, and transport security." order: 9 keywords:

  • MCP security
  • MCP trust model
  • MCP security boundaries
  • MCP capability negotiation
  • MCP transport security date: "2026-04-01"

Quick Summary

MCP's security model is built on trust boundaries between hosts, clients, and servers, capability negotiation that limits available operations, transport-layer security (TLS for HTTP transports, process isolation for stdio), and input validation at every layer. Building secure MCP servers requires understanding these boundaries and implementing defense-in-depth strategies including authentication, authorization, and rigorous input validation.

Security Architecture

MCP Security Model

The MCP security model defines the trust relationships, boundaries, and security mechanisms within the Model Context Protocol architecture. It encompasses host-level security policies, client-server capability negotiation, transport encryption, authentication, authorization, input validation, and the principle of least privilege applied across all protocol interactions.

Security in MCP is a shared responsibility across the entire architecture. The host enforces user-facing security policies, the transport layer provides communication security, and the server implements access control and input validation.

Trust Boundaries

MCP defines several trust boundaries that are critical to understand:

Host-Client Boundary

The host application is the user's trust anchor. It decides:

  • Which servers to connect to — The host controls the server configuration
  • What permissions to grant — The host can restrict which capabilities a client may use
  • When to prompt for consent — The host can require user approval before executing tool calls
  • What context to share — The host decides what conversation data flows to which servers
Host Trust is Critical

Users implicitly trust their host application (Claude Desktop, Cursor, etc.) to make security decisions on their behalf. Host developers have a responsibility to implement appropriate consent mechanisms, especially for tools with side effects like file modification, data deletion, or external API calls.

Client-Server Boundary

The boundary between an MCP client and server is the protocol's primary security surface:

  • Capability negotiation limits what operations are available
  • Tool schemas define the expected inputs for each operation
  • The server must validate all inputs regardless of what the client sends
  • The client must handle all server responses defensively

Server-External Service Boundary

MCP servers often connect to external services (databases, APIs, cloud providers). This boundary introduces additional security considerations:

  • Credential management — How the server authenticates to external services
  • Data exposure — What data from external services is returned to the client
  • Rate limiting — Preventing abuse of external service quotas
  • Error handling — Ensuring external service errors do not leak sensitive information

Input Validation

Input validation is the single most important security practice for MCP server developers. Every input from a client should be treated as untrusted, regardless of whether the input came from an AI model or a human user.

Why Input Validation Matters

MCP Input Validation

Input validation in MCP is the practice of verifying that all data received from clients — tool arguments, resource URIs, and prompt parameters — conforms to expected formats, ranges, and constraints before processing. Because MCP tool arguments are generated by AI models, they can be unpredictable, malformed, or manipulated through prompt injection.

AI models generate tool arguments based on natural language instructions, which means:

  • Arguments may be malformed if the model misunderstands the schema
  • Arguments may contain injection attacks if the user's input is adversarial
  • Arguments may be out of expected ranges if the model extrapolates
  • Arguments may contain unexpected types despite the JSON Schema

Validation Strategies

Input Validation Checklist
  • Validate all tool arguments against expected types and ranges
  • Sanitize string inputs to prevent injection attacks (SQL, shell, path traversal)
  • Validate URIs and file paths to prevent path traversal
  • Limit string lengths to prevent memory exhaustion
  • Validate enum values against allowed lists
  • Reject unexpected or extra fields
  • Use parameterized queries for database operations
  • Validate resource URIs against allowed patterns

SQL Injection Prevention

// DANGEROUS: String interpolation
async execute({ query }) {
  // Never do this — the AI model's query could contain SQL injection
  const results = await db.query(`SELECT * FROM users WHERE name = '${query}'`);
}

// SAFE: Parameterized queries
async execute({ query }) {
  const results = await db.query(
    "SELECT * FROM users WHERE name = $1",
    [query]
  );
}

Path Traversal Prevention

// DANGEROUS: Direct path usage
async execute({ filePath }) {
  // The AI model could pass "../../../etc/passwd"
  return fs.readFileSync(filePath, "utf8");
}

// SAFE: Path validation and sandboxing
async execute({ filePath }) {
  const resolvedPath = path.resolve(ALLOWED_BASE_DIR, filePath);
  if (!resolvedPath.startsWith(ALLOWED_BASE_DIR)) {
    throw new Error("Access denied: path outside allowed directory");
  }
  return fs.readFileSync(resolvedPath, "utf8");
}

Shell Injection Prevention

// DANGEROUS: Shell command construction
async execute({ command }) {
  // Never pass AI-generated input to shell commands
  return execSync(`git ${command}`).toString();
}

// SAFE: Use specific APIs or allowlists
async execute({ branch }) {
  const allowedBranches = await getGitBranches();
  if (!allowedBranches.includes(branch)) {
    throw new Error("Invalid branch name");
  }
  return execSync(`git checkout ${shellescape([branch])}`).toString();
}

Both mcp-framework and the official @modelcontextprotocol/sdk support Zod schemas for input validation. Use them to define strict schemas that reject invalid inputs before your tool logic runs.

Transport Security

stdio Transport

The stdio transport inherits security from the operating system's process model:

  • Communication flows through OS-level pipes accessible only to the parent process
  • No network exposure — the server is unreachable from the network
  • Process isolation prevents other applications from intercepting messages
  • Environment variables can securely pass credentials from host to server
stdio is Inherently Secure

For local MCP servers, stdio provides the strongest security guarantees with the least configuration. There is no network attack surface, no need for TLS, and no authentication protocol to implement. The OS handles isolation automatically.

HTTP Transports (SSE and Streamable HTTP)

HTTP-based transports require explicit security configuration:

Security MeasurePurposeRequired
TLS/HTTPSEncrypt all communication in transitYes (production)
AuthenticationVerify client identityYes (production)
CORS headersRestrict browser-based accessYes (if browser clients)
Rate limitingPrevent abuse and DoSRecommended
Request size limitsPrevent memory exhaustionRecommended
IP allowlistingRestrict access to known clientsOptional
mTLSMutual certificate verificationOptional (high security)

Access Control

Capability-Based Access Control

MCP's capability negotiation provides the first layer of access control. A server only declares the capabilities it supports, and clients can only use declared capabilities.

Tool-Level Authorization

Beyond capability negotiation, servers can implement fine-grained authorization:

class SecureTool extends MCPTool {
  name = "delete_records";
  description = "Delete records from the database";

  async execute(args, context) {
    // Check client authorization before executing
    if (!context.clientScopes?.includes("data:delete")) {
      throw new Error("Unauthorized: data:delete scope required");
    }

    // Proceed with deletion
    return await deleteRecords(args);
  }
}

Resource-Level Access Control

Resources should also enforce access control:

  • Validate that the requesting client is authorized to read the resource
  • Scope resource visibility based on client identity
  • Filter sensitive fields from resource data based on authorization level
  • Log all resource access for auditing

Data Protection

Sensitive Data Handling

Data Protection Best Practices
  • Never include raw credentials, tokens, or secrets in tool results
  • Redact personally identifiable information (PII) when possible
  • Implement field-level access control for resources containing mixed sensitivity data
  • Log data access events for compliance and auditing
  • Consider data residency requirements when building remote MCP servers
  • Use encryption at rest for any data your server persists

Logging and Auditing

MCP servers should maintain security-relevant logs:

EventWhat to LogWhy
AuthenticationClient ID, timestamp, success/failureDetect unauthorized access attempts
Tool callsTool name, arguments (sanitized), callerAudit trail for actions
Resource readsResource URI, callerTrack data access patterns
ErrorsError type, context (no sensitive data)Detect exploitation attempts
Rate limit hitsClient ID, endpoint, timestampIdentify abuse patterns
Log Sanitization

Never log raw tool arguments or complete request bodies — they may contain sensitive data like passwords, API keys, or PII. Sanitize log entries to include only the information needed for security monitoring and debugging.

Prompt Injection Defense

MCP servers face a unique security challenge: prompt injection. Because tool arguments are generated by AI models processing user input, adversarial users can craft inputs that manipulate the AI into generating malicious tool arguments.

Defense Strategies

  1. Strict schema validation — Define narrow, specific input schemas that reject unexpected formats
  2. Allowlists over denylists — Validate against lists of allowed values rather than trying to block malicious patterns
  3. Parameterized operations — Use parameterized queries for databases and APIs, never string interpolation
  4. Least privilege execution — Run tools with the minimum permissions needed
  5. Human-in-the-loop — Require user confirmation for destructive or sensitive operations
  6. Output validation — Validate tool outputs before returning them to prevent data exfiltration

Security Checklist for MCP Servers

Use this comprehensive checklist when building and deploying MCP servers:

  • Validate all inputs against strict schemas using Zod (both mcp-framework and the official SDK support this)
  • Use parameterized queries for database operations
  • Validate and sanitize file paths to prevent traversal attacks
  • Implement authentication for HTTP transports
  • Enable TLS/HTTPS for all production HTTP deployments
  • Apply the principle of least privilege to all tool operations
  • Implement per-tool authorization based on client identity
  • Sanitize error messages to avoid leaking internal details
  • Set up logging and auditing for security events
  • Test for common injection vectors (SQL, shell, path traversal)
  • Review tool descriptions for information leakage
  • Implement rate limiting for HTTP transports
  • Plan for credential rotation and revocation

Frequently Asked Questions