Saltar al contenido
< samuelsantana.dev />
Volver al BlogIlustración de un robot de IA operando un panel de Angular en el navegador: activa el tema oscuro, ajusta el filtro de precio máximo y dispara un aviso para el lector de pantalla.

El Frontend Guiado por IA: WebMCP, Tools y Accesibilidad en Angular

Samuel Santana
Publicado el 20 de julio de 2026
AngularIA

Durante años, el papel del frontend estuvo muy claro: consumir datos de una API (REST o GraphQL), gestionar el estado local y renderizar HTML. Construíamos aplicaciones "tontas" que dependían exclusivamente del clic del usuario para ejecutar cualquier acción.

Pero la profunda integración de la Inteligencia Artificial en nuestro ecosistema cambió las reglas del juego. La IA dejó de ser solo un chat aislado en la esquina de la pantalla. Hoy en día, los modelos actúan como Agentes Autónomos que operan el software para el usuario.

En este nuevo paradigma, el frontend deja de ser un simple visualizador de datos y pasa a actuar como los ojos y las manos de la IA. Y es exactamente aquí donde tres conceptos chocan en la arquitectura moderna de Angular: WebMCP (Web Model Context Protocol), Agent Skills (aquí, acciones expuestas al agente como tools) y accesibilidad (CDK a11y y Angular Aria).

En este artículo, vamos a analizar cómo preparar tu aplicación Angular para hospedar agentes de IA de forma nativa, con buen rendimiento y sin sacrificar la accesibilidad.


1. WebMCP: El Frontend como Proveedor de Contexto (En la Práctica)

Para entender WebMCP, necesitamos observar la pesadilla que es intentar darle contexto a una Inteligencia Artificial hoy en día.

Imagina que tienes un e-commerce. El usuario abre el asistente de IA en la pantalla del carrito y escribe: "¿Tengo saldo suficiente en mi billetera para pagar estos artículos?"

El problema: la IA es ciega. Se ejecuta en un servidor remoto (OpenAI, Anthropic, etc.) y no tiene ni idea de qué artículos están en la pantalla del usuario, y mucho menos de cuál es su saldo.

El "Hack" Tradicional (Context Stuffing)

Históricamente, la solución del mercado para esto era forzar al frontend a enviar todo el contexto en cada mensaje. Siempre que el usuario presionaba Enter, hacíamos algo así antes de llamar a la API de la IA:

const promptOculto = `
  El usuario está en la pantalla del carrito.
  Artículos en el carrito: ${JSON.stringify(this.cartSignal())}
  Saldo del usuario: ${this.userBalanceSignal()}
  
  Pregunta del usuario: "¿Tengo saldo suficiente?"
`;

Esto es terrible. Si el carrito tiene 50 artículos, gastas miles de tokens (y dinero) en cada mensaje, enviando datos que la IA tal vez ni siquiera necesite para responder a esa pregunta en específico.

La Solución: Web Model Context Protocol (WebMCP)

Creado inicialmente por Anthropic y adoptado como un estándar abierto de la industria, el MCP funciona como si fuera una API REST, pero construida específicamente para que la consuman los Agentes de IA. WebMCP lleva la idea al navegador: es una propuesta de API web (no el MCP en sí) incubada en el W3C Web Machine Learning Community Group, con editores de Google y Microsoft, y todavía experimental: en Chrome solo funciona con la flag chrome://flags/#enable-webmcp-testing o mediante un origin trial.

En lugar de empujar (Push) los datos ciegamente a la IA en cada petición, el frontend expone herramientas (tools) y la IA solicita (Pull) la información solo cuando la necesita.

En Angular 22, registramos estas herramientas con una API experimental del propio framework, que las entrega al WebMCP del navegador. Mira cómo ocurre la inversión de control en la práctica:

import { Injectable, declareExperimentalWebMcpTool, signal } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AppContextOrchestrator {
  // Nuestro estado reactivo estándar
  cartItems = signal([{ id: 1, name: 'Teclado Mecánico', price: 450 }]);
  userBalance = signal(500);

  constructor() {
    this.registerWebMcpTools();
  }

  private registerWebMcpTools() {
    // WebMCP solo expone herramientas (tools); leer estado se convierte en una tool sin argumentos.
    // API experimental de Angular 22: sin WebMCP en el navegador, el registro se omite.

    // 1. Expone el Carrito como una tool de solo lectura
    declareExperimentalWebMcpTool({
      name: 'get_cart',
      description: 'Devuelve los artículos del carrito de compras del usuario, en JSON.',
      inputSchema: { type: 'object', properties: {} },
      execute: () => JSON.stringify(this.cartItems()), // Lee el Signal en el momento de la llamada
    });

    // 2. Expone el Saldo como una tool de solo lectura
    declareExperimentalWebMcpTool({
      name: 'get_balance',
      description: 'Devuelve el saldo actual de la billetera virtual del usuario.',
      inputSchema: { type: 'object', properties: {} },
      execute: () => this.userBalance().toString(),
    });
  }
}

El Nuevo Flujo Guiado por IA

Con WebMCP ejecutándose en Angular, la conversación del ejemplo anterior funciona así:

  1. Usuario: "¿Tengo saldo suficiente para pagar estos artículos?"
  2. Agente de IA (Piensa): "Para responder, necesito saber qué hay en el carrito y cuál es el saldo."
  3. Agente de IA (Acción): El agente del navegador llama a las herramientas get_cart y get_balance que registró la página; se ejecutan en el propio JavaScript de la página.
  4. Angular (WebMCP): Lee el valor actual de los Signals y devuelve solo esos datos puntuales a la IA.
  5. Agente de IA (Responde): "El teclado cuesta 450 dólares y tienes 500 dólares de saldo. ¡Sí, tienes saldo suficiente!"

Esta arquitectura reduce el desperdicio de tokens, mantiene el contexto siempre en tiempo real según los Signals de la aplicación y transforma tu frontend en un Servidor de Contexto inteligente.


2. Agent Skills: Transformando Angular Signals en Acciones

Si WebMCP es la forma en que la IA "ve" la aplicación, las Agent Skills son la forma en que la "toca". Una aclaración de nomenclatura: llamo "skill" a cada acción que el agente puede disparar, pero el término técnico es tool (function calling). Agent Skills, como estándar, es otra cosa: el formato abierto creado por Anthropic en el que cada skill es una carpeta con un archivo SKILL.md (metadatos + instrucciones) que los agentes de código cargan bajo demanda; Angular publica las suyas en angular/skills.

En lugar de que la IA responda con texto, la instruimos para que responda con llamadas a funciones (Function Calling). En el Angular moderno, mapeamos estas "Skills" directamente a actualizaciones de Signals o rutas.

Imagina un e-commerce. El usuario le dice al micrófono (o escribe): "Cambia al tema oscuro y muéstrame solo las zapatillas de correr por debajo de 300 dólares".

Mira cómo orquestar esto en Angular usando un servicio enfocado en registrar Skills:

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

// Interfaz que define el contrato de la Skill para el Agente de IA
interface AgentSkill {
  name: string;
  description: string;
  inputSchema: object;
  execute: (args: any) => Promise<void> | void;
}

@Injectable({ providedIn: 'root' })
export class AiAgentOrchestrator {
  private router = inject(Router);
  
  // El Estado de la Aplicación (Lo que la IA verá/alterará vía MCP)
  theme = signal<'light' | 'dark'>('light');
  priceFilter = signal<number | null>(null);

  // Registro de las habilidades que el Agente puede invocar
  private registeredSkills = new Map<string, AgentSkill>();

  constructor() {
    this.registerCoreSkills();
  }

  private registerCoreSkills() {
    this.registeredSkills.set('changeTheme', {
      name: 'changeTheme',
      description: 'Cambia el tema visual de la aplicación. Argumentos aceptados: "light" o "dark".',
      inputSchema: {
        type: 'object',
        properties: { theme: { type: 'string', enum: ['light', 'dark'] } },
        required: ['theme'],
      },
      execute: ({ theme }) => this.theme.set(theme)
    });

    this.registeredSkills.set('filterProducts', {
      name: 'filterProducts',
      description: 'Aplica un filtro de precio máximo en la lista de productos.',
      inputSchema: {
        type: 'object',
        properties: { maxPrice: { type: 'number' } },
        required: ['maxPrice'],
      },
      execute: ({ maxPrice }) => this.priceFilter.set(maxPrice)
    });

    this.registeredSkills.set('navigate', {
      name: 'navigate',
      description: 'Navega al usuario a una ruta específica, como "/carrito" o "/perfil".',
      inputSchema: {
        type: 'object',
        properties: { path: { type: 'string' } },
        required: ['path'],
      },
      execute: async ({ path }) => { await this.router.navigate([path]); }
    });
  }

  // Método llamado por el cliente WebMCP/LLM cuando decide usar una herramienta
  executeSkill(skillName: string, args: any) {
    const skill = this.registeredSkills.get(skillName);
    if (skill) {
      skill.execute(args);
    } else {
      console.warn(`La IA intentó ejecutar una skill inexistente: ${skillName}`);
    }
  }
}

En esta arquitectura, la IA se convierte en un "usuario fantasma". El AiAgentOrchestrator traduce las intenciones de la inteligencia artificial en cambios de estado reales (Signals), actualizando la Vista de forma granular (Fine-Grained Reactivity) y sin depender de Zone.js.


3. El Desafío Invisible: Angular Aria y Accesibilidad

Aquí entramos en el error más grave cometido por los equipos que integran IA en el frontend: destruir la accesibilidad.

Cuando un usuario hace clic en el botón "Filtrar", sabe que la pantalla va a cambiar porque él inició la acción. Pero cuando la IA filtra los productos de manera autónoma, el DOM (Document Object Model) cambia de repente. Para un usuario que depende de lectores de pantalla (Screen Readers), la interfaz simplemente se "rompió" o "desapareció" silenciosamente.

Dado que la IA opera la interfaz de usuario dinámicamente, nosotros necesitamos avisar al usuario sobre lo que el Agente acaba de hacer. El @angular/cdk/a11y resuelve esto de forma elegante con el LiveAnnouncer. No hay que confundirlo con Angular Aria (@angular/aria): reúne directivas headless que implementan patrones WAI-ARIA — Listbox, Combobox, Menu, Tabs, Tree, Grid, entre otros — y se encarga del teclado, el foco y los atributos ARIA, pero no incluye un anunciador; el anuncio queda a cargo del CDK.

Vamos a refactorizar nuestro orquestador para que sea accesible:

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

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

  private registerCoreSkills() {
    this.registeredSkills.set('filterProducts', {
      name: 'filterProducts',
      description: 'Aplica un filtro de precio máximo.',
      inputSchema: {
        type: 'object',
        properties: { maxPrice: { type: 'number' } },
        required: ['maxPrice'],
      },
      execute: ({ maxPrice }) => {
        // 1. Actualiza el estado visual
        this.priceFilter.set(maxPrice);
        
        // 2. Anuncia el cambio al lector de pantalla (Accesibilidad)
        this.announcer.announce(`La Inteligencia Artificial aplicó un filtro para productos hasta ${maxPrice} dólares.`, 'polite');
      }
    });
  }
}

El valor 'polite' (parámetro politeness de announce) es crucial. Le dice al lector de pantalla del sistema operativo (como VoiceOver o NVDA) que espere a que el usuario deje de interactuar antes de hablar, evitando interrumpir la navegación bruscamente.

Si la IA ejecutara una acción de emergencia (ej. cerrar la sesión del usuario por cuestiones de seguridad), usaríamos 'assertive' para interrumpir todo y avisar al usuario inmediatamente.


Conclusión

La transición de interfaces estáticas a "Anfitrionas de Agentes" todavía depende de APIs experimentales, pero es la arquitectura que vale la pena empezar a diseñar hoy.

Al combinar WebMCP para proporcionarle el contexto de la aplicación a la IA, las Agent Skills atadas al sistema reactivo de Signals, y el LiveAnnouncer del CDK para mantener la mutación del DOM accesible, creamos sistemas que no solo son inteligentes, sino robustos, rápidos e inclusivos.

El frontend ya no es un consumidor pasivo de APIs. Ahora es el espacio de trabajo (workspace) de tu Agente de Inteligencia Artificial. Y Angular nos brinda buenas herramientas para orquestar esta complejidad sin perder el control.

Comentarios

Cargando comentarios...