refactor(forms): add provideExperimentalWebMcpForms

This enables the use of the `experimentalWebMcpTool` option on signal forms and implicitly declares a WebMCP tool based on the form data model. This is an experiment inspirted by the WebMCP declarative forms API to see if Angular's framework-level knowledge of the form's declarative data model can produce higher quality WebMCP tools than the web standard can on its own with less effort from the developer.

Example:

```typescript
// main.ts

import {bootstrapApplication} from '@angular/platform-browser';
import {provideExperimentalWebMcpForms} from '@angular/forms';
import {MyComp} from './form';

bootstrapApplication(MyComp, {
  providers: [
    // Activate the feature.
    provideExperimentalWebMcpForms(),
  ],
});
```

```typescript
// form.ts

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

@Component({ /* ... */ })
export class MyComp {
  private readonly f = form(signal({
    firstName: '',
    lastName: '',
  }), {
    // Implicitly creates a WebMCP tool named `createUser` which accepts a `firstName` and `lastName` as parameters.
    experimentalWebMcpTool: {
      name: 'createUser',
      description: 'Creates a user with the given name.',
    },

    // Invokes the submit action when the agent calls the WebMCP tool.
    submission: {
      action: () => {
        console.log('User clicked submit, or agent called the tool!');
      },
    },
  });

  // ...
}
```
This commit is contained in:
Douglas Parker
2026-05-04 14:05:20 -07:00
committed by Leon Senft
parent 358d2e63fb
commit 1963a0eb18
12 changed files with 548 additions and 1 deletions
@@ -6,6 +6,7 @@
import { AbstractControl } from '@angular/forms';
import { DebounceTimer } from '@angular/core';
import { EnvironmentProviders } from '@angular/core';
import { HttpResourceOptions } from '@angular/common/http';
import { HttpResourceRequest } from '@angular/common/http';
import * as i0 from '@angular/core';
@@ -205,6 +206,10 @@ export interface FormFieldBindingOptions {
// @public
export interface FormOptions<TModel> {
experimentalWebMcpTool?: {
name: string;
description: string;
};
injector?: Injector;
name?: string;
submission?: FormSubmitOptions<TModel, unknown>;
@@ -546,6 +551,9 @@ export class PatternValidationError extends BaseNgValidationError {
readonly pattern: RegExp;
}
// @public
export function provideExperimentalWebMcpForms(): EnvironmentProviders;
// @public
export function provideSignalFormsConfig(config: SignalFormsConfig): Provider[];