Phase 13 - Lesson 09
MCP Transports — stdio vs Streamable HTTP vs SSE Migration
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
O stdio funciona localmente e em nenhum outro lugar. O Streamable HTTP (26-03-2025) é o padrão remoto. O antigo transporte HTTP+SSE foi descontinuado e será removido em meados de 2026. Escolher o transporte errado custa uma migração; escolher o correto garante um servidor MCP hospedável remotamente com continuidade de sessão e proteção contra DNS-rebinding.
Type: Learn Languages: Python (stdlib, esqueleto de endpoint Streamable HTTP) Prerequisites: Phase 13 · 07, 08 (servidor e cliente MCP) Time: ~45 minutos
Learning Objectives
- Escolher entre stdio e Streamable HTTP com base no modelo de implantação (local vs remoto, processo único vs frota).
- Implementar o padrão de endpoint único do Streamable HTTP: POST para requisições, GET para stream de sessão.
- Aplicar validação de
Origine semântica de session-id para evitar ataques de DNS-rebinding. - Migrar um servidor HTTP+SSE legado para Streamable HTTP antes dos prazos de remoção em meados de 2026.
The Problem
O primeiro transporte remoto do MCP (novembro de 2024) foi o HTTP+SSE: dois endpoints, um para os POSTs do cliente e um canal de Server-Sent-Events para o stream do servidor para o cliente. Funcionava. Mas também era desajeitado: dois endpoints por sessão, caches quebrados na frente de algumas CDNs e uma dependência rígida de conexões SSE de longa duração que alguns WAFs encerram agressivamente.
A especificação de 26-03-2025 o substituiu pelo Streamable HTTP: um único endpoint, POST para requisições do cliente, GET para estabelecer um stream de sessão, ambos compartilhando um cabeçalho Mcp-Session-Id. Todo servidor construído ou migrado desde então usa Streamable HTTP. O modo SSE antigo está sendo descontinuado — o Atlassian Rovo o removeu em 30 de junho de 2026; a Keboola em 1º de abril de 2026; a maioria dos servidores corporativos restantes o fará até o final de 2026.
E o stdio ainda é importante para servidores locais. O Claude Desktop, o VS Code e todos os clientes integrados em IDEs iniciam servidores via stdio. O modelo mental correto: stdio para "esta máquina", Streamable HTTP para "pela rede". Sem misturar os dois.
The Concept
stdio
- Transporte de processo filho. O cliente inicia o servidor e se comunica via stdin/stdout.
- Um objeto JSON por linha. Delimitado por quebra de linha.
- Sem session id; a identidade do processo é a própria sessão.
- Nenhuma autenticação necessária (o processo filho herda o limite de confiança do pai).
- Nunca use para servidores remotos — você precisaria de SSH ou socat to fazer o túnel, momento no qual o ideal é usar Streamable HTTP.
Streamable HTTP
Endpoint único /mcp (ou qualquer caminho). Suporta três métodos HTTP:
- POST /mcp. O cliente envia uma mensagem JSON-RPC. O servidor responde com uma única resposta JSON ou com um stream SSE de uma ou mais respostas (útil para respostas em lote e notificações relacionadas a essa requisição).
- GET /mcp. O cliente abre um canal SSE de longa duração. O servidor o utiliza para requisições do servidor para o cliente (sampling, notificações, solicitação de informações).
- DELETE /mcp. O cliente encerra explicitamente a sessão.
As sessões são identificadas pelo cabeçalho Mcp-Session-Id que o servidor define na primeira resposta e o cliente replica em cada requisição subsequente. Os ids de sessão DEVEM ser criptograficamente aleatórios (mais de 128 bits); ids escolhidos pelo cliente são rejeitados por segurança.
Single endpoint vs two
O modo de dois endpoints da especificação antiga ainda pode ser chamado em 2026 — a especificação o declara como "compatível com legado". No entanto, todos os novos servidores devem ter endpoint único. Os SDKs oficiais geram endpoint único; use o modo legado apenas ao se comunicar com um servidor remoto não migrado.
Origin validation and DNS-rebinding
Os navegadores não são clientes MCP (hoje), mas um invasor pode criar uma página web que convença um navegador a fazer um POST para localhost:1234/mcp — onde o servidor MCP local do usuário está escutando. Se o servidor não verificar o cabeçalho Origin, a política de mesma origem (same-origin policy) do navegador não o protegerá, pois Origin: http://evil.com é uma origem cruzada válida.
A especificação de 25-11-2025 exige que os servidores rejeitem requisições cuja Origin não esteja em uma lista de permissões (allowlist). A lista de permissões geralmente contém o host do cliente MCP (https://claude.ai, vscode-webview://*) e variantes do localhost para UIs locais.
Session id lifecycle
- O cliente envia a primeira requisição sem
Mcp-Session-Id. - O servidor atribui um id aleatório e define o cabeçalho
Mcp-Session-Idna resposta. - O cliente replica esse cabeçalho em todas as requisições subsequentes e no
GET /mcppara o stream. - A sessão pode ser revogada pelo servidor; o cliente recebe um erro 404 nas requisições subsequentes e deve reinicializar.
- O cliente pode enviar explicitamente um DELETE na sessão para um encerramento limpo.
Keepalive and reconnect
As conexões SSE caem. O cliente a restabelece fazendo um novo GET com o mesmo Mcp-Session-Id. O servidor DEVE enfileirar eventos perdidos durante a interrupção (até um limite razoável) e reproduzi-los por meio do cabeçalho last-event-id que o cliente envia de volta.
A Fase 13 · 13 aborda Tarefas (Tasks), que permitem que trabalhos de longa duração sobrevivam até mesmo a uma reconexão completa da sessão.
Backwards compatibility probe
Um cliente que deseja oferecer suporte a servidores antigos e novos:
- Envia um POST para
/mcp. - Se a resposta for
200 OKcom JSON ou SSE, trata-se de Streamable HTTP. - Se a resposta for
200 OKcomContent-Type: text/event-streamE um cabeçalhoLocationapontando para um endpoint secundário, trata-se do HTTP+SSE legado; siga oLocation.
Cloudflare, ngrok, and hosting
Os servidores MCP remotos em produção em 2026 são executados no Cloudflare Workers (com seu SDK do MCP Agents), Vercel Functions ou Node/Python conteinerizado. Ponto principal: sua hospedagem deve suportar conexões HTTP de longa duração para o GET do SSE. O plano gratuito da Vercel limita a conexão em 10 segundos e é inadequado. O Cloudflare Workers suporta streams indefinidos.
Gateway composition
Quando você coloca um gateway na frente de vários servidores MCP (Fase 13 · 17), o gateway funciona como um único endpoint Streamable HTTP que reescreve os session ids e realiza a multiplexação upstream. As ferramentas são mescladas na camada do gateway; o cliente enxerga um único servidor lógico.
Transport failure modes
- stdio SIGPIPE. A morte do processo filho no meio de uma gravação gera SIGPIPE; os servidores devem terminar de forma limpa. Os clientes devem detectar EOF e marcar a sessão como morta.
- HTTP 502 / 504. O Cloudflare, nginx e outros proxies emitem esses erros em caso de falha no upstream. Os clientes do Streamable HTTP devem tentar novamente uma vez após um breve tempo de espera (backoff).
- SSE connection drop. TCP RST, timeout de proxy ou alteração na rede do cliente fecham o stream. O cliente se reconecta com o
Mcp-Session-Ide o cabeçalho opcionallast-event-idpara retomar. - Session revocation. O servidor invalida um id de sessão; o cliente vê 404 na próxima requisição. O cliente deve realizar um novo handshake.
- Clock skew. Os cálculos de TTL de recursos no cliente divergem do servidor. O cliente deve tratar os carimbos de data/hora (timestamps) do servidor como autoritativos.
When to bypass Streamable HTTP
Algumas empresas implantam servidores MCP atrás de transportes gRPC ou filas de mensagens (message-queues) dentro de suas próprias redes. Isso não é padrão — a especificação do MCP não define formalmente esses formatos. Os gateways podem expor uma interface Streamable HTTP para clientes MCP enquanto usam gRPC internamente. Mantenha a interface externa compatível com a especificação; o gateway gerencia a tradução.
Use It
O arquivo code/main.py implementa um endpoint Streamable HTTP mínimo usando http.server (stdlib). Ele gerencia POST, GET e DELETE no /mcp, define o Mcp-Session-Id na primeira resposta, valida o Origin e rejeita requisições de origens que não estejam na lista de permissões. O manipulador reutiliza a lógica de despacho do servidor de notas da Lição 07.
O que observar:
- O manipulador POST lê o corpo JSON-RPC, realiza o despacho e grava uma resposta JSON (a variante de resposta única; a variante SSE é estruturalmente semelhante).
- A verificação de
Originrejeita o teste padrão comhttp://evil.example, mas aceitahttp://localhost. - Os ids de sessão são strings hexadecimais aleatórias de 128 bits; o servidor mantém o estado de cada sessão em memória.
Ship It
Esta lição produz o arquivo outputs/skill-mcp-transport-migrator.md. Dado um servidor MCP HTTP+SSE (legado), a skill gera um plano de migração para o Streamable HTTP com continuidade de session-id, verificações de Origin e suporte a testes de compatibilidade retroativa.
Exercises
Execute
code/main.py. Envie um POST deinitializeusando ocurle observe o cabeçalho de respostaMcp-Session-Id. Envie um segundo POST replicando o cabeçalho e verifique a continuidade da sessão.Adicione um manipulador GET que abra um stream SSE. Envie um evento
notifications/progressa cada cinco segundos. Reconecte fazendo um novo GET com o mesmo session id e confirme se o servidor o aceita.Implemente a lógica de reprodução do
last-event-id. Na reconexão, reproduza todos os eventos gerados desde aquele id.Estenda a validação de
Originpara aceitar um padrão curinga (https://*.example.com) e confirme se aceitahttps://app.example.commas rejeitahttps://evil.example.com.attacker.net.Escolha um servidor HTTP+SSE legado do registro oficial (existem vários) e faça um esboço da migração: o que muda na manipulação dos endpoints, na geração do session id e na semântica dos cabeçalhos.
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| stdio transport | "Processo filho local" | JSON-RPC sobre stdin/stdout, delimitado por quebra de linha |
| Streamable HTTP | "O transporte remoto" | Endpoint único com POST + GET + SSE opcional, especificação de 26-03-2025 |
| HTTP+SSE | "Legado" | Modelo de dois endpoints sendo removido em meados de 2026 |
Mcp-Session-Id |
"Cabeçalho de sessão" | ID aleatório atribuído pelo servidor e replicado em cada requisição subsequente |
Origin allowlist |
"Defesa contra DNS-rebinding" | Rejeitar requisições cuja Origin não esteja aprovada |
| Single endpoint | "Uma única URL" | O /mcp gerencia POST / GET / DELETE para todas as operações de sessão |
last-event-id |
"Reprodução SSE" | Cabeçalho usado para retomar um stream interrompido sem perder eventos |
| Backwards-compat probe | "Detecção antigo vs novo" | Verificação de formato de resposta do cliente que seleciona o transporte automaticamente |
| Long-lived HTTP | "Streaming de SSE" | O servidor envia eventos por minutos ou horas em uma única conexão TCP |
| Session revocation | "Forçar reinicialização" | O servidor invalida um id de sessão; o cliente deve realizar o handshake novamente |
Further Reading
- MCP — Basic transports spec 2025-11-25 — referência canônica para stdio e Streamable HTTP
- MCP — Basic transports spec 2025-03-26 — a revisão que introduziu o Streamable HTTP
- Cloudflare — MCP transport — padrões de Streamable HTTP hospedados no Cloudflare Workers
- AWS — MCP transport mechanisms — comparação entre diferentes formatos de implantação
- Atlassian — HTTP+SSE deprecation notice — exemplo prático de prazo de migração