DEV Community

Cover image for Angular Is Preparing for AI Agents: WebMCP, MCP Tooling, and Agent Skills in Angular 22 - - What Changes in NG 22 (Part 10)
Rajat
Rajat

Posted on

Angular Is Preparing for AI Agents: WebMCP, MCP Tooling, and Agent Skills in Angular 22 - - What Changes in NG 22 (Part 10)

How Angular 22 lets AI coding agents build your app faster, debug it live, and — with WebMCP — actually call it like a tool

What if an AI agent didn't just help you write your Angular app, but could also use it directly once it's running — clicking through a form, listing your users, creating a record — the same way it would call an API? That's not a hypothetical anymore. Angular 22 ships real, if early, plumbing for exactly that, alongside a quieter but more immediately useful set of tools that make AI coding agents genuinely better at writing Angular code today.

This is a genuinely confusing area of the release if you only skim the changelog, because "AI features" in Angular 22 actually means two very different things bundled together. One half is about agents that help you build and debug your app. The other half — WebMCP — is about your app becoming something an agent can operate on its own. We're going to untangle both, with working code for each. By the end you'll know:

  • What Agent Skills are and how they change what your coding agent does when it generates Angular code
  • How the Angular CLI's MCP server plugs your agent into your actual project instead of its training data
  • How Angular exposes a live signal graph and dependency injection graph for AI-assisted debugging
  • What WebMCP is, and how to declare a tool an agent can call directly from a component
  • How to auto-generate a WebMCP tool straight from a Signal Form
  • How to unit test the logic behind a WebMCP tool like you would any other method

If you've been following this series on Angular 22 — the stable Resource API, the router changes, the template improvements — this is the odd one out, and arguably the one worth paying closest attention to if you think agentic tooling is going to matter for frontend work over the next couple of years.

Quick ask before we get into it: this is a fast-moving corner of the framework, and I'll be writing more as WebMCP matures past experimental status. Follow along here if you'd rather not have to go digging for the next update yourself.

Before we dive into the examples, a quick note: the code snippets provided here are meant purely for understanding the concept. Some syntax shown may reflect patterns from earlier Angular versions, and a few APIs covered here are explicitly experimental as of this writing. Always refer to the official documentation for the most current API and syntax.

Two different problems, both labeled "AI"

Worth being precise about this before any code, because the two halves of Angular's AI story solve genuinely different problems:

  • Agents that build and debug your app. This is the Angular CLI's MCP server, the new Agent Skills, and in-browser debugging tools exposed through Chrome DevTools. None of this ships in your production bundle — it's tooling that makes Claude, or whichever coding agent you use, better at working inside an Angular codebase.
  • Your app as something an agent can operate. This is WebMCP. It ships in your application code, and it's about exposing specific capabilities — "list users," "create a booking" — that an agent visiting your site can call directly, instead of having to simulate clicks on your UI.

Let's take them in that order.

Agent Skills: teaching your coding agent how Angular actually works

The Angular CLI has shipped an MCP server since v20.1, giving coding agents a way to interact with your project directly rather than guessing from general training data. Angular 22 adds Agent Skills on top of that — a packaged set of guidelines that teach an agent how to generate idiomatic, current Angular code and provide architectural guidance, rather than falling back on outdated patterns it may have picked up from older tutorials.

npx skills add https://github.com/angular/skills
Enter fullscreen mode Exit fullscreen mode

That command installs two skills: one focused on scaffolding new Angular projects correctly, and a second, broader one covering code generation and architecture guidance across the framework. Once installed, an agent working in your repository picks up the relevant skill automatically when you ask it to generate Angular code — you don't have to reference it explicitly in every prompt.

One side effect worth knowing about: with skills now handling code-generation guidance, the CLI's MCP server dropped its find_examples and modernize tools, since the skill covers that ground more thoroughly than a lookup tool could. If you had scripts or workflows depending on those specific tools, that's worth double-checking after upgrading.

Debugging with AI: exposing the signal graph and the DI graph

Angular 22 also registers two debugging tools that a development build exposes for tooling to consume: a signal graph and a dependency injection graph, the same data Angular DevTools already visualizes. These are registered in Chrome DevTools as third-party tools, which means an agent connected through chrome-devtools-mcp can query your application's actual runtime state — which signals exist, how they're connected, what's injected where — instead of trying to infer it from source code alone.

This does need a bit of setup, since third-party DevTools tools require enabling specific MCP flags, but once wired up, an agent debugging a signal that isn't updating the way you expect can look at the real dependency graph rather than guessing from a stack trace.

WebMCP: your app as a tool an agent can call

Here's the part that's genuinely new territory. WebMCP is a proposed web standard — not an Angular-specific idea — that lets a website expose Model Context Protocol capabilities directly from the page itself. Instead of an agent needing a separate MCP server running somewhere on your machine or in the cloud, the website becomes the tool: an agent visiting your app can call a capability you've explicitly exposed, the same way it would call any other MCP tool.

As of this release it's early: WebMCP is only available behind a flag in Chrome Beta, and the Angular APIs built around it are explicitly marked experimental. That said, the shape of the API is worth understanding now, because it's a genuinely different way to think about what a component exposes.

Declaring a tool imperatively

declareExperimentalWebMcpTool(), available in @angular/core, lets you register a callable tool directly inside a component.

import { Component, inject } from '@angular/core';
import { declareExperimentalWebMcpTool } from '@angular/core';
import { UserService } from './user.service';

@Component({
  selector: 'app-users',
  template: `<p>User management is available to connected agents.</p>`,
})
export class Users {
  constructor() {
    declareExperimentalWebMcpTool({
      name: 'list_users',
      description: 'List users with a specific status',
      inputSchema: {
        type: 'object',
        properties: {
          status: { type: 'string', enum: ['ADMINS', 'STUDENTS'] },
        },
        required: ['status'],
        additionalProperties: false,
      },
      execute: ({ status }) => {
        return inject(UserService).list(status);
      },
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Two things worth calling out. First, inject() works inside the tool's execute function, so the tool can lean on Angular's dependency injection exactly like any other piece of component logic — you're not reaching outside the framework to wire this up. Second, Angular destroys the tool automatically when the component is destroyed, so a tool scoped to a page that's no longer active stops being callable without any manual cleanup on your part.

If you'd rather register a tool at the application level instead of tying it to a specific component's lifecycle, provideExperimentalWebMcpTool() does that from your app config.

import { ApplicationConfig } from '@angular/core';
import { provideExperimentalWebMcpTool } from '@angular/core';

export const appConfig: ApplicationConfig = {
  providers: [
    provideExperimentalWebMcpTool([
      {
        name: 'list_users',
        description: 'List users with a specific status',
        inputSchema: {
          type: 'object',
          properties: {
            status: { type: 'string', enum: ['ADMINS', 'STUDENTS'] },
          },
          required: ['status'],
          additionalProperties: false,
        },
        execute: ({ status }) => {
          return inject(UserService).list(status);
        },
      },
    ]),
  ],
};
Enter fullscreen mode Exit fullscreen mode

Would you actually expose write operations — creating or deleting records — through something like this today, or only read-only capabilities until the standard and the tooling around it mature? I lean toward read-only for now, but I'm curious where other people draw that line.

The declarative path: auto-registering tools from Signal Forms

The second half of WebMCP's proposal is a declarative API, where a plain HTML form gets marked up with toolname and tooldescription attributes to become agent-callable automatically. Angular's Signal Forms integrate with this directly, so if your form is already built with form(), you don't need to hand-write a schema at all.

Enable it once, at the application level:

import { ApplicationConfig } from '@angular/core';
import { provideExperimentalWebMcpForms } from '@angular/forms/signal';

export const appConfig: ApplicationConfig = {
  providers: [provideExperimentalWebMcpForms()],
};
Enter fullscreen mode Exit fullscreen mode

Then describe the tool as part of the form definition itself:

import { Component, signal } from '@angular/core';
import { form, required } from '@angular/forms/signals';

interface NewUser {
  name: string;
  email: string;
}

@Component({
  selector: 'app-user-creation',
  template: `
    <form>
      <input [formField]="userForm.name" placeholder="Name" />
      <input [formField]="userForm.email" placeholder="Email" />
    </form>
  `,
})
export class UserCreation {
  protected readonly model = signal<NewUser>({ name: '', email: '' });

  protected readonly userForm = form(
    this.model,
    (path) => {
      required(path.name);
      required(path.email);
    },
    {
      experimentalWebMcpTool: {
        name: 'user_creation',
        description: 'Form to create a new user',
      },
    },
  );
}
Enter fullscreen mode Exit fullscreen mode

Angular takes care of the rest: it generates the tool's input schema from the form fields themselves, and when an agent calls the tool, it fills the form with the provided input and submits it — the same validation your human users go through applies to the agent too. That last part matters more than it might seem: an agent can't bypass your required() and other validators just because it's calling the form programmatically instead of clicking through it.

Testing the logic behind a WebMCP tool

You don't need anything WebMCP-specific to test this — the execute function of a tool is just a function, and the interesting behavior almost always lives in the service it delegates to. Test that directly.

import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';

describe('UserService list()', () => {
  it('returns only users matching the requested status', () => {
    TestBed.configureTestingModule({
      providers: [UserService],
    });

    const service = TestBed.inject(UserService);
    const admins = service.list('ADMINS');

    expect(admins.every((user) => user.status === 'ADMINS')).toBe(true);
  });
});
Enter fullscreen mode Exit fullscreen mode

For the Signal Forms version, the thing actually worth testing is that the form's own validation still runs correctly — since that's exactly what protects you when an agent submits the form instead of a person.

import { TestBed } from '@angular/core/testing';
import { UserCreation } from './user-creation';

describe('UserCreation form', () => {
  it('is invalid when required fields are empty', () => {
    const fixture = TestBed.createComponent(UserCreation);
    fixture.detectChanges();

    const formState = fixture.componentInstance'userForm';
    expect(formState.invalid()).toBe(true);
  });

  it('is valid once name and email are filled in', () => {
    const fixture = TestBed.createComponent(UserCreation);
    const component = fixture.componentInstance;

    component['model'].set({ name: 'Ada Lovelace', email: 'ada@example.com' });
    fixture.detectChanges();

    const formState = component'userForm';
    expect(formState.invalid()).toBe(false);
  });
});
Enter fullscreen mode Exit fullscreen mode

Neither test touches WebMCP directly, and that's deliberate — the tool declaration is just a thin wrapper around logic you should already be testing regardless of whether an agent or a person is the one triggering it.

Bonus tips

  • Treat experimental APIs as exactly that. declareExperimentalWebMcpTool, provideExperimentalWebMcpTool, and provideExperimentalWebMcpForms all carry the experimental naming for a reason — expect the shape of these APIs to shift before they stabilize, and avoid building critical functionality on top of them just yet.
  • Scope tools to the narrowest lifecycle that makes sense. A component-level tool that's cleaned up automatically on destroy is usually safer than an app-wide one that stays registered for the entire session.
  • Pair route-level providers with withExperimentalAutoCleanupInjectors. If you're registering WebMCP tools through route-scoped providers, this router feature ensures the tools — and everything else in that environment injector — are actually torn down when the user navigates away, rather than lingering.
  • Read-only tools are the lower-risk place to start. Exposing a "list" or "search" capability carries a lot less downside than exposing something that mutates data, especially while the surrounding security model for WebMCP is still taking shape.
  • The Agent Skills package is worth adopting even if you have no interest in WebMCP. It's the part of this release most likely to quietly improve your day-to-day experience, since it changes what your coding agent produces by default, not just what your production app can do.

Recap

Angular 22's AI story splits cleanly into two halves once you look past the shared label: Agent Skills and the CLI's MCP server make coding agents better at building and debugging your app, while WebMCP is about your running app exposing capabilities an agent can call directly. The first half is low-risk and immediately useful — install the skills package and your agent's output quietly gets better. The second half is early, genuinely experimental, and worth understanding now specifically so you're not starting from zero once it stabilizes.

If you're curious where this goes next, keep an eye on how the WebMCP standard itself matures outside of Angular — the framework APIs here are clearly built to track it closely, which means they'll likely keep changing until the underlying browser proposal settles down.


What did you think?
Did this approach match how you are solving it, or do you have a different take? Drop a comment — I genuinely read every single one.

Found this helpful?
If this saved you even a few minutes of debugging or confusion, hit that clap button so others can find it too. It really does make a difference.

Want more tips like this?
I share one practical dev insight every week. Follow me here on Medium or subscribe to my newsletter so you never miss one.

Let us connect — find me on LinkedIn or GitHub and let us keep the conversation going.


Follow Me for More Angular & Frontend Goodness:

I regularly share hands-on tutorials, clean code tips, scalable frontend architecture, and real-world problem-solving guides.

  • 💼 LinkedIn — Let’s connect professionally
  • 🎥 Threads — Short-form frontend insights
  • 🐦 X (Twitter) — Developer banter + code snippets
  • 👥 BlueSky — Stay up to date on frontend trends
  • 🌟 GitHub Projects — Explore code in action
  • 🌐 Website — Everything in one place
  • 📚 Medium Blog — Long-form content and deep-dives
  • 💬 Dev Blog — Free Long-form content and deep-dives
  • ✉️ Substack — Weekly frontend stories & curated resources
  • 🧩 Portfolio — Projects, talks, and recognitions
  • ✍️ Hashnode — Developer blog posts & tech discussions
  • ✍️ Reddit — Developer blog posts & tech discussions

Top comments (0)