Pular para o conteúdo
< samuelsantana.dev />
Voltar para o Blog

O Frontend Guiado por IA: Integrando WebMCP, Agent Skills e Angular Aria

Samuel Santana
Publicado em 20 de julho de 2026
AngularIA

Durante anos, o papel do frontend foi muito claro: buscar dados em uma API (REST ou GraphQL), gerenciar o estado local e renderizar HTML. Nós construímos aplicações "burras" que dependiam exclusivamente do clique do usuário para executar qualquer ação.

Mas a integração profunda da Inteligência Artificial no nosso ecossistema mudou as regras do jogo. A IA deixou de ser apenas um chat isolado no canto da tela. Hoje, modelos atuam como Agentes Autônomos que operam o software para o usuário.

Neste novo paradigma, o frontend deixa de ser apenas um exibidor de dados e passa a atuar como os olhos e as mãos da IA. E é exatamente aqui que três conceitos colidem na arquitetura Angular moderna: WebMCP (Model Context Protocol), Agent Skills (Function Calling no cliente) e Angular Aria (Acessibilidade dinâmica).

Neste artigo, vamos dissecar como preparar sua aplicação Angular para hospedar agentes de IA de forma nativa, performática e 100% acessível.


1. WebMCP: O Frontend como Provedor de Contexto (Na Prática)

Para entender o WebMCP, precisamos olhar para o pesadelo que é tentar dar contexto para uma Inteligência Artificial hoje.

Imagine que você tem um e-commerce. O usuário abre o assistente de IA na tela do carrinho e digita: "Tenho saldo suficiente na carteira para pagar por estes itens?"

O problema: A IA é cega. Ela roda em um servidor remoto (OpenAI, Anthropic, etc.) e não faz ideia de quais itens estão na tela do usuário, muito menos qual é o saldo dele.

A "Gambiarra" Tradicional (Prompt Injection)

Historicamente, a solução do mercado para isso era forçar o frontend a enviar todo o contexto a cada mensagem. Sempre que o usuário apertava Enter, nós fazíamos algo assim antes de chamar a API da IA:

const promptOculto = `
  O usuário está na tela de carrinho.
  Itens no carrinho: ${JSON.stringify(this.cartSignal())}
  Saldo do usuário: ${this.userBalanceSignal()}
  
  Pergunta do usuário: "Tenho saldo suficiente?"
`;

Isso é péssimo. Se o carrinho tiver 50 itens, você gasta milhares de tokens (e dinheiro) a cada mensagem, enviando dados que a IA talvez nem precise para responder àquela pergunta específica.

A Solução: Web Model Context Protocol (WebMCP)

Criado inicialmente pela Anthropic e adotado como um padrão aberto da indústria, o MCP funciona como se fosse uma API REST, mas construída especificamente para Agentes de IA consumirem.

Em vez de empurrar os dados cegamente para a IA a cada requisição (Push), o frontend expõe "Recursos" e a IA puxa a informação apenas quando precisa (Pull).

No Angular, nós podemos instanciar um Servidor MCP diretamente no navegador (WebMCP). Veja como a inversão de controle acontece na prática:

import { Injectable, signal } from '@angular/core';
import { WebMcpServer } from '@mcp/sdk/client';

@Injectable({ providedIn: 'root' })
export class AppContextOrchestrator {
  // Nosso estado reativo comum
  cartItems = signal([{ id: 1, name: 'Teclado Mecânico', price: 450 }]);
  userBalance = signal(500);

  constructor() {
    this.initializeMcpServer();
  }

  private initializeMcpServer() {
    // Inicializa o servidor MCP no navegador do cliente
    const mcpServer = new WebMcpServer('MeuAppEcommerce');

    // 1. Expõe o Carrinho como um Recurso
    mcpServer.registerResource(
      'app://state/cart', // URI única do recurso
      'Estado atual do carrinho de compras do usuário',
      () => JSON.stringify(this.cartItems()) // Retorna o valor do Signal dinamicamente
    );

    // 2. Expõe o Saldo como um Recurso
    mcpServer.registerResource(
      'app://state/balance',
      'Saldo atual da carteira virtual do usuário',
      () => this.userBalance().toString()
    );

    mcpServer.listen();
  }
}

O Novo Fluxo Guiado por IA

Com o WebMCP rodando no Angular, a conversa do exemplo anterior funciona assim:

  1. Usuário: "Tenho saldo suficiente para pagar por estes itens?"
  2. Agente de IA (Pensa): "Para responder, eu preciso saber o que está no carrinho e qual é o saldo."
  3. Agente de IA (Ação): Faz uma requisição MCP via WebSocket para o navegador do usuário pedindo as URIs app://state/cart e app://state/balance.
  4. Angular (WebMCP): Lê o valor atual dos Signals e devolve apenas esses dados pontuais para a IA.
  5. Agente de IA (Responde): "O teclado custa 450 reais e você tem 500 reais de saldo. Sim, você tem saldo suficiente!"

Essa arquitetura elimina o desperdício de tokens, mantém o contexto sempre em tempo real de acordo com os Signals da aplicação e transforma o seu frontend em um Servidor de Contexto inteligente.


2. Agent Skills: Transformando Angular Signals em Ações

Se o WebMCP é como a IA "vê" a aplicação, as Agent Skills são como ela "toca" nela.

Em vez de a IA responder com texto, nós a instruímos a responder com chamadas de função (Function Calling). No Angular moderno, nós mapeamos essas "Skills" diretamente para atualizações de Signals ou rotas.

Imagine um e-commerce. O usuário diz ao microfone (ou digita): "Mude para o tema escuro e me mostre apenas os tênis de corrida abaixo de 300 reais".

Veja como orquestrar isso no Angular usando um serviço focado em registrar Skills:

import { Injectable, inject, signal } from '@angular/core';
import { Router } from '@angular/router';

// Interface que define o contrato da Skill para o Agente de IA
interface AgentSkill {
  name: string;
  description: string;
  execute: (args: any) => Promise<void> | void;
}

@Injectable({ providedIn: 'root' })
export class AiAgentOrchestrator {
  private router = inject(Router);
  
  // O Estado da Aplicação (O que a IA vai enxergar/alterar via MCP)
  theme = signal<'light' | 'dark'>('light');
  priceFilter = signal<number | null>(null);

  // Registro das habilidades que o Agente pode invocar
  private registeredSkills = new Map<string, AgentSkill>();

  constructor() {
    this.registerCoreSkills();
  }

  private registerCoreSkills() {
    this.registeredSkills.set('changeTheme', {
      name: 'changeTheme',
      description: 'Altera o tema visual da aplicação. Argumentos aceitos: "light" ou "dark".',
      execute: ({ theme }) => this.theme.set(theme)
    });

    this.registeredSkills.set('filterProducts', {
      name: 'filterProducts',
      description: 'Aplica um filtro de preço máximo na listagem de produtos.',
      execute: ({ maxPrice }) => this.priceFilter.set(maxPrice)
    });

    this.registeredSkills.set('navigate', {
      name: 'navigate',
      description: 'Navega o usuário para uma rota específica, como "/carrinho" ou "/perfil".',
      execute: async ({ path }) => { await this.router.navigate([path]); }
    });
  }

  // Método chamado pelo cliente WebMCP/LLM quando decide usar uma ferramenta
  executeSkill(skillName: string, args: any) {
    const skill = this.registeredSkills.get(skillName);
    if (skill) {
      skill.execute(args);
    } else {
      console.warn(`A IA tentou executar uma skill inexistente: ${skillName}`);
    }
  }
}

Nesta arquitetura, a IA se torna uma "usuária fantasma". O AiAgentOrchestrator traduz as intenções da inteligência artificial em mudanças de estado reais (Signals), atualizando a View de forma granular (Fine-Grained Reactivity) e sem depender de Zone.js.


3. O Desafio Invisível: Angular Aria e Acessibilidade

Aqui entramos no erro mais grave cometido por times que integram IA no frontend: destruir a acessibilidade.

Quando um usuário clica no botão "Filtrar", ele sabe que a tela vai mudar porque ele iniciou a ação. Mas quando a IA filtra os produtos autonomamente, o DOM (Document Object Model) muda de repente. Para um usuário que depende de leitores de tela (Screen Readers), a interface simplesmente "quebrou" ou "sumiu" silenciosamente.

Como a IA opera a UI dinamicamente, nós precisamos avisar o usuário sobre o que o Agente acabou de fazer. O @angular/cdk/a11y resolve isso de forma elegante com o LiveAnnouncer.

Vamos refatorar nosso orquestrador para ser acessível:

import { Injectable, inject, signal } from '@angular/core';
import { LiveAnnouncer } from '@angular/cdk/a11y';

@Injectable({ providedIn: 'root' })
export class AiAgentOrchestrator {
  private announcer = inject(LiveAnnouncer); // Injetando o CDK A11y
  
  priceFilter = signal<number | null>(null);
  
  // ... (código de registro omitido para brevidade)

  private registerCoreSkills() {
    this.registeredSkills.set('filterProducts', {
      name: 'filterProducts',
      description: 'Aplica um filtro de preço máximo.',
      execute: ({ maxPrice }) => {
        // 1. Atualiza o estado visual
        this.priceFilter.set(maxPrice);
        
        // 2. Anuncia a mudança para o leitor de tela (Acessibilidade)
        this.announcer.announce(`A Inteligência Artificial aplicou um filtro para produtos até ${maxPrice} reais.`, 'polite');
      }
    });
  }
}

A flag 'polite' no LiveAnnouncer é crucial. Ela diz ao leitor de tela do SO (como VoiceOver ou NVDA) para aguardar o usuário parar de interagir antes de falar, evitando interromper a navegação bruscamente.

Se a IA executar uma ação de emergência (ex: deslogar o usuário por questões de segurança), usaríamos 'assertive' para interromper tudo e avisar o usuário imediatamente.


Conclusão

A transição de interfaces estáticas para "Hospedeiras de Agentes" não é o futuro, é a arquitetura que precisamos projetar hoje.

Ao combinar o WebMCP para fornecer o contexto da aplicação à IA, as Agent Skills amarradas ao sistema reativo de Signals, e o rigor do Angular Aria para manter a mutação do DOM acessível, nós criamos sistemas que não são apenas inteligentes, mas robustos, performáticos e inclusivos.

O frontend não é mais um consumidor passivo de APIs. Ele agora é o ambiente de trabalho (workspace) do seu Agente de Inteligência Artificial. E o Angular nos dá o ferramental perfeito para orquestrar essa complexidade sem abrir mão de controle.

Comentários

Carregando comentários...

Participe da conversa

Entre com sua conta para comentar neste artigo.