7 MCP Server Security Controls Before Agents Connect

MCP server security comes down to seven controls: per-server consent gates, least-privilege OAuth scopes, tool schema pinning, sandbox isolation, token audience validation, SSRF allowlists, and centralized tool-call logging. The Model Context Protocol, introduced by Anthropic in November 2024, gives language models a standard way to call external tools, and that standard is now the thing an attacker targets. Unlike a traditional API, where a developer controls every call, the model itself decides which tool to invoke, when, and with what parameters — so the defenses that protect REST services cover only part of the surface. This guide maps each control to the attack it stops and to a concrete check your team can run before any agent connects to a new server.
Why MCP changes the threat model
An MCP host passes tool descriptions from every connected server into the model’s context window. That design decision creates risks that did not exist in point-to-point integrations. The most cited attack is tool poisoning: malicious instructions hidden in tool descriptions, parameter schemas or return values that manipulate the model’s behavior. A related pattern, the rug pull, changes tool definitions after the user has already approved them, turning a trusted tool hostile without any new consent prompt. Worse, a malicious server can shadow tools from other servers: because the model reads all descriptions at once, instructions on one server can steer how the agent abuses a second, legitimate server. Treat each connected MCP server as an untrusted, independent security domain, the same way you treat third-party OAuth grants.
Seven controls that matter
Use this table as the review baseline for every server you connect, whether it runs locally over stdio or remotely over Streamable HTTP.
| Control | Attack it stops | How to verify |
|---|---|---|
| Per-server consent gates | Rug pulls, silent installs | Re-prompt for consent whenever tool definitions change |
| Least-privilege OAuth scopes | Over-scoped token abuse | Audit every granted scope against tools actually used |
| Tool schema pinning | Tool poisoning, shadowing | Hash the full definition and compare before each run |
| Sandboxed local servers | Host and credential compromise | Containerize; confirm no full host or network access |
| Token audience validation | Token passthrough | Reject any token not issued to this exact server |
| SSRF allowlists | Metadata credential theft | Validate every discovered URL; block private ranges |
| Centralized tool-call logging | Late or missed detection | Ship full-parameter logs to your SIEM; alert on new tools |
Two of these deserve extra emphasis because teams routinely get them wrong. First, pin the complete tool definition — including input schema, output schema and annotations — not just the human-readable description; a flipped read-only hint can change client approval behavior with no visible text change. Hashes catch metadata drift, not server-side code changes, so pair pinning with the consent gate rather than treating it as enforcement. Second, sandboxing: a bare chroot is not a process sandbox. Run local servers in containers, restrict filesystem access to required directories, and disable network access unless the tool genuinely needs it.
Validate token audience, not presence
The clearest rule in the official guidance concerns token handling: MCP servers must never accept tokens that were not explicitly issued for that specific server. Token passthrough — forwarding an upstream token to a downstream API without checking its audience — breaks rate limits, destroys audit trails, and lets a stolen token pivot between connected services. Validate audience on every request, use short-lived scoped credentials instead of long-lived personal tokens, and pair credential hygiene with the KMS key rotation decisions your team already makes for static secrets. When servers sit behind OAuth, follow the protocol’s OAuth 2.1 profile and never share tokens between servers, no matter how convenient a shared service account looks.
Block metadata endpoint SSRF
Remote servers create a quieter problem: during OAuth metadata discovery, a client fetches URLs that the server itself supplies. A malicious server can populate those fields with internal addresses, and URLs pointing to the cloud metadata endpoint at 169.254.169.254 can exfiltrate instance credentials and hand the attacker IAM keys for your cloud account. The same vector reaches internal admin panels, localhost databases and DNS-rebinding domains. Enforce strict allowlists on every URL the client fetches during discovery, resolve and validate destinations server-side in trusted code, and assume any URL originating from an MCP response is attacker-controlled until proven otherwise. This is the same default-deny posture your egress rules should already enforce.
Pre-connection review procedure
Before an agent connects to any new MCP server, run this five-step check:
- Record the server’s publisher, source repository and transport, and store the initial tool definitions with their hashes.
- Diff requested OAuth scopes against the tools the server exposes; reject wildcard or omnibus scopes such as full-access grants.
- Confirm the sandbox: containerized process, restricted filesystem, no default network egress.
- Verify token handling: audience validation in place, no passthrough path, secrets in OS-native credential storage rather than plaintext config.
- Enable full-parameter logging before the first real call, and route alerts to the same pipeline that guards your audit log integrity.
Repeat the diff whenever definitions change, because approval given yesterday does not cover a tool rewritten today. If a server fails any step, keep it disconnected — the convenience of a one-line registry install is never worth an agent with your credentials.