Especificação MCP stateless: servidores stateless vs stateful explicados
A especificação MCP de 2026-07-28 removeu o handshake de initialize e o header Mcp-Session-Id. Este artigo compara servidores stateless e stateful, mostra para onde vai o estado das ferramentas agora, com handles, tasks e requisições de múltiplas viagens de ida e volta, e lista os passos de migração.
Todo servidor MCP que você construiu antes deste verão provavelmente começa do mesmo jeito: um cliente se conecta, envia initialize, espera a resposta, envia initialized e só então consegue fazer trabalho de verdade. A revisão de 2026-07-28 do Model Context Protocol elimina esse ritual. Não há handshake, nenhum header Mcp-Session-Id e nenhuma sessão no nível do protocolo presa a um único processo. Se você roda um servidor MCP atrás de um load balancer, ou adiou essa implantação porque sticky sessions pareciam uma armadilha, esta é a mudança que você estava esperando.
Este artigo detalha a especificação MCP stateless, o que servidores stateless vs stateful significam na prática e, o mais importante, o que acontece com o estado de que suas ferramentas ainda precisam. Você verá os campos e headers exatos que mudaram, um checklist de migração e uma seção curta sobre como uma conexão de geração de imagens se encaixa no mesmo padrão.
O que mudou na especificação de 2026-07-28
A Agentic AI Foundation, o projeto da Linux Foundation que agora cuida do MCP, resumiu o lançamento no post de migração. Em poucas palavras: o protocolo deixou de presumir uma longa conversa entre um cliente e um servidor e passou a tratar cada chamada como uma requisição HTTP comum.
O handshake acabou
No protocolo da era 2025, a primeira coisa que o cliente fazia era negociar. A requisição initialize carregava uma versão do protocolo e uma lista de capacidades, o servidor respondia com as próprias, e o cliente confirmava com initialized. Tudo o que vinha depois dependia do que tinha sido acordado naquela conexão específica.
A nova revisão remove essa troca por completo. O servidor não constrói mais uma memória privada de cada cliente, então duas requisições do mesmo cliente podem ser respondidas por duas máquinas diferentes sem que nenhuma delas perceba.
Cada requisição carrega seu próprio contexto
Como nada é negociado antecipadamente, cada requisição se identifica sozinha. Um objeto _meta no envelope JSON-RPC carrega a versão do protocolo, a identidade do cliente e as flags de capacidade. As informações do cliente ficam assim:
O efeito prático é um servidor que lê tudo o que precisa da requisição que está na sua frente. Veja o que mudou:
Aspecto
Protocolo da era 2025
Protocolo de 2026-07-28
Acordo de versão
Negociado uma vez em initialize
Enviado em _meta em cada requisição
Identidade do cliente
Armazenada na sessão
Enviada em _meta em cada requisição
Capacidades
Negociadas no momento da conexão
Enviadas por requisição, mais uma chamada de consulta opcional
Rastreamento de sessão
Header Mcp-Session-Id
Removido
Endpoints de listagem
Podiam variar por conexão
Mesma resposta para todos os chamadores
💡 Dica: Um cliente ainda pode buscar as capacidades de um servidor logo no início, se quiser. Agora é uma chamada opcional, não um primeiro passo obrigatório.
Headers de roteamento para gateways
No Streamable HTTP, a especificação também define headers que permitem à infraestrutura rotear o tráfego sem analisar o corpo JSON:
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Um gateway pode enviar tools/call para search a um pool e todo o resto a outro, usando apenas os headers. Limitação de taxa e logs ficam mais simples pelo mesmo motivo.
O que continua igual
Nada na visão que o modelo tem do seu servidor muda. Ferramentas, recursos e prompts continuam sendo as três primitivas, as requisições continuam sendo JSON-RPC, e uma ferramenta continua recebendo argumentos e devolvendo um resultado. A diferença fica nos bastidores: os endpoints de listagem não variam mais por conexão, então tools/list devolve a mesma resposta para todos os chamadores, em vez de uma variação por sessão. Essa regra é o que torna seguro armazenar em cache a lista de ferramentas na borda.
Stateful vs stateless em termos simples
Os termos são usados de forma solta, então aqui está a definição de trabalho. Um servidor stateful mantém algo entre as requisições, e a próxima requisição só faz sentido se chegar ao mesmo lugar. Um servidor stateless não mantém nada entre as requisições, e cada requisição contém tudo o que é necessário para respondê-la.
O café que lembra de você
Imagine um café em que o barista conhece seu pedido, seu nome e o fato de que você não põe açúcar. Fazer o pedido leva três palavras, porque o contexto está na cabeça dela. Esse é um servidor stateful. É rápido e simpático, até o momento em que ela sai para o intervalo e o substituto não faz ideia de quem você é.
O correio que não precisa disso
Uma carta funciona ao contrário. O endereço, o remetente e o selo ficam todos do lado de fora, então qualquer atendente de qualquer agência consegue encaminhá-la sem ligar para ninguém. Esse é um servidor stateless, e é exatamente assim que uma requisição MCP de 2026-07-28 se comporta: versão do protocolo, identidade do cliente e capacidades viajam todas junto com a chamada.
O custo por trás de um load balancer
O transporte Streamable HTTP, introduzido na revisão de 2025-03-26, permitia que um servidor emitisse um Mcp-Session-Id durante a inicialização. O cliente o devolvia em cada requisição seguinte, e o servidor o usava para encontrar a página certa no seu livro de registro: capacidades negociadas, contexto por usuário e, às vezes, assinaturas abertas. Servidores no transporte stdio eram stateful de um jeito ainda mais simples, porque o próprio processo era a sessão.
Assim que esse livro de registro fica na memória de um único processo, o seu load balancer precisa continuar enviando o mesmo cliente para o mesmo processo. As equipes resolveram isso de duas formas. Sticky sessions desequilibram o tráfego e quebram sempre que um nó reinicia. Um armazenamento compartilhado, como o Redis, adiciona latência e um novo ponto único de falha. Nenhuma das duas opções é gratuita.
Sem sessões, qualquer requisição pode cair em qualquer instância atrás de um balanceador round-robin simples, como carros ocupando faixas idênticas de pedágio. Veja a comparação lado a lado:
Questão
Servidor stateful
Servidor stateless
Onde fica a memória?
No processo ou em um armazenamento de sessão
Na requisição, ou no seu próprio banco de dados
Load balancer
Roteamento sticky ou armazenamento compartilhado
Round robin simples
Um nó cai
As sessões daquele nó são perdidas
A próxima requisição vai para outro lugar
Escalar horizontalmente
Adicionar nós mais a infraestrutura de sessão
Adicionar nós
Depuração
Reproduzir uma sessão inteira
Reproduzir uma requisição
Adequação a serverless
Complicada
Natural
Para onde vai o seu estado agora
Tirar as sessões do protocolo não torna sua aplicação stateless. Um carrinho de compras, uma aba do navegador e um fluxo de trabalho pela metade continuam existindo. A diferença é que o estado agora fica onde deveria, no seu próprio armazenamento, e o protocolo não o esconde mais.
💡 Regra prática: Se o modelo precisar continuar algo depois, dê a ele um handle. Se o usuário precisar responder algo no meio da chamada, use uma requisição de múltiplas viagens de ida e volta. Se o trabalho for lento, use uma task.
Handles explícitos
O padrão recomendado é o que as APIs REST usam há décadas. Uma chamada de ferramenta gera um identificador e o devolve, e o modelo o envia de volta como argumento nas chamadas seguintes. A etiqueta de papel dessa cesta cumpre o mesmo papel que um basket_id.
O servidor consulta a cesta em um banco de dados a cada chamada. Qualquer instância pode atender qualquer etapa, uma reinicialização não perde nada, e o modelo pode retomar o trabalho em uma conversa totalmente nova, desde que ainda tenha o ID.
Requisições de várias idas e vindas
Às vezes, uma ferramenta precisa de uma confirmação no meio do caminho, como "excluir estes 40 arquivos?". Em um mundo de sessões, o servidor pausaria e esperaria com uma conexão aberta. Pela SEP-2322, a resposta, em vez disso, traz resultType: "input_required" e um token opaco requestState. O cliente repete a mesma chamada com as respostas em inputResponses.
Como o progresso vai dentro desse token, qualquer instância que receba a repetição pode continuar exatamente de onde a anterior parou.
Tasks para trabalhos lentos
Trabalhos longos seguem o modelo do tíquete de retirada. Com a extensão Tasks (SEP-2663), o cliente recebe um taskId imediatamente e consulta tasks/get até o trabalho terminar. A chamada fica desacoplada da sua execução, então uma renderização de dez minutos nunca mantém uma conexão aberta, e cada consulta pode chegar a qualquer instância.
Situação
Padrão
O que viaja entre as chamadas
Trabalho que continua depois
Handle explícito
Um ID como basket_id
Confirmação no meio da chamada
Requisição de múltiplas viagens de ida e volta
requestState e inputResponses
Trabalho que leva minutos
Extensão Tasks
Um taskId para consultar
Migrar um servidor sem dor de cabeça
Audite o que você armazena
Comece encontrando todos os pontos em que seu servidor se lembra de algo sobre um cliente entre as requisições. Os suspeitos habituais:
Contexto de autenticação salvo no momento de initialize
Caches por sessão ou contadores de limite de taxa mantidos na memória
Verificações de capacidade que leem flags negociadas em vez de _meta
Listas de ferramentas que mudam conforme quem se conectou
Assinaturas presas a uma conexão aberta
Cada um precisa de um novo lar: a própria requisição, seu banco de dados ou um handle explícito.
Use o codemod do SDK
O SDK v2 para TypeScript se divide em pacotes específicos para cada lado e traz um codemod para as mudanças mecânicas:
Os SDKs v2 continuam falando o protocolo da era 2025 por padrão, e servir 2026-07-28 é algo que você ativa explicitamente. Isso permite enviar primeiro a mudança de código e acionar a troca de protocolo quando seus clientes estiverem prontos. A linha v1.x continua recebendo correções de bugs e de segurança por pelo menos seis meses após o lançamento da v2.
Fique de olho no cronograma de descontinuação
Os mantenedores prometem pelo menos doze meses entre a descontinuação e a remoção, e a data mais cedo para remover recursos descontinuados é 28 de julho de 2027. Os textos de migração listam Roots, Sampling e Logging entre os recursos descontinuados (SEP-2577), com os fluxos iniciados pelo servidor passando para requisições de múltiplas viagens de ida e volta. Planeje o trabalho, mas não é uma emergência.
A segurança fica mais rigorosa
Uma sessão permitia que o servidor dissesse "este cliente fez login antes". Esse atalho desaparece. Toda requisição precisa carregar credenciais, e toda requisição precisa ser verificada. Se o custo da validação preocupa você, mantenha o resultado na memória por alguns segundos, mas nunca confie em uma requisição só porque a anterior pareceu correta.
Torne os handles impossíveis de adivinhar. Um handle é apenas um ID, e IDs são alvos clássicos de ataque. b_47f2 funciona em um diagrama. Em produção, gere valores longos e aleatórios, armazene o dono ao lado do registro e verifique, em cada chamada, se quem chama é dono do handle. Expire os que você não usa mais.
Os novos headers de roteamento também ajudam aqui. Como Mcp-Method e Mcp-Name ficam visíveis sem abrir o corpo, um gateway pode aplicar uma política por ferramenta, como limites de taxa mais rígidos para uma ferramenta de pagamento ou uma lista de permissões para uma ferramenta destrutiva, antes que a requisição chegue ao seu código. A defesa em profundidade fica mais fácil quando a camada externa consegue ler a etiqueta do envelope.
💡 Regra prática: Trate cada handle como um parâmetro de URL público. Presuma que alguém vai tentar o próximo.
Vale a pena passar para stateless?
Para a maioria dos servidores, sim. Consultas somente leitura, CRUD sobre um banco de dados, busca e qualquer coisa que encapsule uma API REST não têm nada para lembrar, então a mudança consiste sobretudo em apagar código. Você ganha implantações mais simples, um encaixe natural em plataformas serverless e falhas que atingem uma única requisição em vez de uma conversa inteira.
Algumas ferramentas mantêm algo ativo: uma página do navegador, um shell, uma renderização em andamento. Mantenha esse estado, mas guarde-o atrás de um handle com expiração, em um armazenamento que todas as instâncias consigam alcançar. O protocolo é stateless. Seu backend não precisa ser.
Um teste rápido mostra o quanto um servidor está pronto. Escolha qualquer requisição em andamento, derrube a instância que a está tratando e repita a mesma chamada em outra instância. Se a resposta for idêntica, você é stateless onde importa. Se a repetição falhar, pedir ao cliente que recomece ou devolver algo sutilmente diferente, ainda existe um livro de registro escondido na memória, e esse é o código que você deve mover primeiro para um banco de dados ou para trás de um handle.
Tipo de servidor
Melhor encaixe
Por quê
Consultas de dados somente leitura
Totalmente stateless
Nada para lembrar
CRUD de banco de dados
Stateless, com o ID do registro como handle
O banco de dados já guarda a verdade
Controle de navegador ou shell
Protocolo stateless, backend stateful
O recurso ativo fica atrás de um handle com expiração
Renderizações longas e trabalhos em lote
Extensão Tasks
A consulta substitui as conexões abertas
Gerar imagens via MCP
O MCP também é como os assistentes chegam a ferramentas criativas, e a geração de imagens é um exemplo limpo do padrão de handles. A PicassoIA expõe seus modelos por meio de uma API para desenvolvedores e de uma conexão MCP. A API fica em https://api.picassoia.com/v1, usa um Bearer token que começa com pia_sk_ e segue um layout no estilo Replicate: POST /v1/models/{owner}/{name}/predictions para iniciar um trabalho, GET /v1/predictions/{id} para verificá-lo e POST /v1/predictions/{id}/cancel para interrompê-lo.
IDs de predição também são handles
A geração é assíncrona. Iniciar um trabalho devolve um ID de predição na hora, e o assistente chama a ferramenta de status com esse ID depois da espera sugerida, de novo e de novo, até o status aparecer como succeeded ou failed. Nenhuma conexão aberta fica ociosa enquanto a GPU trabalha, e o ID carrega toda a continuidade. É o padrão basket_id aplicado a pixels.
Alguns limites valem a pena conhecer ao planejar um fluxo de trabalho: 5 predições simultâneas por conta, compartilhadas entre tokens e conexões MCP, prompts de até 4.000 caracteres e um tempo limite de 3 horas por trabalho.
Modelos que você pode chamar
Estes quatro modelos estão disponíveis tanto pela API quanto pela conexão MCP:
As fotos deste artigo vieram do P Image, um dos muitos modelos de texto para imagem da plataforma. Ao escrever as descrições de ferramentas e os esquemas JSON que o seu próprio servidor MCP vai expor, um modelo de linguagem economiza tempo. Claude Sonnet 5, GPT 5.6 Sol e Gemini 3.5 Flash estão todos disponíveis para redigir e revisar esse tipo de texto estruturado.
Sua vez: crie imagens com a Picasso IA
Agora você viu o quadro completo: sessões fora, handles dentro, qualquer instância pode responder a qualquer requisição. A forma mais rápida de sentir o padrão é usá-lo. Abra a Picasso IA, escolha um modelo de texto para imagem e escreva um prompt para a cena que você gostaria que o seu próprio diagrama de arquitetura parecesse. Experimente um café aconchegante, uma praça de pedágio movimentada ou uma fileira silenciosa de servidores, depois mude um detalhe de cada vez e veja como o resultado muda.
Quando estiver pronto para mais, explore todos os modelos na página de todos os modelos, transforme uma imagem favorita em um clipe curto com um modelo de vídeo e continue experimentando. Cada prompt que você escreve é uma pequena requisição que carrega tudo o que precisa, e isso é exatamente o ponto desta especificação.