MCP: Quais os componentes da arquitetura do protocolo

Entenda em detalhes a arquitetura do MCP, seus componentes fundamentais e a forma como eles trabalham juntos para criar experiências de IA mais ricas e contextualizadas

O Model Context Protocol (MCP) representa uma evolução significativa na forma como aplicações de IA interagem com fontes de dados e ferramentas externas. Neste artigo, vamos explorar em detalhes a arquitetura do MCP, seus componentes fundamentais e como eles trabalham juntos para criar experiências de IA mais ricas e contextualizadas.

O que está incluído no escopo do MCP?

O Model Context Protocol é composto por diferentes projetos que trabalham em conjunto:

  • MCP Specification: Uma especificação completa que define os requisitos de implementação para clientes e servidores

  • MCP SDKs: Kits de desenvolvimento para diferentes linguagens de programação que implementam o protocolo

  • Ferramentas de desenvolvimento: Incluindo o MCP Inspector, que auxilia no desenvolvimento de servidores e clientes

  • Implementações de referência: Exemplos de servidores MCP que servem como base para novos desenvolvimentos

É importante destacar que o MCP foca exclusivamente no protocolo para troca de contexto. Ele não determina como as aplicações de IA utilizam os LLMs ou gerenciam o contexto fornecido - essa flexibilidade permite que diferentes aplicações implementem suas próprias estratégias.

Entendendo os participantes do ecossistema MCP

Arquitetura cliente-servidor

O MCP segue uma arquitetura cliente-servidor onde um MCP Host - uma aplicação de IA como Claude Code ou Claude Desktop - estabelece conexões com um ou mais servidores MCP. Para cada servidor, o host cria um cliente MCP dedicado que mantém a conexão.

Os principais participantes são:

Participante

Função

MCP Host

A aplicação de IA que coordena e gerencia múltiplos clientes MCP

MCP Client

Componente que mantém conexão com um servidor MCP e obtém contexto para o host

MCP Server

Programa que fornece contexto aos clientes MCP

Servidores locais vs remotos

Um ponto importante: o termo "servidor MCP" refere-se ao programa que serve dados de contexto, independente de onde ele executa. Existem duas categorias principais:

Servidores locais: Executam na mesma máquina que o cliente, usando o transporte STDIO. Um exemplo é o filesystem server que o Claude Desktop pode iniciar localmente.

Servidores remotos: Executam em infraestrutura remota e usam o transporte Streamable HTTP. O servidor MCP oficial da Sentry é um exemplo desse tipo.

As duas camadas fundamentais do MCP

A arquitetura do MCP é organizada em duas camadas distintas que trabalham em conjunto:

Data layer: o cérebro do protocolo

A data layer implementa um protocolo de troca baseado em JSON-RPC 2.0 que define a estrutura e semântica das mensagens. Esta camada inclui:

Gerenciamento de ciclo de vida: Controla a inicialização da conexão, negociação de capacidades e encerramento entre clientes e servidores.

Recursos do servidor: Permite que servidores forneçam:

  • Tools: Funções executáveis para ações de IA

  • Resources: Dados de contexto

  • Prompts: Templates de interação

Recursos do cliente: Permite que servidores solicitem:

  • Sampling: Completions do modelo de linguagem

  • Elicitation: Input adicional do usuário

  • Logging: Registro de mensagens

Recursos utilitários: Suporta capacidades adicionais como notificações em tempo real e rastreamento de progresso.

Transport layer: a infraestrutura de comunicação

A transport layer gerencia os canais de comunicação e autenticação entre clientes e servidores. O MCP suporta dois mecanismos de transporte:

STDIO transport: Usa streams de entrada/saída padrão para comunicação direta entre processos locais, oferecendo performance ótima sem overhead de rede.

Streamable HTTP transport: Usa HTTP POST para mensagens cliente-servidor com suporte opcional para Server-Sent Events. Este transporte possibilita comunicação com servidores remotos e suporta métodos padrão de autenticação HTTP, incluindo bearer tokens, API keys e headers customizados.

A camada de transporte abstrai os detalhes de comunicação da camada de protocolo, permitindo que o mesmo formato de mensagem JSON-RPC 2.0 funcione em todos os mecanismos de transporte.

Protocolo da data layer: onde a mágica acontece

O núcleo do MCP está na definição do schema e semântica entre clientes e servidores. Esta é provavelmente a parte mais interessante para desenvolvedores, pois define as formas de compartilhar contexto.

Gerenciamento de ciclo de vida

O MCP é um protocolo stateful que requer gerenciamento de ciclo de vida. O propósito é negociar as capacidades que cliente e servidor suportam. Clientes e servidores enviam requisições um ao outro e respondem adequadamente, enquanto notificações podem ser usadas quando nenhuma resposta é necessária.

Primitives: os blocos de construção do MCP

As primitives do MCP são o conceito mais importante do protocolo. Elas definem o que clientes e servidores podem oferecer um ao outro, especificando os tipos de informação contextual que podem ser compartilhados com aplicações de IA.

Primitives do servidor

O MCP define três primitives principais que servidores podem expor:

Tools: Funções executáveis que aplicações de IA podem invocar para realizar ações, como operações de arquivo, chamadas de API ou consultas a banco de dados.

Resources: Fontes de dados que fornecem informação contextual, como conteúdo de arquivos, registros de banco de dados ou respostas de API.

Prompts: Templates reutilizáveis que ajudam a estruturar interações com modelos de linguagem, incluindo system prompts e exemplos few-shot.

Cada tipo de primitive possui métodos associados para descoberta (*/list), recuperação (*/get) e, em alguns casos, execução (tools/call). Esta estrutura permite que as listagens sejam dinâmicas.

Exemplo prático: Considere um servidor MCP que fornece contexto sobre um banco de dados. Ele pode expor:

  • Tools para consultar o banco

  • Resource contendo o schema do banco

  • Prompt com exemplos few-shot para interagir com as tools

Primitives do cliente

O MCP também define primitives que clientes podem expor, permitindo interações mais ricas:

Sampling: Permite que servidores solicitem completions de modelos de linguagem do cliente, mantendo independência de modelo.

Elicitation: Permite que servidores solicitem informações adicionais dos usuários ou confirmação de ações.

Logging: Habilita servidores a enviarem mensagens de log para clientes para debugging e monitoramento.

Primitives utilitárias

Além das primitives de servidor e cliente, o protocolo oferece primitives utilitárias cross-cutting:

Tasks (Experimental): Wrappers de execução durável que habilitam recuperação adiada de resultados e rastreamento de status para requisições MCP, como computações caras, automação de workflow e operações multi-etapa.

Sistema de notificações em tempo real

O protocolo suporta notificações em tempo real para habilitar atualizações dinâmicas entre servidores e clientes. Por exemplo, quando as tools disponíveis de um servidor mudam, ele pode enviar notificações de atualização para informar clientes conectados sobre essas mudanças.

As notificações são enviadas como mensagens JSON-RPC 2.0 (sem esperar resposta) e permitem que servidores MCP forneçam atualizações em tempo real.

Exemplo prático: ciclo completo de interação MCP

Vamos acompanhar um exemplo passo a passo de interação cliente-servidor, focando no protocolo da data layer.

Passo 1: Inicialização e negociação de capacidades

O MCP começa com gerenciamento de ciclo de vida através de um handshake de negociação de capacidades. O cliente envia uma requisição initialize:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "elicitation": {}
    },
    "clientInfo": {
      "name": "example-client",
      "version": "1.0.0"
    }
  }
}

O servidor responde com suas próprias capacidades:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": {
        "listChanged": true
      },
      "resources": {}
    },
    "serverInfo": {
      "name": "example-server",
      "version": "1.0.0"
    }
  }
}

Entendendo a troca de inicialização:

  1. Negociação de versão do protocolo: O campo protocolVersion garante compatibilidade entre cliente e servidor

  2. Descoberta de capacidades: O objeto capabilities permite que cada parte declare quais recursos suporta

  3. Troca de identidade: Os objetos clientInfo e serverInfo fornecem identificação para debugging

Neste exemplo:

  • O cliente declara suporte para elicitation (pode receber chamadas elicitation/create)

  • O servidor declara suporte para tools com listChanged: true (pode enviar notificações tools/list_changed) e resources

Passo 2: Descoberta de tools

Após estabelecer a conexão, o cliente pode descobrir tools disponíveis enviando uma requisição tools/list:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

O servidor responde com metadados completos sobre cada tool:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "weather_current",
        "title": "Get Current Weather",
        "description": "Retrieves current weather information for a specified location",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name or coordinates"
            },
            "units": {
              "type": "string",
              "enum": ["metric", "imperial"],
              "default": "metric"
            }
          },
          "required": ["location"]
        }
      }
    ]
  }
}

Compreendendo a resposta de descoberta:

Cada objeto de tool inclui campos-chave:

  • name: Identificador único para a tool

  • title: Nome legível para exibir aos usuários

  • description: Explicação detalhada da tool

  • inputSchema: JSON Schema definindo parâmetros esperados

Passo 3: Execução de tool

O cliente pode executar uma tool usando o método tools/call:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "weather_current",
    "arguments": {
      "location": "San Francisco",
      "units": "imperial"
    }
  }
}

A resposta demonstra o sistema flexível de conteúdo do MCP:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Current weather in San Francisco:\nTemperature: 72°F\nConditions: Partly cloudy\nHumidity: 65%"
      }
    ]
  }
}

Elementos-chave da execução:

  • O array content permite respostas multi-formato (texto, imagens, resources)

  • Cada objeto de conteúdo tem um campo type

  • A resposta fornece informação acionável que a aplicação de IA pode usar como contexto

Passo 4: Atualizações em tempo real via notificações

Quando as tools disponíveis do servidor mudam, ele pode notificar proativamente os clientes conectados:

{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed"
}

Recursos-chave das notificações MCP:

  • Sem resposta requerida (não há campo id)

  • Baseado em capacidades (apenas servidores que declararam listChanged: true)

  • Orientado a eventos (o servidor decide quando enviar)

Ao receber esta notificação, o cliente tipicamente reage solicitando a lista atualizada de tools, criando um ciclo de refresh que mantém o entendimento atual.

Como isso funciona em aplicações de IA reais

Durante a inicialização

O gerenciador de cliente MCP da aplicação de IA estabelece conexões com servidores configurados e armazena suas capacidades:

# Pseudo-código
async with stdio_client(server_config) as (read, write):
    async with ClientSession(read, write) as session:
        init_response = await session.initialize()
        if init_response.capabilities.tools:
            app.register_mcp_server(session, supports_tools=True)
        app.set_server_ready(session)

Durante a descoberta de tools

A aplicação busca tools disponíveis de todos os servidores MCP conectados e os combina em um registro unificado:

# Pseudo-código
available_tools = []
for session in app.mcp_server_sessions():
    tools_response = await session.list_tools()
    available_tools.extend(tools_response.tools)
conversation.register_available_tools(available_tools)

Durante a execução de tools

Quando o modelo de linguagem decide usar uma tool, a aplicação intercepta a chamada e a roteia para o servidor MCP apropriado:

# Pseudo-código
async def handle_tool_call(conversation, tool_name, arguments):
    session = app.find_mcp_session_for_tool(tool_name)
    result = await session.call_tool(tool_name, arguments)
    conversation.add_tool_result(result.content)

Durante notificações

Quando a aplicação recebe uma notificação sobre mudança de tools, ela atualiza imediatamente seu registro:

# Pseudo-código
async def handle_tools_changed_notification(session):
    tools_response = await session.list_tools()
    app.update_available_tools(session, tools_response.tools)
    if app.conversation.is_active():
        app.conversation.notify_llm_of_new_capabilities()

Perguntas frequentes sobre a arquitetura MCP

O MCP funciona apenas com modelos de linguagem específicos?

Não. O MCP é agnóstico em relação ao modelo de linguagem. Ele fornece o protocolo para troca de contexto, mas não determina qual LLM usar.

Posso usar MCP para conectar múltiplos servidores simultaneamente?

Sim. Um MCP host pode gerenciar conexões com múltiplos servidores MCP simultaneamente, cada um através de seu próprio cliente MCP dedicado.

Qual a diferença entre STDIO e HTTP transport?

STDIO é ideal para servidores locais com overhead zero de rede, enquanto HTTP permite servidores remotos com autenticação padrão HTTP.

As notificações são obrigatórias?

Não. Notificações são opcionais e baseadas em capacidades. Servidores declaram durante a inicialização se suportam notificações.

Conclusão

A arquitetura do Model Context Protocol oferece uma base sólida e flexível para construir aplicações de IA que precisam acessar contexto externo de forma estruturada e eficiente. Com suas duas camadas bem definidas - data layer e transport layer - e seu sistema robusto de primitives, o MCP permite que desenvolvedores criem integrações ricas entre aplicações de IA e fontes de dados diversas.

O design orientado a capacidades e o suporte para comunicação bidirecional através de notificações tornam o MCP especialmente adequado para ambientes dinâmicos onde o contexto pode mudar em tempo real. Seja você desenvolvendo um servidor MCP local para acessar o filesystem ou um servidor remoto integrado com APIs corporativas, a arquitetura do MCP fornece as ferramentas necessárias para criar experiências de IA contextualizadas e poderosas.