WebMCP in der Praxis: Umwandlung eines Aufgabenbretts in Tools für KI-Agenten
WebMCP in der Praxis: Eine Aufgabenliste, die in Tools für KI-Agenten mit deklarativen und skriptbasierten Werkzeugen, einer sich ändernden Werkzeugliste, einer MCP-Brücke sowie einer Ablehnung umgewandelt wurde.
Agenten, die über Ihre Website rätseln
Heutzutage rät ein mit einer Website arbeitender KI-Agent meistens nur. Er macht ein Screenshot und sucht nach etwas, das wie eine Schaltfläche aussieht, oder er analysiert das DOM in der Hoffnung, dass die Klassennamen tatsächlich das bedeuten, was sie zu bedeuten scheinen. Nach einem Klick prüft er, ob sich die Seite auf eine Weise verändert hat, die auf Erfolg hindeutet. Das ist ein beeindruckender Trick, der auf einer schwachen Grundlage beruht, da die Website dem Agenten nie etwas mitteilt und jede Schlussfolgerung ausgeschlossen wird.
WebMCP ist Chromes Vorschlag, dieses Raten zu beenden. Eine Seite gibt ihre Fähigkeiten bekannt, der Agent liest diese Mitteilung und ruft eine Funktion mit strukturierten Argumenten auf, anstatt auf ein Rechteck auf dem Bildschirm zu zielen. Die Veränderung scheint gering zu sein, verlagert aber die Intelligenz: Anstatt den Zweck einer Anwendung aus Pixeln und Markup neu zu konstruieren, erhält der Agent diesen Zweck direkt von der Anwendung selbst.
Um zu überprüfen, ob dies in der Praxis funktioniert, wurde ein kleines Arbeits-Taskboard erstellt und ein echter Agent darauf zugewiesen. Das aufschlussreichste Ergebnis trat ein, als der Agent eine Anfrage kategorisch ablehnte.
Drei Rollen
Jeder Moment im Experiment beinhaltet einen von drei Akteuren.
- Die Seite ist der Anbieter. Sie registriert Tools. Jedes Tool verknüpft einen Namen mit einer Beschreibung für ein Modell, einem JSON Schema, das die Argumente beschreibt, sowie einer Funktion, die die Arbeit ausführt.
- Der Browser ist das Register. Für jede Tabellenansicht speichert er die Liste der Tools, erzeugt soweit wie möglich Schemata aus dem HTML und entscheidet, wann ein Tool angezeigt oder entfernt wird.
getTools() nach den verfügbaren Funktionen und ruft eine ausgewählte Funktion mit executeTool() auf. Der DOM bleibt außerhalb seines Zugriffs, und er hat keine Möglichkeit, Fähigkeiten nachzubilden, die die Seite nie bereitgestellt hat.Genau dieser letzte Punkt ist das Herzstück der Idee. Chromes Dokumentation beschreibt die API ausreichend klar, doch das Lesen einer Erklärung ist nicht dasselbe wie das Verstehen einer Sache – daher war der schnellste Weg, die kleinste mögliche Version zu entwickeln.
Die Demo: ein Aufgabenboard in drei Dateien
Die Plattform besteht aus index.html, app.js und style.css. Es muss nichts erstellt oder installiert werden. Die Nutzer können Aufgaben hinzufügen, sie abhaken und die Liste filtern – es handelt sich dabei um ein Projekt, das in einer Nachmittagszeit erledigt werden kann. Neu ist, dass die Seite sich außerdem über ein von dem Browser bereitgestelltes Objekt als eine Reihe von aufrufbaren Tools einem KI-Agenten präsentiert.
const mc = document.modelContext; // undefined if WebMCP is off
Jene einzige Zeile ist der gesamte Eingangspunkt. Wenn das Objekt vorhanden ist, kann die Seite Tools registrieren. Wenn nicht, ist die Seite lediglich ein Aufgabenboard – so sollte sie auch im Fehlfall funktionieren.
Um beide Komponenten sichtbar zu halten, zeigt die Demo-Seite sie nebeneinander an. Links befindet sich das Board, also der Anbieter. Rechts spielt ein „Pretend Agent“-Panel die Rolle des Verbrauchers und sendet getTools() sowie executeTool()-Aufrufe genauso wie ein echter Agent, wodurch zusätzliche Verbindungen vermieden werden. Dieses Panel ist auf jedem der folgenden Screenshot zu sehen.
WebMCP trägt weiterhin den Status „Proposed“ im Chrome Platform Status und ist standardmäßig nirgends aktiv, weshalb zunächst ein Flag erforderlich ist.
Öffnen Sie chrome://flags/#enable-webmcp-testing, stellen Sie es auf „Enabled“ ein und starten Sie Chrome erneut. Ohne das ist document.modelContext undefiniert. Chrome bietet außerdem einen WebMCP-Origin-Test an, der ab Chrome 149 verfügbar ist. Der Flag eignet sich für lokale Experimente, während der Origin-Test der Weg ist, den Chrome für umfassendere Tests vorsieht.
Zuerst der abgeschlossene Loop
Es ist einfacher, die API zu verstehen, nachdem man gesehen hat, was sie erzeugt. Claude Code wurde mit dem Board verbunden und erhielt einen Satz, in dem es gebeten wurde, vier Aufgaben hinzuzufügen: Informationen suchen und recherchieren, Blog-Überlegungen schreiben, einen vollständigen Blog mit Beispielen erstellen und ihn veröffentlichen. Es erschienen vier Aufgaben. Ein zweiter Satz bat darum, die Aufgaben 3, 4 und 5 als erledigt zu markieren, und das funktionierte ebenfalls.
Claude hat weder ein Screenshot des Boards erstellt noch dessen HTML gelesen. Er fragte den Browser nach den verfügbaren Tools, entdeckte add-task und rief es viermal mit strukturierten Argumenten auf. Hier ist derselbe Moment aus Sicht des Browsers.
Die vier neuen Aufgaben befinden sich nun auf den Plätzen #3 bis #6 im Board, und das DevTools-Fenster (Application, anschließend WebMCP) listet alle sechs Tools auf, die die Seite derzeit bereitstellt. Eines davon, clear-completed, war noch vor einer Minute nicht vorhanden, und der Grund wird bald klar. Die drei Abschlüsse werden Aufruf für Aufruf protokolliert.
Jeder Aufruf wird zusammen mit seinen Argumenten ({"id":3}, {"id":4} und {"id":5}) angezeigt, und die Zusammenfassung gibt insgesamt drei Aufrufe an, ohne Fehler, Stornierungen oder noch laufende Aufrufe. Das Debuggen von WebMCP ist hier am schnellsten, denn das Panel zeigt genau an, was der Agent gesendet hat.
Ein in eine Terminalzeile eingegebener Satz wurde somit zu vier strukturierten Funktionsaufrufen innerhalb eines Browser-Fensters. Die nächste Frage ist, was die Seite tun musste, um das zu erreichen.
Zwei Möglichkeiten, ein Tool zu veröffentlichen
Die erste Methode erfordert überhaupt kein JavaScript. Ein vorhandenes Formular erhält vier zusätzliche Attribute.
<form id="add-form"
toolname="add-task"
tooldescription="Add a new task to the user's task board."
toolautosubmit>
<input name="title" required maxlength="80"
toolparamdescription="Short description of the task to add.">
<select name="priority"
toolparamdescription="How urgent the task is.">
<option value="low">low</option>
<option value="normal" selected>normal</option>
<option value="high">high</option>
</select>
<button type="submit">Add</button>
</form>
Dieses Formular ist das add-task-Tool, das Claude viermal aufgerufen hat. Die Feldnamen, required-Attribute sowie <select>-Optionen werden vom Browser gelesen, der anschließend das JSON Schema selbst zusammenstellt. Der Agent sieht eine erforderliche Zeichenkette sowie eine Enum mit drei Werten – und niemand hat das Schema manuell eingegeben. In einer bestehenden Anwendung handelt es sich dabei vermutlich um das einfachste WebMCP-Experiment, da ein gewöhnliches HTML-Formular bereits einen Vorteil bietet. Alles, was hinzugefügt wird, ist eine Beschreibung dessen, was das Formular für einen Agenten bedeutet.
Ein Detail, das erst nach kurzem Nachdenken verstanden wird: Derselbe submit-Handler bedient sowohl eine Person, die auf „Hinzufügen“ klickt, als auch einen Agenten, der das Tool aufruft – und das Ereignis gibt an, um welchen Fall es sich handelt.
$('#add-form').addEventListener('submit', (e) => {
e.preventDefault();
const task = addTask(new FormData(e.target).get('title'), /* ... */);
if (!e.agentInvoked) {
e.target.reset(); // human — clear the box
} else {
e.respondWith?.(Promise.resolve(
text(`Added task #${task.id}: "${task.title}".`)
));
}
});
Die Flagge agentInvoked gibt an, wer auf die Schaltfläche gedrückt hat, und respondWith() gibt ein Ergebnis an den Agenten zurück, ohne wegzuwechseln. Es gibt einen Codepfad mit zwei Aufrufern, was eine gute Designentscheidung ist, denn niemand möchte eine „KI-Version“ jeder Aktion in einer App. Dieselbe Logik sollte sowohl Menschen als auch Agenten bedienen, solange das sinnvoll ist.
Der deklarative Ansatz ist wohl der weniger interessante Teil, zieht aber vermutlich die Aufmerksamkeit auf sich, da er sich gut demonstrieren lässt und keiner weiteren Überlegung bedarf. Interessant wird es dort, wo ein Formular nicht ausdrücken kann, was gemeint ist – das ist der zweite Ansatz, registerTool, der sehr ähnlich aussieht wie das, was man für einen Backend-MCP-Server schreiben würde.
await mc.registerTool({
name: 'list-tasks',
description: 'List the tasks on the board. Use this before acting so you know the task IDs.',
inputSchema: {
type: 'object',
properties: {
status: { type: 'string', enum: ['all', 'open', 'done'] },
},
},
annotations: { readOnlyHint: true },
async execute({ status = 'all' }) {
const rows = visible(tasks, status);
return text(rows.map((t) => `#${t.id} [${t.done ? 'x' : ' '}] ${t.title}`).join('\n'));
},
});
Betrachten Sie die description genau. Sie ist für ein Modell und nicht für einen Entwickler verfasst, und eine Zeile wie „Verwenden Sie dies vor dem Handeln, damit Sie die Task-IDs kennen“ gibt Hinweise darauf, wann sie aufgerufen werden soll. Beschreibungen sind nun Teil der API-Oberfläche, und vage Beschreibungen führen zu Agenten, die raten müssen.
Die Flagge readOnlyHint signalisiert, dass ein Tool ohne vorherige Anfrage beim Benutzer sicher aufgerufen werden kann. list-tasks und estimate-task tragen diese Flagge. complete-task und clear-completed tun das nicht, weil sie Änderungen vornehmen.
Tools können außerdem langsam sein, und ein Agent kann seine Meinung unterwegs ändern. Das Tool estimate-task wartet absichtlich drei Sekunden und erhält als zweites Argument ein AbortSignal.
async execute({ id }, { signal }) {
const t = findTask(tasks, id);
if (!t) {
return text(`No task #${id}.`);
}
await sleep(3000, signal); // throws if the agent aborts
return text(
`Task #${t.id} is about ${
t.priority === 'high' ? '2 hours' : '30 minutes'
}.`
);
}
Respektieren Sie dieses Signal, dann funktioniert die Stornierung. Ignorieren Sie es, läuft das Tool weiter, nachdem der Agent gegangen ist.
Eine Tool-Liste, die sich während der Seite-Öffnung ändert
Der stärkste Grund, Tools in einem Skript zu registrieren anstelle eines statischen Manifests zu verwenden, ist, dass die Liste laufend geändert werden kann. Das Board verfügt über ein Tool namens clear-completed, das jede abgeschlossene Aufgabe löscht. Das macht nur Sinn, wenn etwas abgeschlossen ist – was erklärt, warum es auf dem früheren Screenshot direkt nachdem drei Aufgaben als erledigt markiert wurden, erschien. Es existiert also nur in solchen Momenten.
let clearCtl = null;
async function syncClearTool() {
const has = tasks.some((t) => t.done);
if (has && !clearCtl) {
const ctl = new AbortController();
clearCtl = ctl;
await mc.registerTool(
{
name: 'clear-completed',
/* ... */
},
{
signal: ctl.signal
}
);
} else if (!has && clearCtl) {
const ctl = clearCtl;
clearCtl = null;
setTimeout(() => ctl.abort(), 0); // abort() IS unregister
}
}
Es gibt keine unregisterTool()-Funktion. Bei der Registrierung wird ein AbortSignal übergeben, und dessen Beendigung löscht das Tool. Genau da macht das Design Sinn: Das Signal, das einen laufenden Aufruf abbricht, entzieht gleichzeitig auch die Berechtigung – ein Mechanismus erledigt somit zwei Aufgaben.
Wenn eine Aufgabe als erledigt markiert wird, erscheint clear-completed in der Liste des Agents; wenn sie wieder deaktiviert wird, verschwindet das Tool. Der Agent erfährt davon über ein toolchange-Event und muss nicht nachfragen.
mc.addEventListener('toolchange', refreshTools);
Die Liste der Tools ist also kein einmal veröffentlichtes Manifest. Sie beschreibt, was die App im aktuellen Zustand gerade tun kann.
Wie sich das von einem Backend-MCP-Server unterscheidet
Anschließend wurde von Claude Code verlangt, das Board auf abgeschlossene Aufgaben einzuschränken.
Der Agent rief die Funktion filter-tasks mit {"status":"done"} auf, der „Done“-Button wurde aktiviert und das Board zeigte nur noch abgeschlossene Aufgaben an. Der Agent hatte keine gefilterte Kopie der Daten abgerufen – er änderte lediglich den Anblick, den der Benutzer sah.
Ein Backend-MCP-Server kann das nicht bewältigen. Da er sich auf der anderen Seite der Netzwerkgrenze befindet, arbeitet er mit gespeicherten Daten und hat keinerlei Kenntnis davon, was gerade auf einem Bildschirm angezeigt wird. WebMCP-Tools befinden sich innerhalb der Tab-Seite und teilen sich deren DOM, Sitzung und Cookies, sodass Agent und Benutzer denselben Bildschirm sehen und jeder von ihnen ihn ändern kann. Das ist sowohl eine echte Stärke als auch ein echtes Risiko, wobei das Risiko im folgenden Abschnitt ausführlich behandelt wird. Genau deshalb unterschätzt die Bezeichnung „MCP im Browser“ WebMCP. Es spielt eine Rolle, wo sich das Tool befindet, da es mit dem genauen Seitenzustand verbunden ist, den der Benutzer betrachtet.
Verbindung mit einem externen Agenten
Das Pretend Agent-Panel hilft während der Entwicklung, ist aber kaum nützlich, da es die Seite selbst ist, die aufgerufen wird. Ein echter Test benötigt etwas außerhalb des Browsers, das nur das sehen kann, was getTools() meldet. Dafür gibt es agent.mjs – ein kleines Kommandozeilenwerkzeug mit einigen Funktionen des Chrome DevTools Protocols und ohne Abhängigkeiten, da Node 22 ein globales WebSocket bereitstellt. Per Konstruktion kann es nur das sehen, was getTools() meldet, und nur über executeTool() agieren, wobei kein DOM-Scraping möglich ist.
node agent.mjs list
node agent.mjs call add-task '{"title":"Ship the demo","priority":"high"}'
Diese beiden Befehle listen die Tools auf und rufen anschließend add-task mit einem Titel und einer Priorität auf. Die Konfiguration, die die Screenshote erzeugt hat, geht noch einen Schritt weiter. Claude Desktop, Claude Code und ChatGPT verwenden MCP und nicht WebMCP, weshalb mcp-bridge.mjs als Adapter fungiert – und zwar ein kleiner, da die Protokolle fast exakt übereinstimmen: tools/list entspricht getTools() und tools/call entspricht executeTool(). Claude Code erkennt dies über eine .mcp.json-Datei.
{
"mcpServers": {
"webmcp-board": {
"command": "node",
"args": ["C:\\projects\\web-mcp-demo\\mcp-bridge.mjs"],
"env": { "PAGE_URL": "https://tusharkanjariya.github.io/web-mcp-demo/" }
}
}
}
Die gesamte Kette besteht somit darin, dass Claude Code über MCP mit der Brücke kommuniziert, die Brücke über CDP mit Chrome spricht, und Chrome die von der Seite registrierten Tools aufruft. Das sind vier Schritte, und die Seite am Ende kann nicht erkennen, welcher Client auf der anderen Seite ist.
Claude Code
↓
MCP
↓
mcp-bridge.mjs
↓
Chrome DevTools Protocol
↓
WebMCP
↓
my task board
Noch ein Vorteil: Die Brücke startet ihren eigenen Chrome, falls am Debug-Port keine Antwort kommt, und öffnet die Seite, wenn die Registerkarte nicht vorhanden ist. Ein MCP-Client kann alles von vorne starten.
Die Ablehnung
Dann wurde vom Agenten verlangt, eine einzelne Aufgabe zu löschen.
Der obere Teil des Screenshot zeigt die zuvor eingegangene Filteranfrage. Der untere Teil ist der interessante Teil: Claude sagte, es gäbe auf diesem Board kein delete-task-Tool, die einzige mögliche Löschung sei clear-completed, was auch die Aufgaben #2, #3, #4 und #5 löschen würde, und dass er das nicht tun werde.
Niemandes Schutzleiste, Systemanweisung oder Sicherheitsschicht führte zu dieser Ablehnung. Die Möglichkeit, eine einzelne Aufgabe zu löschen, existierte einfach nicht, und der Agent bemerkte das. Es wäre ein Fehler, zu viel in einen einzigen Austausch in einer Spiel-App hineinzuinterpretieren. Dennoch verändert das die Sicht auf das Problem. Ein Agent, der eine Seite über Pixel und Koordinaten steuert, hätte etwas Ähnliches wie eine Löschfunktion gefunden und es ausprobiert, denn Screen-Scraping-Agenten haben nur Improvisation als Ausweichmöglichkeit. Dieser Agent zählte seine sechs Werkzeuge, stellte fest, dass keines zur Entfernung einer Aufgabe diente, erkannte die Nebenwirkungen der nächstbesten Option und hielt inne, um nachzufragen.
Die Liste der Werkzeuge bildete die Grenze. Niemand hatte eine Regel gegen das Löschen von Inhalten festgelegt. Die Seite bot einfach nie die Löschfunktion als mögliche Option an, und das reichte aus – auch wenn WebMCP die Agenten nicht magisch sicher macht.
Wo Chrome und die Spezifikationen unterschiedlicher Auffassung sind
Durch den Betrieb des Programms kamen Unterschiede zwischen der Dokumentation und dem Browser zum Vorschein, und es dauerte einen Nachmittag, sie zu beseitigen. Drei davon betreffen die Struktur der Daten.
- Argumente für
executeTool(): In der Spezifikation wird ein Objekt beschrieben, doch Chrome 151 erwartet einen JSON-String, wodurchFailed to parse input argumentsausgelöst wird. RegisteredTool.inputSchema: In der Spezifikation als Objekt definiert, liefert Chrome jedoch einen JSON-String – daher muss dieser vor dem Lesen derpropertiesinterpretiert werden.- Was
executeTool()tatsächlich zurückgibt: Laut Spezifikation soll es sich um eineDOMStringhandeln, was zwar zutrifft, aber es handelt sich dabei um eine serialisierte{content:[…]}-Umhüllung, die zweimal entpackt werden muss, um zum Text zu gelangen.
Alles das ist nicht schwierig, sobald man die Zusammenhänge kennt. Die beiden wirklich problematischen Fälle waren Lebenszyklusfehler, die nur auftreten, wenn ein echter Agent die Seite aufruft.
Ein Aufruf von form.reset() während ein vom Agenten ausgelöster Absendevorgang läuft, stört den Tool-Aufruf mit der Meldung Tool execution cancelled by a form reset. Ein völlig gewöhnlicher Handler, der wie die meisten den Eingabefeldern nach dem Absenden den Inhalt entzieht, führte dazu, dass jeder vom Agenten gesteuerte add-task-Aufruf fehlschlug. Die Aufgabe wurde zwar erstellt, doch die Antwort kam nie an – deshalb resetzt der zuvor gezeigte Handler nur bei von Menschen ausgeführten Absendevorgängen.
In Versionen vor Chrome 153 führt das Entfernen eines Tools auch dazu, dass alle noch laufenden Aufrufe dieses Tools abgebrochen werden. Das ist unbedenklich, solange sich ein Tool nicht aufgrund eines Erfolgs selbst entfernt. clear-completed löscht alle abgeschlossenen Aufgaben, sodass nichts mehr erledigt ist und das Tool sich selbst zurückzieht. In Version 151 wurde der Abbruch bereits vor der Rückgabe die eigene Antwort abschneiden. Die Lösung ist setTimeout(() => ctl.abort(), 0): Durch das Aufschieben des Abbruchs um einen Takt lässt sich der Aufruf zuerst abschließen. Das ist nachvollziehbar und funktioniert, doch das Aufschieben der Aufräumarbeiten um einen Takt ist eine Art Patch, der nach einigen Chrome-Updates erneut überprüft werden sollte.
Veröffentlichung der Demo
Die Demo ist vollständig statisch, sodass GitHub Pages sie unverändert bereitstellen kann, und HTTPS liefert den sicheren Kontext, den WebMCP erfordert. Auf diese Weise erhält jeder ein funktionsfähiges Aufgabenboard, aber kein funktionsfähiges WebMCP, da Besucher, die das entsprechende Flag noch nicht gesetzt haben, weiterhin document.modelContext als undefiniert sehen. Um das zu beheben, ist ein Origin-Testtoken im <head> erforderlich, das als First-Party-Token registriert sein muss, da Chrome Drittanbieter-Tokens, die in Meta-Tags platziert werden, ablehnt. Bei einem sauberen Profil ohne Flags wurde modelContext zusammen mit allen sechs Tools als „object“ zurückgegeben. Der Testlauf gilt bis Chrome 156.
Die Sicherheitsfrage ohne gute Antwort
Die WebMCP-Tools werden innerhalb eines angemeldeten Tabs ausgeführt. Das ist sowohl der Sinn als auch das ganze Problem.
Die Spezifikation enthält einen untrustedContentHint, der lediglich als Hinweis dient. Wie mit Prompt-Injection umgegangen werden soll, ist dort noch unklar, und kein Teil dieser API fungiert als Autorisierungsbarriere. Wenn vom Angreifer kontrollierter Text auf einer Seite angezeigt werden kann und ein Agent ihn liest, kann readOnlyHint nicht helfen.
Die Brücke kann auch über HTTP über einen Tunnel bereitgestellt werden, damit Chats GPTs Connector darauf zugreifen können. Sie funktioniert, doch man sollte sorgfältig darüber nachdenken, bevor man dies tut, denn der Tunnel macht einen ohne Authentifizierung verfügbaren Endpunkt zugänglich, der in der angemeldeten Browser-Tab Tools ausführt – für jeden, der die Adresse erraten kann. Zwanzig Minuten an Experimenten sind in Ordnung, doch es ist nicht ratsam, ihn über Nacht laufen zu lassen.
Testen in Ihrer eigenen Anwendung
Die Betreiber einer Webanwendung können die API an einem Nachmittag beurteilen, da sie klein ist. Wählen Sie irgendein vorhandenes Formular aus, geben Sie ihm die Attribute toolname und tooldescription zu und öffnen Sie anschließend das WebMCP-Panel in den DevTools – dort erscheint das Tool. Etwa zehn Minuten damit bringen mehr bei als eine weitere Stunde Lesen.
Die Bedeutung geht über die Syntax hinaus. Ehrlich zu beschreiben, was Ihre App kann, ist zu einem Bestandteil dessen geworden, was Sie bereitstellen, anstatt zu Dokumentationen, die später erstellt werden. Das Board bot keine Funktion zum Löschung einzelner Aufgaben, weshalb der Agent niemals etwas löschte. Was getTools() zurückgibt, bestimmt, wie ein Agent die Fähigkeiten Ihrer App wahrnimmt, und dieses Bild entwickelt sich stetig zur eigentlichen Benutzeroberfläche. In der Demo waren sechs Tools in drei Dateien ohne Abhängigkeiten enthalten – überlegen Sie daher, was Ihre eigene Seite über sich selbst sagen würde. Um dies nachzuvollziehen, aktivieren Sie das Flag chrome://flags/#enable-webmcp-testing und führen Sie anschließend node agent.mjs list aus. Wenn sechs Tools zurückgegeben werden, kommunizieren Sie mit einer Webseite auf die Weise, wie es ein Agent tun würde.
Kurze Antworten
Was ist WebMCP? Es handelt sich um eine vorgeschlagene Browser-API, über die eine Seite ihre eigenen Funktionen als aufrufbare Tools an einen KI-Agenten bereitstellt, wobei document.modelContext verwendet wird. Die Agenten rufen diese Tools direkt auf, umgehen somit das Scannen des DOMs sowie das Koordinieren von Klicks.
Worin unterscheidet es sich von einem herkömmlichen MCP-Server? Backend-Server laufen jenseits der Netzwerkgrenze und arbeiten mit gespeicherten Daten. WebMCP-Tools laufen innerhalb der Tab-Seite, sodass sie das von dem Benutzer Gesehene verändern können und die Sitzung sowie Berechtigungen der Seite wiederverwenden. Der Aufruf von filter-tasks änderte das Board sichtbar.
Wie registriert eine Seite ein Tool? Entweder fügt man die Attribute toolname und tooldescription zu einem vorhandenen Formular hinzu und lässt den Browser das Schema aus den Feldern ableiten, oder man ruft document.modelContext.registerTool() mit einem Namen, einer Beschreibung, einem JSON Schema sowie einer execute-Funktion auf. Formulare eignen sich für einfache Aktionen, während registerTool alles abdeckt, was ein Formular nicht ausdrücken kann.
Ist ein Flag erforderlich? Derzeit ja. Aktivieren Sie das Flag und starten Sie Chrome erneut, oder starten Sie es mit --enable-features=WebMCP. Für Besucher, die das Flag noch nicht aktiviert haben, funktioniert ein First-Party-Origin-Test-Token im <head> der Seite.
Können Claude Desktop oder ChatGPT diese Tools aufrufen? Nicht von selbst, da sie MCP statt WebMCP verwenden. Ein kleiner Adapter übersetzt tools/list in getTools() und tools/call in executeTool(). Der hier verwendete Adapter umfasst etwa 130 Zeilen, benötigt keine Abhängigkeiten und funktioniert über stdio für lokale Clients.
Ist es sicher? Die Frage bleibt offen. untrustedContentHint und readOnlyHint sind lediglich Hinweise; keiner davon markiert eine Autorisierungsgrenze, und in der Spezifikation wurde noch keine Lösung für Prompt-Injection gefunden. Entwickeln Sie die Tool-Oberfläche unter der Annahme, dass ein Agent dazu verleitet werden könnte, alles aufzurufen, was Sie bereitstellen.
Verwandte Literatur
- Wenn ein KI-Agent 1.000 MCP-Tools hat: Auswahl, Kontext und Fähigkeiten — Das Verbinden von Agenten mit vielen MCP-Servern führt zu einer Überflutung an Tools, einem übermäßig großen Kontext und schlechten Auswahlentscheidungen. Warum Entdeckungsmöglichkeiten, Fähigkeiten und Gateways wichtiger sein können als reiner Zugriff.
- Praktische Hinweise: MCP für Forschungslabore – ein Vertrag für Tools, Daten und — Detaillierte Anleitung zu den Praktischen Hinweisen: MCP für Forschungslabore – ein Vertrag für Tools, Daten und: Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.