How to Secure MCP Servers in Production
Written by
HimanshuReviewed by
Rohit Joshi
Published 13 November 2026
Expert Verified

Short answer
To secure MCP servers in production, enforce authentication and authorization, validate tool inputs, restrict permissions, and protect credentials. Use execution isolation, network controls, dependency checks, and monitoring to reduce security risks. For protected remote servers, validate token issuers, audiences, and scopes before allowing access to sensitive tools
The TL;DR
- The gap: The MCP spec treats authorization as optional, so MCP server security depends on controls you add yourself.
- Where to start: Step 2. Reject any token not issued for your server and never forward tokens to another API, then work through the other seven steps.
MCP server security is the set of controls that decide who can call your server’s tools, what those tools can touch and what record each call leaves. The MCP protocol does not require authentication, so a server accepts any caller until you add it. HTTP transports should implement authorization, and stdio servers should read credentials from the environment instead. As AI moves into more business use cases, the CRMs, billing tools and help desks your server connects to are reachable through its tools.
The NSA’s AI Security Center reached the same conclusion in its May 2026 guidance on MCP, finding that adoption has outpaced the protocol’s security model. Its recommendations on MCP security hardening cover identity, input validation, sandboxing and logging, and each of those areas has its own step below. We follow the 2026-07-28 revision of the spec, the latest dated revision as of November 2026, and we tested the Step 2 code against seven cases.
Why MCP Servers Need Stronger Security in Production
Traditional APIs typically receive requests from applications following predefined logic. An MCP server, however, exposes tools that AI agents can select and execute dynamically. These tools may access databases, retrieve customer information, modify records, or interact with external services. This flexibility introduces security risks because the agent’s decisions can be influenced by information it receives during execution.
One major concern is prompt injection through tool descriptions and responses. A malicious instruction hidden in a tool’s metadata or retrieved content can influence an agent’s next action. For example, an attacker could place instructions in a support ticket that encourage an agent to retrieve private customer records and send them to an unauthorized destination. If the connected tools have excessive permissions, the consequences can extend beyond an incorrect response to unauthorized data access or system changes.
The Model Context Protocol standardizes communication between AI applications and external tools, but it does not automatically enforce every security control a deployment needs. Authentication, tool-level authorization, credential management, execution isolation, and monitoring must be configured appropriately. As agentic AI systems connect to more business applications, weaknesses in any of these controls can affect multiple systems.
Securing an MCP server therefore means controlling both who can access its tools and what those tools are allowed to do. The following eight steps address these risks, from restricting network exposure and validating credentials to protecting tool execution and monitoring suspicious activity.

How to Secure MCP Servers in Production in 8 Steps
Securing an MCP server requires controls at multiple levels, from network access and authentication to tool execution and monitoring. The following eight steps provide a practical approach to reducing security risks in production.
Step 1. Limit MCP Server Network Exposure
The first step is to reduce unnecessary network access. An MCP server should only expose the endpoints required for its intended clients and operations. This limits opportunities for unauthorized access and attacks against publicly reachable services.
Apply these security measures:
- Restrict local connections: Bind local HTTP-based MCP servers to
127.0.0.1instead of0.0.0.0unless external access is necessary. Validate the Host header and reject unexpected hostnames, as recommended in OWASP’s MCP Security Cheat Sheet. Stdio servers communicate through process streams rather than network ports. - Encrypt remote connections: Use TLS to protect communication between remote MCP clients and servers. This helps prevent interception or modification of data transmitted over the network.
- Validate request origins: Check the
Originheader on incoming HTTP requests and return403 Forbiddenfor disallowed origins. This helps prevent DNS rebinding attacks. Non-browser clients that omit the header should not be rejected solely for its absence. - Isolate production infrastructure: Deploy MCP servers in private subnets behind a controlled entry point, such as a load balancer or API gateway. Follow AWS MCP deployment guidance to restrict inbound traffic and avoid unnecessary public exposure.
- Secure development and debugging tools: Developer utilities can introduce serious vulnerabilities when exposed to untrusted networks. For example, CVE-2025-49596 affected MCP Inspector and received a critical CVSS 4.0 score of 9.4 from its CNA. Keep debugging interfaces restricted and require appropriate access controls.
- Protect local server configurations: Stdio-based MCP servers may execute commands defined in client configuration files. Restrict who can modify these files, verify executable paths, and review commands before allowing a server to run.
Step 2. Configure MCP Authentication and Authorization With OAuth 2.1
After restricting network access, the next step is to verify who can access your MCP server and which actions they are allowed to perform. For protected remote servers using MCP’s OAuth-based authorization framework, the MCP server acts as a resource server, while an authorization server issues access tokens.
Using a dedicated identity provider helps separate authentication, token issuance, key rotation, and revocation from your MCP tool logic.
A protected MCP server should handle three core tasks:
- Publish authorization metadata: Provide OAuth Protected Resource Metadata so clients can identify the authorization server. Return
401 Unauthorizedwith aWWW-Authenticateheader when authentication is required. - Validate access tokens: Accept bearer tokens through the
Authorizationheader. Reject expired tokens, tokens from untrusted issuers, and tokens not intended for your server. Never accept access tokens through URL query parameters. - Enforce tool permissions: Verify the caller’s scopes and access rights before executing protected tools. A valid token should not automatically grant access to every available operation.
The MCP authorization specification also requires clients to use Proof Key for Code Exchange (PKCE) for authorization-code flows. Clients must verify PKCE support through authorization-server metadata, including code_challenge_methods_supported.
For client registration, the July 2026 specification recommends Client ID Metadata Documents. Dynamic Client Registration remains available for backward compatibility but is deprecated for new implementations.

Example: Validating OAuth Access Tokens in Python
The following example uses Starlette and PyJWT to illustrate access-token validation in an MCP server. It checks the token’s signature, issuer, audience, and expiry while also validating the request Origin.
import jwtfrom jwt import PyJWKClientfrom starlette.middleware.base import BaseHTTPMiddlewarefrom starlette.responses import PlainTextResponseRESOURCE = "https://mcp.example.com/mcp"ISSUER = "https://auth.example.com/"JWKS_URL = "https://auth.example.com/.well-known/jwks.json"METADATA_URL = ( "https://mcp.example.com/.well-known/" "oauth-protected-resource")ALLOWED_ORIGINS = {"https://app.example.com"}jwks_client = PyJWKClient(JWKS_URL)def validate_token(token: str) -> dict: signing_key = jwks_client.get_signing_key_from_jwt(token) return jwt.decode( token, signing_key.key, algorithms=["RS256"], audience=RESOURCE, issuer=ISSUER, options={"require": ["exp", "aud", "iss"]}, )class AuthGuard(BaseHTTPMiddleware): async def dispatch(self, request, call_next): origin = request.headers.get("origin") if origin and origin not in ALLOWED_ORIGINS: return PlainTextResponse( "Forbidden", status_code=403 ) auth = request.headers.get("authorization", "") challenge = { "WWW-Authenticate": f'Bearer resource_metadata="{METADATA_URL}"' } if not auth.startswith("Bearer "): return PlainTextResponse( "Unauthorized", status_code=401, headers=challenge, ) try: request.state.claims = validate_token(auth[7:]) except jwt.PyJWTError: return PlainTextResponse( "Unauthorized", status_code=401, headers=challenge, ) return await call_next(request)
Important: This is an illustrative authentication middleware, not a complete production MCP server. It assumes a trusted authorization server that issues RS256-signed JWT access tokens and publishes a JWKS endpoint. Other token formats may require a different validation method.
Before deployment, configure the Starlette application, expose the Protected Resource Metadata endpoint outside the authentication guard, validate allowed hosts, and enforce tool-specific scopes. Use the authorization server’s verified configuration rather than accepting arbitrary metadata or signing-key endpoints.
Test Authentication Before Deployment
Run the following checks against your configured server:
| Test case | Expected result |
|---|---|
| Valid token with required permissions | Request succeeds |
| Missing bearer token | 401 Unauthorized |
| Expired token | 401 Unauthorized |
| Token issued for another resource | 401 Unauthorized |
| Token from an untrusted issuer | 401 Unauthorized |
| Disallowed Origin header | 403 Forbidden |
| Valid token with insufficient tool permissions | 403 Forbidden |
These are recommended test cases, not results from an independently executed test suite.
Finally, never forward the MCP client’s access token directly to another API. This practice, known as token passthrough, is prohibited by the MCP security guidance because the token may not be intended for the upstream service.
Instead, obtain a separate token authorized for the upstream API and restrict it to the permissions required for that operation.
Step 3. Enforce Least-Privilege Access for Every MCP Tool
A valid access token confirms that a caller is authorized to access a protected resource, but it does not automatically grant permission to every tool. Each MCP tool should enforce its own access rules based on the caller’s identity, granted scopes, and the requested operation.
For example, an AI customer service agent may need permission to check order details but should not be able to issue refunds without additional authorization.
Apply these access controls:
- Assign minimum permissions: Grant only the scopes required for each operation. For example, use
orders:readfor retrieving order information and a separaterefunds:writescope for processing refunds. Request additional permissions through step-up authorization when necessary, rather than granting broad access upfront. - Avoid excessive scopes: Do not request wildcard permissions such as
*orallunless they are explicitly necessary and supported by your authorization system. A compromised token with broad privileges can expose multiple tools and connected services. Advertising supported scopes does not itself grant those permissions. - Restrict tool visibility: Filter the
tools/listresponse according to the caller’s granted permissions. A read-only caller should not see tools intended for privileged operations. However, tool visibility is not a security boundary. Recheck authorization whenevertools/callis executed. - Require approval for sensitive actions: Financial transactions, destructive operations, and data-sharing requests should require additional authorization or explicit human confirmation. MCP annotations such as
destructiveHintdescribe a tool’s behavior but do not enforce security policies. - Limit upstream credentials: Avoid using one highly privileged service credential for every caller. Where supported, use user-specific or narrowly scoped credentials so an agent cannot access more data than the requesting user is permitted to see. The Cloud Security Alliance highlights the risks of excessive permissions in agent-connected systems.
- Bind state to authenticated identities: In stateless MCP deployments, applications may use explicit identifiers such as cart IDs or workflow IDs to maintain state. These identifiers must not act as proof of authorization. Associate each stored record with the verified user or tenant identity and validate ownership on every request. See MCP360’s stateless MCP migration guide for additional context.
When a caller lacks the required permissions, return an appropriate authorization error. For insufficient OAuth scopes, a 403 Forbidden response with insufficient_scope and the required scope information allows compatible clients to request additional authorization.
Step 4. Validate MCP Tool Inputs and Protect Against Prompt Injection
MCP tools process inputs selected by AI agents, which may contain malicious instructions or unauthorized requests. Even with valid authentication, tool inputs and outputs should never be trusted automatically.
The MCP tools specification requires servers to validate inputs, enforce access controls, apply rate limits, and sanitize outputs.
Apply these security measures:
- Enforce strict input schemas: Use JSON Schema to define accepted parameters, data types, and size limits. Reject unexpected fields with
additionalProperties: falseand validate inputs against business rules. - Verify input sources: Treat information from emails, websites, and external documents as untrusted. Confirm that requested actions match the caller’s permissions and intended workflow.
- Prevent command injection: Use parameterized database queries, fixed executable paths, and structured arguments instead of building commands from untrusted text. Restrict file access to approved locations. OWASP identifies this risk as MCP05.
- Treat tool outputs as untrusted: API responses and retrieved content may contain prompt injection attempts. Keep external content separate from trusted instructions and enforce security decisions in application code.
- Limit exposed information: Return only necessary data. Remove credentials, sensitive personal information, and internal system details before sending tool results to the agent.
Step 5. Protect Secrets in MCP Server Configurations and Logs
MCP servers often use API keys, OAuth tokens, and service credentials to access external systems. If these secrets appear in configuration files, debug logs, or model context, attackers may use them to access connected services.
OWASP identifies token mismanagement and secret exposure as MCP01 in its MCP Top 10. To reduce these risks, follow these practices:
- Use secure secret storage: Store credentials in managed services such as AWS Secrets Manager or Azure Key Vault instead of hardcoding them or saving them in configuration files.
- Limit credential permissions: Assign separate IAM roles or service identities to workloads, with access limited to the resources they need.
- Prefer short-lived credentials: Use temporary access tokens and rotate secrets regularly to reduce the impact of compromised credentials.
- Keep secrets out of model context: Never include API keys, OAuth tokens, or passwords in prompts, tool descriptions, or responses. Inject credentials securely at execution time.
- Protect logs and error messages: Redact tokens, personal information, and sensitive tool parameters before logging. Record only the operational details needed for monitoring and audits.
Step 6. Isolate MCP Tool Execution and Restrict Outbound Traffic
MCP tools may execute code, access files, or communicate with external services. If an attacker manipulates an agent through prompt injection, these capabilities could expose sensitive data or trigger unauthorized actions. Execution isolation and network restrictions help limit the damage, even when a tool is compromised.
Apply these security measures:
- Sandbox tool execution: Run tools in isolated environments using controls such as seccomp, AppArmor, SELinux, or AppContainers, as recommended in the NSA’s MCP security guidance. Restrict file system access, system privileges, and network capabilities to what each tool requires.
- Restrict outbound connections: Route external requests through a controlled proxy or firewall. Allow connections only to approved domains and services to reduce unauthorized communication and data exfiltration.
- Prevent Server-Side Request Forgery (SSRF): Block requests to unauthorized private, loopback, link-local, and cloud metadata addresses, including
169.254.0.0/16. Validate destinations after DNS resolution and on redirects, using established network security controls rather than custom URL filters. - Separate sensitive workloads: Isolate tools handling payments, authentication, or personal information from general-purpose tools. Apply separate credentials, permissions, and network policies to each environment.
Even if an attacker influences an MCP tool, sandboxing and outbound traffic restrictions can prevent that access from spreading across connected systems. These controls are particularly important when MCP servers connect to AI business automation tools.
Step 7. Verify MCP Server Packages and Tool Definitions
MCP servers depend on external packages and tool definitions that may introduce security risks. Tool poisoning occurs when malicious instructions are hidden in tool descriptions, schemas, or responses. A rug-pull attack happens when a previously approved tool changes its behavior or metadata without proper review.

Even when choosing from the best MCP servers for AI agents, review their source code, dependencies, and tool definitions before deployment.
Apply these security measures:
- Pin and verify tool definitions: Generate hashes of approved tool metadata, including descriptions,
inputSchema,outputSchema, and annotations. Flag changes for review before accepting them. Hashes detect metadata changes but cannot reveal malicious behavior hidden in unchanged definitions. - Verify package sources: Install packages from trusted repositories and check their names carefully to avoid typosquatting. Attackers may distribute malicious packages with names resembling legitimate MCP servers.
- Check package integrity: Pin dependency versions, verify available checksums or signatures, and scan packages for known vulnerabilities before deployment.
- Review server maintenance: Check release history, security updates, and repository activity. Avoid unmaintained or archived projects unless your team can independently maintain and secure them.
- Monitor updates: Recheck tool definitions, permissions, and dependencies whenever a server or package changes. Require approval for updates that introduce new capabilities or access requirements.
Step 8. Set Rate Limits and Monitor MCP Tool Activity
MCP servers can receive repeated or resource-intensive tool requests that overload connected systems or increase operational costs. Rate limiting, structured logging, and continuous monitoring help detect unusual activity, prevent misuse, and investigate security incidents.
For example, a WhatsApp AI agent handling multiple conversations needs per-caller monitoring to identify repeated requests, failed operations, or unauthorized tool usage.
Apply these security measures:
- Set rate limits and quotas: Restrict requests per user, tenant, and tool. Configure execution timeouts, concurrency limits, and maximum retries to prevent excessive resource consumption.
- Maintain secure audit logs: Record authenticated caller identity, tool name, timestamp, request ID, execution status, and relevant permission checks. Redact credentials, personal information, and sensitive parameters before storing logs.
- Monitor suspicious activity: Send logs to a Security Information and Event Management (SIEM) system. Configure alerts for unusual call frequency, repeated authorization failures, and unexpected tool usage.
- Enable distributed tracing: Use OpenTelemetry to trace requests across MCP clients, servers, and connected APIs. The July 2026 MCP specification documents trace-context propagation through
_metafields such astraceparent,tracestate, andbaggage. Avoid propagating sensitive information through tracing metadata. - Track server inventory: Maintain a record of deployed MCP servers, owners, and versions. Regularly check for unauthorized or forgotten deployments, commonly called shadow MCP servers.
Centralized monitoring becomes important when multiple MCP servers are deployed. An MCP gateway such as MCP360 can provide a central layer for managing authentication, traffic controls, and monitoring, depending on its configured capabilities. However, individual servers still need input validation, execution isolation, and tool-level authorization.
Rate limits help prevent resource abuse, while monitoring and audit logs make suspicious activity easier to detect and investigate. Apply these controls consistently across every production MCP server.
Common MCP Server Security Risks and Their Mitigations
Even with security controls in place, MCP servers remain exposed to risks involving credentials, tool execution, and third-party dependencies. The table summarizes common threats, their potential impact, and recommended safeguards.
| Security Risk | Potential Impact | Recommended Mitigation |
|---|---|---|
| Token misuse | Unauthorized access to connected services | Validate token audiences and use separate upstream credentials |
| Excessive permissions | Compromised tools access sensitive operations | Enforce least-privilege scopes and tool-level authorization |
| Command injection | Malicious inputs trigger unauthorized commands | Validate inputs and use safe execution methods |
| Secret exposure | Credentials leak through logs or configurations | Use managed secret storage and redact sensitive data |
| Tool poisoning | Malicious instructions influence agent behavior | Review tool metadata and treat outputs as untrusted |
| Supply-chain attacks | Compromised dependencies introduce malicious code | Pin versions and verify package integrity |
| Insufficient monitoring | Suspicious activity goes undetected | Maintain structured audit logs and security alerts |
| Shadow MCP servers | Unapproved deployments create security gaps | Maintain a server inventory and review network exposure |


