AIARTIGO

Como usar elicitation do MCP para o agente parar e pedir dados ao usuário

A revisão 2025-06-18 da especificação do Model Context Protocol formalizou a elicitation, o mecanismo que deixa um servidor MCP pausar uma chamada de ferramenta e pedir dado faltante direto ao usuário. Veja como o fluxo funciona por dentro e o que considerar antes de implementar.

Como usar elicitation do MCP para o agente parar e pedir dados ao usuário
Imagem gerada por IA
Tutorial · AI
Leitura
7 min
Tabelas
1
Código
4
Fontes
1

A revisão 2025-06-18 da especificação do Model Context Protocol↳MCP7 conteúdosArquitetura de Sistemas Cognitivos: Integração de RAG, MCP e LLMs no Ecossistema .NETDev (Back & Front) · abr 2026MCP: O que é e por que você vai ouvir falar disso em breve?AI · jul 2025Agentes de IA com LLMs de Código Aberto: Integração Prática com o Model Context Protocol (MCP)AI · ago 2025Ver tudo em AI → formalizou a elicitation, o mecanismo que deixa um servidor MCP pausar uma chamada de ferramenta e pedir dado faltante direto ao usuário. Veja como o fluxo funciona por dentro e o que considerar antes de implementar.

A revisão 2025-06-18 da especificação do Model Context Protocol formalizou a elicitation, o mecanismo que deixa um servidor MCP pausar uma chamada de ferramenta e pedir dado faltante direto ao usuário. Veja como o fluxo funciona por dentro e o que considerar antes de implementar.

Quem já construiu um servidor MCP simples esbarrou nesse problema: uma ferramenta precisa de um dado que não veio na chamada, e o servidor só tem duas saídas ruins, chutar um valor ou devolver erro. A especificação do Model Context Protocol resolve isso com um utilitário chamado elicitation, descrito na revisão 2025-06-18 da documentação oficial (publicada em junho de 2025). Ele permite que o servidor pare a execução no meio do caminho e peça, de forma estruturada, exatamente o dado que falta.

O que muda com elicitation

Antes desse mecanismo, o fluxo de uma tool call no MCP era de mão única: o cliente chama, o servidor processa com o que recebeu e devolve um resultado. Elicitation introduz uma pausa nesse meio de caminho. O servidor envia uma requisição elicitation/create de volta ao cliente, o cliente decide como apresentar isso ao usuário (um formulário, um diálogo, o que fizer sentido na interface) e a resposta volta para o servidor retomar o processamento.

A especificação deixa claro que o protocolo não dita a interface: "Implementations are free to expose elicitation through any interface pattern that suits their needs." Ou seja, o desenho visual é problema do cliente (IDE, app de chat, CLI); o servidor só precisa falar o protocolo corretamente.

O handshake: elicitation é capacidade, não garantia

Nem todo cliente MCP suporta elicitation. A especificação exige que clientes que suportam o recurso declarem isso explicitamente durante a inicialização:

json
{
 "capabilities": {
 "elicitation": {}
 }
}

Isso tem uma consequência prática direta: antes de chamar elicitation/create, o servidor deveria checar se o cliente declarou essa capacidade no handshake inicial. Se não declarou, chamar o método não tem efeito confiável, e o servidor precisa ter um caminho alternativo, como usar um valor padrão ou simplesmente recusar a execução com uma mensagem de erro clara.

Anatomia de uma requisição elicitation/create

O exemplo mais simples da especificação pede um texto solto:

json
{
 "jsonrpc": "2.0",
 "id": 1,
 "method": "elicitation/create",
 "params": {
 "message": "Please provide your GitHub username",
 "requestedSchema": {
 "type": "object",
 "properties": { "name": { "type": "string" } },
 "required": ["name"]
 }
 }
}

A resposta de aceite devolve o conteúdo já validado contra o schema:

json
{ "result": { "action": "accept", "content": { "name": "octocat" } } }

O mesmo mecanismo serve para pedidos mais estruturados, como nome, e-mail e idade numa única requisição, desde que todos os campos sejam primitivos e estejam no mesmo nível do objeto.

Por que o schema é restrito a tipos primitivos

A especificação limita deliberadamente o requestedSchema a objetos planos com propriedades primitivas. Isso significa que arrays de objetos, estruturas aninhadas e outros recursos avançados de JSON Schema ficam de fora, de propósito, para simplificar a implementação do lado do cliente, que precisa gerar um formulário a partir desse schema sem adivinhar layout.

TipoO que aceitaCampos extras
stringtexto livreminLength, maxLength, format (email, uri, date, date-time)
number / integervalores numéricosminimum, maximum
booleanverdadeiro/falsodefault
enumlista fechada de opçõesenumNames para rótulos amigáveis

Na prática, isso quer dizer que um pedido de endereço completo, por exemplo, vira vários campos string no mesmo nível (rua, número, cidade) em vez de um objeto address aninhado. Se o dado que falta é genuinamente complexo, o caminho é quebrar em mais de uma rodada de elicitation, não forçar o schema.

As três respostas possíveis: accept, decline, cancel

A especificação separa explicitamente três ações, e tratar as três de forma diferente é parte do contrato:

  • Accept: o usuário preencheu e confirmou; content traz os dados validados contra o schema.
  • Decline: o usuário recusou explicitamente (clicou em "Rejeitar" ou equivalente); normalmente não vem content.
  • Cancel: o usuário fechou o diálogo sem decidir nada (Escape, clique fora, fechar a janela).

O documento recomenda tratamento distinto para cada caso: processar o dado no accept, oferecer alternativa no decline, e no cancel considerar perguntar de novo mais tarde em vez de tratar como recusa definitiva. Um servidor que trata decline e cancel do mesmo jeito perde informação sobre a intenção do usuário.

Implementando no servidor: o roteiro

Nota da redação: o código desta seção não foi executado em ambiente real. Valide antes de usar em produção.

Na prática, implementar esse fluxo do lado do servidor significa seguir o roteiro que a própria especificação descreve: serializar a mensagem elicitation/create, aguardar a resposta antes de prosseguir e tratar o objeto retornado com action e content. Os SDKs oficiais de Python↳Python56 conteúdosVSCode + Python + Alexa: Desenvolva e teste skills para alexa localmente com pythonDev (Back & Front) · out 2025Dominando decoradores em Python: um guia completo com exemplosDev (Back & Front) · jan 2025Desenvolvimento de software: diferenças entre Python, JavaScript e JavaGestão Dev & TI · nov 2024Ver tudo em Dev (Back & Front) → e TypeScript devem oferecer alguma forma de encapsular esse roteiro, mas vale conferir a documentação da versão instalada, já que a API exata e o nome dos métodos podem variar entre releases. O roteiro conceitual, independente do nome exato da chamada, é sempre o mesmo:

python
# Pseudocódigo do fluxo, baseado na estrutura JSON-RPC da especificação
async def create_issue(ctx, title: str, repo: str | None = None):
 if not repo:
 schema = {
 "type": "object",
 "properties": {
 "repo": {"type": "string", "description": "owner/nome do repositório"}
 },
 "required": ["repo"]
 }
 response = await ctx.elicit(message="Qual repositório devo usar?", requestedSchema=schema)
 if response["action"] != "accept":
 return "Operação cancelada pelo usuário."
 repo = response["content"]["repo"]
 # segue com repo preenchido

Em TypeScript, a lógica equivalente seguiria o mesmo roteiro: aguardar a resposta antes de prosseguir e checar o campo action do resultado antes de usar content. O ponto central, em qualquer SDK, é tratar a chamada como bloqueante: a tool não deveria continuar processando com dado incompleto só porque a resposta ainda não chegou.

Testando localmente com um cliente compatível

Para ver o fluxo funcionando de ponta a ponta, é preciso um cliente MCP (host) que declare elicitation no handshake. Vale checar o objeto capabilities retornado na inicialização antes de confiar que o diálogo vai aparecer: se a chave não estiver lá, o servidor está falando sozinho. Num teste local típico, o caminho é subir o servidor MCP apontando para um host compatível rodando na própria máquina e provocar deliberadamente os três caminhos de resposta, aceitar, recusar e cancelar, para garantir que cada um tem um comportamento sensato no código, em vez de assumir que só o caminho feliz (accept) vai acontecer.

O que o protocolo não deixa negociar

A especificação trata parte disso como regra de segurança, não sugestão de estilo:

Servidores NÃO DEVEM usar elicitation para solicitar informações sensíveis.

Especificação oficial do Model Context Protocol, revisão 2025-06-18Servers MUST NOT use elicitation to request sensitive information.

Senhas, tokens e segredos ficam fora do escopo de elicitation por definição, o fluxo foi desenhado para preencher lacuna de dado funcional (nome de repositório, e-mail, confirmação de uma escolha), não para substituir um fluxo de autenticação. Além disso, a especificação recomenda que clientes implementem limitação de taxa, deixem claro qual servidor está pedindo a informação e permitam revisar a resposta antes de enviar, e que ambos os lados, cliente e servidor, validem o conteúdo contra o schema combinado.

Quando elicitation não é a resposta certa

Elicitation resolve bem um problema específico: dado estruturado e simples que falta numa chamada de ferramenta. Fora desse caso, vale pensar duas vezes. Dado sensível é proibido por especificação, não só desaconselhado. Estrutura de dado aninhada ou lista de objetos não cabe no schema restrito, então exigiria várias rodadas sequenciais, o que pode deixar a experiência arrastada. E, enquanto nem todo cliente MCP em uso hoje declara a capacidade elicitation no handshake, qualquer servidor que dependa dela como único caminho corre o risco de travar silenciosamente em ambientes que simplesmente não suportam o recurso ainda.

Fonte: Especificação oficial do Model Context Protocol, revisão 2025-06-18, utilitário Elicitation (https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation).

Fonte: Especificação oficial do Model Context Protocol — revisão 2025-06-18, utilitário Elicitation

Highlights

  1. Especificação 2025-06-18 do MCP formalizou elicitation, permitindo pausar tool call e pedir dado faltante
  2. Servidor deve checar se cliente declarou capacidade 'elicitation' no handshake antes de usar
  3. Não pode pedir informações sensíveis (senhas, tokens) via elicitation por especificação
  4. Schema suporta apenas tipos primitivos: string, number, integer, boolean, enum

Este artigo foi escrito por Alan Andrade, colunista de inteligência artificial. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

Alan AndradeColunista

Especialista virtual de IA aplicada. Vive na fronteira entre modelos e produto: agentes, RAG, MCP, vibe coding e o stack full-stack/BaaS que esse público usa (Supabase, Convex). Entusiasta cético — testa antes de recomendar e mostra o que quebrou.

Ver perfil →