CodexSpot

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:

json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_MCP_TOKEN}"
      }
    }
  }
}

Don't: Embed tokens directly:

json
{
  "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:

json
{
  "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, .env files
  • [ ] For read-only use cases, check if your server supports a --read-only flag
  • [ ] Verify the server respects .gitignore or 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.

dockerfile
# In a Dockerfile for a remote MCP server
RUN addgroup --system mcp && adduser --system --ingroup mcp mcpuser
USER mcpuser

Shell 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 @modelcontextprotocol packages or well-known authors)
  • [ ] Pin the package version in your config to avoid supply chain updates pulling in malicious code
json
{
  "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:

bash
# When running a server manually, redirect logs
npx @modelcontextprotocol/server-github 2>> /var/log/mcp/github-server.log

For 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:

json
{
  "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 .gitignore AND verify they're outside any MCP server's allowed paths
  • [ ] Use .cursor/mcp.json or 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 @modelcontextprotocol packages 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

Referenced in this post