CodexSpot

MCP Security Best Practices

March 11, 2026 · 3 min read

TL;DR

  • MCP servers can access local files, databases, and APIs — always review permissions before installing
  • Prefer local stdio transport for sensitive operations and remote HTTP with OAuth for shared servers
  • Audit environment variables and never expose secrets in client-side configuration

Why MCP Security Matters

MCP servers act as a bridge between AI clients and your local or remote systems. A filesystem server can read and write files on your machine. A database server can execute queries. A GitHub server can create commits and open pull requests on your behalf.

This power is exactly what makes MCP useful, but it also means a misconfigured or malicious server can cause real damage. Unlike browser extensions that operate in a sandbox, MCP servers run with the same permissions as your user account. There is no built-in permission boundary unless you create one.

Before installing any MCP server, review its source code or documentation to understand what capabilities it exposes. Pay special attention to write operations — a server that can only read files is far less risky than one that can delete them.

Transport Security

MCP supports two primary transport mechanisms: stdio (local) and HTTP with SSE (remote).

For local development and sensitive operations, prefer stdio transport. The server runs as a child process on your machine, and communication happens through standard input and output. There is no network exposure:

json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/safe/path"]
    }
  }
}

For remote or shared servers, use HTTP transport with proper authentication. The MCP specification supports OAuth 2.0 for remote connections. Never expose a remote MCP server without authentication — an unauthenticated endpoint gives anyone with the URL full access to whatever capabilities the server provides.

bash
# Verify a remote server requires auth before connecting
curl -s https://mcp.example.com/.well-known/oauth-authorization-server | jq .

If the server does not return an OAuth metadata document, it may not enforce authentication.

File System Access

The filesystem MCP server accepts a list of allowed directories as arguments. Always scope access to the narrowest set of directories your workflow requires.

Bad practice — granting access to your entire home directory:

bash
npx @modelcontextprotocol/server-filesystem /Users/you

Good practice — restricting access to a single project:

bash
npx @modelcontextprotocol/server-filesystem /Users/you/projects/my-app

If you need access to multiple directories, list them explicitly rather than granting a parent directory. This limits the blast radius if the AI agent makes an unexpected file operation.

Review the server's tool list to understand what file operations it supports. Some servers expose write_file and delete_file tools — consider whether you actually need those capabilities or whether read-only access is sufficient.

Environment Variables and Secrets

MCP configurations often include environment variables for API keys, tokens, and database credentials. These secrets deserve careful handling:

  • Never commit your MCP config to version control if it contains secrets. Add the config file to .gitignore.
  • Use references to system environment variables or a secrets manager rather than hardcoding values.
  • Rotate credentials if you suspect they have been exposed through a shared configuration.
  • Audit regularly which servers have access to which secrets. A server that only needs a GitHub token should not also receive your database password.

Keep your configuration files readable only by your user account:

bash
chmod 600 ~/Library/Application\ Support/Claude/claude_desktop_config.json

Treating MCP server configuration with the same care as SSH keys or cloud credentials will prevent most security issues before they happen.

Referenced in this post