PTENES
MODULE 5.3

🌐 HTTP/SSE Transport

Convert your MCP Server from STDIO to HTTP — enabling remote access and cloud deployment.

6
Topics
35
Minutes
Advanced
Level
Practice
Type
1

🔄 STDIO vs HTTP

MCP supports two transport models: STDIO (standard input/output) and HTTP (over the network). STDIO is local, simple, and fast — ideal for development and personal use. HTTP is remote, accessible over the network, and perfect for cloud deployment. The key question is: when to migrate? When others need to access your server — whether it's your team, your clients, or your production infrastructure.

💎 Core Concept

STDIO works like a Unix pipe: the client launches the server as a child process and communicates via stdin/stdout. It’s zero-config and instant, but limited to the local machine. HTTP exposes the server as a web service: any client on the network can connect via URL. This enables scenarios such as multiple simultaneous clients, deployment in containers, and access from anywhere in the world. The tradeoff is that HTTP requires network, security, and infrastructure configuration — but the gain in flexibility is enormous.

❌ Avoid
  • •Use HTTP for local use when STDIO is sufficient
  • •Expose HTTP without authentication on the internet
  • •Keep STDIO when multiple clients need access
  • •Ignore network latency when migrating to HTTP
✅ Do
  • •Start with STDIO for rapid development
  • •Switch to HTTP when you need remote access
  • •Keep both transports available in the code
  • •Test locally over HTTP before deploying
📊 Data and Research

The MCP specification officially defines two transports: STDIO e HTTP with SSE. In practice, most MCP Servers in production use HTTP/SSE to allow integration with multiple clients and cloud deployment. The HTTP protocol typically adds 1–5 ms latency per request on local networks, but this difference is imperceptible compared to the tools’ processing time. The latest version of the protocol also supports Streamable HTTP, an evolution of SSE with better reconnection support.

2

🌐 Configuring HTTP in FastMCP

FastMCP abstracts away all the complexity of configuring an HTTP server. With a single line of code, you can switch the transport from STDIO to HTTP or SSE. The framework handles routes, JSON-RPC serialization, connection management, and streaming — you focus on your tools’ logic.

💎 Core Concept

Configuring HTTP in FastMCP means changing a single parameter:

# Antes — transporte STDIO (padrão)
mcp.run()

# Depois — transporte HTTP
mcp.run(transport="http", host="0.0.0.0", port=8000)

# Ou com SSE (Server-Sent Events)
mcp.run(transport="sse", host="0.0.0.0", port=8000)

The parameter host="0.0.0.0" accepts connections from any IP (required for Docker/cloud). The port sets the server port. FastMCP internally uses the uvicorn as an ASGI server, ensuring performance and compatibility with the Python ecosystem.

💡 Practical Tip

Use an environment variable to switch between transports without modifying the code: transport = os.getenv("MCP_TRANSPORT", "stdio"). For local development, use STDIO. In production, define MCP_TRANSPORT=http. This way, the same code works in both scenarios without any changes to the source.

📋 Steps to Migrate from STDIO to HTTP
Step 1

Add uvicorn e starlette to the dependencies in the pyproject.toml.

Step 2

Change mcp.run() to mcp.run(transport="http", host="0.0.0.0", port=8000).

Step 3

Test locally by accessing http://localhost:8000 and verify that the tools respond over HTTP.

3

📡 Server-Sent Events

SSE (Server-Sent Events) is a technology that lets the server send continuous updates to the client over a persistent HTTP connection. Unlike WebSockets (bidirectional), SSE is unidirectional: the server sends, the client receives. This is ideal for long-running operations where the client needs to track progress in real time.

💎 Core Concept

With MCP’s SSE transport, the client makes an HTTP request and keeps the open connection. The server sends JSON-RPC messages as SSE events while processing requests. This allows for streaming partial results, progress notifications, and incremental responses. MCP uses SSE as the response channel while the client sends requests via regular POST. This architecture is robust and works well with proxies, load balancers, and CDNs—unlike WebSockets, which require special infrastructure support.

❌ Avoid
  • •Use polling instead of SSE for updates
  • •Don't handle reconnection when the SSE connection drops
  • •Send huge payloads over SSE without chunking
  • •Ignore timeouts in long-running operations
✅ Do
  • •Use SSE for operations that take more than 1s
  • •Implement a heartbeat to keep the connection alive
  • •Handle automatic reconnection in the client
  • •Send progress notifications for slow tools
📊 Data and Research

SSE is natively supported by all modern browsers and most HTTP frameworks. Compared with WebSockets, SSE uses Standard HTTP, which means full compatibility with reverse proxies (Nginx, Cloudflare) without special configuration. Automatic reconnection is built into the SSE spec — if the connection drops, the browser reconnects automatically using the last Last-Event-ID. The evolution of SSE in MCP is Streamable HTTP, which combines POST for sending and SSE for receiving through a single endpoint.

4

🔒 Security in HTTP

Exposing an MCP Server over HTTP means exposing it to the network—and potentially to the internet. Security is not optional: HTTPS required in production, authentication via headers, CORS configuration, and rate limiting are the minimum. An unprotected MCP server is an open door to arbitrary code execution.

💎 Core Concept

Security checklist for an HTTP MCP Server:

  • 1.HTTPS/TLS — encrypts traffic. Use Let's Encrypt or your cloud provider's TLS.
  • 2.Authentication — validate tokens in headers (Authorization: Bearer <token>).
  • 3.CORS — restrict allowed origins to prevent requests from unauthorized domains.
  • 4.Rate Limiting — limit requests per IP/token to prevent abuse.
  • 5.Firewall/VPN — in corporate environments, restrict access to the internal network.
🚨 Alert

NEVER use HTTP without TLS in production! Without HTTPS, authentication tokens and request and response data travel in plain text—anyone on the same network can intercept them. An MCP Server exposes tools that can execute code, access databases, and manipulate files. Using HTTP without TLS in production is like leaving the vault door open with the password taped to the wall.

❌ Avoid
  • •Plain HTTP in production (without TLS)
  • •Tokens hardcoded in the source code
  • •CORS with allow_origins=["*"] in production
  • •Server exposed to the internet without authentication
✅ Do
  • •HTTPS with valid certificates (Let's Encrypt)
  • •Tokens in environment variables
  • •CORS restricted to specific domains
  • •Rate limiting + access logging
5

☁️ Cloud Deployment

With the server running over HTTP, the next step is to put it in the cloud. There are several options—from simple platforms like Railway e Fly.io all the way to complete infrastructure with AWS Lambda or Docker on a VPS. The choice depends on your budget, scale, and control requirements.

💎 Core Concept

A basic Dockerfile for deploying the MCP Server:

FROM python:3.12-slim

WORKDIR /app
COPY . .

RUN pip install --no-cache-dir .

ENV MCP_TRANSPORT=http
ENV PORT=8000
EXPOSE 8000

CMD ["meu-server"]

The Dockerfile installs the Python package, sets environment variables, and exposes the port. Platforms like Railway and Fly.io automatically detect the Dockerfile and build the app. For AWS Lambda, use an adapter like mangum to convert ASGI to a Lambda handler.

📋 Deployment Steps
Step 1

Create the Dockerfile in the project root with the HTTP server configuration.

Step 2

Configure environment variables on the platform: API tokens, MCP_TRANSPORT, port, and secrets.

Step 3

Push the code to the Git repository connected to the platform—the deploy happens automatically.

Step 4

Check the deployment logs, test the public URL, and configure a custom domain if needed.

💡 Practical Tip

For personal projects and MVPs, Railway e Fly.io are the fastest options—deploy directly from GitHub in minutes, with automatic HTTPS and a free tier. For production with more control, use Docker + VPS (Hetzner, DigitalOcean) with Nginx as a reverse proxy and Let's Encrypt for TLS. Always use .dockerignore to delete .env, .git e __pycache__.

6

🧪 Testing Remotely

With the server deployed, it’s time to verify that everything works from outside — from another machine, on another network, as a real client would. Remote testing reveals problems that local tests hide: firewalls, DNS, network latency, and CORS settings.

💎 Core Concept

Testing with curl and configuring a remote client:

# Testar se o server responde
$ curl https://meu-server.railway.app/sse

# Configurar no Claude Desktop (claude_desktop_config.json)
{
  "mcpServers": {
    "meu-server": {
      "url": "https://meu-server.railway.app/sse"
    }
  }
}

For HTTP/SSE clients, just point to the deployed server’s URL. The client connects via HTTPS, keeps the SSE connection open, and sends requests as usual. Check latency with curl -w "%{time_total}" to ensure the response time is acceptable.

💡 Practical Tip

Test starting from multiple environments: your local machine, a VM in another region, and your phone (via a 4G hotspot). Each environment reveals different problems — DNS can fail on one network, CORS can block in a browser, and latency can be unacceptable from another region. Use mcp-cli or npx @modelcontextprotocol/inspector to inspect the JSON-RPC messages exchanged.

📋 Remote Testing Checklist
Step 1

Check that the public URL responds with curl — HTTP 200 on the health check.

Step 2

Connect a remote MCP client and list the available tools with tools/list.

Step 3

Run a tool and measure latency — verify that the response time is less than 5 seconds for simple operations.

📝 Module Summary

  • ✓ STDIO is local and simple; HTTP is remote and scalable—migrate when others need to access your server.
  • ✓ FastMCP abstracts away the complexity—switching from STDIO to HTTP means changing one parameter in mcp.run().
  • ✓ SSE enables streaming and continuous updates over a persistent HTTP connection.
  • ✓ Security is mandatory: HTTPS, authentication, CORS, and rate limiting are the minimum.
  • ✓ Cloud deployment with Docker — Railway, Fly.io, or a VPS with Nginx and Let's Encrypt.
  • ✓ Test remotely across multiple environments to ensure the server works for everyone.

Next Module: 5.4 — MCP with TypeScript