Skip to content

Claude Code Mods Tutorial: Eigenen Mod erstellen, testen und installieren, plus 15 Community-Beispiele

Aktualisiert am

Claude Code Mods (ab v2.1.287) sind Plugins aus TypeScript-Funktionen, die Panels zeichnen, sofort ausgeführte Slash-Commands hinzufügen und Tool-Aufrufe absichern. Anleitung: drei funktionierende Mods erstellen und testen, 15 Community-Mods ansehen und vor dem Installieren die Sicherheitschecks durchführen.

Ein Claude-Code-Mod ist ein Plugin aus JavaScript- oder TypeScript-Funktionen, die direkt in Claude Code laufen. Ein Mod kann ein Panel oder eine Zeile über dem Prompt zeichnen, einen Slash-Command hinzufügen, der sofort ausgeführt wird, und einen Tool-Aufruf stoppen oder umschreiben, bevor er läuft. Mods wurden am 1. Oktober 2026 mit Claude Code 2.1.287 eingeführt und sind standardmäßig aktiviert.

Der schnellste Einstieg, je nach Ziel:

Sie möchtenSo geht es
Einen Mod nutzen, ohne Code zu schreibenBeschreiben Sie ihn in einer Session, zum Beispiel mit „Erstelle einen Mod, der anzeigt, wie lange jeder Turn gedauert hat“. Claude schreibt den Mod und fragt einmal, ob Hot Reloading eingeschaltet werden soll
Einen fremden Mod installieren/plugin install <name>@<marketplace> in einer Terminal-Session oder claude plugin install <name>@<marketplace> in Ihrer Shell
Beim Entwickeln einen Ordner ladenclaude --plugin-dir ./my-mod
Den eingebauten Side-Agent ausprobieren/plugin enable cc-plugin-you-should-know@builtin

Prüfen Sie zuerst Ihre Version. claude --version sollte 2.1.287 oder neuer ausgeben. Die Desktop-App bringt eine eigene Kopie von Claude Code mit, und dort laufen Mods ab 2.1.286. Geben Sie im Code-Tab /status ein, um zu sehen, welche Version dort läuft.

Was ich getestet habe. Am 7. Oktober 2026 habe ich mit Claude Code 2.1.293 im Code-Tab der Desktop-App unter macOS drei Mods gebaut: einen Befehls-Guard, eine Turn-Anzeige über dem Prompt und einen /pyenv-Command für die Arbeit mit Python. Alle drei bestehen claude plugin validate und 8 automatisierte Tests mit claude plugin test. Den Guard habe ich außerdem live in einer Session mit aktiviertem Hot Reloading laufen lassen. Die Community-Abschnitte stützen sich auf etwa 50 japanische Beiträge auf Zenn, Qiita und note.com vom 1. bis 7. Oktober, auf die offizielle Mods-Dokumentation (opens in a new tab) und auf die Scan-Daten des Katalogs awesome-claude-code-mods (opens in a new tab) vom 6. Oktober.

Was ein Mod ist und wann etwas anderes besser passt

Vor den Mods haben Sie Claude Code von außen erweitert: mit Settings-Hooks, Skills, einem Statuszeilen-Skript oder einem MCP-Server. Der Unterschied liegt darin, wo der Code läuft. Ein Settings-Hook ist ein Skript, das Claude Code von außen startet. Die Funktionen eines Mods laufen im Prozess von Claude Code selbst. Deshalb kann ein Mod in der Oberfläche zeichnen, die anderen Varianten können das nicht.

Die offizielle Übersicht vergleicht sie ungefähr so:

ModSettings-HookSkillMCP-Server
Was es istJS- oder TS-Funktionen in einem PluginEin Shell-Befehl, HTTP-Aufruf oder Prompt in settings.jsonEine SKILL.md-Datei mit AnweisungenEin externer Prozess, der Claude Tools bereitstellt
Kann in der Oberfläche zeichnenJaNeinNeinNein
Was sich damit ändern lässtTool-Aufrufe, Prompts, Commands, Turns, die OberflächeOb ein Aufruf durchgeht, seine Argumente und sein Ergebnis, zusätzlicher KontextWas Claude weiß und tutWelche Tools Claude hat
Passt, wennSie ein Panel, eine Leiste oder einen sofortigen Command brauchen oder ein Event umschreiben wollenSie bereits ein Skript haben, das blockiert oder protokolliertSie immer wieder dieselben Anweisungen einfügenClaude ein externes System erreichen muss

Eine Falle bei den Begriffen: Auf den Mods-Seiten der Doku bedeutet „hook“ eine Funktion eines Mods, die alte Variante heißt dort „settings hook“. Settings-Hooks funktionieren weiterhin und sind nicht veraltet. Ein Plugin kann einen Mod, einen Skill und einen MCP-Server zugleich enthalten.

Wo Mods funktionieren

Hooks laufen fast überall. Gezeichnet wird nur im Terminal und in der Desktop-App.

Wo Claude Code läuftHooks laufenMod-UI erscheint
claude im Terminal, auch in Editor-Terminals und JetBrainsJaJa
Desktop-App, Code-TabJaJa, außer reinen Terminal-Elementen
Desktop-App, WSL-SessionNeinNein
Chat-Panel der VS-Code-ErweiterungJaNein
claude -p und das Agent SDKJaNein
Cloud-SessionsJa, wenn das Plugin in der Session ankommtNein

Die Tabelle stammt aus der offiziellen Übersicht. Ein Guard-Mod schützt Sie also auch in VS Code und in claude -p, eine Anzeige findet dort dagegen keinen Platz zum Zeichnen.

Achten Sie auf zwei Kopien von Claude Code. Mehrere japanische Autoren bekamen verwirrende validate-Fehler, weil neben der in der Desktop-App gebündelten 2.1.286 noch eine alte Terminal-CLI aus Homebrew installiert war, laut ihren Berichten die Versionen 2.1.226 und 2.1.234. Prüfen Sie die Version an jeder Stelle, an der Sie Claude Code nutzen.

Wie ein Mod aufgebaut ist

Ein kleiner Mod besteht aus drei Dateien:

safe-shell/
├── .claude-plugin/
│   └── plugin.json      name, version, description
└── hooks/
    ├── hooks.json       { "modules": ["./register.ts"] }
    └── register.ts      your code

register.ts exportiert eine einzige Funktion, register(on). Jeder Aufruf von on(event, matcher, hook) fügt einen Hook hinzu, und jeder Hook bekommt dieselben drei Argumente.

  • $ ist die Engine. Alles außerhalb Ihres eigenen Codes läuft darüber: $.ui.toast, $.process.run, $.state, $.model.complete.
  • e ist das Event, zum Beispiel der Bash-Befehl, den Claude gleich ausführen will.
  • next(e) reicht das Event an die anderen Mods und danach an Claude Code weiter. Kehrt Ihr Hook zurück, ohne next aufzurufen, antwortet er selbst. Rufen Sie next({ ...e, command }) auf, ändern Sie, was passiert.

Im Modul gibt es weder Node noch ein DOM. Genau diese Grenze erlaubt es Claude Code, alles aufzulisten, was ein Mod aufruft, bevor er läuft. Probieren Sie es an einem beliebigen Mod-Ordner aus:

claude plugin validate ./safe-shell

Mod 1: ein Guard, der destruktive Befehle blockiert

Wenn Sie Claude im Auto mode oder mit Bypass permissions arbeiten lassen, hindert nichts Claude daran, git reset --hard auszuführen. Dieser Mod verweigert drei Arten von Shell-Befehlen und hält .env-Dateien aus der Konversation heraus.

import type { Register } from 'claude-code'
 
// Shell commands an agent should never run without a human typing them.
const BLOCKED: { pattern: RegExp; reason: string }[] = [
  {
    pattern: /\brm\s+-[a-zA-Z]*[rR][a-zA-Z]*\s+(\/|~|\$HOME)\/?\*?(\s|$)/,
    reason: 'recursive delete of / or the home folder',
  },
  {
    pattern: /\bgit\s+push\b.*(--force\b|--force-with-lease\b|\s-f\b).*\b(main|master)\b/,
    reason: 'force push to main or master',
  },
  {
    pattern: /\bgit\s+reset\s+--hard\b/,
    reason: 'git reset --hard throws away uncommitted work',
  },
]
 
// .env, .env.local, config/.env.production ... but not .env.example.
const isSecretEnvFile = (path: string) =>
  /(^|\/)\.env(\.[^/]+)?$/.test(path) && !/\.(example|sample|template)$/.test(path)
 
export const register: Register = on => {
  on('tool.call', { tool: 'Bash' }, ($, e, next) => {
    const hit = BLOCKED.find(rule => rule.pattern.test(e.command))
    if (hit === undefined) {
      return next(e)
    }
    $.ui.toast(`safe-shell blocked: ${hit.reason}`)
 
    return { deny: `safe-shell: blocked (${hit.reason}). Ask the user to run it themselves.` }
  }).catch(($, e, next) =>
    // Fail closed: if the guard itself breaks, refuse instead of letting the command through.
    next.called ? next(e) : { deny: 'safe-shell: the guard failed, so the command was not run.' },
  )
 
  for (const tool of ['Read', 'Edit', 'Write'] as const) {
    on('tool.call', { tool }, ($, e, next) =>
      isSecretEnvFile(e.file_path)
        ? { deny: `safe-shell: ${e.file_path} holds secrets and stays out of the conversation.` }
        : next(e),
    ).catch(($, e, next) =>
      next.called ? next(e) : { deny: 'safe-shell: the guard failed, so the file was not touched.' },
    )
  }
}

Zwei Details sind wichtiger als die regulären Ausdrücke.

Der Guard entscheidet, bevor er next aufruft. Sobald next läuft, ist der Befehl ausgeführt. Ein deny, das danach zurückkommt, macht nichts mehr rückgängig.

Das .catch lässt den Guard im Fehlerfall blockieren (fail closed). Ein Hook, der eine Exception wirft oder sein Zeitbudget von 10 Sekunden überschreitet, wird übersprungen, und ein übersprungener Guard lässt den Befehl durch. Der Handler next.called ? next(e) : deny verweigert stattdessen. validate meldet jeden Gating-Hook, also jeden Hook, der einen Aufruf stoppen kann, und ob er ein .catch hat. Genau das sollten Sie bei einem fremden Guard zuerst prüfen:

❯ ./register.ts hooks: tool.call{tool=Bash}, tool.call{tool=Read|Edit|Write}
❯ ./register.ts gating hook with .catch: tool.call{tool=Bash}
❯ ./register.ts gating hook with .catch: tool.call{tool=Read|Edit|Write}
❯ ./register.ts calls: $.ui.toast
✔ Validation passed

Ohne Session testen

claude plugin test führt die *.test.ts-Dateien eines Mods gegen die Engine aus, ohne Session, Anmeldung oder Netzwerk. Im Test-Kit liegt unter Ihrem Mod nichts. Deshalb registriert jeder Test Platzhalter-Hooks für alles, was der Mod weiterreicht:

import { expect, test } from 'claude-code/testing'
 
const ran = { stdout: 'ran', stderr: '', interrupted: false }
 
test('blocks rm -rf on the home folder', async ($, on) => {
  on('tool.call', { tool: 'Bash' }, () => ({ result: ran }))
  const answer = await $.tool.call({ tool: 'Bash', command: 'rm -rf ~' })
  expect(answer.deny).toContain('recursive delete')
})
 
test('lets ordinary commands through', async ($, on) => {
  on('tool.call', { tool: 'Bash' }, () => ({ result: ran }))
  const answer = await $.tool.call({ tool: 'Bash', command: 'rm -rf ./build && python -m pytest -q' })
  expect(answer.deny).toBeUndefined()
})

Die vollständige Datei enthält vier Tests:

(pass) blocks rm -rf on the home folder [16.23ms]
(pass) blocks a force push to main [7.73ms]
(pass) lets ordinary commands through [7.22ms]
(pass) keeps .env out of Read but allows .env.example [9.40ms]

 4 pass
 0 fail

Mein erster Lauf scheiterte mit on("tool.call") after the test first called $. Registrieren Sie die Platzhalter am Anfang jedes Tests, vor dem ersten $-Aufruf.

Was in einer echten Session passiert ist

Bei aktiviertem Hot Reloading habe ich Claude echo "the words git reset --hard inside an echo" ausführen lassen. Der Guard verweigerte das mit „blocked (git reset --hard throws away uncommitted work)“, und eine Toast-Meldung erschien. Dabei war dieses echo harmlos. Ein Mustervergleich kann einen Befehl nicht von Text unterscheiden, der ihn nur erwähnt. Außerdem übersieht er Befehle, die in einer Variablen, einem Skript oder einem Alias stecken. Japanische Autoren, die ähnliche Guards veröffentlicht haben, etwa rafi-guard, delete-guard und board-guard, berichten von beiden Problemen.

Sehen Sie einen Guard-Mod als zweites Sicherheitsnetz. Was nie passieren darf, gehört zusätzlich in eine deny-Regel der Berechtigungen. Bedenken Sie auch die Gegenrichtung. Laut offizieller Doku kann ein Mod auf einem privaten Rechner ohne Managed Settings einen Aufruf freigeben, den eine deny-Regel ablehnt. Mods laufen nicht in einer Sandbox, sondern mit Ihren Berechtigungen.

Mod 2: eine Anzeige über dem Prompt

Die Leiste über dem Prompt und das Seitenpanel sind die Stellen, an denen Mods am häufigsten zeichnen. Im Katalog-Scan vom 6. Oktober zeichnen 41% der Mods in die Leiste, und 40% öffnen ein Panel. Dieser Mod zeigt Dauer, Tool-Aufrufe und Tokens des letzten Turns, dazu einen Button „Hide“.

Werte, die beim Zeichnen gelesen werden, gehören in $.state, und jeder davon wird in einer kleinen Typdatei deklariert:

// types/index.d.ts, named in plugin.json as "types": "./types/index.d.ts"
export type TurnStats = {
  seconds: number
  tools: number
  inputTokens: number
  outputTokens: number
  model: string | null
}
 
declare module 'claude-code' {
  interface PluginState {
    'turn-meter': { last: TurnStats | null; isHidden: boolean }
  }
}

Die Hooks zählen Tool-Aufrufe, lesen durationMs und usage aus turn.complete und zeichnen die Leiste:

import { atom, read, update } from 'claude-code'
import type { Register } from 'claude-code'
 
import type { TurnStats } from '../types'
 
const last = atom({ plugin: 'turn-meter', key: 'last' } as const, null)
const isHidden = atom({ plugin: 'turn-meter', key: 'isHidden' } as const, false)
 
const formatTokens = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n))
 
export const register: Register = on => {
  let tools = 0
 
  on('prompt.submit', ($, e, next) => {
    tools = 0
    return next(e)
  })
 
  on('tool.call', ($, e, next) => {
    // Count the main conversation's calls; subagents carry an agentId.
    if (e.agentId === undefined) tools += 1
    return next(e)
  })
 
  on('turn.complete', async ($, e, next) => {
    if (e.agentId !== undefined) return next(e)
    const usage = e.usage
    const stats: TurnStats = {
      seconds: Math.round(e.durationMs / 1000),
      tools,
      inputTokens: usage
        ? usage.input_tokens + usage.cache_read_input_tokens + usage.cache_creation_input_tokens
        : 0,
      outputTokens: usage?.output_tokens ?? 0,
      model: usage?.model ?? null,
    }
    await update($, last, () => stats)
    if (stats.seconds > 120) $.ui.toast(`That turn took ${stats.seconds}s`)
    return next(e)
  })
 
  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
    const stats = await read($, last)
    if (e.props.hasSurvey || stats === null || (await read($, isHidden))) return next(e)
 
    const { Box, Button, Text } = $.ui.resolve(e)
    const model = stats.model === null ? '' : ` · ${stats.model}`
    // The band is shared by every mod: keep what the mods beneath drew, then add a row.
    const below = await next(e)
 
    return (
      <Box flexDirection="column">
        {below}
        <Box>
          <Text dimColor>
            {`Last turn: ${stats.seconds}s · ${stats.tools} tool calls · ${formatTokens(stats.inputTokens)} in / ${formatTokens(stats.outputTokens)} out${model} `}
          </Text>
          <Button key="hide" label="Hide" onPress={() => update($, isHidden, () => true)} />
        </Box>
      </Box>
    )
  })
}

Im Test steht in der Leiste, im Terminal wie in der Desktop-App:

Last turn: 42s · 0 tool calls · 18.2k in / 800 out · claude-opus-5-5 [ Hide ]

Drei Dinge, die ich dabei gelernt habe:

  • Halten Sie gezeichnete Werte in $.state, nicht in Modulvariablen. Ein Hot Reload führt register erneut aus und setzt Ihre Variablen zurück, $.state bleibt dagegen erhalten. /clear beginnt von vorn. Schreiben Sie also bei session.end in $.store, wenn ein Wert das überdauern muss.
  • Die Leiste wird geteilt. Rufen Sie next(e) auf und setzen Sie das Ergebnis in Ihre Box, sonst verdecken Sie die Zeilen aller anderen Mods. In einem Beitrag auf note.com verschwand so eine Leiste hinter einem anderen Mod, bis die Ursache klar war.
  • Text-Elemente behalten keinen key. Suchen Sie sie in Tests über ihren Inhalt: ui.find({ type: 'Text', text: /Last turn/ }).

Mod 3: /pyenv, wenn Claude das falsche Python verwendet

Ich habe nach Data-Science-Mods gesucht und eine Lücke gefunden. Von den 2.690 Mods im Scan vom 6. Oktober erwähnt keiner Jupyter, pandas, DataFrames, Polars, venv oder conda im Namen oder in der Beschreibung.

Das Problem hinter diesem Mod ist bei der Arbeit mit Daten verbreitet. Claudes Bash-Tool startet das python3, das in Ihrem PATH zuerst gefunden wird, und das ist oft nicht die Umgebung Ihres Projekts. Das hat das Prüfskript auf meinem Rechner ausgegeben:

python: /Users/<you>/.local/bin/python3 (3.14.2)
env: none (system or tool-managed Python)
pandas: 3.0.1
numpy: 2.4.2
polars: not installed
matplotlib: 3.11.0
pygwalker: not installed

Es war keine virtuelle Umgebung aktiv. Ein pip install von Claude wäre also in einem globalen Interpreter gelandet.

Der Command /pyenv führt dieses Prüfskript aus und antwortet in zwei Teilen. text ist die Zeile, die Sie sehen. context ist eine Notiz, die nur das Modell liest. So wissen Claudes nächste Bash-Aufrufe, welcher Interpreter im Einsatz ist, ohne dass Sie es noch einmal sagen müssen.

import type { Register } from 'claude-code'
 
// Reads package versions from metadata instead of importing them, so it stays fast.
const PROBE = `
import os, sys
from importlib.metadata import PackageNotFoundError, version
env = os.environ.get("VIRTUAL_ENV") or os.environ.get("CONDA_PREFIX") or "none (system or tool-managed Python)"
print(f"python: {sys.executable} ({sys.version.split()[0]})")
print(f"env: {env}")
for name in ("pandas", "numpy", "polars", "matplotlib", "pygwalker"):
    try:
        print(f"{name}: {version(name)}")
    except PackageNotFoundError:
        print(f"{name}: not installed")
`
 
export const register: Register = on => {
  on('session.start', async ($, e, next) => {
    await $.command.register({
      name: 'pyenv',
      description: "Show which Python, environment and data packages this session's shell uses",
    })
    return next(e)
  })
 
  on('command.run', { command: 'pyenv' }, async $ => {
    try {
      const probe = await $.process.run(['python3', '-c', PROBE], { timeoutMs: 15_000 })
      if (probe.exitCode !== 0) {
        return { text: `pyenv: python3 exited with ${probe.exitCode}: ${probe.stderr.trim().slice(0, 300)}` }
      }
      const report = probe.stdout.trim()
      // `text` is the row you see; `context` is a note only the model reads.
      return {
        text: report,
        context: [`Python environment of this session's shell, from /pyenv:\n${report}`],
      }
    } catch (error) {
      return { text: `pyenv: could not run python3 (${String(error).slice(0, 200)})` }
    }
  })
}

Der Slash-Command eines Mods führt Ihre Funktion sofort aus, ohne Turn des Modells und sogar dann, wenn Claude gerade beschäftigt ist. $.process.run erwartet eine Argumentliste ohne Shell und bricht nach 30 Sekunden ab, sofern Sie kein timeoutMs setzen.

Sieht $.process.run denselben PATH wie Claudes Bash-Tool? Ein Autor aus der Community stellte fest, dass in den Prozessen eines Mods das node von nvm fehlte. Also habe ich es mit einem temporären Prüf-Mod nachgeprüft. In meiner Desktop-Session bekam ein einfaches $.process.run genau den PATH des Bash-Tools und dasselbe python3. Über eine Login-Shell (zsh -lc) lieferte das Prüfskript dagegen das falsche Ergebnis. Die Shell fand Python 3.10.9 von python.org, weil eine nicht interaktive Login-Shell ~/.zshrc überspringt, wo die meisten PATH-Ergänzungen stehen. Bleiben Sie beim einfachen Aufruf. Wenn ein Ergebnis auf Ihrem Rechner seltsam aussieht, vergleichen Sie es mit !which python3, eingegeben am Prompt von Claude Code.

Beim Testen zeigte sich noch eine Falle. Aufrufe auf $, etwa $.process.run und $.command.register, brauchen ebenfalls Platzhalter, und ein Platzhalter für einen $-Aufruf antwortet mit { value: ... }. Geben Sie das nackte Ergebnis zurück, lehnt das Test-Kit es ab.

Wenn Ihre Analysen größtenteils in Notebooks statt in Skripten stattfinden, hilft das nur begrenzt. Claude Code bearbeitet .ipynb-Dateien als JSON und sieht den laufenden Kernel nie. RunCell (opens in a new tab) ist ein Notebook-Agent, der Zellen ausführt und ihre Ausgaben direkt liest. Für diese Art von Arbeit passt er deshalb besser.

Den Mod von Claude schreiben lassen

Nichts davon müssen Sie von Hand schreiben. Bitten Sie in einer Session darum, zum Beispiel mit „Erstelle einen Mod, der meine Nutzung im 5-Stunden-Fenster über dem Prompt anzeigt“. Claude lädt den eingebauten Skill plugin-authoring und schreibt die Dateien nach ~/.claude/dev-mods/<session-id>/. Bei der ersten Datei kommt genau eine Frage: „Enable hot reloading for this session?“. Sobald Sie zustimmen, wird jede Änderung neu geladen, wenn Claudes Turn endet. Genau so habe ich die drei Mods oben gebaut und geladen.

Was Doku und Community noch ergänzen:

  • Kopieren Sie den Ordner an einen dauerhaften Ort. Autoren auf Qiita und Zenn berichten, dass dev-mods-Ordner nach etwa 30 Tagen zusammen mit alten Sessions aufgeräumt werden.
  • Entwickeln Sie mit claude --plugin-dir ./my-mod. Ein installierter Mod läuft als zwischengespeicherte Kopie. Änderungen in seinem Ordner bewirken daher nichts, bis Sie das Plugin aktualisieren.
  • Die Desktop-App nimmt keine Flags an. Setzen Sie CLAUDE_CODE_PLUGIN_DIRS im env-Block von ~/.claude/settings.json. Projekteinstellungen werden dafür ignoriert.
  • Führen Sie /plugin aus. Eine abgeblendete Zeile wie 1 mod active · safe-shell bestätigt, dass der Mod geladen ist.
  • Starten Sie während der Entwicklung mit claude --debug. Das Debug-Log nennt jeden übersprungenen Hook und jede Zeichnung, die die Engine abgelehnt hat.

15 Community-Mods, aus denen Sie lernen können

Der Katalog awesome-claude-code-mods (opens in a new tab) mit 316 Sternen hat am 6. Oktober, fünf Tage nach dem Start, 2.690 öffentliche Mods in 1.265 Repositories gescannt. Seine Scan-Daten zeigen, was gebaut wird:

  • 68% fügen einen Slash-Command hinzu
  • 53% hängen sich in Tool-Aufrufe ein
  • 41% zeichnen über dem Prompt, 40% öffnen ein Panel
  • 40% starten Prozesse, 12% rufen ein Modell auf, 11% nutzen das Netzwerk

Diese 15 zeigen die Bandbreite. Die Sterne geben den Stand vom 7. Oktober 2026 wieder.

ModWas er machtSterneLesenswert wegen
terminal-browser (opens in a new tab)Ein Webbrowser neben der Konversation für Websites, lokale HTML-Vorschauen und Pull Requests3.695Das bisher ehrgeizigste Panel
claude-image-view (opens in a new tab)Vorschaubilder eingefügter Bilder über dem Prompt statt [Image #1]160Bilder im Terminal zeichnen
hamzafer/claude-code-mods (opens in a new tab)Ein Set aus Kontextleiste, Blast-Radius-Guard, Markdown-Vorschau und Subagent-Dashboard138Mehrere Mod-Arten in einem Repo
claude-auto-handoff (opens in a new tab)Übergibt eine lange Session mit einem strukturierten Briefing an eine neue60Kontextmanagement
prismantis (opens in a new tab)Gestaltete Antworten: Tabellen, Code, Diagramme als Box-Art, Text von rechts nach links49Claudes eigene Nachrichten umgestalten
cc-arcade (opens in a new tab)Neun Spiele über dem Prompt, die pausieren, wenn Claude fertig ist41Animation mit einem Frame-Takt
jev-permission-gate (opens in a new tab)Ein Entscheidungsmodell von Jev beurteilt Tool-Aufrufe im Auto mode28Ein sorgfältiger Abschnitt zum Datenschutz: Der Mod sendet Ihre letzten drei Nachrichten, je bis zu 1.500 Zeichen, an die API von TypeSafe
prompt-rail (opens in a new tab)Eine Leiste mit Ihren früheren Prompts: zum Lesen darüberfahren, zum Springen klicken22Das Herzstück des japanischen Mod-Überblicks mit den meisten Likes auf Zenn
claude-paste-view (opens in a new tab)Vorschau für eingefügte Bilder und lange eingefügte Texte18Kleiner, gut lesbarer Code
claude-gfm-render (opens in a new tab)GitHub-Alerts, Aufgabenlisten und Mermaid in Antworten, als Box-Art oder SVG14Je nach Oberfläche unterschiedlich zeichnen
claude_qamods (opens in a new tab)qa-guide erklärt Claudes Rückfragen und Optionen in einem Seitenpanel10Einen eingebauten Dialog verbessern
CC-Usage-Band (opens in a new tab)Limits für 5 Stunden und 7 Tage, Kontext und Cache-Trefferquote über dem Prompt10Die häufigste Mod-Art: eine Anzeige
harness-scope (opens in a new tab)Profile pro Repo, die globale Skills, Agents und Regeln ausblenden1Der Autor hat gemessen, wie die Skill-Liste von 98 auf 49 Einträge schrumpfte
touch-map (opens in a new tab)Zeigt, welche Dateien Claude aufgelistet, gelesen, bearbeitet oder erstellt hat0Der Autor stellte fest, dass Claude bei einer einzigen Refactoring-Analyse 125 von 304 Dateien angefasst hat
claude-mods-router (opens in a new tab)Ordnet jeden Prompt mit $.model.classify einer Effort-Stufe zu0Der Qiita-Artikel dazu (26 Likes) weist darauf hin, dass ein Modellwechsel das Prompt Caching bricht

Anthropic veröffentlicht außerdem drei Beispiele in claude-code-playground (opens in a new tab): token-weather, blast-radius und replay-theater. Der Quellcode der eingebauten Mods, darunter /diff, liegt im claude-code-Repository (opens in a new tab).

Best Practices, auf die sich die Community geeinigt hat

In der ersten Woche haben allein japanische Autoren etwa 50 Beiträge mit funktionierenden Mods, Messungen und Fehlerberichten veröffentlicht. Diese Gewohnheiten tauchten darin immer wieder auf.

  1. Lesen Sie einen Mod, bevor Sie ihn installieren. Klonen Sie ihn, führen Sie claude plugin validate aus und lesen Sie die Zeilen hooks: und calls:. Lesen Sie den Quellcode überall dort, wo $.process, $.http, $.fs.write, $.env.get oder $.model vorkommt. Validieren Sie nach jedem Update erneut. Eine bestandene Prüfung bedeutet, dass die Engine den Code laden kann, nicht, dass der Code sicher ist.
  2. Guards entscheiden vor next und blockieren im Fehlerfall. Mods, die nur beobachten, sollten im Fehlerfall durchlassen (fail open), mit .catch(($, e, next) => next(e)). So blockiert ein Bug in einer Anzeige nie Ihre Arbeit.
  3. Warten Sie innerhalb von $-Aufrufen. Ein Hook bekommt 10 Sekunden für seine eigene Laufzeit. Ein laufendes $.process.run oder $.ui.ask zählt nicht dazu, Ihre eigenen Promises dagegen schon.
  4. Speichern oder destrukturieren Sie $ nie. Reichen Sie es nur an Funktionen weiter, die auf der obersten Ebene der Datei deklariert sind. Bei mehreren Autoren luden Mods stillschweigend nicht, bis sie das behoben hatten.
  5. Achten Sie auf den Prompt-Cache. Wer mitten in der Session das Modell wechselt oder den System-Prompt zwischen Anfragen ändert, verwirft den Cache.
  6. Verzweigen Sie anhand von e.surface. Svg zeichnet nur in der Desktop-App. Raster und Image zeichnen nur im Terminal.
  7. Pinnen Sie für Teams eine Version. Die API ist im Early Access und ändert sich zwischen Releases. Fünf der sechs Releases nach dem Start, 2.1.288 bis 2.1.293, haben das Verhalten von Mods geändert oder korrigiert.

Das Maskieren von Secrets ist das warnende Beispiel. Ein Autor auf note.com baute einen Mod, der API-Keys in der Tool-Ausgabe ersetzte, bevor Claude sie sah. Beim Debuggen einer fehlgeschlagenen Bearbeitung mit od -c gab Claude die echten Werte trotzdem aus, und ein Write auf die komplette Datei speicherte die Platzhalter anstelle der echten Keys. Gehalten hat nur eine deny-Regel der Berechtigungen für diese Datei. Ein Mod, der ändert, was der Bildschirm zeigt, verbirgt nichts vor dem Modell.

Häufige Probleme

SymptomWahrscheinliche UrsacheLösung
/plugin listet den Mod nichtNicht vertrauenswürdiger Ordner, --safe-mode, --bare oder disableAllHooksDem Ordner vertrauen und ohne das Flag neu starten
hooks modules are turned off in this processAnthropic hat installierte Mods aus der Ferne abgeschaltetLokal gibt es nichts zu ändern. Aktualisieren, denn 2.1.289 und 2.1.290 haben zwei Fälle behoben, in denen Mods abgeschaltet blieben
validate scheitert mit „expected record, received undefined“Eine alte CLI steht in Ihrem PATH weiter vornclaude --version ausführen und aktualisieren
Ein Hook wird ohne sichtbaren Fehler übersprungenEr hat eine Exception geworfen, zum Beispiel durch den Aufruf $.plugin.name(), obwohl das eine Property istclaude --debug ausführen und die Skip-Zeile lesen
Ein Panel öffnet sich nieEin Panel, das sich ungefragt öffnet, erscheint erst ab 144 Spalten, dockt nur im Vollbild-Layout neben dem Transkript an, und /diff kann es verdeckenFenster verbreitern, das Vollbild-Layout ausprobieren, /diff schließen
Läuft im Terminal, aber nicht in der Desktop-AppDie Desktop-App bringt eine eigene Version mit, und manche Elemente gibt es nur im Terminal/status im Code-Tab prüfen und anhand von e.surface verzweigen
Keine Mod-UI in VS Code oder claude -pDiese Oberflächen zeichnen nichtAuf eine Zeile im Transkript oder den Text eines Commands ausweichen
Ein Test scheitert mit „nothing beneath the plugins answers“Das Test-Kit hat keine EnginePlatzhalter-Hooks ergänzen und $-Aufrufe mit { value } beantworten

Ihren Mod teilen

Legen Sie eine marketplace.json neben die plugin.json in .claude-plugin/:

{
  "name": "my-mods",
  "owner": { "name": "you" },
  "plugins": [{ "name": "safe-shell", "source": "./" }]
}

Pushen Sie den Ordner zu GitHub. Danach kann ihn jeder aus einer Terminal-Session installieren:

/plugin install safe-shell --marketplace you/safe-shell

In der Desktop-App führt der Weg in lokalen und SSH-Sessions über +, dann Plugins, dann Add plugin. Wenn Sie dem Repository das Topic claude-code-mod hinzufügen, nimmt der Community-Katalog es meist innerhalb weniger Stunden nach Ihrem nächsten Push auf.

FAQ

Verwandte Guides