WebMCP en tu sitio|INEMA.CLUB-PRO

En esta lección vas a

  1. 1Los campos de una tool y las reglas de nombre y descripción
  2. 2inputSchema en JSON Schema, cerrado y descrito
  3. 3executeTool: entra un objeto, sale texto JSON
  4. 4Tu primera tool en extras.mjs

Objetivo: registrar una tool con nombre, descripción, inputSchema y execute, y llamarla como la llamaría un agente, viendo el resultado y la pantalla.

01De la definición al resultado

Haz clic en cada paso.

Haz clic en cada bloque del diagrama para ver qué hace.

Spec del 16/10/2026 y Chromium 156.0.8078.4. Si cambia, la clase 1 avisa: confirma la fecha antes.

02La tool de búsqueda del kit

Fragmento de kit/pagina/ferramentas.mjs. La misma agenda.buscar atiende el formulario y la tool.

Fragmento · 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 };
  })
}
Fragmento · registrar con detección (ferramentas.mjs)
const mc = document.modelContext;   // nombre actual (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);

03Llamar como lo llamaría un agente

listar.mjs hace getTools; executar.mjs hace executeTool con el objeto que le pasas y muestra la pantalla después.

Terminal · listar y ejecutar
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: $?"
Ejemplo del repositorio
== 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)": el navegador devuelve texto JSON, como manda la spec. La lista de la pantalla también quedó con 1 taller.

04Tu primera herramienta

El bloque copia la página a un ensayo, escribe un extras.mjs con contar_vagas y lo verifica. Para que valga en el kit, pega la misma lista en kit/pagina/extras.mjs.

Terminal · ensayo con 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: $?"
Ejemplo del repositorio
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 del extras.mjs, la cuenta era 4. La suma de HTML: 3 cupos en of-101 y 0 en of-102.

05Práctica

Modo nativo; cámbialo por polyfill si quieres comparar. Cada ejercicio termina con un listo cuando.

E1 · Llamar la búsqueda

5 min

Ejecuta listar y executar. Cambia el tema a html y luego a cobol, y compara.

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

E2 · contar_vagas en el kit

10 min

Pega la lista de contar_vagas en kit/pagina/extras.mjs (dentro del return [ ]).

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

E3 · Una herramienta tuya

15 min

Escribe otra herramienta de solo lectura en extras.mjs, por ejemplo proxima_oficina (la de fecha más cercana). Nombre con _, descripción que diga lo que no hace, schema cerrado.

Listo cuando: node scripts/executar.mjs nativo [nome] '{}' → resultado (string): con el JSON esperado y saída: 0.

06Prueba de la clase

La explicación aparece después de la respuesta.

Pregunta 1 de 4

¿Qué devuelve executeTool en la spec del 16/10/2026?

07En tres frases

Definiciónname con regla, description clara, inputSchema cerrado y execute que devuelve un objeto.
LlamadagetTools lista; executeTool recibe un objeto y devuelve texto JSON.
En la pantallaEl execute usa la misma regla del formulario y le muestra a la persona lo que recibió el agente.

Para ir más allá

Clase anteriorSiguiente clase