Treat every MCP server as a supplier with access to your systems, not as a plugin. Keep one list of approved servers with the exact versions you reviewed. Give each server its own narrowly scoped credentials, limit the hosts it can reach, require a person to approve anything irreversible and log every tool call. Send every new server, and every new version of an approved one, through the same review before it reaches anyone's agent. Servers that fail stay out until their publisher fixes them.
What goes wrong without a policy
In our MCP security review case, servers that had nothing else in common failed on the same conditions: tool descriptions and output that carried instructions for the agent, broad file access or a shell, tokens written to logs, OAuth scopes far broader than the tools needed, outbound access to any host, and unpinned versions with install scripts and unverified downloads. Each step below closes one or more of them.
1. Find what is already installed
MCP servers are added in the configuration of editors and desktop AI clients, often by one person for their own use, without passing procurement or security. Before writing a policy, collect those configurations and list every server, its version, who uses it and which credentials it was given. Running a server locally means, in the MCP documentation's words, that you "download code from the internet and run it as a child process of your user account". A server on a developer's laptop can reach whatever that developer can.
2. Keep one approved list, pinned
List each approved server with its exact version and the digest of the package you reviewed, and install from that list only. Pinning is what makes a review mean anything. An unpinned server can become different code on its next start.
3. Review before a server joins the list, and on every change
New servers go through two checks: vetting the package before install and reviewing how the agent may call it. A new version is new code and gets the same treatment. That is how the review tooling we use on client work runs: on the servers in a client's AI workflows before they go live, and again when a server changes.
4. One credential per server, scoped to its tools
Don't share one broad token across servers. Each server gets its own credential with the narrowest scope its tools need, enforced by the system that issues it. Secrets stay in the server's environment, where the model can't see or repeat them. For remote servers that use OAuth, the MCP authorization specification requires each server to check that a token was issued for it and to refuse any other: "MCP servers MUST NOT accept or transit any other tokens." A server that forwards your user's token to another API breaks that rule.
5. Limit what each server can reach
A server that needs one API should reach only that API. Run local servers in a container or another sandbox with only the directories they need, as the MCP security guidance recommends: "Launch MCP servers with restricted access to the file system, network, and other system resources." Restrict outbound traffic to an allow-list, so a successful injection ends in a refused connection instead of a leak.
6. Keep reading untrusted content apart from writing
An agent that reads customer tickets, email or web pages is reading text written by people outside the company. In our sample report, a ticket that made the agent close other tickets was fixed in three places: ticket content marked as untrusted data in the prompt, write tools blocked in any turn that had read untrusted content, and an approval step for closing a ticket. Configure every agent that reads outside content the same way.
7. A person approves anything irreversible
Payments, deletions, outbound messages and permission changes need an explicit approval, shown with the exact arguments the agent wants to use. The MCP specification puts it as "there SHOULD always be a human in the loop with the ability to deny tool invocations".
8. Log every call
Keep the tool name, the arguments, the caller, the result and the content the agent read just before the call, and keep secrets out of all of it. When something goes wrong, you need to know which document triggered which action.
9. Give every server an owner, and remove what nobody owns
Each approved server has an owner who answers for its version, its credentials and its next review. When a server is no longer used, uninstall it everywhere and revoke its credentials. An unused server with a live token is access nobody is watching.
Sources
- MCP documentation: Security Best Practices ↗ and Local Server Security ↗
- MCP specification 2026-07-28: Authorization ↗
- MCP specification 2026-07-28: Tools ↗
- Case: an MCP security review that became the tool we use for clients
This is the kind of work we do in agent and MCP security review. If your teams are adding MCP servers, start a project.
