Künstliche Intelligenz

WebMCP implementieren: Schritt-für-Schritt-Anleitung mit Best Practices für Chrome 146+

Eine praktische Schritt-für-Schritt-Anleitung zur Implementierung von WebMCP (Web Model Context Protocol) in Next.js mit Codebeispielen. Behandelt deklarative HTML-Attribute, imperative Tool-Registrierung, Manifest-Erkennung und Best Practices.

İlker Ulusoy 2026-02-15 15 min Min. Lesezeit .md

Chrome 146 führt WebMCP (Web Model Context Protocol) ein, eine browsernative API, die es Websites ermöglicht, strukturierte Tools für KI-Agenten bereitzustellen. Anstatt auf Screen Scraping oder fragile Selektoren angewiesen zu sein, können Agenten nun Formulare entdecken, ihren Zweck verstehen, sie intelligent ausfüllen und sogar imperative JavaScript-Funktionen direkt aufrufen. Diese Schritt-für-Schritt-Anleitung führt durch die Implementierung aller drei WebMCP-Schichten in einem realen Next.js-Projekt, mit Codebeispielen und Best Practices aus der Produktion.

Live ausprobieren

Wir haben WebMCP auf unserer eigenen Website implementiert. Wenn Sie Chrome 146+ mit aktiviertem WebMCP haben, kann Ihr KI-Agent das Kontaktformular über deklarative und imperative Pfade entdecken und damit interagieren.Auf der Kontaktseite testen

Was ist WebMCP und warum ist es wichtig?

WebMCP ist für KI-Agenten das, was robots.txt für Suchmaschinen-Crawler ist: eine standardisierte Möglichkeit für Websites, mit automatisierten Systemen zu kommunizieren. Aber anstatt Crawlern mitzuteilen, was sie nicht indexieren sollen, teilt WebMCP KI-Agenten mit, was sie auf einer Seite tun können.

Stellen Sie es sich als ein strukturiertes Menü für KI vor. Wenn ein Agent eine Seite mit WebMCP-Unterstützung besucht, weiß er sofort: "Diese Seite hat ein Kontaktformular, das Name, E-Mail und Nachricht akzeptiert. Ich kann entweder das Formular visuell ausfüllen oder eine JavaScript-API aufrufen, um die Daten programmatisch zu übermitteln."

Drei Schichten arbeiten zusammen, um dies zu ermöglichen:

SchichtFunktionsweiseWann KI sie nutzt
Deklaratives HTMLAttribute an Formularen und Eingaben beschreiben den Tool-ZweckAgent füllt Formular visuell aus und klickt Absenden
Imperatives JavaScriptnavigator.modelContext.registerTool() stellt eine API bereitAgent ruft die Tool-Funktion direkt per Code auf
Manifest-Erkennung.well-known/webmcp-Endpunkt und seitenbezogenes JSONAgent entdeckt verfügbare Tools vor der Navigation

TypeScript-Deklarationen für WebMCP einrichten

Bevor Sie WebMCP-Attribute hinzufügen, richten Sie TypeScript-Deklarationen ein. Ohne diese wird JSX benutzerdefinierte Attribute wie toolname und tooldescription mit Kompilierungsfehlern ablehnen.

Erstellen Sie eine types/webmcp.d.ts-Datei, die die globalen Interfaces deklariert, die Chrome 146 bereitstellt:

types/webmcp.d.ts
export {};

declare global {
  interface WebMCPSubmitEvent extends Event {
    agentInvoked?: boolean;
    respondWith?: (response: string) => void;
  }

  interface WebMCPTool {
    name: string;
    description: string;
    execute: (params: Record<string, unknown>) => unknown | Promise<unknown>;
    inputSchema: {
      type: string;
      properties?: Record<string, {
        type: string;
        description?: string;
        enum?: string[];
      }>;
      required?: string[];
    };
  }

  interface ModelContext {
    registerTool: (tool: WebMCPTool) => void;
    unregisterTool: (name: string) => void;
  }

  interface Navigator {
    modelContext?: ModelContext;
  }
}

declare module "react" {
  interface HTMLAttributes<T> {
    toolname?: string;
    tooldescription?: string;
    toolparamdescription?: string;
  }
}

Best Practice: Warum globale Deklarationen?

Diese WebMCP-APIs befinden sich auf den nativen Browser-Objekten (Navigator, SubmitEvent), nicht in einem npm-Paket. Globale Typdeklarationen in einer .d.ts-Datei sind der korrekte Weg, um Browser-APIs zu typisieren, die nicht in TypeScripts eingebauten lib-Definitionen enthalten sind.

Deklarative HTML-Attribute zu Formularen hinzufügen

Die deklarative Schicht ist am einfachsten zu implementieren. Fügen Sie drei Attribute zu Ihren bestehenden Formularen hinzu:

  1. 1toolname am Formularelement: ein eindeutiger Bezeichner, den der Agent verwendet, um dieses Tool zu referenzieren
  2. 2tooldescription am Formularelement: eine natürlichsprachliche Beschreibung, die dem Agenten sagt, wann und warum er dieses Formular verwenden soll
  3. 3toolparamdescription an jedem Input, Select und Textarea: Kontext für jedes Feld, der den Agenten leitet, welchen Wert er bereitstellen soll
Declarative WebMCP Form Example
<form
  id="contactForm"
  toolname="contact_form"
  tooldescription="Submit a contact request with name, email, reason, and message."
  noValidate
  onSubmit={handleSubmit}
>
  <input
    type="text"
    name="name"
    required
    toolparamdescription="Full name of the person submitting the request"
  />
  <input
    type="email"
    name="email"
    required
    toolparamdescription="Email address for follow-up communication"
  />
  <select
    name="reason"
    toolparamdescription="Reason for contact: 'support', 'sales', 'partnership', or 'other'"
  >
    <option value="support">Support</option>
    <option value="sales">Sales</option>
  </select>
  <textarea
    name="message"
    required
    toolparamdescription="Detailed message describing the request"
  />
  <button type="submit">Send</button>
</form>

Best Practice: Unterschiedliche Namen verwenden

Wenn Sie auch ein imperatives Tool registrieren möchten, müssen der deklarative toolname und der name des imperativen Tools unterschiedlich sein. Die Verwendung desselben Namens löst eine "Duplicate tool name"-DOMException aus.

Benutzerdefinierte UI-Komponenten behandeln

Wenn Ihr Formular benutzerdefinierte UI-Komponenten wie Button-Gruppen oder Radio-Karten anstelle nativer Select-Elemente verwendet, fügen Sie ein verstecktes <select>-Element hinzu. KI-Agenten können Optionen nur über Standard-HTML-Formularelemente entdecken.


Agent-Formularübermittlungen in React verarbeiten

Wenn ein KI-Agent ein deklaratives Formular ausfüllt und absendet, feuert Chrome ein normales submit-Event mit zwei zusätzlichen Eigenschaften am nativen Event:

  • agentInvoked: boolean — wahr, wenn der KI-Agent das Absenden ausgelöst hat
  • respondWith(response: string) — sendet eine Textantwort zurück an den Agenten
React Submit Handler with WebMCP Agent Detection
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();

  const nativeEvent = e.nativeEvent as WebMCPSubmitEvent;
  if (nativeEvent.agentInvoked) {
    const fd = new FormData(e.currentTarget);
    const data = {
      name: fd.get("name") as string,
      email: fd.get("email") as string,
      reason: fd.get("reason") as string,
      message: fd.get("message") as string,
    };

    const ref = "REF-" + Math.random().toString(36).substring(2, 8).toUpperCase();

    // MUST be called synchronously, before any await!
    nativeEvent.respondWith?.(
      `Contact submitted successfully. Reference: ${ref}`
    );

    await submitToBackend(data);
    setSubmitted(true);
    return;
  }

  // Human path (unchanged)
  setIsSubmitting(true);
};

Kritisch: respondWith() muss synchron sein

Der respondWith()-Aufruf muss synchron innerhalb des Submit-Handlers erfolgen, vor jedem await-Statement. Wenn Sie ihn nach einer asynchronen Operation aufrufen, hat Chrome den Antwortkanal bereits geschlossen und der Agent erhält kein Feedback.

Imperative Tools mit Best Practices registrieren

Die imperative Schicht gibt KI-Agenten einen zweiten Weg: Anstatt Formulare visuell auszufüllen, ruft der Agent eine JavaScript-Funktion direkt auf. Dies ist schneller, zuverlässiger und funktioniert auch bei komplexer oder dynamischer Formular-UI.

Best Practice: Das Ref-Guard-Registrierungsmuster

Imperative Tool Registration with Ref Guard (React)
const toolRegisteredRef = useRef(false);

useEffect(() => {
  const mc = navigator.modelContext;
  if (!mc || toolRegisteredRef.current) return;
  toolRegisteredRef.current = true;

  mc.registerTool({
    name: "submit_contact_request",
    description: "Submit a contact request programmatically.",
    inputSchema: {
      type: "object",
      properties: {
        name: { type: "string", description: "Full name" },
        email: { type: "string", description: "Email address" },
        reason: { type: "string", description: "Contact reason" },
        message: { type: "string", description: "Message body" },
      },
      required: ["name", "email", "reason", "message"],
    },
    execute: async (params: Record<string, unknown>) => {
      return dispatchAndWait("webmcp:submitContact", params);
    },
  });
}, []);

Keine React Hooks für die Registrierung verwenden

Der Strict Mode von React mountet Komponenten in der Entwicklung doppelt, wodurch registerTool zweimal aufgerufen wird. Chrome wirft eine "Duplicate tool name"-DOMException. Verwenden Sie useEffect mit einem useRef(false)-Guard.

Die dispatchAndWait-Brücke zwischen Tools und React

Die execute-Funktion des imperativen Tools läuft außerhalb von Reacts Komponentenbaum. Um React-State zu aktualisieren, verwenden Sie das dispatchAndWait-Muster:

dispatchAndWait Helper Function
export function dispatchAndWait(
  eventName: string,
  detail: Record<string, unknown>,
  timeoutMs = 30000
): Promise<string> {
  return new Promise((resolve, reject) => {
    const requestId = Math.random().toString(36).substring(2, 15);
    const completionEvent = `tool-completion-${requestId}`;
    let timer: ReturnType<typeof setTimeout>;

    const handleCompletion = (e: Event) => {
      clearTimeout(timer);
      window.removeEventListener(completionEvent, handleCompletion);
      const customEvent = e as CustomEvent<{ result: string }>;
      resolve(customEvent.detail?.result ?? "Action completed");
    };

    window.addEventListener(completionEvent, handleCompletion);
    timer = setTimeout(() => {
      window.removeEventListener(completionEvent, handleCompletion);
      reject(new Error(`WebMCP tool timeout: ${eventName}`));
    }, timeoutMs);

    window.dispatchEvent(
      new CustomEvent(eventName, { detail: { ...detail, requestId } })
    );
  });
}

Manifest-basierte Erkennung implementieren

Die Manifest-Schicht ermöglicht Vor-Navigations-Erkennung. Bevor ein Agent überhaupt eine Seite öffnet, kann er das Site-Manifest abrufen.

Site-Level-Manifest in Next.js erstellen

app/.well-known/webmcp/route.ts
import { NextResponse } from "next/server";

export const runtime = "edge";

export async function GET() {
  const manifest = {
    spec: "webmcp/0.1",
    site: {
      name: "My Website",
      version: "2026.02",
      description: "Website description for AI agents.",
      pages: [
        {
          url: "/contact",
          intents: ["contact_form", "submit_contact_request"],
        },
      ],
      flows: [
        {
          id: "contact_inquiry",
          description: "Submit a contact request.",
          steps: [{ intent: "contact_form", page: "/contact" }],
        },
      ],
    },
  };

  return NextResponse.json(manifest, {
    headers: {
      "Cache-Control": "public, max-age=86400, s-maxage=86400",
      "Access-Control-Allow-Origin": "*",
    },
  });
}

Best Practice: Aus Middleware ausschließen

Stellen Sie sicher, dass /.well-known- und /webmcp-Pfade von der i18n-Middleware ausgeschlossen werden. Andernfalls leitet die Middleware die Manifest-URL auf eine lokalisierte Version um.

Seitenbezogenes Manifest hinzufügen

Betten Sie ein <script type="application/json" id="webmcp">-Tag in jeder Seite ein:

Page-Level WebMCP Manifest
{
  "spec": "webmcp/0.1",
  "page": { "url": "/contact", "title": "Contact Us" },
  "context": {
    "purpose": "Contact form for inquiries and support requests",
    "entities": ["contact_request"],
    "auth": { "required": false }
  },
  "intents": [
    {
      "id": "contact_form",
      "description": "Submit a contact request",
      "inputs": [
        { "name": "name", "type": "string", "required": true },
        { "name": "email", "type": "email", "required": true },
        { "name": "message", "type": "string", "required": true }
      ],
      "policy": { "rateLimit": "5/min" }
    }
  ]
}

Visuelles Feedback mit WebMCP-CSS-Pseudoklassen

Chrome 146 fügt zwei neue CSS-Pseudoklassen hinzu:

  • :tool-form-active — wird auf das Formularelement angewendet, während der Agent damit interagiert
  • :tool-submit-active — wird auf den Absende-Button angewendet, während der Agent absendet
components/WebMCPStyles.tsx
"use client";
import { useEffect } from "react";

export default function WebMCPStyles() {
  useEffect(() => {
    const style = document.createElement("style");
    style.setAttribute("data-webmcp", "true");
    style.textContent = [
      "*:tool-form-active {",
      "  outline: 2px solid rgba(147, 51, 234, 0.5);",
      "  outline-offset: 2px;",
      "}",
      "*:tool-submit-active {",
      "  background: linear-gradient(110deg, #7c3aed 30%, #a78bfa 50%, #7c3aed 70%);",
      "  background-size: 200% 100%;",
      "  animation: webmcp-shimmer 2s infinite linear;",
      "}",
      "@keyframes webmcp-shimmer {",
      "  to { background-position: 200% center; }",
      "}",
    ].join("\n");
    document.head.appendChild(style);
    return () => { style.remove(); };
  }, []);
  return null;
}

Häufige Implementierungsfehler und wie man sie vermeidet

Best Practices: Fehler vermeiden

Basierend auf unserer Produktionserfahrung sind hier die kritischsten Fallstricke:
  1. 1Gleicher Name für deklarative und imperative Tools. Chrome wirft eine "Duplicate tool name"-DOMException. Verwenden Sie immer unterschiedliche Namen.
  2. 2respondWith() nach await aufrufen. Der Antwortkanal schließt sich, bevor die asynchrone Operation abgeschlossen ist.
  3. 3React Hooks für registerTool verwenden. Der Strict Mode mountet doppelt und ruft registerTool zweimal auf.
  4. 4Fehlende TypeScript-Deklarationen. Ohne die .d.ts-Datei verursachen die Attribute TSX-Kompilierungsfehler.
  5. 5Manifest-Routen nicht aus der i18n-Middleware ausschließen. Die Middleware leitet /.well-known/webmcp um und unterbricht die Erkennung.
  6. 6WebMCP zu sensiblen Formularen hinzufügen. Fügen Sie niemals toolname zu Formularen mit Passwörtern oder Kreditkarten hinzu.

Best Practices und wichtige Erkenntnisse

  • WebMCP bietet ein standardisiertes Protokoll für die KI-Website-Interaktion und ersetzt fragiles Screen Scraping durch strukturierte Tool-Erkennung.
  • Die Drei-Schichten-Architektur (deklarativ, imperativ, Manifest) gibt Agenten mehrere Wege zur Interaktion mit Ihrer Website.
  • TypeScript-Deklarationen sind unverzichtbar und sollten der erste Schritt sein.
  • Das Ref-Guard-Muster ist der korrekte Weg zur Registrierung imperativer Tools in React.
  • respondWith() muss synchron sein. Dies ist die wichtigste Regel in der deklarativen Schicht.
  • WebMCP-Manifeste fungieren als robots.txt für KI-Agenten.

Da KI-Agenten in Browser-Workflows immer häufiger werden, positioniert WebMCP Ihre Website als erstklassigen Teilnehmer im agentischen Web. Der Implementierungsaufwand ist überschaubar, aber der Nutzen ist erheblich: Ihre Formulare werden für jeden Chrome 146+ KI-Agenten erkennbar und nutzbar.