Primeira ferramenta: registerTool com inputSchema e execute
Uma ferramenta WebMCP é um objeto com nome, descrição, esquema de entrada e uma função execute. A página registra; o agente lista com getTools e chama com executeTool. Nesta aula você lê a ferramenta de busca do kit, chama do jeito que um agente chamaria e registra a sua primeira.
1Os campos de uma ferramenta e as regras de nome e descrição
2inputSchema em JSON Schema, fechado e descrito
3executeTool: entra objeto, volta texto JSON
4A sua primeira ferramenta no extras.mjs
Objetivo: registrar uma ferramenta com nome, descrição, inputSchema e execute, e chamá-la como um agente chamaria, vendo o resultado e a tela.
01 · Da definição ao resultado
Clique em cada passo.
Clique em cada bloco do diagrama para ver o que ele faz.
Spec de 16/10/2026 e Chromium 156.0.8078.4. Se mudar, a aula 1 avisa: confira a data antes.
02 · A ferramenta de busca do kit
Trecho de kit/pagina/ferramentas.mjs. A mesma agenda.buscar atende o formulário e a ferramenta.
Trecho · kit/pagina/ferramentas.mjs
{
name: 'buscar_oficinas',
title: 'Buscar oficinas',
description: 'Lista as oficinas da agenda por tema. Só lê: não reserva nada. Use apenasComVaga=true para ver só as que ainda têm vaga.',
inputSchema: {
type: 'object',
properties: {
tema: { type: 'string', enum: TEMAS, description: 'Tema da oficina.' },
apenasComVaga: { type: 'boolean', description: 'true = só oficinas com vaga.' }
},
additionalProperties: false
},
annotations: { readOnlyHint: true },
execute: comErroUtil(async input => {
const lista = agenda.buscar(input);
ui.mostrarResultados(lista, input); // a pessoa vê o mesmo que o agente recebeu
return { total: lista.length, oficinas: lista };
})
}
Trecho · registrar com detecção (ferramentas.mjs)
const mc = document.modelContext; // nome atual (16/10/2026)
if (!mc || typeof mc.registerTool !== 'function') {
aviso?.('Este navegador não expõe WebMCP. Tudo funciona pelo formulário.');
return { modo: 'sem', registradas: 0 };
}
const pagina = new AbortController();
addEventListener('pagehide', () => pagina.abort(), { once: true });
await registrar(mc, defs, pagina.signal);
03 · Chamar como um agente chamaria
listar.mjs faz getTools; executar.mjs faz executeTool com o objeto que você passa e mostra a tela depois.
"resultado (string)": o navegador devolve texto JSON, como a spec manda. A lista da tela também ficou com 1 oficina.
== Chromium 156.0.8078.4 (Playwright) · modo: nativo
navigator.modelContext (nome antigo): undefined
entrada em texto JSON em vez de objeto: TypeError
execute que lança: UnknownError: Tool was executed but the invocation failed. For example, the script function threw an error
== Chromium 156.0.8078.4 (Playwright) · modo: polyfill
navigator.modelContext (nome antigo): undefined
entrada em texto JSON em vez de objeto: TypeError
execute que lança: UnknownError: Tool execution failed
Exemplos antigos passavam JSON.stringify(input) para contornar uma implementação de setembro: hoje dá TypeError nos dois. E o motivo de um throw não chega ao agente (UnknownError genérico). Por isso o kit devolve { erro } como dado (aula 7).
04 · A sua primeira ferramenta
O bloco copia a página para um ensaio, escreve um extras.mjs com contar_vagas e confere. Para valer no kit, cole a mesma lista em kit/pagina/extras.mjs.
Terminal · ensaio com contar_vagas
cd ~/projetos/formacao-webmcp-site-v72/kit
E=${TMPDIR:-/tmp}/ensaio-webmcp-site/a3; rm -rf $E; mkdir -p $E; cp -r pagina/. $E/
cat > $E/extras.mjs <<'FIM'
export function extras(agenda) {
return [{
name: 'contar_vagas',
description: 'Soma as vagas livres das oficinas de um tema. Só lê: não reserva nada.',
inputSchema: {
type: 'object',
properties: { tema: { type: 'string', enum: ['html', 'javascript', 'webmcp', 'mcp'], description: 'Tema da oficina.' } },
required: ['tema'],
additionalProperties: false
},
annotations: { readOnlyHint: true },
async execute({ tema }) {
const lista = agenda.buscar({ tema });
return { tema, vagas: lista.reduce((soma, o) => soma + o.vagas, 0) };
}
}];
}
FIM
PAGINA=$E node scripts/listar.mjs nativo | tail -1
PAGINA=$E node scripts/executar.mjs nativo contar_vagas '{"tema":"html"}'; echo "saída: $?"
Escreva outra ferramenta só de leitura no extras.mjs, por exemplo proxima_oficina (a de data mais próxima). Nome com _, descrição que diz o que não faz, schema fechado.
Pronto quando:node scripts/executar.mjs nativo [nome] '{}' → resultado (string): com o JSON esperado e saída: 0.
06 · Teste da aula
A explicação aparece depois da resposta.
Pergunta 1 de 4
O que executeTool devolve na spec de 16/10/2026?
Correto
executeTool devolve Promise: o navegador serializa o retorno do execute em JSON. Quem chama faz JSON.parse, como o testar.mjs.
Não é essa
executeTool devolve Promise: o navegador serializa o retorno do execute em JSON. Quem chama faz JSON.parse, como o testar.mjs.Rever: A ferramenta de busca do kit
Pergunta 2 de 4
Qual nome de ferramenta registerTool recusa?
Correto
O nome aceita de 1 a 128 caracteres: letras e números ASCII, _ - e ponto. Espaço não entra, e o registro rejeita com InvalidStateError.
Não é essa
O nome aceita de 1 a 128 caracteres: letras e números ASCII, _ - e ponto. Espaço não entra, e o registro rejeita com InvalidStateError.Rever: Da definição ao resultado
Pergunta 3 de 4
Por que a busca do kit chama ui.mostrarResultados dentro do execute?
Correto
Agente e pessoa trabalham na mesma página. Se o agente busca e a tela não muda, a pessoa perde o fio. A spec não obriga; é decisão de desenho do kit.
Não é essa
Agente e pessoa trabalham na mesma página. Se o agente busca e a tela não muda, a pessoa perde o fio. A spec não obriga; é decisão de desenho do kit.Rever: A ferramenta de busca do kit
Pergunta 4 de 4
Um tutorial manda chamar executeTool(t, JSON.stringify(entrada)). O que acontece no Chromium 156?
Correto
A entrada é object na spec. O contorno com texto era de uma implementação de setembro e hoje dá TypeError no nativo e no polyfill (medido em 19/10/2026).
Não é essa
A entrada é object na spec. O contorno com texto era de uma implementação de setembro e hoje dá TypeError no nativo e no polyfill (medido em 19/10/2026).Rever: A ferramenta de busca do kit
Teste concluído
Você acertou {a} de {n}. Acertando todas, a aula é marcada como concluída.
Escolha uma alternativa. A explicação aparece depois da sua tentativa.
07 · Em três frases
Definiçãoname com regra, description clara, inputSchema fechado e execute que devolve um objeto.
ChamadagetTools lista; executeTool recebe objeto e devolve texto JSON.
Na telaO execute usa a mesma regra do formulário e mostra à pessoa o que o agente recebeu.