MCP Library updated 9 min read

MCP Security Best Practices: Protecting Your AI Integrations

Security guide for MCP servers. Learn to secure credentials, manage permissions, and protect sensitive data in AI workflows.

RP

Rajesh Praharaj

Sep 10, 2025 Β· Updated Dec 28, 2025

MCP Security Best Practices: Protecting Your AI Integrations

TL;DR - Security Essentials

Secure your MCP integrations with these core principles:

πŸ†• 2025: MCP security now includes OAuth 2.1 with PKCE, RFC 9700 best practices, and Zero Trust architecture alignment. For an introduction to MCP, see the MCP Introduction guide.

The Golden Rules:

  1. πŸ” Least Privilege: Grant minimal required permissions
  2. πŸ”‘ Scoped Tokens: Use service-specific API keys
  3. πŸ“ Secure Storage: Never commit credentials
  4. πŸ‘οΈ Audit Logs: Monitor access regularly
  5. πŸ”„ Rotation: Change keys periodically

Quick Security Checklist:

☐ Use read-only access when possible
☐ Create dedicated API keys for MCP
☐ Store credentials in environment variables
☐ Add config files to .gitignore
☐ Enable audit logging on services
☐ Rotate credentials quarterly
☐ Review access scope monthly

Security Model Overview

Understanding how MCP security works:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MCP Security Layers                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚   AI Host   │───▢│ MCP Server  │───▢│  Service    β”‚      β”‚
β”‚  β”‚(Claude/etc) β”‚    β”‚             β”‚    β”‚(GitHub/AWS) β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚        β”‚                  β”‚                  β”‚               β”‚
β”‚        β–Ό                  β–Ό                  β–Ό               β”‚
β”‚  User approves        Scoped             Service-side       β”‚
β”‚  each server          access             permissions        β”‚
β”‚                                                              β”‚
β”‚  Layer 1: User        Layer 2: Token     Layer 3: Service   β”‚
β”‚  Control              Permissions        Access Control     β”‚
β”‚                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Three Layers of Protection

LayerWhat It ProtectsYou Control
1. User ControlWhich MCP servers runConfig file
2. Token PermissionsWhat each server can doAPI token scopes
3. Service AccessWhat resources are accessibleService-side policies

2025 Security Enhancements

FeatureDescription
OAuth 2.1 + PKCEAuthorization Code flow with Proof Key
RFC 9700IETF best practices for OAuth security
Resource IndicatorsExplicit target resource specification
No Token PassthroughMCP servers don’t pass tokens upstream
Zero TrustBehavioral analytics and pattern detection

Credential Management

Never Do This

// ❌ BAD: Credentials in version control
{
  "mcpServers": {
    "github": {
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_real_token_12345"
      }
    }
  }
}

Do This Instead

Option 1: Environment Variables

// βœ… GOOD: Reference environment variables
{
  "mcpServers": {
    "github": {
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}

Option 2: Separate Config (not in version control)

Keep claude_desktop_config.json out of your repo by:

  • Adding to .gitignore
  • Using system-level paths only
  • Never copying to project directories

Option 3: Secret Manager (Enterprise)

# Use a secret manager to inject credentials
export GITHUB_TOKEN=$(aws secretsmanager get-secret-value \
  --secret-id mcp/github --query SecretString --output text)

Credential Storage Locations

PlatformConfig LocationSecure?
macOS~/Library/Application Support/Claude/...βœ… User-only
Windows%APPDATA%/Claude/...βœ… User-only
Linux~/.config/Claude/...βœ… User-only

Verify permissions:

# macOS/Linux - Should be readable only by you
ls -la ~/Library/Application\ Support/Claude/
# Expected: -rw-------

For more on responsible AI usage, see the Understanding AI Safety, Ethics, and Limitations guide.


Principle of Least Privilege

By Service Type

ServiceMinimum RequiredAvoid
GitHubrepo:read, specific reposadmin:org, all repos
AWSRead-only, specific resourcesAdministratorAccess
SlackSpecific channels, read-onlyWorkspace admin
FilesystemSpecific directoriesHome directory
DatabaseRead-only, specific tablesDBA privileges

GitHub Token Permissions

For Code Review (Read-Only):

β˜‘οΈ repo (read only)
β˜‘οΈ read:org
☐ write:packages
☐ admin:org
☐ delete_repo

For PR Creation (Limited Write):

β˜‘οΈ repo (read & write)
β˜‘οΈ read:org
☐ admin:org
☐ delete_repo

AWS IAM Policies

Minimal S3 Read:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::specific-bucket",
        "arn:aws:s3:::specific-bucket/*"
      ]
    }
  ]
}

Filesystem Restrictions

{
  "mcpServers": {
    "filesystem": {
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/me/projects/safe-project"  // βœ… Specific folder
        // NOT "/Users/me"                  // ❌ Home directory
      ]
    }
  }
}

For more on file access patterns, see the Filesystem MCP guide.


Token Scoping Strategies

Strategy 1: One Token Per Service

{
  "mcpServers": {
    "github": {
      "env": { "GITHUB_TOKEN": "ghp_repo_readonly_token" }
    },
    "slack": {
      "env": { "SLACK_BOT_TOKEN": "xoxb_channel_readonly" }
    },
    "aws": {
      "env": { "AWS_ACCESS_KEY_ID": "AKIA_readonly_key" }
    }
  }
}

Strategy 2: Environment Separation

{
  "mcpServers": {
    "github-prod": {
      "env": { "GITHUB_TOKEN": "ghp_prod_readonly" }
    },
    "github-dev": {
      "env": { "GITHUB_TOKEN": "ghp_dev_full_access" }
    }
  }
}

Strategy 3: Read-Only by Default

Start with read-only access, upgrade only when needed:

Week 1: Read-only access ─────▢ Verify patterns
Week 2: Same ─────────────────▢ Build confidence
Week 3: Selective write ──────▢ Specific operations only
Week 4: Review and audit ─────▢ Adjust as needed

Audit and Monitoring

Enable Service-Side Logging

ServiceHow to EnableWhat’s Logged
GitHubSettings β†’ Audit logAPI calls, repos accessed
AWSCloudTrailAll API calls
SlackWorkspace AnalyticsMessages, channels
CloudflareAudit LogsZone changes, API calls
SentryAPI LogsIssues accessed

What to Monitor

βœ… Monitor:
- API call frequency
- Unusual access patterns
- Failed authentication attempts
- Access to sensitive resources

⚠️ Alert on:
- Tokens used from new locations
- Access outside normal hours
- Rate limit warnings
- Permission denied errors

Monthly Security Review

1. Review API key usage
2. Check access logs for anomalies
3. Revoke unused tokens
4. Update permissions if scope creep
5. Rotate credentials if needed

For more on AI agent capabilities, see the AI Agents guide.


Secure Configuration Patterns

Pattern 1: Read-Only Production

{
  "mcpServers": {
    "github-prod": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PROD_READONLY}"
      }
    }
  }
}

Pattern 2: Restricted Filesystem

{
  "mcpServers": {
    "files-readonly": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "--read-only",
        "/safe/directory/only"
      ]
    }
  }
}

Pattern 3: Scoped Database

{
  "mcpServers": {
    "postgres": {
      "env": {
        "DATABASE_URL": "postgresql://mcp_reader:pass@host/db"
        // User has SELECT only, no INSERT/UPDATE/DELETE
      }
    }
  }
}

Pattern 4: Split by Sensitivity

{
  "mcpServers": {
    // High security - minimal access
    "aws-prod": {
      "env": {
        "AWS_PROFILE": "mcp-prod-readonly"
      }
    },
    // Lower security - more access
    "aws-dev": {
      "env": {
        "AWS_PROFILE": "mcp-dev-full"
      }
    }
  }
}

Common Security Mistakes

Mistake 1: Overly Broad Permissions

❌ "I'll just give it admin access to make it work"
βœ… "Start with minimum, add only what's needed"

Mistake 2: Sharing Credentials

❌ Using the same token for personal and MCP use
βœ… Create dedicated MCP tokens for audit clarity

Mistake 3: Forgetting File Access

❌ Granting home directory to Filesystem MCP
βœ… Grant only specific project folders

Mistake 4: Committing Config Files

❌ Pushing claude_desktop_config.json to GitHub
βœ… Add to .gitignore, use environment variables

Mistake 5: Never Rotating Keys

❌ Using the same token for years
βœ… Rotate quarterly or after any security event

Emergency Procedures

If a Token is Compromised

Immediate Actions (within minutes):

  1. Revoke the token at the service
  2. Create new token with same permissions
  3. Update MCP config with new token
  4. Review audit logs for unauthorized access

Follow-up (within hours):

  1. Assess impact - what was accessed?
  2. Notify stakeholders if sensitive data involved
  3. Review how compromise occurred
  4. Implement preventive measures

Service-Specific Revocation

ServiceHow to Revoke
GitHubSettings β†’ Developer settings β†’ Tokens β†’ Revoke
AWSIAM β†’ Users β†’ Security credentials β†’ Deactivate
SlackWorkspace settings β†’ Apps β†’ Revoke
CloudflareProfile β†’ API Tokens β†’ Revoke

Enterprise Security Considerations

Team Usage

PracticeImplementation
Shared service accountsCreate MCP-specific service accounts
Centralized secretsUse secret managers (Vault, AWS SM)
Access reviewsMonthly review of MCP permissions
OffboardingInclude MCP token revocation in process

Compliance

RequirementMCP Consideration
SOC 2Document MCP access, enable audit logs
GDPREnsure no personal data via Filesystem
HIPAAAvoid healthcare data in MCP-accessible systems
PCINever give MCP access to cardholder data

Security Checklist

Initial Setup

☐ Create dedicated API tokens for MCP
☐ Apply minimum required permissions
☐ Store credentials securely
☐ Add config files to .gitignore
☐ Verify file permissions on config
☐ Test with read-only first

Ongoing Maintenance

☐ Review access logs monthly
☐ Rotate credentials quarterly
☐ Revoke unused tokens
☐ Update permissions as needs change
☐ Audit which servers are configured

Before Production Use

☐ Use read-only for production data
☐ Enable service audit logs
☐ Document what AI can access
☐ Set up monitoring alerts
☐ Create incident response plan

Summary

MCP security is about layers of protection:

  • βœ… Layer 1: You control which servers run
  • βœ… Layer 2: Token scopes limit each server
  • βœ… Layer 3: Service policies restrict resources

2025 Security Standards:

  • OAuth 2.1 with PKCE (RFC 9700)
  • Resource Indicators (RFC 8707)
  • No token passthrough to upstream APIs
  • Zero Trust architecture alignment
  • Separated authorization/resource servers

Key Practices:

PracticeWhy
Least privilegeLimit blast radius
Scoped tokensClear audit trail
Secure storagePrevent exposure
Regular auditsCatch issues early
Key rotationLimit compromise impact

Start secure, stay secure - it’s much easier to add permissions than to recover from a security incident.

Next: Learn about Combining Multiple MCPs β†’ for powerful workflows.


Questions about MCP security? Check the MCP specification or RFC 9700 for OAuth best practices.

Was this page helpful?

Let us know if you found what you were looking for.