Ferramentas MCP agora têm etiqueta de preço: declare quanto cada chamada custa e limite o que um chat pode gastar

Você descobre no fim do mês: alguma ferramenta MCP rodou umas quarenta vezes e cada chamada cobrou créditos de verdade. Olhando a transcrição, ela se comportou exatamente como um leitor de arquivos gratuito — o mesmo JSON na entrada, o mesmo “done” de uma linha na saída. Nada na conversa dizia quais chamadas estavam gastando dinheiro.
É o ponto incômodo em que o ecossistema MCP está agora. Geração de imagem, vídeo e 3D e APIs pagas chegam todas como servidores MCP, e um agente as vê do mesmo jeito que vê read_file. O PR #142470, mesclado em 21 de outubro de 2026, adiciona as duas peças que faltavam: um custo declarado por ferramenta e um orçamento por chat.
Três chaves novas
Dentro de uma entrada mcp_servers no config.yaml:
mcp_servers:
renders:
command: "render-mcp"
trust: untrusted
tool_costs:
create_image: 20 # cerca de 20 créditos por chamada
animate: {credits: [5, 20], note: "per animation"} # um intervalo, com uma nota curta
get_status: 0 # grátis; igual a deixar de fora
spend_limit: 100 # por chat; 0 ou ausente = sem limite
cost_unit: credits # rótulo nos prompts (padrão: credits)
tool_costs aceita três formatos:
- um número não negativo, para custo fixo;
- um intervalo
[min, max], que cai bem em ferramentas precificadas por resolução ou duração; - um objeto com
creditscontendo um número ou um intervalo, mais umnotepara uma linha em linguagem simples.
spend_limit é um teto por chat; 0 ou ausente significa sem limite. cost_unit só muda o texto dos prompts e dos totais (padrão credits), então um serviço cobrado em “runs” ou “points” pode dizer isso.
O prompt de aprovação vira uma conta
Antes das declarações, um servidor trust: untrusted perguntava “allow create_image?” antes de uma chamada com capacidade de escrita. Com custo declarado, o mesmo prompt mostra:
Costs about 20 credits.
Um intervalo aparece como Costs 5-20 credits (per animation). Depois que o chat já gastou algo naquele servidor, uma segunda linha aparece:
This chat has used about 40 credits on 'renders' (limit 100).
O valor aqui é que a aprovação deixa de ser só uma questão de segurança e passa a ser uma questão de orçamento. Você não está mais aprovando uma ação; está aprovando mais 20 créditos.
Onde o total corrente fica guardado
Estas regras importam mais que a config, porque são elas que decidem se você confia no número:
- Os totais são mantidos por chat e por servidor; nada passa de um chat para outro.
- Só contam as chamadas que foram de fato despachadas. Chamadas recusadas ou bloqueadas não somam nada.
- A cobrança usa a estimativa declarada, e o topo do intervalo — o desenho erra para o lado de perguntar antes.
- Uma chamada cujo servidor morre antes de recebê-la ainda conta, pelo mesmo motivo.
- O acumulado vive em memória: é um orçamento de uma conversa, não a fatura do fornecedor. Reiniciar o Hermes zera todos os totais.
- O total acompanha a conversa através da compressão de contexto e do
/branch. Na CLI,/newabre um total novo (o mesmo vale para um novo chat no Desktop); nas plataformas de mensagem o total pertence ao chat, então sobrevive ao/new. Cada execução de cron tem o seu próprio total.
O que acontece quando o orçamento é estourado
Esta é a parte que vale memorizar:
- Ele pergunta mesmo num servidor
trust: full. Um servidor assim normalmente roda ferramentas com custo sem prompt; quando uma chamada cruzaria ospend_limit, ele para e pergunta. - Pergunta toda vez. Escolher “permitir nesta sessão” não silencia as chamadas com custo seguintes naquele chat.
- Onde ninguém pode responder, ele recusa sem despachar. Jobs de cron,
hermes chat -qe um gateway sem aprovador caem todos aqui. O modelo recebe um erro de ferramenta nomeando o gasto e o limite e avisando para não tentar de novo — não uma falha silenciosa. - Abaixo do limite, nada muda.
trust: fullcontinua sem prompt, e ferramentas anotadas comreadOnlyHint: truenão são acordadas a menos que o orçamento exija.
Em outras palavras, spend_limit não é um acelerador. É um portão que diz “depois desta linha, um humano precisa concordar”.
Pacotes portáveis também podem declarar
Um pacote de plugin portável carrega a mesma tabela para o seu servidor dentro do plugin.json:
"extensions": {
"com.nousresearch.hermes": {
"servers": {
"meshy": {
"trust": "untrusted",
"costs": { "meshy_remesh": 5, "meshy_animate": { "credits": [5, 20], "note": "per animation" } },
"spend_limit": 100,
"cost_unit": "credits"
}
}
}
}
Isso resolve uma assimetria real: o autor do plugin sabe exatamente quanto custa uma ferramenta, e o usuário normalmente não sabe. O costs / spend_limit / cost_unit do pacote viram as chaves nativas.
Cinco armadilhas
- Uma tabela de custos malformada derruba o servidor inteiro, em vez de ser ignorada. Qualquer uma das três chaves em formato errado impede o servidor de carregar, e o erro nomeia a chave. É deliberado: um erro de digitação não pode descartar seu orçamento em silêncio.
- As chaves de
tool_costsprecisam ser os nomes de ferramenta do próprio servidor, não o prefixo de exibição do Hermesmcp_<server>_. Uma chave errada não falha — imprime um aviso no momento da conexão, fácil de passar batido. - Herança em override de mesmo nome: se você adiciona a sua própria entrada
mcp_serverspara o mesmo servidor (digamos, para elevá-lo atrust: full), as chaves de custo do pacote continuam valendo, a menos que a sua entrada as defina.spend_limit: 0desliga o limite do pacote;tool_costs: {}descarta os custos dele. - É um orçamento, não uma fatura. A cobrança do fornecedor pode divergir da declaração, e os totais reiniciam no restart. Não trate isso como contabilidade.
hermes plugins validatelistaserver costs: <name>. Confira essa linha antes de instalar, em vez de reconstruir o gasto a partir da transcrição depois.
Dá para usar hoje?
O recurso está na main e não está na v0.22.4 já publicada — o intervalo de comparação v0.22.3 para v0.22.4 tem 14 commits e este recurso não é um deles. Instalações de produção esperam a próxima release; checkouts de código que acompanham a main podem testar agora.
O crédito do design vai para um projeto da comunidade, o Adolanium/hermes-tripo, que implementou “cada crédito, pedido” e “um limite por chat” com um hook nativo de pre_tool_call. Pacotes portáveis não conseguem carregar hooks, então isso entrou como recurso de core movido por dados declarados — o que também significa que plugins oficiais, como o da Meshy, podem usar.
Se você ainda está decidindo quais servidores merecem trust: full, nosso guia de segurança do catálogo MCP cobre os níveis de trust. Declarações de custo e níveis de trust respondem perguntas diferentes; eles funcionam melhor juntos.