Skip to main content
Die mods API ist die Menge von Methoden, die ein Mod aufruft, um zu handeln: Befehle und Tools hinzufügen, ein Modell aufrufen, Arbeiten zwischen Ereignissen ausführen und auf das Dateisystem, Prozesse und das Netzwerk zugreifen. Jeder Hook erhält sie als sein erstes Argument, $, mit den Methoden in Namespaces wie $.ui und $.fs gruppiert. Ereignisse entscheiden, wann ein Hook ausgeführt wird, und die mods API ist das, was der Hook aufruft, sobald er dies tut. Erstellen Sie Ihren ersten Mod, bevor Sie hier beginnen. Für jede Methode siehe mods API Methoden oder lesen Sie die Typen für Ihren Build.

Fügen Sie einen Befehl oder ein Tool hinzu

Ein Mod kann einen Befehl hinzufügen, den der Benutzer ausführen kann, und ein Tool, das Claude aufrufen kann. Registrieren Sie beide in einem session.start Hook. Claude Code wartet auf diesen Hook vor der ersten Eingabeaufforderung, sodass das, was Sie registrieren, ab der ersten Runde verfügbar ist.

Fügen Sie einen Befehl hinzu

Ein Befehl ist für den Benutzer. Registrieren Sie ihn und behandeln Sie dann command.run für seinen Namen. Dieses Beispiel fügt einen /standup Befehl hinzu, der eine optionale Anzahl von Tagen akzeptiert:
Nach dem Start der Sitzung erscheint /standup mit seiner Beschreibung in der Liste, die Sie sehen, wenn Sie / eingeben. Der argumentHint wird in der Eingabeaufforderung angezeigt, nachdem Sie den Befehl und ein Leerzeichen eingeben, wie in /standup [days]. Wenn Sie /standup 3 ausführen, gibt der zweite Hook Summary for the last 3 day(s): ... zurück, und das Transkript zeigt diesen Text nach dem Namen des Plugins. Der Hook ruft niemals next auf, da der Befehl kein anderes Verhalten als Ihres hat. Der text, den Sie zurückgeben, wird im Transkript gedruckt und Claude liest ihn. Um nichts zu drucken, wie ein Befehl, der nur einen Bereich öffnet, geben Sie {} zurück. Um den Befehl auszuführen, während Claude arbeitet, fügen Sie immediate: true zur Registrierung hinzu. Wählen Sie einen Namen, den kein integrierter Befehl verwendet. Geben Sie / in einer Sitzung ein, um sie zu sehen. $.command.register wirft einen Fehler für einen verwendeten Namen mit einer Nachricht wie "/focus" refused: it is the built-in /focus". Ein Hook, der einen Fehler wirft, wird übersprungen, sodass der Rest Ihres session.start Hooks auch nicht ausgeführt wird. Registrieren Sie Befehle zuletzt in diesem Hook oder wickeln Sie den Aufruf in try und catch.

Fügen Sie ein Tool hinzu

Ein Tool ist für Claude. Registrieren Sie es mit einem Namen, einer Beschreibung, die Claude liest, und einem JSON Schema für seine Eingabe. Claude sieht es unter einem längeren Namen, der aus mcp__, dem Namen Ihres Plugins, zwei Unterstrichen und dem Namen besteht, den Sie registriert haben. Sie behandeln seine Aufrufe in einem tool.call Hook, der auf diesen vollständigen Namen gefiltert ist. Dieses Beispiel aus einem Plugin namens my-mod registriert ticket, sodass der vollständige Name mcp__my-mod__ticket ist. Es gibt Claude ein Tool, das ein Ticket in einem Issue-Tracker nachschlägt:
Wenn Sie nach einem Ticket fragen, kann Claude mcp__my-mod__ticket mit seiner ID aufrufen. Der zweite Hook ruft das Ticket ab und gibt den Antwortkörper zurück, den Claude als Ergebnis des Tools liest. Wenn der Server mit einem Fehlerstatus antwortet, liest Claude Lookup failed with status und die Nummer.

Rufen Sie ein Modell auf

Ein Mod kann ein Modell eine Frage stellen, außerhalb des Gesprächs, für eine kleine Aufgabe wie das Sortieren oder Zusammenfassen eines Textstücks. $.model.complete sendet eine Eingabeaufforderung an ein Modell mit den Anmeldedaten Ihrer Sitzung und wird in die Antwort aufgelöst. Es hat keine Gesprächsverlauf. Dieser Hook beantwortet einen /triage Befehl, registriert als Befehl, indem er ein kleines Modell fragt, den nach dem Befehl eingegebenen Text zu kennzeichnen:
Wenn Sie /triage the export button does nothing ausführen, sendet der Mod diesen Text an das Modell und druckt seine Antwort, wie Label: bug. Claudes Gespräch ist nicht Teil der Anfrage. Wenn das Modell nicht antwortet, ist die Bezeichnung unknown. Ein Claude API Fehler lehnt den Aufruf nicht ab, daher überprüfen Sie r.isAnswered und lesen Sie r.reason, wenn es false ist. Der Aufruf lehnt nur für eine Anfrage ab, die Claude Code nicht sendet, wie ein Modell, das Ihre Organisation blockiert. Die Typen für Ihren Build listen die anderen Optionen auf, wie effort, und die Limits geben den maxTokens Standard an. $.model.fork({ prompt }) stellt stattdessen eine Frage über das aktuelle Gespräch, mit demselben Modell und Systemaufforderung, sodass die Claude API die meisten davon aus dem Prompt Cache bedient. Diese Aufrufe verwenden den Plan oder API-Schlüssel des Benutzers.

Führen Sie Arbeiten im Hintergrund aus

Arbeiten, die ein Ereignis überdauern, wie das Überprüfen von etwas einmal pro Minute, laufen auf einem Timer, den Sie von session.start starten. Ein Hook selbst läuft für ein Ereignis und hat ein Zeitlimit von 10 Sekunden seiner eigenen Laufzeit. Die Zeit, die auf next oder auf einen mods API Aufruf wartet, zählt nicht, außer einem $.clock.sleep. $.clock.every und $.clock.after ersetzen setInterval und setTimeout, mit der Verzögerung in Millisekunden zuerst: $.clock.after(5000, fn) ruft fn einmal auf, fünf Sekunden von jetzt an. Jeder gibt einen Timer mit einer cancel() Methode zurück, und await $.clock.now() gibt die Zeit in Millisekunden an. Dieser Hook schlägt die Überprüfungen eines Pull Requests einmal pro Minute nach und zeigt das Ergebnis unter der Eingabeaufforderung an. summarize ist eine Funktion Ihres eigenen, die die JSON-Ausgabe des Befehls in ein paar Wörter umwandelt:
Die Sitzung startet wie gewohnt. Eine Minute später erscheint eine Zeile unter der Eingabeaufforderung mit einem ⚠, dem Namen des Mods und dann checks: und Ihrer Zusammenfassung. Sie wird einmal pro Minute danach ersetzt. Der Callback des Timers läuft außerhalb eines Ereignisses, sodass er zwischen Runden weiterläuft und keinen startet. Wenn der Callback einen Fehler wirft, geht der Fehler zum Debug-Protokoll und der Timer läuft beim nächsten Intervall erneut.

Zeigen Sie etwas an, ohne eine Runde zu starten

Ein Hintergrund-Job kann dem Benutzer etwas anzeigen, ohne eine Runde zu starten. Jeder dieser Aufrufe setzt Text an einen anderen Ort:

Starten Sie eine Runde aus einem Hintergrund-Job

Wenn ein Hintergrund-Job etwas findet, das Claudes Aufmerksamkeit benötigt, kann er eine Runde starten, indem er eine Eingabeaufforderung mit $.prompt.submit({ text }) einreicht. Claude liest den Text nach einem Satz, der Ihren Mod als Absender benennt. Um ihn als die eigenen Worte des Benutzers zu senden, ohne diesen Satz, fügen Sie asUser: true hinzu. Der Aufruf wartet, bis die Sitzung untätig ist, und startet dann eine neue Runde. Er wird aufgelöst, wenn diese Runde startet, daher await ihn nicht in einem Handler, der läuft, während Claude arbeitet.

Beenden Sie Hintergrund-Arbeiten

Hintergrund-Arbeiten enden auf zwei Arten. Timer enden, wenn das Modul neu geladen wird. Für lang laufende Arbeiten in einem Hook ist next.signal ein AbortSignal, das abbricht, wenn das Ereignis, das Ihr Hook behandelt, aufgegeben wird, zum Beispiel wenn der Benutzer unterbricht, daher übergeben Sie es an alles, das lang läuft.

Senden und empfangen Sie Nachrichten zwischen Sitzungen

Ein Mod kann eine Klartextnachricht an eine andere Ihrer Sitzungen oder an einen der Subagenten dieser Sitzung senden und die Nachrichten beobachten, die ankommen und gehen. $.session.send({ to, text }) sendet eine, die gleiche Lieferung, die das SendMessage Tool macht. to ist { sessionId } für eine Sitzung, { agentId } für einen Subagenten von $.agent.list() oder die Zeichenkettenadresse, von der eine empfangene Nachricht kam. Der Aufruf wird aufgelöst, sobald die Nachricht in die Warteschlange eingereiht ist, mit { isDelivered: true }. Wenn nichts geliefert wurde, wird es mit { isDelivered: false, reason } aufgelöst, und reason sagt, warum. Dieser Hook beantwortet einen /ping Befehl, registriert als Befehl, indem er die Sitzung fragt, deren ID Sie nach ihm eingeben, um einen Status zu erhalten:
Wenn die Nachricht in die Warteschlange eingereiht wird, erscheint nichts in Ihrer Sitzung, und Claudes andere Sitzung liest Status? One line. Wenn nichts geliefert wurde, gibt ein kleines Feld oben rechts den Grund an und verschwindet nach ein paar Sekunden. Zwei Ereignisse lassen einen Mod die Nachrichten beobachten. Geben Sie next(e) von beiden zurück, um jede Nachricht unverändert durchzuleiten: Eine Sitzung, die auf eingehende Nachrichten ablehnen eingestellt ist, lehnt eine Nachricht ab, bevor session.receive ausgelöst wird, daher sieht ein Hook sie nie. Eine Nachricht, die für Ihre Genehmigung gehalten wird, erreicht zuerst den Hook, daher kann ein Mod eine Nachricht lesen, die Sie noch nicht genehmigt haben. Der next(e) des Hooks lehnt ab, wenn die Nachricht nicht geliefert wird. Der Name des Absenders auf einer empfangenen Nachricht ist das, was der Absender geschrieben hat, daher treffen Sie keine Entscheidung darauf.

Erreichen Sie Dateien, Prozesse und das Netzwerk

Ein Mod erreicht das Dateisystem, Prozesse und das Netzwerk durch die mods API, mit den gleichen Berechtigungen wie der Benutzer, der Claude Code ausführt. Das Hooks-Modul selbst hat keine Node.js APIs, keine Timer-Globale wie setTimeout und keinen Netzwerk- oder Dateizugriff. Standard-JavaScript und Web-APIs wie URL, TextEncoder, AbortController und crypto.subtle sind verfügbar. Jeder Namespace unten behandelt eine Art von Zugriff: Dateien und Prozesse haben ein paar Regeln ihrer eigenen:
  • Pfade: ein relativer Pfad ist unter dem Arbeitsverzeichnis der Sitzung
  • $.fs.list: gibt die Einträge eines Verzeichnisses als { name, kind, size, isLink } zurück und steigt nicht in Unterverzeichnisse ab
  • $.process.run: nimmt eine Argumentliste und verwendet keine Shell. Es wird aufgelöst zu { exitCode, stdout, stderr } unabhängig vom Exit-Code. Es lehnt ab, wenn das Programm nicht starten kann oder beim Timeout noch läuft, das standardmäßig 30 Sekunden beträgt, daher wickeln Sie es in try und catch.
Jeder dieser Aufrufe ist selbst ein Ereignis, benannt nach seinem Namespace und seiner Methode ohne das $., wie fs.read für $.fs.read. Ein Mod früher in der Kette kann Ihren Aufruf beobachten, umschreiben oder ablehnen, was ist, wie eine Organisation einschränkt, was Mods erreichen.

Nächste Schritte