MCP Security Best Practices for Production

MCP servers are powerful — they give AI access to your files, databases, and services. Here's how to deploy them safely.

The Security Landscape

MCP servers run with real permissions on real systems. Unlike a chatbot that can only generate text, an MCP-connected AI can read files, execute queries, make API calls, and modify data. This power demands careful security practices.

The good news: MCP's architecture has security built into its design. The challenge is configuring and deploying it correctly.

Principle 1: Least Privilege

The most important security principle for MCP: grant only the minimum access necessary.

Filesystem Access

// ❌ Don't expose your entire home directory
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you"]

// ✅ Expose only the specific project directory
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects/current-project"]

Database Access

-- ❌ Don't use admin/root database credentials
-- ✅ Create a read-only user for the MCP server
CREATE USER mcp_reader WITH PASSWORD 'secure_password';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;
-- Only grant write access if the server specifically needs it

API Tokens

When configuring API tokens for MCP servers (GitHub, Slack, etc.), create tokens with minimal scopes. If the server only needs to read repos, don't give it write access.

Principle 2: Input Validation

If you're building custom MCP servers, validate all inputs rigorously:

// Validate and sanitize file paths
server.tool("read_config", "Read a config file", {
  filename: z.string()
    .regex(/^[a-zA-Z0-9_-]+\.json$/)  // Only allow safe filenames
    .describe("Config filename (e.g., 'app.json')")
}, async ({ filename }) => {
  // Prevent path traversal
  const safePath = path.join(CONFIG_DIR, path.basename(filename));
  if (!safePath.startsWith(CONFIG_DIR)) {
    return { content: [{ type: "text", text: "Invalid path" }], isError: true };
  }
  const content = await fs.readFile(safePath, "utf-8");
  return { content: [{ type: "text", text: content }] };
});

Common Injection Attacks to Prevent

Principle 3: Secure Credential Management

Never hardcode credentials in MCP server code or configuration files that get committed to git.

Environment Variables

// In claude_desktop_config.json — credentials via env vars
{
  "github": {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-github"],
    "env": {
      "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
    }
  }
}

Important: The Claude Desktop config file contains your tokens in plain text. Ensure this file has appropriate permissions:

# macOS/Linux: Restrict to owner only
chmod 600 ~/Library/Application\ Support/Claude/claude_desktop_config.json

Secret Managers

For production deployments, use a secret manager (AWS Secrets Manager, HashiCorp Vault, etc.) instead of environment variables.

Principle 4: Audit and Monitor

Review Server Source Code

Before installing any MCP server, especially from unknown publishers:

Log MCP Activity

If building production servers, log all tool invocations:

server.tool("sensitive_operation", "...", schema, async (args) => {
  console.error(JSON.stringify({
    timestamp: new Date().toISOString(),
    tool: "sensitive_operation",
    args: args,
    // Don't log sensitive data like passwords
  }));
  // ... execute operation
});

Principle 5: Network Security

Local vs Remote Servers

Local servers (stdio) communicate through standard input/output — no network exposure. This is the most secure transport.

Remote servers (SSE/HTTP) communicate over the network. For these:

Don't Expose Internal Services

An MCP server should never be the only security boundary for internal services. If your MCP server connects to an internal database, ensure the database itself has proper access controls.

Principle 6: Data Protection

Security Checklist

Use this checklist before deploying MCP servers to production:

FAQ

Are MCP servers secure by default?

MCP servers running locally over stdio are as secure as any local program — they run with your user permissions. However, remote MCP servers need additional security measures like TLS, authentication, and input validation.

Can MCP servers access all my files?

Only if configured to. The filesystem server only accesses directories you explicitly specify in the configuration. Always use the principle of least privilege.

Should I audit MCP servers before installing them?

Yes, especially for servers from unknown sources. Check the GitHub repository, review the source code, and only install servers from trusted publishers.

Browse Verified Servers

MCP Hub reviews servers for quality and security

Browse Directory →