WebMCP no seu site|INEMA.CLUB-PRO

Nesta aula você vai

  1. 1Os campos de uma ferramenta e as regras de nome e descrição
  2. 2inputSchema em JSON Schema, fechado e descrito
  3. 3executeTool: entra objeto, volta texto JSON
  4. 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.

01Da 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.

02A 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);

03Chamar como um agente chamaria

listar.mjs faz getTools; executar.mjs faz executeTool com o objeto que você passa e mostra a tela depois.

Terminal · listar e executar
cd ~/projetos/formacao-webmcp-site-v72/kit
node scripts/listar.mjs nativo
node scripts/executar.mjs nativo buscar_oficinas '{"tema":"webmcp","apenasComVaga":true}'; echo "saída: $?"
Exemplo do repositório
== Chromium 156.0.8078.4 (Playwright) · modo: nativo
buscar_oficinas      readOnlyHint
listar_comentarios   readOnlyHint, untrustedContentHint
minhas_reservas      readOnlyHint
reservar_vaga        consequentialHint
4 ferramentas registradas
== Chromium 156.0.8078.4 (Playwright) · modo: nativo
resultado (string): {"total":1,"oficinas":[{"id":"of-301","titulo":"Primeira ferramenta WebMCP","tema":"webmcp","data":"2026-11-18","vagas":4}]}
tela · resultados: 1 · reservas: Nenhuma reserva.
saída: 0

"resultado (string)": o navegador devolve texto JSON, como a spec manda. A lista da tela também ficou com 1 oficina.

04A 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: $?"
Exemplo do repositório
5 ferramentas registradas
== Chromium 156.0.8078.4 (Playwright) · modo: nativo
resultado (string): {"tema":"html","vagas":3}
tela · resultados: 6 · reservas: Nenhuma reserva.
saída: 0

Antes do extras.mjs, a contagem era 4. A soma de HTML: 3 vagas em of-101 e 0 em of-102.

05Prática

Modo nativo; troque por polyfill se quiser comparar. Cada exercício termina num pronto quando.

E1 · Chamar a busca

5 min

Rode listar e executar. Troque o tema para html e depois para cobol e compare.

Pronto quando: node scripts/executar.mjs nativo buscar_oficinas '{"tema":"webmcp","apenasComVaga":true}' → resultado (string): {"total":1, e saída: 0; com cobol → {"erro":"tema inválido: cobol"}.

E2 · contar_vagas no kit

10 min

Cole a lista de contar_vagas em kit/pagina/extras.mjs (dentro do return [ ]).

Pronto quando: node scripts/listar.mjs nativo | tail -1 → 5 ferramentas registradas (antes: 4).

E3 · Uma ferramenta sua

15 min

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.

06Teste da aula

A explicação aparece depois da resposta.

Pergunta 1 de 4

O que executeTool devolve na spec de 16/10/2026?

07Em 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.

Para ir além

Aula anteriorPróxima aula