MCP por dentro: transportes, conexões e retornos
Atualizado em 19 de setembro de 2026
Uma explicação direta sobre MCP, JSON-RPC, stdio, Streamable HTTP e a relação com REST API, GraphQL, WebSocket e WebRPC.
MCP significa Model Context Protocol, um protocolo aberto para conectar aplicações de IA a servidores que oferecem dados e operações. Um cliente MCP consulta um catálogo de tools, lê resources e chama uma operação com argumentos validados. O contrato não muda. O servidor pode acessar um banco, uma API REST ou arquivos locais por trás da mesma interface.
A arquitetura tem três papéis. O host conversa com o modelo, como o Claude Code, e mantém um client MCP para cada conexão. Esse client conversa com um server MCP, que informa suas capacidades e executa as operações solicitadas. O server pode ser um processo local ou um serviço remoto. Roda em uma máquina que recebe chamadas e devolve respostas.
flowchart LR accTitle: Transportes do MCP accDescr: Comparação entre stdio e Streamable HTTP para transportar mensagens JSON-RPC até um server MCP. H[Host<br/>Claude Code] --> C[Client MCP] C -->|JSON-RPC| T1[stdio] C -->|POST /mcp| T2[Streamable HTTP] T1 --> S[Server MCP] T2 --> S
As peças da comunicação
JSON-RPC é o formato de cada mensagem. Ele define campos como jsonrpc, id, method, params, result e error, e o client usa esses campos para associar uma resposta à requisição correta.
Em HTTP, a mensagem JSON-RPC vai no corpo da requisição, também chamado payload. Em stdio, o mesmo objeto passa pelo stdin. O objeto contém os campos que organizam a comunicação, enquanto os dados da operação ficam dentro de params ou result.
O transporte leva a mensagem até o outro processo. MCP define transportes como stdio e Streamable HTTP, e em ambos os casos a mensagem segue o formato JSON-RPC.
Uma chamada para a tool buscarPokemon pode ser enviada ao server assim:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "buscarPokemon",
"arguments": {
"nomeOuNumero": "25"
}
}
}
O method informa a operação do MCP, params carrega o nome da tool e seus argumentos, e id liga a resposta à requisição. O transporte apenas entrega essa mensagem ao servidor.
O server mantém o mesmo id no retorno e coloca o resultado em result:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"content": [
{
"type": "text",
"text": "Pikachu tem 0,4 m e pesa 6 kg."
}
],
"isError": false
}
}
O MCP organiza o conteúdo retornado em content, que pode conter texto ou outros tipos previstos pelo protocolo. isError: true indica que a tool falhou, mesmo quando a mensagem chegou corretamente ao servidor.
O ciclo de uma chamada
O client inicia a conexão e negocia as capacidades do server. Depois consulta as tools disponíveis, entrega os schemas ao modelo e transforma a escolha do modelo em uma chamada MCP.
sequenceDiagram accTitle: Sequência de uma chamada MCP accDescr: Sequência de uma chamada MCP entre client, modelo e server. participant C as Client MCP participant M as Modelo participant S as Server MCP C->>S: initialize S-->>C: capacidades C->>S: tools/list S-->>C: tools e schemas C->>M: prompt e schemas M-->>C: tool_use C->>S: tools/call S-->>C: content ou erro C->>M: tool_result
O fluxo tem estas etapas:
initializenegocia a versão e as capacidades da conexãotools/listpede ao server a lista de tools e seus schemas- O client entrega o prompt e os schemas ao modelo
- O modelo escolhe uma tool e devolve
tool_useao client - O client envia
tools/callao server - O server retorna
contentou um erro - O client entrega o
tool_resultao modelo
tool_use é a decisão do modelo. O client converte essa decisão em tools/call, a chamada que chega ao server. O server valida os argumentos, executa a função e monta o retorno que volta ao modelo como tool_result.
Stdio para processos locais
No transporte stdio, o host inicia o server como subprocesso e mantém os canais padrão abertos:
stdinleva mensagens do client ao serverstdoutleva mensagens do server ao clientstderrrecebe logs e diagnósticos
O mcp-pokeapi usa o SDK oficial do MCP e começa com StdioServerTransport:
const servidor = new McpServer({
name: 'mcp-pokeapi',
version: '1.0.0',
})
const transporte = new StdioServerTransport()
await servidor.connect(transporte)
console.error('mcp-pokeapi pronto via stdio')
O stdout fica reservado para JSON-RPC, portanto um console.log misturado às mensagens pode quebrar a comunicação. O log vai para stderr.
Esse modelo funciona bem quando o host e o server estão na mesma máquina, pois o host controla o processo e não precisa publicar uma porta TCP. Para compartilhar o server entre máquinas, o client precisa de outro transporte.
Streamable HTTP para servidores remotos
Streamable HTTP usa um endpoint MCP, em geral /mcp, que aceita POST e pode responder como JSON ou como fluxo SSE. O client envia cada mensagem JSON-RPC em um POST. O server responde com um objeto JSON de uma vez ou transmite eventos, quando a operação produz mensagens ao longo do tempo.
No mcp-pokeapi, o transporte continua sendo stdio dentro do container publicado como psatin/mcp-pokeapi:1.0.0. Um server HTTP precisa de uma implementação diferente, com listener, porta e configuração de bind.
O endereço 0.0.0.0 costuma ser usado dentro de um container que recebe tráfego pela porta publicada, enquanto uma execução local deve preferir 127.0.0.1. Um endpoint remoto também precisa de autenticação, TLS e validação de Origin.
O formato HTTP+SSE com /sse e /messages aparece em servers antigos. Clientes novos usam Streamable HTTP no endpoint /mcp, que substituiu o transporte HTTP+SSE legado na especificação atual.
Retornos e erros
Uma resposta curta pode sair como application/json:
HTTP/1.1 200 OK
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"content": [
{
"type": "text",
"text": "ok"
}
]
}
}
Uma execução que produz notificações pode sair como text/event-stream, mantendo mensagens JSON-RPC dentro dos eventos SSE. O HTTP organiza a conexão, e o MCP define o significado dessas mensagens.
Os erros aparecem em pontos diferentes da cadeia:
- Timeout e conexão recusada indicam falha de transporte
- JSON inválido e método inexistente indicam falha de protocolo
- Um Pokémon inexistente indica falha da tool, que pode retornar
isError: true
No mcp-pokeapi, o schema do Zod rejeita uma entrada vazia antes da chamada à PokeAPI. Um nome inexistente retorna uma mensagem de erro da tool, e um timeout do fetch também aparece como isError: true.
MCP e REST API
Numa REST API, o contrato passa por endpoints, verbos HTTP, parâmetros e regras de autenticação conhecidos de antemão pela aplicação cliente. Um cliente chama GET /books/123 ou POST /loans porque essa interface foi documentada e o código foi escrito para ela.
MCP acrescenta um contrato comum para clientes de IA. O client pode descobrir tools, resources e prompts quando abre a conexão, sem precisar conhecer previamente os endpoints internos do serviço.
| Aspecto | REST API | MCP |
|---|---|---|
| Objetivo | Integrar aplicações e serviços | Expor contexto e operações para clientes de IA |
| Descoberta | Documentação ou schema publicado | Catálogos consultados durante a conexão |
| Contrato | Endpoints, verbos, payloads e autenticação variam por API | JSON-RPC, primitivas MCP e schemas seguem um padrão comum |
| Chamada | GET, POST, PUT, DELETE e respostas HTTP | tools/call, resources/read, prompts/get e retornos MCP |
| Implementação | Recebe chamadas de aplicações | Pode encapsular uma ou várias APIs existentes |
Um server MCP pode receber tools/call para buscarPedido, validar os argumentos e chamar internamente GET /orders/{id}. O client de IA enxerga uma tool com schema conhecido, enquanto a API de pedidos continua atendendo o site e o aplicativo móvel.
Essa composição transforma o server MCP em um adaptador para clientes de IA. A API existente continua sendo útil, e o modelo recebe uma interface que consegue descobrir e usar com argumentos estruturados.
Onde entram GraphQL, WebSocket e WebRPC
flowchart LR accTitle: Camadas e alternativas de comunicação accDescr: O diagrama separa contrato, transporte e alternativas web ao comparar MCP, JSON-RPC, HTTP, GraphQL, WebSocket e WebRPC. C[Contrato<br/>MCP e JSON-RPC<br/>tools, resources, prompts] --> T[Transporte<br/>stdio ou Streamable HTTP<br/>caminho dos bytes] T --> A[Alternativas web<br/>REST, GraphQL,<br/>WebSocket e WebRPC]
HTTP define métodos, cabeçalhos, códigos de status e corpos. REST organiza recursos em URLs e verbos HTTP. GraphQL define consultas e mutações a partir de um schema, em geral sobre HTTP.
WebSocket mantém um canal bidirecional persistente. O canal resolve o envio contínuo entre client e server, porém a aplicação ainda precisa definir nomes de operações, schemas de entrada e formato de erro.
WebRPC aproxima uma chamada remota de uma chamada de função, gerando clientes e servers a partir de um schema. A diferença está no objetivo. WebRPC conecta aplicações entre si, enquanto MCP padroniza a conexão entre hosts de IA e servers que oferecem tools, resources e prompts.
GraphQL, WebRPC ou REST podem ficar atrás de um server MCP. Uma tool chama o serviço interno, converte a resposta para o formato MCP e entrega ao client de IA um retorno que segue o mesmo contrato das outras tools.
O Docker distribui o server
O mcp-pokeapi foi publicado em linux/amd64 e linux/arm64 como psatin/mcp-pokeapi:1.0.0:
docker run -i --rm psatin/mcp-pokeapi:1.0.0
O -i mantém a entrada padrão aberta. Sem essa opção, um server stdio pode encerrar ao perceber que não há stdin disponível. Na primeira vez que rodei o container sem essa flag, o server saía antes de qualquer log aparecer, e levei um tempo para perceber que faltava justamente o -i.
O Docker resolve a distribuição e o isolamento do processo. Ele não transforma stdio em HTTP. Para HTTP, o server precisa subir um listener e publicar uma porta.
Um critério para escolher
Stdio funciona bem quando o host e o server estão na mesma máquina e o host consegue iniciar o processo. Streamable HTTP entra quando o server precisa atender clients remotos, compartilhar uma instância entre eles ou ficar atrás de proxy e autenticação.
Para contratos entre serviços da própria aplicação, REST, GraphQL ou WebRPC ainda servem. MCP faz sentido quando um cliente de IA precisa descobrir operações e oferecê-las ao modelo com schemas. Quando o sistema precisa de um fluxo bidirecional persistente, use WebSocket.
O transporte cuida do caminho dos bytes. JSON-RPC dá forma à mensagem. MCP determina as operações que o client de IA pode descobrir e chamar.