Nutze @file-Referenzen, allowed-tools, Subagenten und MCP-Tools, um Slash Commands von Abkürzungen zu einer Team-Workflow-Bibliothek auszubauen.
Die ersten beiden Artikel behandelten, was ein Slash Command ist (eine Markdown-Datei) und wie man mit dem !-Präfix Shell-Output in den Kontext injiziert. Dieser geht weiter: wie man einen einzigen Command so baut, dass er die stärksten Fähigkeiten von Claude Code orchestriert — Dateireferenzen, Subagenten, MCP-Tools — und die Berechtigungen dabei im Griff behält.
Auf dieser Ebene ist ein Command keine „Prompt-Abkürzung" mehr, sondern ein wiederverwendbarer kleiner Workflow.
@file-Referenzen: die bessere statische Injektion als !cat!cat file.md schiebt zwar den Inhalt einer Datei in den Kontext, geht dafür aber über die Shell — mit mehreren Nachteilen: bei jedem Aufruf wird ein Subprozess gestartet; Leerzeichen oder Sonderzeichen im Pfad brauchen zusätzliches Escaping; und Claude Code erkennt das Ergebnis nicht als „Datei", sondern nur als einen Block Text.
Die @-Referenz ist nativ:
---
description: Änderungen nach Projektrichtlinien prüfen
---
Ziehe folgende Richtlinien heran:
@.claude/context/coding-standards.md
@.claude/context/security-checklist.md
Prüfe jetzt die Änderungen im git diff und weise auf jede Verletzung der Richtlinien hin.
!`git diff HEAD`
@pfad sagt Claude Code: „hänge diese Datei als Anlage an die Konversation". Der Unterschied:
| Situation | !cat |
@ |
|---|---|---|
Pfad kommt aus Argument ($ARGUMENTS) |
✅ nur !cat geht |
❌ @ unterstützt keine Variablenexpansion |
| Feste Projektrichtlinien, Templates | ⚠️ geht, aber schwerfällig | ✅ nativ, spart einen Shell-Aufruf |
| Dynamische Inhalte (diff, Logs, Testergebnisse) | ✅ ! Pflicht |
❌ geht nicht |
Faustregel: statische Dateien mit @, dynamische Ausgaben mit !, Argument-Pfade mit !cat $ARGUMENTS.
allowed-tools: dem Command Berechtigungsgrenzen setzenStandardmäßig darf das Modell während der Command-Ausführung alle Tools der Session benutzen. Das ist nicht immer erwünscht — /review ist zum Beispiel ein reines Lese-Review, und man will nicht, dass „so nebenbei" eine Zeile Code geändert wird.
Trägt man allowed-tools ins Frontmatter ein, sind während der Ausführung nur die gelisteten Tools erlaubt:
---
description: Nur-Lesen Code-Review
allowed-tools: Read, Grep, Glob, Bash(git diff:*), Bash(git log:*)
---
Prüfe die Unterschiede zwischen dem aktuellen Branch und master, nur lesen, nichts ändern.
!`git diff master...HEAD`
Ein paar Punkte dazu:
Bash(git diff:*) ist fein granuliert — nur Bash-Aufrufe, die mit git diff beginnen, sind erlaubt; git push wird blockiertRead / Grep / Glob gibt gezielt nur Lese-Tools freiEdit / Write fehlen: selbst wenn das Modell wollte, könnte es keinen Code verändernUmgekehrt lässt sich ein Command mit hohen Rechten wie /deploy explizit freischalten:
---
description: Aktuellen Branch deployen
allowed-tools: Bash(kamal deploy:*), Bash(git push:*), Read
---
Fest zu verdrahten, „was dieser Command darf", ist verlässlicher, als jedes Mal bei der Ausführung manuell einen Bash-Prompt abzunicken.
Manche Aufgaben sprengen den Kontext der Hauptkonversation — Dutzende Dateien nach allen Aufrufen einer Funktion durchsuchen, Statistiken über die Codebase, einen großen Log-Block analysieren. Macht man das direkt, bleiben tausende Zeilen Output im Kontext liegen, und die weitere Konversation wird langsam und unschärfer.
Der richtige Weg: solche Arbeit an einen Subagent abgeben. Der Subagent läuft in seinem eigenen Kontext und bringt nur die Schlussfolgerung zurück. Im Command reicht eine explizite Anweisung:
---
description: Tiefenrecherche zu allen Verwendungen eines Symbols
allowed-tools: Task
---
Verwende den Explore-Subagent, um alle Verwendungen des folgenden Symbols gründlich zu recherchieren: $ARGUMENTS
Der Subagent soll abdecken:
- Alle Aufrufstellen (inklusive Testdateien)
- Die betroffenen fachlichen Szenarien
- Ob es äquivalente alternative Implementierungen gibt
Wenn der Subagent zurückkommt, gib mir nur eine Zusammenfassung von ≤300 Wörtern, keine Roh-Code-Snippets einfügen.
Mit /trace SomeClass#some_method startet Claude Code einen Explore-Subagent, der die Codebase parallel durchforstet; die Hauptkonversation sieht nur das destillierte Ergebnis. Kein grep-Output, keine Dateischnipsel, sauberer Kontext.
Ausbaustufe:
---
description: Drei Lösungsansätze parallel recherchieren
allowed-tools: Task
---
Starte 3 Subagenten parallel, jeder recherchiert einen der folgenden Implementierungswege:
1. Vorhandenes ActiveJob + Sidekiq nutzen
2. Solid Queue nutzen
3. Eine eigene schlanke Queue bauen
Jeder Agent antwortet zu: Aufwand, Risiko, Eingriffstiefe in den bestehenden Code. Wenn alle drei Ergebnisse da sind, mache ich den Vergleich.
Drei Subagenten laufen parallel, die Hauptkonversation wartet nur einmal. Das ist einer der größten Hebel, die ein Command bieten kann: Rechercheaufgaben, die normalerweise viele Tokens kosten, in einen Ein-Klick-Workflow verwandeln.
Wenn an der Session MCP-Server hängen (Linear, GitHub, Sentry, ein eigener DB-Proxy …), kann ein Command das Modell direkt anweisen, diese Tools zu verwenden:
---
description: Implementierungs-Todo aus einer Linear-Issue erzeugen
allowed-tools: mcp__linear__*, Read, Grep
---
Lies die vollständige Beschreibung und die Kommentare der Linear-Issue $ARGUMENTS.
Gleiche das mit dem aktuellen Zustand der Codebase ab (finde mit Grep/Read selbst die relevanten Dateien) und erstelle eine Implementierungs-Todo:
- Welche Dateien müssen geändert werden
- Ist jeder Schritt ein eigener Commit oder gemeinsam
- Gibt es Unklarheiten, die vorher mit dem PM geklärt werden müssen
Fang noch nicht an zu coden, nur der Plan.
mcp__linear__* gibt alle Linear-MCP-Tools frei — das Modell kann Issue-Details, Kommentare, Status ziehen. Der ganze Command wird zum Startpunkt eines Workflows „vom Ticket zum Umsetzungsplan".
Wichtig: In allowed-tools muss man MCP-Toolnamen mit dem vollen Präfix schreiben (mcp__<server>__<tool>), sonst greift die Freigabe nicht.
Ein häufiges Missverständnis: in der Datei von /review /test hinzuschreiben und glauben, der test-Command wird ausgelöst. Nein. Ein Slash Command wird nur einmal expandiert, auf der obersten Ebene der Benutzereingabe. Innerhalb eines Commands ist /xxx nur gewöhnlicher Text: das Modell liest ihn, aber Claude Code führt ihn nicht aus.
Wer mehrere Commands kombinieren will, hat folgende saubere Optionen:
Variante A: gemeinsame Logik in eine Kontextdatei auslagern, die mehrere Commands via @ oder !cat referenzieren
@.claude/context/review-checklist.md
@.claude/context/security-checklist.md
Variante B: im Command explizit schreiben „mach es wie /review" + die wichtigsten Anweisungen wiederholen
Nicht elegant, aber es funktioniert. Solange der Prompt klar genug ist, geht das Modell denselben Weg.
Variante C: ein Command startet per Task-Tool einen Subagent, dessen Prompt wiederum dieselben Kontextdateien nutzt
Echte Workflow-Orchestrierung läuft über diesen Weg. Der Eltern-Command kümmert sich um Planung und Zusammenfassung, der Subagent führt die Einzelschritte aus.
Zu vermeidendes Anti-Pattern: einen Command von mehreren hundert Zeilen schreiben, der alles in einer Anweisung erledigen will. Die Granularität explodiert, der Wartungsaufwand schießt hoch, und ein einziger Aufruf verschlingt das gesamte Token-Budget.
An dieser Stelle sind die Mechanismen, um einem Command „externe Fähigkeiten" zu verleihen, in Claude Code weitgehend komplett. Die Auswahl:
| Anforderung | Bevorzugter Mechanismus |
|---|---|
| Feste Richtlinien, Templates, Kontext-Dokumente | @file-Referenz |
| Echtzeitstatus (diff, Logs, Testergebnisse, DB-Abfragen) | !shell-Injektion |
| Dateiinhalt mit Parameter | !cat $ARGUMENTS |
| Kontextintensive Recherche, dateiübergreifende Suche | Subagent via Task |
| Externe Systeme (Issue-Tracker, Monitoring, Produktion) | MCP-Tools + allowed-tools |
| Mehrstufige serielle/parallele Workflows | Eltern-Command dirigiert Subagenten |
Berechtigungsgrenzen explizit über allowed-tools deklarieren — besonders bei Commands, die im Team geteilt werden. Fest festzulegen, was der Command darf, ist zuverlässiger als sich auf menschliche Freigabe bei jedem Aufruf zu verlassen.
Alles zusammengenommen, hier ein Command „Implementierungspfad aus einem Linear-Ticket recherchieren":
---
description: Umsetzungsplan auf Basis eines Linear-Tickets erzeugen
allowed-tools: mcp__linear__*, Task, Read, Grep, Glob, Bash(git log:*)
---
## Kontext
@.claude/context/architecture.md
@.claude/context/coding-standards.md
## Aktueller Stand der Codebase
!`git log --oneline -10`
## Aufgabe
Hol dir die Beschreibung, Kommentare und verknüpfte Tickets des Linear-Tickets $ARGUMENTS.
Starte dann zwei Subagenten parallel:
1. Der erste: finde in der Codebase alle verwandten vorhandenen Implementierungen und wiederverwendbare Module
2. Der zweite: bewerte die Risiken — welche stark frequentierten Code-Pfade berührt diese Änderung, gibt es Lücken in der Testabdeckung
Wenn beide zurück sind, gib aus:
- Umsetzungsschritte (nach Abhängigkeiten sortiert)
- Risikoliste
- Vorgeschlagene Commit-Granularität
Fang noch nicht an zu coden.
Mit /plan ENG-4213 läuft die ganze Kette in einem Rutsch: Ticket ziehen → Codebase parallel recherchieren → Risiken bewerten → Plan zusammenfassen. Der Benutzer muss nur noch das Ergebnis durchlesen und entscheiden, ob er loslegt.
Das ist der komplette Bogen der ersten drei Artikel der Slash-Command-Serie: wiederverwendbare Prompts definieren (intro) → Kontext dynamisch injizieren (context) → Tools und Subagenten orchestrieren (dieser Artikel). Auf dieser Stufe ist .claude/commands/ kein Verzeichnis voller Abkürzungen mehr, sondern die kleine Workflow-Bibliothek des Teams.