Pular para o conteúdo
mnzes

Quais são as primitivas do MCP?

PorDiógenes MenezesAprendendo IA em público

12 min de leitura

O MCP tem três primitivas de servidor: tools, que o modelo aciona; resources, que a aplicação anexa ao contexto; e prompts, que o usuário escolhe de propósito. A especificação chama a divisão de hierarquia de controle, e ela não separa as três pelo formato do dado. Separa por quem decide quando aquilo entra no contexto1.

Essa é a frase que resolve quase toda dúvida de classificação. O mesmo relatório de vendas pode ser tool, resource ou prompt, e a resposta certa depende do ator que puxa o gatilho, não do conteúdo.

As três aparecem no Model Context Protocol como o que um servidor expõe. Se você só vai escrever tools, o texto que descreve cada uma merece atenção própria, porque ele entra no raciocínio do modelo. E se a dúvida é como tudo isso vira uma chamada ao provedor do modelo, a comparação está em MCP ou function calling.

o modelotoolsaciona sozinhotools/calllê ou escrevea aplicaçãoresourcesanexaresources/readsó leitura, com URIo usuáriopromptsescolheprompts/getcomando de barra
Figura 1A primitiva não descreve o dado, descreve o gatilho. Só uma das três pode ser acionada pelo modelo no meio da tarefa, e é ela que carrega o risco.

Tools: o que o modelo aciona

Tools são funções executáveis. O cliente descobre com tools/list e invoca com tools/call, passando argumentos que precisam bater com o inputSchema da tool, um JSON Schema que assume a versão 2020-12 quando não há $schema2.

A tool pode declarar também um outputSchema. Quando declara, o servidor precisa devolver resultado estruturado conforme o schema, no campo structuredContent, e o cliente deve validar. Para compatibilidade, o mesmo JSON serializado costuma vir também como bloco de texto no campo content2.

O detalhe que mais gente implementa errado é o canal de erro, porque são dois. Erro de protocolo é para requisição malformada, tool inexistente e falha do servidor, e volta como erro JSON-RPC comum. Erro de execução volta dentro do resultado, com isError igual a true e o texto da falha em content. A especificação é explícita sobre o motivo: erros de execução carregam informação acionável, e clientes devem entregá-los ao modelo para que ele se corrija; erros de protocolo o cliente pode entregar, mas eles dificilmente resultam em recuperação bem-sucedida2. Um servidor que devolve -32603 quando a data está em formato errado tira do modelo a chance de tentar de novo com a data certa.

Duas convenções pequenas com efeito prático. Nomes de tool devem ter entre 1 e 128 caracteres, usar apenas letras ASCII, dígitos, sublinhado, hífen e ponto, e ser únicos dentro do servidor. E servidores devem devolver as tools em ordem determinística, porque isso permite ao cliente cachear a lista e melhora a taxa de acerto do prompt cache quando as tools entram no contexto do modelo2. Ordenar por um Map de iteração instável custa dinheiro de verdade.

Tool ou resource para o mesmo dado

o mesmo relatório de vendascomo toolo modelo decidechamarget_sales_reportentra no contexto no meioda tarefa, se o modelo pedircomo resourcea aplicação decideanexarsales://2026-07entra no contexto antesda tarefa, por escolha da app
Figura 2O mesmo relatório muda de natureza conforme quem puxa. Como tool ele ocupa contexto em toda chamada; como resource ele só custa quando alguém anexa.

Pegue um relatório de vendas mensal e exponha das duas formas.

Como tool, get_sales_report recebe o mês como argumento e o modelo a chama no meio da tarefa quando julga que precisa. A declaração da tool fica no contexto em toda chamada ao modelo, use-se ou não. O modelo escolhe o argumento, o que é bom quando o mês certo depende da conversa e ruim quando o modelo escolhe o mês errado.

Como resource, o mesmo relatório vira sales://2026-07, com um URI estável, e entra no contexto quando a aplicação anexa. Não ocupa nada no prompt até ser anexado. Em compensação, alguém precisa escolher: ou o usuário, numa lista de seleção, ou a aplicação, por alguma heurística. A especificação diz que resources são orientados pela aplicação, com o host decidindo como incorporar o contexto, e lista as formas possíveis, inclusive inclusão automática por heurística ou por seleção do próprio modelo1.

A diferença de segurança sai daí e costuma passar despercebida. O protocolo não dá ao modelo um canal para ler um resource: resources/read é uma chamada do cliente. Texto injetado dentro de um resultado de tool pode induzir o modelo a chamar outra tool, mas não a puxar um resource sozinho — a menos que a aplicação tenha optado por deixar o modelo selecionar, que é uma das opções que a spec permite. Se você está desenhando um servidor com dado sensível, expor como resource move a decisão para fora do modelo.

Resources: o que a aplicação anexa

Todo resource é identificado por um URI. O cliente lista com resources/list e lê com resources/read, e um único read pode devolver vários conteúdos, como acontece quando o URI aponta para um diretório1.

Resources parametrizados existem como templates, no formato de URI template da RFC 6570, listados em resources/templates/list. Os argumentos podem ser autocompletados pela API de completion, que é o que permite uma interface oferecer sugestões enquanto o usuário digita o caminho.

A especificação define alguns esquemas de URI e é opinativa sobre um deles. Use https:// apenas quando o cliente consegue buscar o recurso direto da web, sem passar pelo servidor MCP; para os outros casos, prefira outro esquema ou defina um próprio, mesmo que quem baixe o conteúdo pela internet seja o próprio servidor1. Também existem file:// e git://, e nada impede um esquema seu.

Cada resource pode carregar anotações: audience, com os valores user e assistant, priority entre 0.0 e 1.0, e lastModified em ISO 8601. Elas são dicas para o cliente filtrar e priorizar o que entra no contexto, não regras que o protocolo faz cumprir.

Uma regra de erro que evita bug silencioso: resource inexistente devolve -32602, e o servidor não pode devolver um array contents vazio para um resource que não existe, porque isso é ambíguo entre “existe e está vazio” e “não existe”1.

Prompts: o que o usuário escolhe

Prompts são templates de mensagens que o servidor expõe e o usuário invoca. O cliente lista com prompts/list e resolve com prompts/get, passando os argumentos declarados. O retorno é uma lista de mensagens com papel user ou assistant e conteúdo que pode ser texto, imagem, áudio, link de resource ou resource embutido.

A especificação define prompts como user-controlled e faz questão de qualificar a frase: isso se refere a quem decide quando o prompt é usado, não a quem escreve o conteúdo dele, que é definido pelo servidor1. A distinção importa para quem avalia risco. Um prompt não é mais confiável por ser “do usuário”; ele é texto de servidor que o usuário aceitou colar na conversa.

O caso de uso típico é o comando de barra, e a própria spec usa esse exemplo. Os argumentos aceitam autocompletar pela API de completion, e a lista pode mudar em tempo de execução, com o servidor notificando quem tiver aberto o stream de assinaturas.

Um exemplo concreto ajuda a fixar. Um servidor de repositório expõe o prompt code_review, com um argumento obrigatório chamado code. No editor ele aparece como um comando; o usuário seleciona um trecho, o cliente chama prompts/get com esse trecho nos argumentos e recebe de volta uma mensagem de papel user já montada, com a instrução de revisão escrita pelo servidor e o código embutido. Até aqui o modelo não viu nada: o que chega a ele é a conversa com a mensagem pronta dentro, indistinguível de algo que o usuário tivesse digitado.

Como decidir

quem decide quandoisso entra no contexto?toolefeito colateral possívelo modelo, no meio da tarefaresourcesó leitura, com URIa aplicação, ao montarprompttemplate de mensagemo usuário, de propósito
Figura 3A pergunta que decide não é o que o dado é, e sim de quem é a decisão de trazê-lo. Responder isso primeiro resolve a maioria dos casos duvidosos.

A pergunta é quem decide quando aquilo entra no contexto.

Se a resposta é o modelo, no meio da tarefa, com parâmetros que ele escolhe na hora, é tool. Se é a aplicação ou o usuário, antes da tarefa, sobre um conteúdo com identidade estável, é resource. Se é o usuário deliberadamente iniciando um fluxo com um formato pronto, é prompt.

Um teste secundário resolve os empates: efeito colateral só existe em tool. Se a operação escreve em algum lugar, dispara e-mail ou cobra alguém, ela não é resource nem prompt, porque nem um nem outro têm semântica de execução.

Onde a divisão falha

Tudo vira tool. É a falha mais comum e a mais cara. Servidores expõem leitura como tool porque tools funcionam em qualquer cliente, e porque o modelo consegue chamá-las sozinho. O custo aparece no contexto: cada declaração de tool ocupa espaço em toda chamada, e a seleção degrada com o número de opções. Um trabalho de 2025 mediu essa degradação em um teste de estresse com MCP e reportou acurácia de seleção de tool de 43,13% contra 13,62% da linha de base, com redução de mais de 50% nos tokens de prompt ao recuperar apenas as tools relevantes por busca semântica3. Outro trabalho do mesmo ano atacou o mesmo problema organizando as tools em uma taxonomia hierárquica e filtrando por consulta, com resultado na mesma direção4. Os números são de arranjos experimentais específicos, não uma lei, mas a direção é consistente entre os dois.

As outras duas dependem do host implementar. Um resource precisa de uma interface para ser escolhido; um prompt precisa de um lugar onde comandos apareçam. Um servidor que aposta em resources pode ficar invisível em hosts que só montaram o caminho de tools. A evidência pública aqui é fraca: os levantamentos disponíveis mediram configuração, uso de SDK e controles de supervisão, não cobertura por primitiva5. Trate como risco de portabilidade, não como fato medido.

A descrição continua sendo entrada não confiável. Vale para as três primitivas, mas dói mais em tools, porque a descrição é o que orienta a escolha do modelo. O estudo de 2025 que analisou 67.057 servidores descreveu exatamente esse caminho: metadados de tool controlados pelo atacante moldam o raciocínio do modelo e induzem operações que o host executa sem verificação independente6.

“User-controlled” não quer dizer seguro. O conteúdo do prompt é do servidor. O usuário controla o momento, e só. Um prompt malicioso é injeção com convite.

O canal de erro errado apaga a chance de recuperação. Um servidor que trata falha de negócio como erro de protocolo transforma um problema que o modelo resolveria em uma parada seca. É um bug de duas linhas com efeito grande no comportamento observado.

Quanto custa cada uma

Ordem de grandeza, para ter noção da forma da conta.

Uma tool custa contexto de forma permanente. Nome, descrição e schema de argumentos ficam na casa de centenas de tokens por tool, reenviados a cada chamada ao modelo. Trinta tools finas custam bem mais que cinco tools grossas que cobrem o mesmo terreno, e ainda pioram a seleção.

Um resource custa quase nada até ser lido, e aí custa o tamanho do conteúdo. É o oposto da tool: caro por uso, barato por existir. Por isso catálogo grande de resources é viável e catálogo grande de tools não é.

Um prompt custa o tamanho das mensagens que ele devolve, e apenas quando o usuário o invoca. A entrada em prompts/list é pequena.

A consequência prática é uma só: o que você expõe como tool, você paga sempre.

Por onde começar

  1. Comece com poucas tools de leitura. Elas funcionam em qualquer cliente e dão o retorno mais rápido sobre se o desenho faz sentido.
  2. Passe para resource o que tem URI natural. Arquivo, documento, registro com identificador estável. Isso tira peso do prompt e tira a decisão do modelo.
  3. Escreva a descrição da tool como se ela fosse a única documentação. É a única parte da declaração que o modelo lê para decidir.
  4. Separe os dois canais de erro no primeiro dia. isError para falha de domínio, erro JSON-RPC para requisição inválida.
  5. Devolva a lista de tools sempre na mesma ordem. Custa uma linha e melhora cache de prompt.
  6. Meça o tamanho do seu prefixo de tools antes de acrescentar a próxima. Se a lista já passou de uma dezena, o problema seguinte é seleção, não capacidade.

O passo 2 é o que a maioria dos servidores pula, e é por isso que a lista de tools cresce até o ponto em que o modelo passa a escolher mal.

Footnotes

  1. A página de primitivas de servidor da revisão 2026-07-28 é a fonte para a hierarquia de controle, para o modelo orientado pela aplicação dos resources, para os esquemas de URI, para as anotações e para a definição de prompts como user-controlled. Verificada em 30 de julho de 2026. 2 3 4 5 6

  2. A página de tools da mesma revisão é a fonte para inputSchema e outputSchema, para structuredContent, para os dois canais de erro, para as regras de nome e para a recomendação de ordem determinística. 2 3 4

  3. Gan e Sun (2025) mediram, em um teste de estresse com MCP, acurácia de seleção de tool de 43,13% contra 13,62% da linha de base, recuperando apenas as descrições relevantes por busca semântica e cortando mais de 50% dos tokens de prompt.

  4. Antonioni et al. (2025) organizaram tools MCP em uma taxonomia hierárquica e filtraram por consulta, reduzindo o tamanho do prompt sem perda relevante de capacidade e melhorando a seleção conforme o número de tools cresce.

  5. Majeed et al. (2026) caracterizaram 1.723 aplicações consumidoras de MCP por configuração, uso de SDK e mecanismos de supervisão humana, sem quebrar os dados por primitiva.

  6. Li e Gao (2025) descreveram como metadados de tool controlados pelo atacante moldam o raciocínio do modelo e induzem operações que o host executa sem verificação independente, a partir de 67.057 servidores em seis registros.

Perguntas frequentes

Quais são as primitivas do MCP?
São três, todas expostas pelo servidor: tools, que o modelo aciona; resources, que a aplicação anexa; e prompts, que o usuário escolhe. A especificação chama isso de hierarquia de controle, e ela é a chave para entender a divisão: cada primitiva tem um ator diferente decidindo quando ela é usada.
Qual a diferença entre tool e resource no MCP?
Tool é executável e o modelo a invoca por conta própria com tools/call, podendo ter efeito colateral. Resource é conteúdo identificado por URI, lido com resources/read por decisão da aplicação. A diferença prática é o gatilho e o custo: uma tool ocupa contexto em toda chamada, um resource só quando alguém o anexa.
Quando usar um resource em vez de uma tool?
Quando o conteúdo é de leitura, tem identidade estável e faz sentido o usuário ou a aplicação escolherem antes da tarefa começar. Arquivo, esquema de banco, documento de política. Se o modelo precisa buscar aquilo no meio do raciocínio, com parâmetros que ele decide na hora, aí é tool.
O que é a primitiva prompt no MCP?
É um template de mensagens que o servidor expõe e o usuário invoca de propósito, tipicamente como comando de barra. O servidor devolve uma lista de mensagens já montadas em prompts/get, com argumentos preenchidos. Usuário controla quando o prompt é usado; quem escreve o conteúdo continua sendo o servidor.
Uma tool pode devolver dado estruturado?
Sim. O resultado pode trazer structuredContent, um valor JSON que segue o outputSchema declarado pela tool. Servidores que declaram outputSchema precisam devolver resultado conforme o schema, e clientes devem validar. Por compatibilidade, o mesmo JSON serializado costuma vir também como bloco de texto.
Erro de tool é erro de protocolo?
Não, e confundir os dois custa caro. Falha de negócio, validação de entrada e erro de API voltam no resultado com isError igual a true, e o cliente deve entregá-los ao modelo para que ele se corrija. Erro de protocolo é para tool inexistente e requisição malformada, coisas que o modelo dificilmente conserta.

Referências

  1. Agentic AI Foundation. Model Context Protocol specification, revision 2026-07-28 — Server primitives (2026)
  2. Agentic AI Foundation. Model Context Protocol specification, revision 2026-07-28 — Tools (2026)
  3. Gan, T., Sun, Q.. RAG-MCP: Mitigating Prompt Bloat in LLM Tool Selection via Retrieval-Augmented Generation (2025)arXiv:2505.03275
  4. Antonioni, E. et al.. JSPLIT: A Taxonomy-based Solution for Prompt Bloating in Model Context Protocol (2025)arXiv:2510.14537
  5. Li, X., Gao, X.. A First Look at the Security Issues in the Model Context Protocol Ecosystem (2025)arXiv:2510.16558
  6. Majeed, M. H. A., Mahmoud, M., Nadi, S.. An Empirical Study of Model Context Protocol Applications (2026)arXiv:2607.25635