MCP Security Best Practices: A Guide to Securing AI Tool Servers
A Model Context Protocol (MCP) server can pull last night’s error logs, diff the deploy, and draft the fix in one conversation, the kind of tooling engineers wanted long before large language models (LLMs) made it practical. Behind that convenience sits privileged infrastructure.
Your server executes tools, reads file systems, calls downstream services, and relays model output under its own credentials, and teams might mistakenly deploy one with the ceremony of a Slack integration. Attackers exploit the mismatch between the server’s broad execution privileges and the light-touch review teams apply before deploying one.
This guide covers the MCP security best practices against documented attack vectors, the six control categories that address them, and the audit logging that verifies those controls in production.
What Is MCP?
MCP or “Model Context Protocol” is a client-server protocol that connects your AI application to tools. The host runs an MCP client that holds a session with each server. Common MCP hosts include Claude Desktop, Cursor, and VS Code Copilot.
The server advertises each tool’s name and description. It also provides an input schema, and the model picks a tool. The client then sends a tools/call request using JavaScript Object Notation (JSON) Remote Procedure Call (RPC), or JSON-RPC, that the server executes before returning the result into the model’s context. Every step runs under the server’s credentials and has broad execution privileges which can differ from the requesting user’s permissions.
Those broad privileges make MCP servers a valuable target, and many production deployments leave them exposed. A study of 119 internet-reachable servers found that every one returned its tool listings without authentication.
Key MCP Security Risks and Attack Vectors
MCP servers face two overlapping categories of risk. The first covers failures specific to the protocol itself, including tool poisoning, token passthrough, and rug pull attacks. The second covers risks common to any generative AI system that lets a model trigger code execution against real infrastructure, the same risks GenAI security teams already track.
The eight vectors below span both categories:
- Tool poisoning: Instructions hidden in a tool’s description, parameter schema, or return values steer the LLM into calling the tool with attacker-chosen arguments or executing actions the user never requested. The LLM reads the description field, and the user never sees it.
- Prompt injection: Data a tool retrieves can carry instructions the model executes as if you typed them. Attackers can plant instructions in user-submitted content the agent later reads, such as a support ticket message or a database row, directing the server to pull private Structured Query Language (SQL) data and write it back to a field the attacker can see.
- Token passthrough: A server accepts a token that its own authorization service never issued and forwards it downstream, so the downstream service trusts a caller it never authorized. The MCP authorization spec prohibits this pattern, but servers that skip audience validation still accept and forward these tokens.
- Server-side request forgery (SSRF): MCP clients fetch Open Authorization (OAuth) metadata from addresses a malicious server controls, and any tool that fetches arbitrary model-supplied web addresses turns your server into a proxy into your private network.
- Session and state handle hijacking: Long-running MCP sessions carry downstream access tokens, so a stolen or predictable handle becomes an authenticated agent in an attacker’s hands. A vulnerability in mcp-remote, CVE-2025-6514 details, let a malicious authorization_endpoint execute arbitrary operating system commands on the connecting machine. The vulnerability reached more than 437,000 installed environments.
- Supply chain attacks: An attacker publishes a malicious MCP server package, hijacks a trusted maintainer’s registry account to push a poisoned update, or slips code into a transitive dependency that MCP servers pull in at install time. The malicious code then runs inside your server process with the same privileges as every legitimate tool. Recent examples include a fake postmark-mcp npm package impersonating Postmark that built trust over 15 versions before shipping a malicious version that secretly BCC’d emails to an external server.
- Rug pull attacks: Teams approve a tool registration once, then fail to re-verify it, so a server that behaved at install time can rewrite its tool definitions afterward. In the Cursor configuration flaw tracked as CVE-2025-54136, an attacker could commit a benign MCP config to a shared repository, wait for a developer to approve it in Cursor, and then swap in a malicious command that Cursor kept trusting because the config’s key name never changed.
- Confused deputy problem: The server holds broad ambient authority, and a model-initiated call or a malicious client borrows that authority to do something the actual user never authorized. When a third-party authorization server uses a static client ID and the proxy lacks per-client consent tracking, an attacker can register a client with a redirect to their own domain and exchange the resulting code for tokens scoped to the victim.
These vectors rarely appear in isolation. A single deployment often exposes several at once, which is why the controls in the next section address them as a set rather than one at a time.
MCP Security Best Practices: Six Controls for Production Servers
Six controls move an MCP server from exposed to production-ready. They cover authentication, least-privilege authorization, input validation, runtime sandboxing, transport and session hardening, and supply chain verification.
A 2025 analysis of 5,200 servers found that roughly eight and a half percent of them use OAuth while 53 percent rely on long-lived static secrets, which puts most deployments below the entry-level bar of the Cloud Security Alliance (CSA) maturity model. The CSA model grades MCP deployments across four cumulative levels, and Level one already assumes baseline hygiene like authentication and transport encryption.
The six controls below draw from three published sources. The official MCP guide and the OWASP guide document the baseline that closes unauthenticated tool listings and similar exposures. The CSA security guide layers additional requirements into its four-level maturity model, where each level assumes every control below it.
Enforce Strong Authentication
A protected MCP server is an OAuth 2.1 resource server. Proof Key for Code Exchange (PKCE) is mandatory for every public client, and your enterprise identity provider handles identity. Short-lived OAuth tokens and automated scope expiry replace static keys and personal access tokens.
Audience validation kills token passthrough. Clients send Request for Comments (RFC) 8707’s resource parameter, and the server rejects any token whose audience claim omits it. Service-to-service hops need mutual authentication too.
Apply Least Privilege and Fine-Grained Authorization
Tool-level scope minimization fixes the confused deputy problem because a server that can only do what the current tool needs has no ambient authority to borrow. A tool that reads files shouldn’t carry a scope permitting file deletion.
OAuth scopes can follow a pattern such as mcp:tool:read_file:read, while the server enforces role-based access control (RBAC) per tool rather than per connection and requires just-in-time re-authorization for high-privilege operations. Your proxies should also keep a per-user registry of approved client_id values.
Validate All Inputs and Enforce Schema
Tool parameters come from model output shaped by hostile context, so your server must treat them as untrusted. A strict JSON Schema per tool sets additionalProperties: false and pattern constraints on string fields. Sanitization blocks SQL and command injection. It also blocks path traversal injection. The Kubernetes command-injection flaw, CVE-2025-53355 in mcp-server-kubernetes, exemplifies when things go wrong, where the server passed unsanitized parameters into child_process.execSync.
Pinning each tool definition at discovery with a Secure Hash Algorithm 256-bit (SHA-256) hash and re-hashing before execution catches the rug pull attack.
Sandbox and Isolate Runtimes
The container or hypervisor layer must enforce filesystem and network limits instead of relying on controls inside the server. Path checks written inside the server itself have failed in practice, where a prefix and symlink bypass in the reference Filesystem MCP server gave attackers full read/write access to the host, which is why the isolation layer has to sit below the server.
The CSA isolation baseline (section 3.6 of the CSA security guide) blocks filesystem access by default, permits outbound network only to an allowlist, and sets per-execution CPU and memory quotas with hard timeouts.
Kubernetes deployments should use a securityContext with runAsNonRoot: true, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, every capability dropped, and seccompProfile.type: RuntimeDefault, layered with an AppArmor or SELinux profile.
Secure Transport and Session Management
Remote MCP traffic must run over Transport Layer Security (TLS) with certificates issued by a certificate authority the client trusts. Your server-side clients should block private and reserved address ranges when fetching OAuth metadata, which closes the SSRF path through discovery.
MCP servers must not treat sessions as credentials because they must be prevented from using sessions for authentication. The server must bind each state handle as <user_id>:<handle> and derive the user ID from the verified token. To reach Level two of the CSA maturity model, deployments should use short-lived access tokens and rotate refresh tokens on every use.
Verify Your Supply Chain
The official MCP Registry’s namespace authentication offers limited assurance. It proves control of a GitHub account or domain at publish time and delegates security scanning to external parties. Researchers successfully smuggled a benign test payload into nine of 11 registries, demonstrating that a malicious one would have landed just as easily.
Supply chain verification starts with a curated internal registry of reviewed servers and version pinning: every npx -y @some-package/mcp-server becomes @some-package/[email protected], and you commit the lockfile to version control. A software bill of materials, software composition analysis in the build pipeline, and prompt remediation of critical findings finish the control.
Observability and Audit Logging for MCP
Knowing the server is up says nothing about whether each tool call was authorized. A complete inventory should record server name, version, deployment location, and business owner because developers using Claude Desktop, Cursor, or VS Code Copilot may have configured dozens of servers without central IT awareness.
The following controls turn tool calls into evidence that auditors, incident responders, and on-call engineers can use to reconstruct who called what, when, and whether the call was authorized:
- Structured audit logging: Every invocation records the requesting agent identity, tool name, input parameters after the logging layer redacts sensitive values, timestamp, response status, and duration. Your security policy determines how long you retain those records and when you forward them to a centralized security information and event management (SIEM) platform.
- Anomaly detection on invocation patterns: Unusual call volume from one agent can signal prompt injection and exfiltration. So can calls at odd hours or from unexpected source addresses, especially when file enumeration is followed by outbound data transfer.
- Human-in-the-loop for destructive tools:
ToolAnnotationscarryreadOnlyHintanddestructiveHint. They can also carryidempotentHint. These risk-related hints can inform approval or confirmation flows. A trusted server must provide these annotations before clients trust them because they offer hints rather than guarantees. Clients should never base decisions onToolAnnotationsfrom untrusted servers. - Traces for every tool call: The OpenTelemetry MCP semantic conventions define
mcp.clientandmcp.serverspans. Atools/callspan carriesgen_ai.operation.name, which the instrumentation sets toexecute_tool, alongside gen_ai.tool.name, mcp.method.name, mcp.session.id, and jsonrpc.request.id, while clients propagate Trace Context throughparams._meta.
Those spans join the agent’s own reasoning in AI agent monitoring, so plan, handoff, sub-agent tool calls, and final answer read as one tree. The spans follow standard conventions, so they flow over the OpenTelemetry Protocol (OTLP) into whatever backend you already run, with MCP monitoring riding the same OpenTelemetry Collector (the agent that receives, processes, and forwards telemetry) as the rest of your signals.
Coralogix’s multi-layer architecture ingests those spans, and its AI Guardrails block prompt injection and personally identifiable information (PII) policy violations before content reaches the model.
See Your MCP Traffic in Coralogix
Authentication, authorization, validation, isolation, transport hardening, and supply chain review each close a specific attack path, while observability verifies all six controls.
Coralogix’s AI Center is that verification layer for MCP-powered workloads. It ingests GenAI spans that follow OpenTelemetry conventions, including tool-call child spans with gen_ai.* attributes alongside the rest of your telemetry.
It also runs real-time evaluators on each interaction, blocks unsafe prompts and responses with AI Guardrails, and tracks code agents such as Claude Code and Codex CLI from one dashboard.
If you’re running MCP servers today, you can start a free 14-day Coralogix trial and point your Collector at it. You’ll see which agent called which tool, with what arguments, and which calls tripped a policy before anyone opens an incident.

Frequently Asked Questions About MCP Security Best Practices
What are the best practices for MCP authentication?
For implementations that support OpenID Connect (OIDC) and PKCE, remote connections use them with OAuth 2.1. Audience validation against the server’s own identity is mandatory, and downstream calls need a separate, audience-scoped token rather than the one the client sent. Your implementation should use short-lived access tokens and rotate refresh tokens according to the OAuth configuration and applicable maturity requirements.
What is the confused deputy problem in MCP?
The confused deputy failure happens when an MCP server or proxy uses its own broad authority for an action the user never approved. A malicious client may hijack a consent flow, or a forwarded token may make a downstream service trust the wrong caller. Mitigations are per-client consent tracked server-side, tool-level scopes, and caller identity taken from the verified token.
What are the biggest security disadvantages of the MCP protocol?
The protocol’s value comes from letting a model trigger code execution against real systems. That design widens the surface for tool poisoning and prompt injection. It also creates SSRF exposure. Tool descriptions that can change and remote execution make supply chain verification and runtime isolation harder than for a conventional HTTP service. The spec’s controls only help where you adopt them.
How do you monitor MCP servers in production?
You start production monitoring with a complete inventory, then log every invocation with caller identity, tool name, redacted parameters, status, and duration. The gen_ai.* spans ship through your OpenTelemetry-native ingestion path into the same backend as your application traces. Per-agent baselines for call volume and sequence surface injection-driven bursts, and destructive tools sit behind a confirmation step.