AI in Development
Clusterify.AI
© 2025 All Rights Reserved, Clusterify Solutions FZCO
AI-Driven Sales: The New Playbook to Maximize Ecommerce ROI
Secure MCP Server with Python and NextJS
Guide to Securing MCP AI Servers 2of2
Guide to Securing MCP AI Servers 1of2
NEW Conditional Logic in CSS: From Classic CSS Techniques to the New if() Function
GraphQL May Expose Promo Codes in Magento 2.4.8
July 12, 2025
AI in Development
Continue from part #1 of MCP AI Server Security 1 of 2
The landscape of Artificial Intelligence (AI) is evolving rapidly, with agentic AI leading the charge—intelligent systems designed to autonomously achieve goals and act on behalf of users. This shift calls for a reliable, standardized approach to enable AI agents to seamlessly interact with external data sources and services. Enter the Model Context Protocol (MCP), a groundbreaking standard that fosters interoperability, moving away from isolated integrations toward a unified AI ecosystem.
Dubbed the “AI USB port,” MCP serves as a versatile interface, connecting Large Language Models (LLMs) and their applications to a variety of systems—think enterprise databases, local files, web APIs, and external tools. This connectivity boosts development speed and equips AI agents with real-time insights, surpassing the limits of their original training data.
Yet, this expanded connectivity brings forth new security challenges. MCP’s open, integration-friendly design creates a broader attack surface that developers must address proactively. Security now extends beyond individual applications to every MCP server in the network. This guide offers a detailed, layered defense strategy for architects and engineers, covering the entire security process—from initial design and threat analysis to secure coding and operational excellence—ensuring a safe platform for agentic AI innovation.
Securing an MCP AI server starts with a clear grasp of its unique vulnerabilities. This threat environment combines risks from the AI layer, API infrastructure, and communication protocols, revealing a complex security landscape that demands careful attention.
The Model Context Protocol (MCP) is an open framework that standardizes how applications deliver context to LLMs, paving the way for advanced workflows and intelligent agents. Understanding its structure and components is key to identifying and mitigating potential security gaps.
MCP relies on a client-server model with three essential components:
MCP Host: The primary AI-driven application users interact with, such as development environments like Cursor, desktop tools like Claude Desktop, or custom AI solutions. It oversees the user interface and manages links to multiple MCP servers.
MCP Client: Integrated into the MCP Host, this component establishes a dedicated, one-to-one connection with a single MCP server. A host can support multiple clients simultaneously, aggregating diverse capabilities and context from various servers.
MCP Server: A streamlined program that exposes specific functions through the MCP interface. These servers can operate locally to access device-based files or services, or remotely to tap into web APIs and online resources.
Client-server interactions follow the JSON-RPC 2.0 standard, utilizing message types like requests, responses, notifications, and errors. The transport layer adapts to the deployment type: local servers use standard I/O (stdio) processes, while remote servers leverage HTTP streams such as Server-Sent Events (SSE) or WebSockets for interactive use.
For MCP servers that require interactive, bidirectional communication, WebSockets are the de facto transport layer. However, the flexibility and performance of WebSockets come with a unique set of security challenges that must be addressed to protect the communication channel between the client and the server.
ws://
to wss://
The foundational security measure for any WebSocket-based application is the use of encryption. The WebSocket protocol defines two schemes:
ws://
: An unencrypted, plaintext communication channel.wss://
: WebSockets secured with Transport Layer Security (TLS), the same encryption that powers HTTPS.Using the unencrypted ws://
protocol in any production environment is a critical vulnerability. It exposes all traffic to eavesdropping and Man-in-the-Middle (MITM) attacks, where an attacker can intercept, read, and modify all data exchanged between the client and the server.
Therefore, the use of wss://
is non-negotiable for all MCP server connections that traverse untrusted networks. TLS encryption provides essential confidentiality and integrity for the data in transit. Moreover, modern web browsers now enforce this practice, often blocking insecure WebSocket connections from pages loaded over HTTPS, making wss://
a prerequisite for both security and functionality.
A significant challenge in securing WebSockets is that the protocol itself does not handle authentication or authorization. An even greater complication is that the standard browser WebSocket
API in JavaScript does not allow developers to set custom HTTP headers, such as the Authorization
header typically used for sending Bearer tokens. This limitation forces developers to adopt alternative patterns to authenticate connections.
The choice of an authentication method involves a direct trade-off between implementation simplicity and the level of security provided. The most straightforward, stateless methods tend to introduce security risks like credential leakage, while the most secure methods are inherently stateful and add architectural complexity. Teams must consciously evaluate this trade-off based on their application’s risk profile. A low-risk internal tool might accept the risks of a simpler method, whereas a public-facing, high-stakes application must invest in the complexity of a more robust, stateful pattern.
Several patterns have emerged to solve this problem:
In this widely used approach, the client first authenticates with a standard HTTP endpoint to obtain a short-lived credential, typically a JSON Web Token (JWT). This token is then appended as a query parameter to the WebSocket connection URL.
wss://mcp.example.com/ws?token=eyJhbGciOiJIUzI1Ni...
This pattern avoids placing the token in the URL. The client establishes an initially unauthenticated WebSocket connection and then immediately sends the token as the first data message over the established channel.
wss://mcp.example.com/ws
.{"type": "auth", "token": "eyJhbGciOiJIUzI1Ni..."}
.This is a highly secure, stateful pattern that mitigates the risks of the other methods by using a single-use, ephemeral credential.
/api/ws-ticket
).wss://mcp.example.com/ws?ticket=...
.The following table provides a comparative overview of these authentication methods.
Comparison of WebSocket Authentication Methods
Cross-Site WebSocket Hijacking (CSWH) is a specific and dangerous attack that leverages a Cross-Site Request Forgery (CSRF) vulnerability on the WebSocket handshake process.
The attack unfolds as follows :
mcp-server.com
). Their browser holds a valid session cookie for this domain.evil-site.com
).wss://mcp-server.com/ws
).mcp-server.com
to this cross-origin request.evil-site.com
now has full, two-way control over this hijacked connection, allowing them to send messages on the victim’s behalf and read any sensitive data sent back by the server.Preventing CSWH requires breaking the chain of trust that the attacker exploits. The following controls are essential:
Origin
HTTP header indicates the domain that initiated the request. During the handshake, the server must inspect this header and compare it against a strict allowlist of trusted domains (e.g., the domain of the legitimate client-side application). If the value in the Origin
header is not on the allowlist, the server must reject the connection request immediately.