Security in MCP
Security fundamentals
This guide explains the security features of the Model Context Protocol:
- Security model - Understand the core security principles that govern MCP
- Authentication options - Learn how to implement secure authentication for your MCP server
- Data protection - Discover techniques for keeping sensitive information secure
- Best practices - Explore proven approaches to building secure AI applications with MCP
Security Model
Core Security Principles
MCP's security model is designed around several key principles:
- Principle of Least Privilege - MCP servers and clients should only have access to the resources they need
- Defense in Depth - Multiple security layers protect against different types of threats
- Zero Trust - Every access request is verified regardless of source
- Secure by Default - Default configurations prioritize security over convenience
Authentication and Authorization
Authentication Options
MCP supports multiple authentication methods to fit different security requirements:
- OAuth 2.0 - Standard protocol for secure delegated access
- Dynamic Client Registration - Automatic client registration with OAuth servers
- API Key Authentication - Simple authentication for server-to-server communication
OAuth 2.0 Integration
MCP uses the OAuth 2.0 protocol for authentication and authorization, which enables:
- Secure access to user data without sharing credentials
- Fine-grained permission control through scopes
- Token-based authentication with limited lifetimes
- Standardized flows for different application types
Example OAuth 2.0 flow in MCP:
// MCP Client with OAuth configuration
const client = new MCPClient({
serverUrl: 'https://example-mcp-server.com',
auth: {
type: 'oauth2',
clientId: 'your-client-id',
scopes: ['tools:read', 'tools:execute']
}
});
// Initiating the OAuth flow
const authUrl = await client.getAuthorizationUrl({
redirectUri: 'https://your-app.com/callback'
});
// Redirect user to authUrl
// After user authorizes and is redirected back:
await client.handleCallback(callbackUrlWithCode);
// Now the client is authenticated and can access protected resources
Dynamic Client Registration
MCP supports OAuth 2.0 Dynamic Client Registration, allowing clients to automatically register with OAuth servers:
// Dynamically register a client
const registration = await client.registerClient({
clientName: 'My MCP Client',
redirectUris: ['https://my-app.com/callback'],
logoUri: 'https://my-app.com/logo.png'
});
// Use the registered client ID and secret
console.log(registration.clientId);
console.log(registration.clientSecret);
API Key Authentication
For simpler scenarios or server-to-server communication, MCP supports API key authentication:
// MCP Client with API key authentication
const client = new MCPClient({
serverUrl: 'https://example-mcp-server.com',
auth: {
type: 'api_key',
apiKey: 'your-api-key'
}
});
Data Protection
Data Security Guide
Follow these practices to protect sensitive data in your MCP implementation:
- Use encryption - Implement proper encryption for data in transit and at rest
- Minimize data transfer - Only send what's necessary for the task
- Set data expiration - Implement automatic cleanup of unused data
- Validate all inputs - Prevent injection attacks through thorough validation
Encryption
MCP implements multiple layers of encryption:
- Transport Layer Security (TLS): All HTTP and WebSocket communications use TLS for encryption in transit.
- Token Encryption: Authentication tokens can be encrypted at rest.
- Payload Encryption: Sensitive data within MCP payloads can be encrypted.
Data Minimization
MCP encourages data minimization practices:
- Only transmit necessary data
- Limit context window size
- Implement automatic data expiration
- Use resource references instead of raw data when possible
Example of data minimization:
// Instead of sending the entire document
const badExample = await client.request({
method: 'tools/call',
params: {
name: 'analyze_document',
arguments: {
document: veryLargeDocument // Bad practice: sending entire document
}
}
});
// Send a reference to the document
const goodExample = await client.request({
method: 'tools/call',
params: {
name: 'analyze_document',
arguments: {
documentId: 'doc-123' // Good practice: sending just a reference
}
}
});
Tool Security
Tool Security Features
MCP provides several features to ensure tool safety:
- Permission Models - Control which users or clients can access each tool
- Input Validation - Verify that all parameters meet security requirements
- Execution Sandboxing - Isolate tool execution from the rest of the system
- Rate Limiting - Prevent abuse through usage limits
Tool Permission Models
MCP implements permission models for tools to control access:
- Public Tools: Available to all authenticated clients
- Protected Tools: Require specific OAuth scopes
- Private Tools: Limited to specific clients or users
Example tool definition with permissions:
const sensitiveDataTool = {
name: 'access_sensitive_data',
description: 'Access sensitive user data',
permissions: {
requiredScopes: ['data:sensitive:read'],
requiredRoles: ['admin', 'data-analyst']
},
// ... tool implementation
};
Input Validation
To prevent injection attacks and other security issues, MCP emphasizes thorough input validation:
// Tool with JSON Schema validation
const secureCalculatorTool = {
name: 'calculator',
description: 'Perform calculations',
parameters: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['add', 'subtract', 'multiply', 'divide'] // Restricted to known operations
},
a: {
type: 'number',
minimum: -1000, // Set reasonable bounds
maximum: 1000
},
b: {
type: 'number',
minimum: -1000,
maximum: 1000
}
},
required: ['operation', 'a', 'b'],
additionalProperties: false // No unexpected properties allowed
},
execute: async (params) => {
// Validation already happened, so we can safely use the inputs
// ...
}
};
Prompt Security
Prompt Injection Prevention
Prevent prompt injection attacks with these critical practices:
- Define clear boundaries between system instructions and user content
- Sanitize user inputs to remove potentially harmful content
- Validate prompt templates before using them with user-supplied data
- Use parameter validation to restrict what can be inserted into prompts
Prompt Injection Protection
MCP helps prevent prompt injection attacks through:
- Clear Boundaries: Defining strict boundaries between system and user content
- Input Sanitization: Removing potentially harmful content from inputs
- Template Validation: Validating prompt templates before use
Example of secure prompt handling:
// Secure prompt template with parameter validation
const secureGreetingPrompt = {
name: 'secure_greeting',
description: 'A securely implemented greeting template',
template: `
System: You are a helpful assistant for {{company_name}}.
User's name: {{user_name}}
Please provide a friendly greeting to the user.
`,
parameters: {
type: 'object',
properties: {
company_name: {
type: 'string',
maxLength: 100,
pattern: '^[a-zA-Z0-9 ,.\\-]+$' // Only allow safe characters
},
user_name: {
type: 'string',
maxLength: 50,
pattern: '^[a-zA-Z0-9 ,.\\-]+$'
}
},
required: ['company_name', 'user_name'],
additionalProperties: false
}
};
Network Security
Cross-Origin Resource Sharing (CORS)
MCP servers should implement proper CORS policies to prevent unauthorized web applications from accessing the API:
// Server-side CORS configuration
const server = new MCPServer({
// ...
cors: {
origin: ['https://trusted-app.com', 'https://admin.trusted-app.com'],
methods: ['GET', 'POST'],
allowHeaders: ['Authorization', 'Content-Type'],
maxAge: 86400 // Cache preflight requests for 24 hours
}
});
Rate Limiting
Implement rate limiting to protect against abuse and denial-of-service attacks:
// Server with rate limiting
const server = new MCPServer({
// ...
rateLimit: {
windowMs: 60 * 1000, // 1 minute
max: 100, // Limit each IP to 100 requests per windowMs
standardHeaders: true, // Return rate limit info in the headers
legacyHeaders: false,
handler: (req, res) => {
res.status(429).json({
error: 'Too many requests',
retryAfter: res.getHeader('Retry-After')
});
}
}
});
Next Steps
Continue Learning
- Context Management - Understand how MCP handles context securely
- MCP Architecture - Learn how security integrates with the overall architecture
- OAuth MCP Server - Build a secure MCP server with OAuth