MCP Security Checklist for Production
March 15, 2026 · 7 min read
TL;DR
- Production MCP deployments require treating servers as trusted processes with real system access — not as sandboxed chat plugins
- Credential management, filesystem sandboxing, and principle of least privilege are the three most critical controls
- Audit logging of all MCP tool calls is essential for incident response and compliance in production environments
MCP servers have real access to your systems. A filesystem server can read and write files. A shell server can execute commands. A GitHub server can push code and open pull requests. In development, the blast radius of a misconfiguration is small. In production — or in any environment where sensitive data or infrastructure is involved — the stakes are much higher.
This checklist covers the security controls you should have in place before deploying MCP servers in a production or team context.
Authentication and Credential Management
Never Store Credentials in MCP Config Files
MCP config files (.cursor/mcp.json, ~/.config/claude/mcp.json, etc.) are often in directories that get backed up, synced, or accidentally committed. Treat them like .env files.
Do: Reference environment variables:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_MCP_TOKEN}"
}
}
}
}Don't: Embed tokens directly:
{
"env": {
"GITHUB_TOKEN": "ghp_actualTokenValueHere"
}
}Add your MCP config files to .gitignore. In team settings, document which environment variables need to be set without including the values.
Use Minimal-Scope Tokens
Every token and credential you give an MCP server should have only the permissions the server actually needs.
GitHub server checklist:
- [ ] Use a fine-grained personal access token, not a classic token
- [ ] Scope the token to only the repositories the AI needs to access
- [ ] Grant only the permissions required: read for exploration, write only if the AI will push changes
- [ ] Set a short expiry (30–90 days) and rotate regularly
API keys checklist:
- [ ] Create dedicated API keys for MCP use, separate from application keys
- [ ] Enable IP restriction on API keys where supported
- [ ] Set spending limits on AI provider API keys
Rotate Credentials Regularly
MCP server credentials should be in your regular rotation schedule. Because they're in environment variables and not hard-coded, rotation just means updating the variable and restarting the server process.
Set calendar reminders or use a secrets manager (AWS Secrets Manager, HashiCorp Vault, 1Password Secrets Automation) to automate rotation.
Filesystem Sandboxing
Restrict the Filesystem Server to a Directory
The filesystem MCP server accepts a list of directories it's allowed to access. Always specify explicit paths rather than allowing unrestricted access:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/home/user/projects/myapp"
]
}
}
}Never pass / or ~ as the allowed path. The AI doesn't need access to your entire filesystem.
Checklist for filesystem server:
- [ ] Restrict allowed paths to project directories only
- [ ] Exclude directories containing secrets:
~/.ssh,~/.aws,~/.config,.envfiles - [ ] For read-only use cases, check if your server supports a
--read-onlyflag - [ ] Verify the server respects
.gitignoreor configure explicit excludes
Run with a Non-Privileged User
MCP server processes should run as a non-root user. On Linux and macOS, this is typically the case for local stdio servers (they run as your current user). For remote MCP servers or Docker deployments, verify the container or process is not running as root.
# In a Dockerfile for a remote MCP server
RUN addgroup --system mcp && adduser --system --ingroup mcp mcpuser
USER mcpuserShell Server Controls
The shell MCP server (@modelcontextprotocol/server-shell or similar) is the highest-risk MCP server. It can run arbitrary commands.
Only enable the shell server when:
- You're working on a local development machine
- The AI task genuinely requires running commands
- You understand what commands will be run before approving them
Checklist for shell server:
- [ ] Never enable the shell server in any shared or remote environment
- [ ] Disable the shell server when not actively using it (remove from config or comment out)
- [ ] Use a tool that shows you the proposed command before execution (Cursor's agent mode shows commands before running them)
- [ ] Never run the shell server as root
If you need command execution in a more controlled way, consider a shell server that limits allowed commands (allowlist-based) or that requires per-command confirmation.
Network Isolation
Remote MCP Servers
If you're running MCP servers as remote processes (HTTP-based transport), they need proper network controls:
- [ ] Require TLS (HTTPS) for all remote MCP server connections
- [ ] Use a reverse proxy (nginx, Caddy) with valid certificates rather than exposing the server port directly
- [ ] Authenticate connections — MCP over HTTP should require a bearer token or mutual TLS
- [ ] Restrict inbound connections to known IP ranges if possible
Localhost Servers
For stdio-based servers running locally:
- [ ] Verify the server is not binding to a network port (stdio servers don't, but some implementations do)
- [ ] Check that the server binary comes from a trusted source (official
@modelcontextprotocolpackages or well-known authors) - [ ] Pin the package version in your config to avoid supply chain updates pulling in malicious code
{
"args": ["-y", "@modelcontextprotocol/server-filesystem@0.6.2"]
}Audit Logging
Log All MCP Tool Calls
In production or team environments, you want a record of what the AI did through MCP. This is essential for:
- Debugging unexpected behavior
- Incident response if something goes wrong
- Compliance requirements in regulated industries
Most MCP servers log to stderr. Capture this output:
# When running a server manually, redirect logs
npx @modelcontextprotocol/server-github 2>> /var/log/mcp/github-server.logFor Docker deployments, ensure container logs are captured by your logging infrastructure (CloudWatch, Datadog, etc.).
Logging checklist:
- [ ] Capture MCP server stderr in your log aggregation system
- [ ] Log tool name, arguments, and caller identity for each tool call
- [ ] Set log retention appropriate to your compliance requirements (minimum 90 days recommended)
- [ ] Alert on anomalous patterns: unusually high call volume, calls to unexpected tools
What to Log
At minimum, each tool call log entry should include:
- Timestamp (ISO 8601)
- Tool name
- Tool arguments (may need sanitization if they contain sensitive data)
- Response status (success/error)
- Session identifier if your server supports it
Avoid logging full response bodies unless necessary — they can be large and may contain sensitive data from your systems.
Principle of Least Privilege
Give MCP Servers the Minimum Access They Need
Each MCP server should have the minimum permissions required for its job. This applies to:
File permissions: If the AI only needs to read configuration files, the filesystem server's allowed path should contain only those files.
Database permissions: Use read-only database users for exploration. Only grant write access to specific tables that require it.
GitHub permissions: If the AI is only reviewing PRs, don't give it push access. If it needs to create branches but not merge, scope accordingly.
API scopes: Review the exact scopes each MCP server requests and reduce them if possible.
Separate MCP Servers for Different Trust Levels
Don't run a single "super" MCP server with all permissions. Run separate servers for different purposes:
{
"mcpServers": {
"filesystem-project": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/myproject"]
},
"github-readonly": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_READONLY_TOKEN}" }
},
"github-write": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_WRITE_TOKEN}" }
}
}
}Enable only the servers you need for a given session. Disable write-capable servers when you're doing read-only exploration.
Environment Variable Handling
Don't Expose Secrets Through MCP Tools
Be aware that MCP servers can sometimes expose environment variables through their tools. A misconfigured filesystem server with access to a project directory containing a .env file can return the contents of that file when the AI asks to read it.
Checklist:
- [ ] Add
.env,.env.local, and similar files to your project's.gitignoreAND verify they're outside any MCP server's allowed paths - [ ] Use
.cursor/mcp.jsonor equivalent with env var references, not embedded values - [ ] Audit what files are accessible through your filesystem server by listing the allowed directories
CI/CD Considerations
If you use AI assistants in CI/CD pipelines with MCP:
- [ ] Use short-lived tokens (GitHub Actions OIDC tokens, not long-lived secrets)
- [ ] Restrict what the CI environment can access via MCP
- [ ] Review AI-generated commands before they run in CI (use approval gates)
- [ ] Don't give the CI MCP server access to production systems
Third-Party MCP Servers
The MCP ecosystem includes many community-contributed servers. Before using any third-party server:
- [ ] Check the package's npm/pip download count and GitHub stars as a rough trust signal
- [ ] Review the source code, especially what the server does with credentials and what system calls it makes
- [ ] Pin to a specific version and verify the checksum if possible
- [ ] Prefer official
@modelcontextprotocolpackages or servers from well-known vendors - [ ] Check for security advisories before installing
Running npx -y some-mcp-server downloads and executes code from npm. Treat it with the same scrutiny as any other code you run.
Quick Reference Checklist
Before enabling any MCP server:
- [ ] Credentials in environment variables, not config files
- [ ] Config files in
.gitignore - [ ] Minimal-scope tokens and permissions
- [ ] Filesystem paths restricted to what's needed
- [ ] Logging configured and captured
Ongoing:
- [ ] Rotate credentials on a schedule
- [ ] Review access logs periodically
- [ ] Disable servers not in active use
- [ ] Keep MCP server packages updated (but test before updating)
For team/production deployments:
- [ ] Separate tokens per environment (dev/staging/prod)
- [ ] Audit log retention policy defined
- [ ] Incident response procedure documented
- [ ] Regular review of which MCP servers are enabled