Angular v22 WebMCP Tools: Give AI Direct Access to Your App's State
Angular v22 ships an experimental API called provideWebMcpTools() that lets you register tools for AI models to call. Instead of relying on DOM scraping, models like Gemini can execute functions that access Angular's dependency injection and signals. This means the AI works with real business logic, not just rendered HTML.
The Problem: AI Is Blind to App State
Most AI interactions with web apps are limited to what the model can see in the rendered page. This is brittle and surface-level. Hidden metrics—like retention risk calculations or account flags—are invisible to the AI. Without a structured way to expose these capabilities, the model guesses based on incomplete information.
The Solution: Angular Signal State + WebMCP Tools
Before giving the AI tools, you need a clean source of truth. The article uses a UserStore service with the @Service() decorator and signals:
import { computed, Service, signal } from '@angular/core';
import { USER_ACCOUNTS, type UserKey } from './user.mock-data';
@Service()
export class UserStore {
private readonly selectedUserKeyState = signal('sarah');
readonly users = [
{ key: 'sarah', user: USER_ACCOUNTS.sarah.user },
{ key: 'marcus', user: USER_ACCOUNTS.marcus.user },
] as const;
readonly selectedUserKey = this.selectedUserKeyState.asReadonly();
readonly currentUser = computed(() => USER_ACCOUNTS[this.selectedUserKey()].user);
readonly account = computed(() => USER_ACCOUNTS[this.selectedUserKey()].account);
readonly isHighRiskAccount = computed(() => {
const account = this.account();
return (
account.daysSinceLastLogin > 14 ||
account.paymentFailures > 0 ||
account.unresolvedPriorityTickets > 0
);
});
selectUser(userKey: UserKey): void {
this.selectedUserKeyState.set(userKey);
}
}
The isHighRiskAccount signal computes risk from multiple factors—days since last login, payment failures, unresolved tickets. This is exactly the kind of hidden logic an AI wouldn't know from the UI alone.
Registering WebMCP Tools
Angular v22's provideWebMcpTools() registers tools through the provider system. These tools run inside the Angular injection context, so they can use dependency injection to access services and signals. The article registers tools globally in app.config.ts:
import { ..., provideWebMcpTools } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [
provideWebMcpTools([])
]
};
Each tool requires a name, description, inputSchema, and execute function.
Tool 1: Summarize the Current Customer
A simple tool that returns the current user's details from the signal:
{
name: 'get_current_user_summary',
description: 'Returns a summary of the current user.',
inputSchema: { type: 'object', properties: {} },
execute: () => {
const user = inject(UserStore).currentUser();
return {
content: [
{
type: 'text',
text: `Name: ${user.name}
Email: ${user.email}
Plan: ${user.plan}
Status: ${user.status}
Last login: ${user.lastLogin}
Open tickets: ${user.openTickets}`,
},
],
};
},
}
The AI calls this tool instead of scraping the DOM. It reads state directly from the UserStore.
Tool 2: Analyze Retention Risk
This tool uses the isHighRiskAccount computed signal to return a risk assessment with reasons and recommended actions:
{
name: 'get_retention_risk',
description: 'Analyzes the current account and explains retention risk.',
inputSchema: { type: 'object', properties: {} },
execute: () => {
const store = inject(UserStore);
const user = store.currentUser();
const account = store.account();
const isHighRisk = store.isHighRiskAccount();
return {
content: [
{
type: 'text',
text: isHighRisk ?
`${user.name} is currently considered high risk.
Reasons:
- ${account.daysSinceLastLogin} days since last login
- ${account.paymentFailures} recent payment failures
- ${account.unresolvedPriorityTickets} unresolved priority ticket
Recommended next action:
Have customer success schedule a live onboarding session.` :
`${user.name} is currently considered low risk.
No significant warning signs detected.
Recommended next action:
No immediate action needed.`
},
],
};
},
}
Tool 3: Draft a Customer Success Note
This tool drafts an outreach message that adapts based on risk level:
{
name: 'draft_customer_success_note',
description: 'Drafts a customer success outreach note for the current account.',
inputSchema: { type: 'object', properties: {} },
execute: () => {
const store = inject(UserStore);
const user = store.currentUser();
const isHighRisk = store.isHighRiskAccount();
return {
content: [
{
type: 'text',
text: isHighRisk ?
`Hi ${user.name},
I noticed you may have run into a few issues recently, and I wanted to reach out personally to see if we can help.
If you'd like, we can schedule a quick onboarding session to walk through the platform and help resolve any blockers.
Thanks,
Customer Success Team` :
`Hi ${user.name},
Just wanted to check in and make sure everything is still going smoothly.
Thanks for being a customer, and let us know if there's anything we can help with.
Thanks,
Customer Success Team`
},
],
};
},
}
Testing with the Inspector
Once registered, all three tools appear in the WebMCP Model Context Tool Inspector. When you ask Gemini questions like "Can you summarize this customer account?" or "Is this customer at risk?", it calls the appropriate tool instead of scraping the page. The responses change as underlying signal state changes.
What This Means for Angular Developers
Angular v22's WebMCP tools turn the browser into a collaborative environment where AI understands app context. By exposing app-defined capabilities, you get safe, explicit, and reactive AI integration backed by existing services and logic. The feature is experimental, but it previews where Angular and browser-based AI tooling are heading.
Next Steps
To try it yourself, check the source code and the commit that made this possible. Also read the WebMCP unofficial draft. If you want to dive deeper into Angular's new forms model, Brian Treese's Signal Forms course is available.

