WebMCP in production|INEMA.CLUB-PRO

Lesson 4 · 18 min

A frozen battery for your tools, and regression when the spec changes

When the code or the spec changes, a site with WebMCP fails silently: detection does not find the API, falls back to the form, and nobody notices. Only a battery catches it. In this lesson you freeze the contract and the cases for the tools, run them in all four modes, and watch the battery catch the old API name.

Start the lesson
A dark workbench with analog gauges without numbers, a notebook with a terminal, and a sealed acrylic box with a blank label.

In this lesson you will

  1. 1What freezing is and why the hash
  2. 2The four modes: sem, polyfill, native, and MCP
  3. 3The silent regression of the old name
  4. 4What to do when the expected result really changes

Goal: freeze the contract and cases for your tools, run them in four modes, and watch the battery catch the old API name regression.

01From the frozen battery to the verdict

Click each step.

Click each block in the diagram to see what it does.

The battery in course 2 tests the page; this one tests the page and the server against a contract that does not change without a decision.

02Rules for a battery that counts

Inherited from LOOP-R Engenharia (frozen tests) and applied to the tools.

1. Frozen

The expected result does not change just to make the test pass. Did the spec or the rule change? Re-freeze and explain it in the commit.

The hash makes the change visible: nobody edits casos.json without the battery refusing.

03The full battery

Four modes, 24 checks, no model and no cost.

Terminal · frozen battery
cd ~/projetos/formacao-webmcp-expert-v72/kit
node scripts/bateria.mjs; echo "saída: $?"
Example from the repository
== Chromium 156.0.8078.4 (Playwright) · bateria congelada (spec 2026-10-16, MCP 2026-07-28)
ok    [sem] fallback: página sem WebMCP e sem erro de JavaScript · sem
ok    [sem] fallback: a pessoa reserva pelo formulário
ok    [polyfill] contrato: 4 ferramentas com as anotações congeladas · 4 registradas
ok    [polyfill] c1 buscar_oficinas · of-301
ok    [polyfill] c2 buscar_oficinas · erro
ok    [polyfill] c3 reservar_vaga (pessoa recusa) · 0 reserva(s)
ok    [polyfill] c4 reservar_vaga (pessoa confirma) · 1 reserva(s)
ok    [polyfill] c5 reservar_vaga (pessoa confirma) · erro, 1 reserva(s)
ok    [polyfill] c6 listar_comentarios · 2 comentário(s)
ok    [polyfill] nenhum erro de JavaScript
ok    [nativo] contrato: 4 ferramentas com as anotações congeladas · 4 registradas
ok    [nativo] c1 buscar_oficinas · of-301
ok    [nativo] c2 buscar_oficinas · erro
ok    [nativo] c3 reservar_vaga (pessoa recusa) · 0 reserva(s)
ok    [nativo] c4 reservar_vaga (pessoa confirma) · 1 reserva(s)
ok    [nativo] c5 reservar_vaga (pessoa confirma) · erro, 1 reserva(s)
ok    [nativo] c6 listar_comentarios · 2 comentário(s)
ok    [nativo] nenhum erro de JavaScript
ok    [mcp] contrato: 2 ferramentas com as anotações congeladas · buscar_oficinas,reservar_vaga
ok    [mcp] c1 buscar_oficinas · of-301
ok    [mcp] c2 buscar_oficinas · erro
ok    [mcp] c3 reservar_vaga (pessoa recusa) · 0 reserva(s)
ok    [mcp] c4 reservar_vaga (pessoa confirma) · 1 reserva(s)
ok    [mcp] c5 reservar_vaga (pessoa confirma) · erro, 1 reserva(s)
BATERIA: 24/24 ok
saída: 0

c5 asks the person and they confirm, but the rule refuses (of-102 has no spots left): an error and no new booking. In MCP, the question to the user comes before the rule's refusal.

04The silent regression: the old name

navigator.modelContext is the old name (before PR #177, accepted on 05/19/2026). A copy of the page that uses it: the site keeps working, and only the battery notices.

Terminal · page with the old name
cd ~/projetos/formacao-webmcp-expert-v72/kit
E=$(bash scripts/copia.sh a4)
# a regressão: alguém cola um exemplo antigo que usa o nome de antes de 19/05/2026
sed -i 's/const mc = document.modelContext; /const mc = navigator.modelContext; /' $E/pagina/ferramentas.mjs
cd $E && node scripts/bateria.mjs sem nativo | grep -E "FALHA|ok    \[sem\]|BATERIA"; echo "saída: ${PIPESTATUS[0]}"
Example from the repository
ok    [sem] fallback: página sem WebMCP e sem erro de JavaScript · sem
ok    [sem] fallback: a pessoa reserva pelo formulário
FALHA [nativo] contrato: 4 ferramentas com as anotações congeladas · 0 registradas
FALHA [nativo] c1 buscar_oficinas · ferramenta ausente
FALHA [nativo] c2 buscar_oficinas · ferramenta ausente
FALHA [nativo] c3 reservar_vaga · ferramenta ausente
FALHA [nativo] c4 reservar_vaga · ferramenta ausente
FALHA [nativo] c5 reservar_vaga · ferramenta ausente
FALHA [nativo] c6 listar_comentarios · ferramenta ausente
BATERIA: 3/10 ok
saída: 1

The sem mode passes: the person books normally. In nativo, the detection does not find navigator.modelContext in Chromium 156, the page falls back, and the four tools disappear. No JavaScript error: without the battery, nobody would see it.

05Rehearsal: the expected result changed

On a throwaway copy of the kit.

Terminal · casos.json changed
cd ~/projetos/formacao-webmcp-expert-v72/kit
E=$(bash scripts/copia.sh a4c)
# o erro comum: mudar o esperado para o teste passar
sed -i 's/"reservas": 0/"reservas": 1/' $E/bateria/casos.json
cd $E && node scripts/bateria.mjs mcp; echo "saída: $?"

06Practice

The battery goes green, the regression gets caught, and a case of your own. Each exercise ends in a done when.

E1 · Green battery

5 min

Run the full battery.

Done when: node scripts/bateria.mjs; echo "saída: $?" → BATERIA: 24/24 ok and saída: 0.

E2 · Catch the old name

5 min

Run the rehearsal for the page that uses navigator.modelContext.

Done when: The block prints FALHA [nativo] contrato: 4 ferramentas com as anotações congeladas · 0 registradas, BATERIA: 3/10 ok and saída: 1.

E3 · The battery refuses to run

3 min

Run the rehearsal with the changed casos.json.

Done when: The block prints BATERIA RECUSADA: casos.json ou contrato.json mudou depois de congelado. and saída: 2.

E4 · A case of your own

15 min

In a copy of the kit (bash scripts/copia.sh e4), add a case c7 to bateria/casos.json (e.g. buscar_oficinas with tema mcp, expecting of-302), re-freeze it with --recongelar, and run the battery on the copy.

Done when: In the copy, node scripts/bateria.mjs; echo "saída: $?" → BATERIA: 27/27 ok and saída: 0 (c7 in polyfill, nativo and mcp).

07Lesson quiz

The explanation appears after the answer.

Question 1 of 4

The page uses navigator.modelContext. What does the visitor see in Chromium 156?

08In three sentences

FrozenContract and cases with a hash: the expected result only changes with a decision.
Four modesNo API, polyfill, native and MCP server: the fallback first, then each door.
SilenceThe old API name doesn't break the screen; the battery is what sees it.

Going further

Previous lessonNext lesson