Phase 13 - Lesson 06

Fundamentos do MCP — Primitivos, Ciclo de Vida, Base JSON-RPC

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Cada integração antes do MCP era única. O Model Context Protocol, lançado originalmente pela Anthropic em novembro de 2024 e agora sob a tutela da Agentic AI Foundation da Linux Foundation, padroniza a descoberta e a invocação para que qualquer cliente possa se comunicar com qualquer servidor. A especificação 2025-11-25 define seis primitivos (três do servidor, três do cliente), um ciclo de vida de três fases e um formato de transmissão JSON-RPC 2.0. Ao aprender esses conceitos, o restante do capítulo de MCP desta fase se tornará apenas leitura de documentação.

Tipo: Aprender Linguagens: Python (stdlib, parser JSON-RPC) Pré-requisitos: Fase 13 · 01 a 05 (a interface de ferramentas e chamada de funções) Tempo: ~45 minutos

Objetivos de Aprendizado

  • Nomear todos os seis primitivos do MCP (ferramentas, recursos e prompts no servidor; raízes, amostragem e elicitação no cliente) e dar um caso de uso para cada um.
  • Explicar o ciclo de vida de três fases (inicialização, operação e encerramento) e indicar quem envia cada mensagem em cada fase.
  • Analisar e emitir envelopes de requisição, resposta e notificação do JSON-RPC 2.0.
  • Explicar o que é a negociação de capacidades na fase de initialize e o que deixa de funcionar sem ela.

O Problema

Antes do MCP, cada agente que utilizava ferramentas tinha seu próprio protocolo. O Cursor tinha um sistema de ferramentas similar ao formato do MCP, mas incompatível. O Claude Desktop foi lançado com outro diferente. A extensão Copilot do VS Code tinha um terceiro. Uma equipe que criasse uma ferramenta de "consulta Postgres" precisava escrevê-la três vezes, cada uma para a API de um host diferente. Reutilizá-la exigia copiar código.

O resultado foi uma explosão cambriana de integrações únicas e um teto para a velocidade de evolução do ecossistema.

O MCP resolve isso padronizando o formato de transmissão. Um único servidor MCP funciona em qualquer cliente MCP: Claude Desktop, ChatGPT, Cursor, VS Code, Gemini, Goose, Zed, Windsurf e mais de 300 clientes até abril de 2026. Mais de 110 milhões de downloads mensais de SDKs. Mais de 10.000 servidores públicos. A Linux Foundation assumiu a tutela em dezembro de 2025 sob a nova Agentic AI Foundation.

A revisão da especificação utilizada nesta fase é a 2025-11-25. Ela adiciona Tasks assíncronas (SEP-1686), elicitação em modo URL (SEP-1036), amostragem com ferramentas (SEP-1577), consentimento de escopo incremental (SEP-835) e semântica de indicador de recursos do OAuth 2.1. As lições da Fase 13 · 09 a 16 cobrem essas extensões. Esta lição foca apenas na base.

O Conceito

Três primitivos do servidor

  1. Ferramentas. Ações chamáveis. O mesmo ciclo de quatro etapas da Fase 13 · 01.
  2. Recursos. Dados expostos. Conteúdo somente leitura endereçável por URI: file:///path, db://query/..., esquemas personalizados.
  3. Prompts. Templates reutilizáveis. Comandos de barra na interface do host; o servidor fornece o template e o cliente preenche os argumentos.

Três primitivos do cliente

  1. Raízes. O conjunto de URIs que o servidor tem permissão para acessar. O cliente as declara; o servidor as respeita.
  2. Amostragem. O servidor solicita ao modelo do cliente para realizar uma conclusão. Permite loops de agentes hospedados no servidor sem chaves de API no lado do servidor.
  3. Elicitação. O servidor solicita informações estruturadas ao usuário do cliente durante a execução. Formulários ou URLs (SEP-1036).

Cada capacidade no MCP pertence a exatamente um desses seis primitivos. As lições da Fase 13 · 10 a 14 cobrem cada uma delas em detalhes.

Formato de transmissão: JSON-RPC 2.0

Cada mensagem é um objeto JSON com estes campos:

  • Requisições: {jsonrpc: "2.0", id, method, params}.
  • Respostas: {jsonrpc: "2.0", id, result | error}.
  • Notificações: {jsonrpc: "2.0", method, params} — sem id, nenhuma resposta é esperada.

A especificação base tem aproximadamente 15 métodos, agrupados por primitivo. Os mais importantes são:

  • initialize / initialized (handshake)
  • tools/list, tools/call
  • resources/list, resources/read, resources/subscribe
  • prompts/list, prompts/get
  • sampling/createMessage (servidor para cliente)
  • notifications/tools/list_changed, notifications/resources/updated, notifications/progress

Ciclo de vida de três fases

Fase 1: inicialização.

O cliente envia initialize com suas capabilities e clientInfo. O servidor responde com suas próprias capabilities, serverInfo e a versão da especificação que utiliza. O cliente envia notifications/initialized quando tiver processado a resposta. A partir deste ponto, ambos os lados podem enviar requisições de acordo com as capacidades negociadas.

Fase 2: operação.

Bidirecional. O cliente chama tools/list para descobrir e tools/call para invocar. O servidor pode enviar sampling/createMessage se tiver declarado essa capacidade. O servidor pode enviar notifications/tools/list_changed quando seu conjunto de ferramentas for alterado. O cliente pode enviar notifications/roots/list_changed quando o usuário alterar o escopo raiz.

Fase 3: encerramento.

Qualquer um dos lados fecha o transporte. Não há um método estruturado de encerramento no MCP; o transporte (stdio ou HTTP com Stream, Fase 13 · 09) carrega o sinal de fim de conexão.

Negociação de capacidades

As capabilities no handshake initialize formam o contrato. Exemplo de um servidor:

{
  "tools": {"listChanged": true},
  "resources": {"subscribe": true, "listChanged": true},
  "prompts": {"listChanged": true}
}

O servidor declara que pode emitir notificações tools/list_changed e suporta resources/subscribe. O cliente concorda declarando as suas próprias:

{
  "roots": {"listChanged": true},
  "sampling": {},
  "elicitation": {}
}

Se o cliente não declarar sampling, o servidor não deve chamar sampling/createMessage. O mesmo vale simetricamente: se o servidor não declarar resources.subscribe, o cliente não deve tentar se inscrever.

Isso é o que previne a fragmentação do ecossistema. Um cliente que não suporta amostragem ainda é um cliente MCP válido; um servidor que não chama sampling ainda é um servidor MCP válido. Eles apenas não utilizam esse recurso juntos.

Conteúdo estruturado e formatos de erro

tools/call retorna uma array content de blocos tipados: text, image, resource. A lição da Fase 13 · 14 adiciona MCP Apps (interface interativa ui://) a essa lista.

Os erros utilizam códigos de erro JSON-RPC. As adições definidas pela especificação são: -32002 "Resource not found", -32603 "Internal error", além de dados específicos do MCP em error.data.

Capacidades do cliente vs detalhes da chamada de ferramenta

Uma confusão comum: capabilities.tools indica se o cliente suporta notificações de alteração na lista de ferramentas. Se o cliente IRÁ chamar ferramentas específicas é uma escolha de execução guiada por seu modelo, não um sinalizador de capacidade. O sinalizador de capacidade é o contrato ao nível de especificação. A escolha do modelo é ortogonal.

Por que JSON-RPC e não REST?

O JSON-RPC 2.0 (2010) é um protocolo bidirecional leve. O REST é iniciado pelo cliente. O MCP precisava de mensagens iniciadas pelo servidor (amostragem, notificações), portanto, o JSON-RPC com seu formato simétrico de requisição/resposta foi uma escolha natural. O JSON-RPC também se integra de forma limpa sobre stdio e WebSocket/HTTP com Stream, sem precisar reinventar o formato de requisição do HTTP.

Use It

O arquivo code/main.py fornece um parser e emissor mínimo de JSON-RPC 2.0 e, em seguida, executa manualmente a sequência initializetools/listtools/callshutdown, imprimindo cada mensagem. Não há transporte real; apenas os formatos das mensagens. Compare com a especificação vinculada em Leituras Adicionais para verificar cada envelope.

O que observar:

  • initialize declara capacidades para ambos os lados; a resposta contém serverInfo e protocolVersion: "2025-11-25".
  • tools/list retorna uma array tools; cada entrada possui name, description e inputSchema.
  • tools/call utiliza params.name e params.arguments.
  • O content da resposta é uma array de blocos {type, text}.

Ship It

Esta lição produz o arquivo outputs/skill-mcp-handshake-tracer.md. Com base em uma transcrição no estilo pcap de uma interação cliente-servidor MCP, a skill anota cada mensagem com seu respectivo primitivo, fase do ciclo de vida e capacidade da qual ela depende.

Exercícios

  1. Execute code/main.py. Identifique a linha onde ocorre a negociação de capacidades e descreva o que mudaria se o servidor não declarasse tools.listChanged.

  2. Estenda o parser para lidar com notifications/progress. O formato da mensagem é: {method: "notifications/progress", params: {progressToken, progress, total}}. Emita essa notificação enquanto uma chamada tools/call de longa duração estiver em andamento e confirme se o manipulador do cliente exibiria uma barra de progresso.

  3. Leia a especificação do MCP 2025-11-25 de ponta a ponta — o documento completo tem cerca de 80 páginas. Identifique o único sinalizador de capacidade que a maioria dos servidores NÃO precisa. Dica: está relacionado à assinatura de recursos.

  4. Esboce no papel a qual primitivo pertenceria um recurso hipotético de "tarefa agendada" (cron job). (Dica: o servidor deseja que o cliente o invoque em um horário agendado. Nenhum dos seis primitivos se encaixa hoje.) O roadmap do MCP para 2026 tem uma proposta SEP preliminar para isso.

  5. Analise o log de sessão de um servidor MCP de código aberto no GitHub. Conte as mensagens de requisição, resposta e notificação. Calcule qual fração do tráfego corresponde ao ciclo de vida em comparação com a operação.

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
MCP "Model Context Protocol" Protocolo aberto para descoberta e invocação de ferramentas por modelos
Primitivo do servidor "O que um servidor expõe" ferramentas (ações), recursos (dados), prompts (templates)
Primitivo do cliente "O que um cliente permite que os servidores usem" raízes (escopo), amostragem (callbacks de LLM), elicitação (entrada do usuário)
JSON-RPC 2.0 "O formato de transmissão" Envelopes simétricos de requisição/resposta/notificação
Handshake initialize "Negociação de capacidades" Primeiro par de mensagens; servidores e clientes declaram os recursos que suportam
tools/list "Descoberta" O cliente solicita ao servidor seu conjunto de ferramentas atual
tools/call "Invocação" O cliente solicita ao servidor a execução de uma ferramenta com argumentos
notifications/*_changed "Eventos de mutação" O servidor informa ao cliente que sua lista de primitivos foi alterada
Bloco de conteúdo "Resultado tipado" `{type: "text"
SEP "Spec Evolution Proposal" Proposta preliminar nomeada de evolução da especificação (ex: SEP-1686 para Tasks assíncronas)

Leituras Adicionais

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).