MCP Security: What Builders Must Know
TL;DR
- MCP security comes down to three things: what you expose, to who, and how you store secrets.
- Local servers have a smaller attack surface than remote ones. Start there.
- Always scope tool permissions to the minimum needed. Never grant blanket access.
- Community servers can run arbitrary code. Review them before you run them.
- Never hardcode secrets. Use environment variables or a secrets manager.
MCP security is not complicated. But it is easy to get wrong, especially when you are moving fast and just want the thing to work. This guide covers what you actually need to know before you ship anything into production.
If you are new to MCP, read the Model Context Protocol guide first. Then come back here.
What makes MCP different from a regular API?
With a normal API, you control what the client can do. The client sends a request. Your server handles it. You write the rules.
With MCP, an AI model is calling your tools. The model decides what to call and when. That changes the threat model. A regular API gets called by code you wrote. An MCP server gets called by a model that is making decisions based on context, instructions, and whatever the user said. If your tool does something destructive and the model calls it at the wrong time, that is a real problem. This is why MCP security starts with understanding what you are actually building.
The threat model for MCP is not what can a hacker do. It is what can a confused model do at the worst possible moment.
Local vs remote servers: which is safer?
Local servers run on the same machine as the client. Remote servers run over the network. Local is safer by default. Here is why:
- No network exposure. Nothing can reach your server from outside.
- Authentication is simpler. The client and server share the same environment.
- Secrets stay local. You are not passing credentials over a connection.
Remote servers are more powerful. They can be shared across teams, run as persistent services, and connect to cloud resources. But they come with more surface area. If you are just starting out, run local. If you need remote, read the sections below on authentication and scoping carefully.
I build most of my early-stage MCP work through Devwiz as local servers first. We only move to remote when there is a clear reason to. You can see how this plays out in practice in how to build an MCP server and Claude MCP for internal tools.
How do you scope permissions correctly?
Scoping is where most builders get it wrong. The mistake is giving a tool access to everything it might ever need. You want to give it access to exactly what it needs right now, and nothing more. For each tool you build, ask these three questions:
- What data does this tool actually need to read?
- What data does this tool actually need to write or modify?
- What should happen if this tool is called at the worst possible time?
If the answer to question three is catastrophic, you have not scoped tightly enough.
Read vs write access. Give read access freely. Be careful with write access. Be very careful with delete access. If a tool does not need to write, do not give it write permission.
Filesystem access. If your tool reads files, scope it to a specific directory. Do not give it access to the whole filesystem. A tool that reads from your documents folder has no business touching your keys or SSH folder.
Database access. Create a dedicated database user for your MCP server. Give it only the permissions it needs. Do not use your admin credentials.
Network access. If your tool calls external APIs, scope it to the endpoints it actually uses. An outbound allowlist is better than open network access.
Claude Code has a good model for this. The settings and permissions system shows how to think about granular access controls in practice.
Scope once, scope tight, and document why. Future you will be grateful.
What do you need to know about community servers?
There are hundreds of community-built MCP servers on GitHub. Some are excellent. Some are risky. The problem is that MCP servers can run arbitrary code on your machine. If you install and run a server without reviewing it, you are trusting that code completely. Here is a minimum review process before running any community server:
Check the source. Is it from a known developer or organisation? Does the repo have activity, issues, and contributors? A single-commit repo from an unknown account is a red flag.
Read the tool definitions. Look at what tools the server exposes. Do the tools match what the README says? Are there tools that seem unrelated to the stated purpose?
Check what the server does on startup. Some servers phone home, write to disk, or call external APIs when they initialise. Read the code.
Check how it handles credentials. Does it ask for secrets? Where does it store them? If it reads your environment variables, does it log them anywhere?
Run it in isolation first. Test new servers in a sandboxed environment before running them in your normal workflow. None of this takes long. But skipping it is how you end up with a tool that does something you did not expect.
How should you handle secrets?
This is the most common mistake I see. Never put secrets in your code. Not API keys, not tokens, not passwords. Not even in a config file that you plan to gitignore. Plans change. Gitignore files get misconfigured. Repos get made public by accident. Here is the approach that works:
Use environment variables. Your MCP server should read secrets from the environment, not from a file in the repo. Set them in your shell profile or use an env file that is explicitly gitignored.
Use a secrets manager for production. If your server runs in production, use a proper secrets manager. A managed secrets service or an encrypted credential store is better than environment variables in a production server config.
Rotate credentials regularly. If a key is compromised, rotation is your recovery path. If you never rotate, you have no recovery path.
Audit access logs. For any server with real access to real systems, make sure you can see what was called and when. Logs are how you find out something went wrong before it becomes a bigger problem.
Never log secrets. This sounds obvious. It is not. Logging full request objects, environment dumps, or debug output is how secrets end up in log files. Be explicit about what you log.
What about authentication for remote servers?
If you are running a remote MCP server, authentication is not optional. The simplest approach for a private remote server is a shared secret in the request headers. The client sends a token. The server checks it. If it does not match, the request is rejected. For multi-user setups, you need proper authentication. OAuth 2.0 is the right model here. The MCP spec supports it. A few rules for remote auth:
- Use HTTPS. Always. No exceptions.
- Validate tokens on every request. Not just on connection.
- Expire tokens. Short-lived tokens with refresh are better than long-lived tokens.
- Do not roll your own crypto. Use a library or a service.
If you are not sure whether your remote server needs auth, assume it does.
FAQ
What is the biggest MCP security mistake builders make?
Scoping access too broadly. Giving a tool access to everything it might need instead of only what it does need. Start with minimum permissions and expand only when required.
Is it safe to use community MCP servers?
It can be. But you need to review the code before you run it. MCP servers execute on your machine. Treat them the same way you would treat any executable you download from the internet.
Do I need authentication for a local MCP server?
Usually not. Local servers are only accessible from your machine. If multiple users share a machine, that changes. For single-user local setups, auth adds complexity without much benefit.
How do I store API keys for an MCP server?
Use environment variables for development. Use a secrets manager for production. Never put keys in your code or in a config file that could end up in version control.
Ready to build safer AI systems?
Getting MCP security right is not hard. It just takes a bit of planning before you ship. Scope tight. Review community code. Handle secrets properly. Start local, go remote only when you need to.
If you want to build production-grade AI tooling for your business, I can help. Book a call here and we can talk through what makes sense for your setup.
Work with James
About the Author
The AI Orchestrator
AI Orchestrator and entrepreneur with 10+ years building digital products. Helping $1M+ business owners scale with AI systems, automation, and implementation through The AI Orchestrators, Devwiz, and Njin.