---
title: "WebMCP no Angular: como expor tools ao agente de IA do browser (e quando esperar)"
description: "Como o Angular expõe tools WebMCP para um agente de IA do browser (bootstrap, rotas, services e Signal Forms), mais a superfície de segurança que se abre e onde eu ainda esperaria antes de colocar em produção."
deck: "O WebMCP deixa sua aplicação Angular entregar tools tipadas para um agente de IA do browser, em vez de deixar o agente clicar pelo DOM. O Angular já traz um suporte experimental atrás de `provideExperimentalWebMcpTools`. Desde 2026-06-01 o ponto de entrada saiu de `navigator` para `document.modelContext`, então o guia que vale agora está em [next.angular.dev/ai/webmcp](https://next.angular.dev/ai/webmcp), e não na doc estável."
author: "André Ramos"
url: "https://andreramos.dev/pt/angular/web-mcp-in-angular/"
lang: "pt-BR"
type: "article"
---

# WebMCP no Angular: como expor tools ao agente de IA do browser (e quando esperar)

> O WebMCP deixa sua aplicação Angular entregar tools tipadas para um agente de IA do browser, em vez de deixar o agente clicar pelo DOM. O Angular já traz um suporte experimental atrás de `provideExperimentalWebMcpTools`. Desde 2026-06-01 o ponto de entrada saiu de `navigator` para `document.modelContext`, então o guia que vale agora está em [next.angular.dev/ai/webmcp](https://next.angular.dev/ai/webmcp), e não na doc estável.

## O que o WebMCP muda de verdade

Um agente de IA que automatiza seu app costuma operar a UI: ele lê o DOM, acha um botão, clica, preenche um campo e torce para o layout não ter mudado. O WebMCP inverte isso. A [spec](https://github.com/webmachinelearning/webmcp) descreve a ideia como deixar o desenvolvedor expor funcionalidades da aplicação web, sejam funções JavaScript ou elementos HTML `<form>`, como tools com descrições em linguagem natural e schemas estruturados para o agente consumir. Seu app declara uma tool `findOrder` com um schema de entrada; o agente chama pelo nome e recebe dados estruturados de volta. Sem adivinhar seletor, sem clique sintético.

Leia o status antes de ler a API. O WebMCP é um [draft de Community Group do W3C](https://webmachinelearning.github.io/webmcp/), do Web Machine Learning CG. Isso é um relatório em rascunho, não um W3C Standard e nem está na Standards Track. O formato ainda pode mudar debaixo de você.

Essa é uma camada diferente do [Angular CLI MCP server](/angular/angular-cli-mcp-ai-generated-angular-code/), que entrega contexto do projeto para um assistente enquanto você escreve Angular na sua máquina. Aquele ajuda a gerar código. O WebMCP é runtime: é o seu app publicado expondo capacidades para qualquer agente que o usuário final esteja rodando. O raio de impacto é a aplicação em produção, não o editor, e é exatamente por isso que o resto importa.

## Como o Angular liga isso

São quatro lugares para registrar uma tool, e eles correspondem a quanto tempo a tool deve viver. Escolha o escopo mais estreito que cobre a capacidade.

No bootstrap, o [`provideExperimentalWebMcpTools`](https://next.angular.dev/api/core/provideExperimentalWebMcpTools) registra tools para o app inteiro. Cada tool carrega um `name`, uma `description`, um `inputSchema` em JSON Schema e um callback `execute` que roda dentro de um injection context, então consegue dar `inject` em services direto.

No nível da rota você passa o mesmo provider no `providers` da rota, e a tool só existe enquanto aquela rota estiver ativa. Para isso valer, você precisa do [`withExperimentalAutoCleanupInjectors`](https://next.angular.dev/ai/webmcp) no `provideRouter`; sem ele, as tools da rota seguem registradas depois que você navega para fora. Um aviso honesto: essa configuração recomendada tem hoje um bug aberto. Providers de rota com `withExperimentalAutoCleanupInjectors` podem lançar `InvalidStateError: Duplicate tool name` quando você volta para a rota várias vezes ([issue #68899](https://github.com/angular/angular/issues/68899), aberta em 2026-06-02). Se você fizer um spike no caminho da rota, entre e saia algumas vezes e fique de olho.

Dentro de um service, o `declareExperimentalWebMcpTool` registra uma tool a partir de um injection context e a remove sozinho quando esse contexto é destruído. Esse é o lugar natural quando a tool pertence a um service de feature, e não a uma rota.

Para formulários, o `provideExperimentalWebMcpForms` com a opção `experimentalWebMcpTool` no `form()` transforma um Signal Form em tool. O Angular infere o JSON schema a partir dos valores iniciais do modelo do formulário e liga a validação e o submit, então o agente enxerga os erros de campo e consegue se corrigir em vez de mandar lixo. Três restrições vêm junto com essa inferência: o modelo precisa de valores iniciais concretos (`''`, `0`, `false`, nunca `null` ou `undefined`), arrays precisam de pelo menos um elemento para o formato do item ser conhecido, e validadores assíncronos não rodam durante o submit do agente. Aprofundo forms como tools em [Transformando Signal Forms em tools de agente de IA](/angular/signal-forms-as-ai-agent-tools/).

*Bootstrap: uma tool para o app inteiro*

```ts
import { Service, inject, provideExperimentalWebMcpTools } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppRoot } from './app-root';
import { Orders } from './orders';

bootstrapApplication(AppRoot, {
  providers: [
    provideExperimentalWebMcpTools([
      {
        name: 'findOrder',
        description: 'Looks up an order by its number.',
        inputSchema: {
          type: 'object',
          properties: { orderId: { type: 'string' } },
          required: ['orderId'],
        },
        execute: ({ orderId }) => {
          const orders = inject(Orders);
          return { content: [{ type: 'text', text: orders.summary(orderId) }] };
        },
      },
    ]),
  ],
});
```

*Nível de rota: com escopo numa rota só, com cleanup*

```ts
// routes.ts
export const routes: Routes = [{
  path: 'dashboard',
  loadComponent: () => import('./dashboard').then((m) => m.Dashboard),
  providers: [
    provideExperimentalWebMcpTools([{
      name: 'exportDashboardReports',
      description: 'Exports the current dashboard analytics.',
      inputSchema: { type: 'object', properties: {} },
      execute: () => ({ content: [{ type: 'text', text: 'Export triggered.' }] }),
    }]),
  ],
}];

// app.config.ts: sem isto, as tools da rota seguem ativas depois de navegar
provideRouter(routes, withExperimentalAutoCleanupInjectors());
```

*Signal Forms: schema inferido a partir do modelo*

```ts
// provideExperimentalWebMcpForms() precisa estar nos seus providers
readonly model = signal({ firstName: '', lastName: '' });

readonly userForm = form(this.model,
  (f) => {
    required(f.firstName, { message: 'First name is mandatory.' });
    required(f.lastName, { message: 'Last name is mandatory.' });
  },
  {
    experimentalWebMcpTool: { name: 'registerUser', description: 'Registers a new user.' },
    submission: { action: async (formValue) => { /* ... */ } },
  },
);
```

## Dá para rodar isso hoje?

Antes de desenhar tools, veja em que status você está construindo. O suporte a WebMCP chegou com o v22, mas ainda é uma API experimental, e é por isso que o guia dele mora em `next.angular.dev` e não na doc estável do [angular.dev](https://angular.dev/reference/releases).

O ponto de entrada também acabou de mudar. Ele ficava pendurado no `navigator`; desde 2026-06-01 é o `document.modelContext`, depois que a [issue #68947](https://github.com/angular/angular/issues/68947) foi concluída e o [PR #68961](https://github.com/angular/angular/pull/68961) entrou. Até isso assentar entre os consumidores, faça feature detection nos dois: `const modelContext = document.modelContext || navigator.modelContext;`.

Do lado do consumidor, desconfie das demos. O WebMCP é um draft de CG, e eu não consigo te apontar um browser ou agente publicado que consuma `document.modelContext` a partir de uma fonte primária que eu citaria. Então você testa o registro sem esperar por isso: o guia sugere o pacote [`@mcp-b/webmcp-polyfill`](https://next.angular.dev/ai/webmcp) como mock para testes unitários, o que deixa você afirmar que suas tools registram e que o `execute` devolve o que você espera.

O time do Angular é direto sobre tudo isso. Nas palavras deles: "The WebMCP spec is very early in its lifecycle and is undergoing frequent changes. As such, WebMCP support in Angular is currently experimental. APIs are subject to change even outside of major versions." Leia isso assim: um bump de minor pode renomear aquilo que você publicou.

## A superfície que você está expondo

Cada tool que você registra é mais uma coisa que um agente consegue disparar no seu app sem um humano clicar. Essa frase é o modelo de ameaça inteiro. Trate a lista de tools do jeito que você trata endpoints de API pública, porque na prática é o que ela é.

A spec atual registra tools por `document.modelContext.registerTool(tool, { signal, exposedTo })`. A opção `exposedTo` limita quais origens podem chamar uma tool, e um `AbortSignal` deixa você derrubar uma tool. Use por padrão o `exposedTo` mais estreito que você consiga justificar, o mesmo instinto que você levaria para o CORS.

Não confie na entrada. A doc do Angular é explícita: "Angular does not provide any implicit validation that the inputs provided by an agent actually match the defined JSON schema. Consider explicitly validating arguments to the execute function before using them to ensure reliability." O schema documenta a tool; ele não impõe nada. Um agente sob [prompt injection](https://next.angular.dev/ai/webmcp) pode entregar ao seu `execute` o que uma página maliciosa convenceu ele a passar, então valide os argumentos logo no topo do `execute` e aborte em qualquer coisa que você não esperava.

Nomes de tool são um namespace, e um registro duplicado lança erro. Esse também é o mecanismo por trás do bug de autocleanup lá de cima: uma tool de rota antiga que nunca foi removida colide com a nova na próxima visita.

Onde eu fico: eu me recusaria a registrar uma tool que altera dado real sem confirmação nenhuma, e exigiria que todo `execute` que mexe em dinheiro, identidade ou ações destrutivas validasse as próprias entradas e reverificasse a autorização no servidor, exatamente como se a chamada viesse de um cliente não confiável. Porque vem.

## Onde eu faria um spike e onde eu esperaria

Eu faria um spike de WebMCP numa ferramenta interna ou numa rota de baixo risco, atrás de uma flag, para aprender o desenho de tools e os schemas de entrada. Esse investimento sobrevive mesmo que a API mude de nome.

Eu esperaria em qualquer coisa voltada ao usuário em produção, em qualquer fluxo crítico ou regulado, e em qualquer ponto onde uma quebra no meio do ciclo seja cara de perseguir. Com o ponto de entrada ainda saindo de `navigator` para `document.modelContext` e a configuração de rota recomendada carregando um bug aberto de tool duplicada, o custo de tratar isso como estável é real, e ele é independente de a ideia ser boa. A ideia é boa. A superfície é que ainda não assentou.

| Cenário | Spike ou esperar | Por quê |
|---|---|---|
| Ferramenta interna de admin, com flag | Spike | Aprenda desenho de tool e schema onde a quebra é barata. |
| Lookup só-leitura numa rota menor | Spike | Raio de impacto pequeno, fácil de remover se a API mudar. |
| Tools com escopo de rota hoje | Spike, com cuidado | Fique de olho na race de tool duplicada da issue #68899 ao navegar repetidamente. |
| Ação voltada ao usuário em produção | Esperar | Mudanças na spec fora de major podem quebrar fluxos publicados. |
| Fluxo regulado ou de pagamento | Esperar | Tools expostas ampliam a superfície que um agente consegue disparar. |

## Artefato reaproveitável: Gate de spike para WebMCP

- Limite o spike a uma rota interna ou de baixo risco, atrás de uma flag.
- Faça feature detection do ponto de entrada: `document.modelContext || navigator.modelContext`.
- Se você der escopo de rota às tools, conte com a race de tool duplicada do `withExperimentalAutoCleanupInjectors` (issue #68899) e teste navegação repetida.
- Ajuste o `exposedTo` para o conjunto mais estreito de origens de que a tool precisa.
- Valide toda entrada do `execute` em runtime; o JSON schema é documentação, não imposição.
- Anote o que cada tool exposta deixa o agente disparar, e reverifique a autorização no servidor para qualquer coisa que altere dado.
- Recheque status e nomes de API a cada minor do Angular, não só nos majors.

## Perguntas frequentes

### O WebMCP é estável no Angular?

Não. O suporte do Angular é experimental e o time avisa que as APIs "are subject to change even outside of major versions." A spec por baixo é um [draft de Community Group do W3C](https://webmachinelearning.github.io/webmcp/), não um padrão.

### É `navigator.modelContext` ou `document.modelContext`?

Desde 2026-06-01 o ponto de entrada passou para `document.modelContext` ([PR #68961](https://github.com/angular/angular/pull/68961)). Faça feature detection dos dois com `const modelContext = document.modelContext || navigator.modelContext;` até a mudança assentar entre os consumidores.

### Qual a diferença entre o WebMCP e o Angular CLI MCP server?

O [Angular CLI MCP server](/angular/angular-cli-mcp-ai-generated-angular-code/) é uma ferramenta de tempo de desenvolvimento: entrega contexto do projeto para um assistente enquanto você escreve código. O WebMCP é runtime: o seu app publicado expõe tools para o agente que roda no browser do usuário final. Camada diferente, superfície bem maior. Eu comparo as duas de frente em [WebMCP vs Angular CLI MCP server](/angular/webmcp-vs-angular-cli-mcp-server/).

### Eu mesmo preciso validar as entradas do agente?

Sim. A doc afirma que o Angular "not provide any implicit validation that the inputs provided by an agent actually match the defined JSON schema." Valide os argumentos no início de todo `execute`, e reverifique a autorização no servidor para qualquer coisa que altere dado.

### De qual versão do Angular eu preciso?

O suporte a WebMCP chegou com o v22, mas ainda é uma API experimental. É por isso que o guia mora hoje em [next.angular.dev/ai/webmcp](https://next.angular.dev/ai/webmcp).

### Dá para testar tools WebMCP sem um browser que suporte isso?

Dá. O guia sugere o pacote `@mcp-b/webmcp-polyfill` como mock para testes unitários, então você consegue afirmar que as tools registram e que o `execute` devolve o que você espera.

## Fontes consultadas

- https://next.angular.dev/ai/webmcp
- https://next.angular.dev/api/core/provideExperimentalWebMcpTools
- https://webmachinelearning.github.io/webmcp/
- https://github.com/webmachinelearning/webmcp
- https://angular.dev/ai/mcp
- https://angular.dev/guide/forms/signals/overview
- https://angular.dev/reference/releases
- https://github.com/angular/angular/issues/68899
- https://github.com/angular/angular/issues/68947
- https://github.com/angular/angular/pull/68961

## Leia também

- [WebMCP vs Angular CLI MCP server: tools em runtime vs ajuda em dev-time](https://andreramos.dev/pt/angular/webmcp-vs-angular-cli-mcp-server/)
- [Segurança de WebMCP no Angular: o agente que chama suas tools pode ser sequestrado](https://andreramos.dev/pt/angular/web-mcp-security-angular/)
- [Transformando Signal Forms em tools de agente de IA](https://andreramos.dev/pt/angular/signal-forms-as-ai-agent-tools/)
