Capítulo 4 — Primitivas de Cliente: Comportamentos Agênticos e Controle
Quarta postagem do passeio capítulo a capítulo pelo LLM Primer IV: Projetando a Cognição da IA com MCP. Primitivas de servidor expõem o que o servidor pode oferecer; primitivas de cliente expõem o que o host emprestará de volta — e cada empréstimo é uma capacidade que o usuário concede e um risco que o host aceita.
Por que este capítulo existe
Um servidor que só expõe resources, prompts e tools não sabe nada sobre seu host: não o modelo que roda, não os arquivos que pode ver, nem se o usuário está ao teclado. Para muitas integrações essa parede é intencional. Para categorias inteiras de comportamento útil ela é alta demais. Um servidor que precisa resumir um documento longo não deveria ter que embarcar seu próprio LLM. Um servidor que quer operar sobre um projeto deveria saber qual projeto. Um servidor que precisa de permissão do usuário para um passo destrutivo deveria poder pedir. Primitivas de cliente são como o MCP abre pequenos buracos controlados na parede.
As três primitivas — Sampling, Roots, Elicitation — cada uma estende o alcance do servidor para o território do host de modo preciso e negociado. Cada uma é também uma superfície de segurança que o host aceita em nome de seu usuário, e cada uma compõe com as outras para produzir comportamento mais agêntico que a soma das partes.
4.1 Sampling: pegando o cérebro do host emprestado
Com sampling habilitado, um servidor pode pedir ao host para rodar uma chamada de inferência e devolver o resultado. Ele não embarca modelo, não guarda chave de API, e nunca aprende qual modelo o host de fato usou — manda mensagens mais preferências leves (custo, velocidade, inteligência), e o host roda a chamada. Do ponto de vista do servidor, o host virou um endpoint LLM genérico.
A alavanca é real. Um servidor de armazenamento de documentos pode rodar pequenos passos de raciocínio dentro da própria lógica — recuperar, ranquear, comparar — sem vazar conhecimento de domínio ao host nem embarcar inferência. O risco é igualmente real. Um servidor malicioso pode usar o modelo do host — e o orçamento do usuário — para fazer trabalho que o usuário nunca aprovou. O ataque clássico é um payload de sampling disfarçado como instrução de usuário. O host é a única linha de defesa, razão pela qual hosts maduros por padrão negam sampling a menos que o usuário tenha optado por aquele servidor específico, mostram o prompt de cada chamada para inspeção, limitam chamadas por sessão, e cobram o custo contra a carteira do usuário em vez da do servidor.
Uma preocupação mais sutil: sampling pode encapsular um loop agêntico interno. Para o host parece uma chamada de sampling; dentro do servidor, um sub-agente inteiro rodou. O padrão que vale ser nomeado é o sub-agente limitado — o usuário concede um orçamento de N chamadas, T segundos, X dólares; o servidor roda o que quiser dentro desse envelope e retorna ou um resultado ou um parcial gracioso. Sampling não dá ao servidor acesso à conversa também; ele vê só o que mandou, e um host que contrabandeia contexto de conversa para payloads de sampling enfraqueceu a fronteira de confiança independentemente da intenção.
4.2 Roots: fronteiras de filesystem e escopo de projeto
Um root é uma URI — geralmente file://, embora a spec seja geral — que o host declarou como em-escopo. O servidor chama roots/list e pergunta "com o que estou trabalhando?" O host anuncia uma capacidade roots na inicialização e emite notifications/roots/list_changed quando o usuário troca de projeto. A lista é só uma lista; não há linguagem de permissão aninhada, sem padrões glob, sem regras de incluir/excluir.
A grosseria é deliberada, e reflete uma escolha de design abrangente do MCP que vale entender. Uma linguagem de permissão de granularidade fina na camada de protocolo cria falsa sensação de segurança: usuários leem uma lista longa de escopo e assumem que o protocolo a aplica, quando na verdade o protocolo não pode impedir o servidor de se comportar mal de maneiras que a linguagem nunca antecipou. Uma primitiva grosseira apoiada por isolamento externo — fronteiras de processo, montagens de container, controle de acesso no nível do SO — é honesta sobre onde a aplicação de fato mora. Roots são um sistema de honra na camada de protocolo, tornado aplicável na camada de runtime quando há sandbox em jogo.
Duas consequências práticas. Primeira, quando roots mudam, servidores bem-comportados descartam estado em cache vinculado ao root antigo — índices, ASTs parseadas, subscriptions de arquivo monitorado — ou vazam estado entre fronteiras de projeto. Segunda, roots limitam o que o servidor deveria olhar, não o que ele tem permissão para fazer. Um arquivo sensível dentro de um root concedido — um dump de credenciais, um envfile, correspondência pessoal — continua sensível, e um servidor educado ainda aplica julgamento sobre o que expõe.
4.3 Elicitation: deixar o servidor fazer uma pergunta
Elicitation é a mais nova das três e a que reflete o que os designers aprenderam da primeira onda de deploys de agentes. O servidor emite elicitation/create com uma mensagem (a pergunta) e um requestedSchema (a forma da resposta esperada). O host renderiza a pergunta na sua UI, coleta a resposta, valida-a e a retorna. O servidor retoma seu trabalho com a resposta em mãos.
O schema é o que torna elicitation mais seguro que prompts em formato livre. Um booleano não pode ser respondido com prosa; um enum não pode ser respondido com uma quarta opção. O host pode mostrar ao usuário numa UI clara que ele está sendo perguntado por um sim/não, e recusar qualquer outra coisa. A spec restringe schemas deliberadamente a objetos planos de primitivos — para formulários reais, use uma tool cujo schema de argumento seja o formulário, onde o usuário pode revisar os valores preenchidos pelo modelo antes da invocação. Elicitation é para os casos de um ou dois campos.
O perfil de risco tem formato de phishing: um servidor que expõe "o sistema requer sua chave de acesso AWS para continuar" está tentando fazer o usuário digitar um segredo no lugar errado. Hosts mitigam com atribuição clara — cada prompt de elicitation rotulado com o servidor de origem, separado da voz do assistente — e recusando schemas que pareçam ter formato de credencial. O lado positivo é o padrão de confirmação de tool destrutiva: o primeiro trabalho de uma tool é elicitar "tem certeza?" e só na confirmação ela age. Esta é uma das práticas de endurecimento MCP mais eficazes em produção.
4.4 Compondo as três
As primitivas são desenhadas para compor. Um servidor com as três tem, em efeito, um runtime de agente completo delegado ao host: ele pode ler escopo (roots), raciocinar sobre ele (sampling), fazer perguntas clarificadoras (elicitation), e agir através de suas próprias tools. As combinações importam. Sampling mais roots é um servidor de agente autônomo; sampling mais elicitation é um servidor conversacional sem alcance de filesystem; roots mais elicitation é um auxiliar determinístico. Cada um sozinho é limitado; juntos eles se multiplicam, e a UI de consentimento do host está no seu melhor quando consegue nomear a combinação que o usuário está concedendo em vez de pedir permissão para cada um isoladamente.
O que o Capítulo 4 prepara
Primitivas de servidor e primitivas de cliente entre si descrevem tudo que host e servidor podem fazer um ao outro. O que ainda não tratamos é como qualquer disso viaja pelo wire. tools/list e sampling/createMessage não são apenas mensagens abstratas — viajam num transporte, e a escolha do transporte decide silenciosamente quase toda propriedade operacional de uma integração MCP. Servidores também precisam ser encontráveis: um host que quer usar um servidor tem que saber que ele existe, onde mora, e se vale confiar na alegação. O Capítulo 5 toma ambos.
Próximo — Capítulo 5: Protocolos de Transporte e Descoberta. Os três transportes que o MCP suporta — stdio, SSE, Streamable HTTP — comparados com honestidade, e a camada .well-known/mcp.json mais Server Card que transforma integrações pontuais em algo que se parece com ecossistema.