Beiträge

Warum wir einen nativen MCP-Server für Retros gebaut haben

Redaktionelle Illustration eines Retro-Boards mit Haftnotizen, die in ein Chat-Panel links fließen, sanfter lila-pinker Farbverlauf, moderner flacher Vektorstil, der Chat wählt Tools aus einer kleinen Palette, kein lesbarer Text oder UI-Labels
Kelly Lewandowski

Kelly Lewandowski

Zuletzt aktualisiert am 19/05/20267 Min. Lesezeit

Wir hätten an einem Nachmittag einen Kollabe-MCP-Server ausliefern können, indem wir unsere OpenAPI-Spezifikation durch einen Code-Generator gejagt hätten. Stattdessen haben wir ein paar Wochen damit verbracht, die Tool-Oberfläche von Hand zu entwerfen. Das hat uns an dieser Entscheidung am meisten überrascht: Es ging fast ausschließlich um Retros. Standups und Planning Poker sind mechanisch. Du gibst Antworten ein; du gibst eine Stimme ab. Ein Modell, das JSON lesen und JSON schreiben kann, kommt mit einem generierten Wrapper gut zurecht. Retros haben die entgegengesetzte Form. Sie sind lang, chaotisch, teilweise anonym, werden abgestimmt, mit Reaktionen versehen, gruppiert, zusammengefasst und verweisen auf Personen, die man möglicherweise nicht über den Namen nachschlagen kann. Die erste Version, die wir ausprobiert haben — die REST eins zu eins gespiegelt hat — ist in dem Moment umgekippt, als ein Modell versuchte, jemandem Kudos zu geben.

"Nativ" heißt nicht "anderer Code"

Ein nativer MCP-Server ist kein separates Backend. Unserer ist eine dünne Schicht über denselben /api/v1/-Endpunkten, die jeder mit einem persönlichen Access Token direkt ansprechen kann. Dieselben Handler, dieselben Zod-Schemas, dieselben Berechtigungsprüfungen. Wenn wir in einem eine Regel ändern, zieht der andere mit. Was nativ wirklich bedeutet: Die Tool-Oberfläche wurde für das entworfen, was sie benutzt. Eine REST-API liest ein Entwickler mit offener Doku. Einen MCP-Server liest ein Modell mitten in einer Unterhaltung, nachdem es schon tausend Tokens System-Prompt verbraucht hat und ein Nutzer wartet. Beide Aufrufer wollen unterschiedliche Dinge vom selben Backend. Vier Unterschiede haben sich für Retros als entscheidend herausgestellt.

Entscheidung 1: weniger Tools, mit Toggles statt Paaren

Ein generierter Server hätte uns ein retro_create_reaction und ein retro_delete_reaction gegeben, genauso wie unsere REST-Routen Create und Delete trennen. Zwei Tools pro Emoji-Reaktion. Multipliziere das über Items und Kommentare und du verbrennst echte Tokens für Rauschen, bevor das Modell etwas Sinnvolles getan hat. Wir haben jede reversible Aktion in ein einziges Tool zusammengelegt. retro_toggle_reaction ist ein Tool, das ein Emoji an- oder ausschaltet, je nachdem, ob der Aufrufer bereits reagiert hat. Es gibt "added" oder "removed" in der Antwort zurück, damit das Modell erzählen kann, was passiert ist, ohne Reaktions-IDs zu speichern, die es nur zum Löschen bräuchte. Dieselbe Logik hat Item-Stimmen als Paar belassen (du kannst mehrere Stimmen auf demselben Item halten, also brauchst du tatsächlich eine ID, um eine zu entfernen) und Item-Erstellung und -Löschung getrennt gehalten (Items sind kein reversibler Zustand, sondern Datensätze). Toggle, wenn reversibel; getrennt, wenn nicht.

Entscheidung 2: Hinweise in die Beschreibungen schreiben, nicht in die Doku

Das Retro-Kudos-Tool hat uns das beigebracht. Die erste Version akzeptierte eine userId und einen kudoType und gab einen freundlichen Fehler zurück, wenn man jemanden übergab, der nicht im Space war. Modelle haben konsequent eine User-ID erfunden, den Fehler kassiert, sich entschuldigt und den Nutzer gebeten, die richtige ID einzufügen. Nutzlos. Wir haben es behoben, indem wir die Tool-Beschreibung umgeschrieben haben, nicht den Handler:
Gib einem anderen Nutzer Kudos, angehängt an ein bestehendes Retro-Item (erstelle erst eins mit retro_create_item, falls keins existiert). Der Empfänger muss Mitglied des Retro-Space sein — benutze organization_list_users (unterstützt einen Suchfilter), um die User-ID per Namen nachzuschlagen.
Gleicher Code, gleicher Fehler, aber jetzt liest das Modell die Beschreibung, ruft organization_list_users mit dem Namen auf, den der Nutzer laut gesagt hat, bekommt die ID und vergibt die Kudos in einem Zug. Der Handler hat sich nicht geändert. Der Hinweis schon. Illustration einer Sprechblase links mit einem kleinen Workflow rechts, der drei Schritte zeigt: einen Nutzer suchen, seinen Datensatz finden, dann Kudos an ein Retro-Item anhängen, sanfte Pastellpalette, flacher redaktioneller Vektorstil Wir haben angefangen, das überall zu tun. retro_update warnt in der Beschreibung, dass das Löschen einer Spalte auch jedes Item darin löscht. retro_cast_item_vote nennt das Stimmen-Limit pro Board und pro Spalte explizit, damit das Modell den Nutzer vorab informieren kann, bevor es in den 400er rennt. Jedes "das musst du wissen, um mich richtig aufzurufen" landet im Tool selbst, nicht in einem separaten Guide, den niemand liest.

Entscheidung 3: ein semantisches Such-Tool, keine List-and-Filter-Kette

Retros sammeln sich an. Ein Team, das alle zwei Wochen eines macht, hat im Jahr 26 Boards mit vielleicht 800 Items insgesamt. Wenn jemand einen Assistenten fragt "was haben wir letztes Quartal über flaky Deploys gesagt", ist die schlechteste mögliche Antwort, dass das Modell retro_list aufruft, dann retro_list_items für jedes Ergebnis, und alles in den Kontext lädt. Das ist ein Tool-Call-Sturm, der den Nutzer Geld kostet und eine schlechtere Antwort produziert als grep. Also haben wir ein search-Tool gebaut, das semantische Suche über den gesamten Space auf einmal ausführt. Es liefert Retro-Items, Kommentare, Action Items, Standup-Antworten, Umfrageantworten, Eisbrecher-Antworten und Notizen, sortiert nach Kosinus-Ähnlichkeit gegenüber der Anfrage, gruppiert nach Typ. Das Modell bekommt die relevanten 20 Ergebnisse in einem Aufruf, statt sich über hunderte Datensätze zu verteilen.

Entscheidung 4: Zustimmung pro Feature zum OAuth-Zeitpunkt

Der Kollabe-MCP-Server hat rund vierzig Tools über Retros, Standups, Planning Poker, Action Items und Suche hinweg. Einen Nutzer zu bitten, all vierzig in einem Screen abzunicken, ist die Art Entscheidung, die Leute ohne Lesen wegklicken. Wir haben den Consent-Screen nach Kategorie aufgeteilt. Wenn du Kollabe mit Claude oder Cursor verbindest, hakst du die Kategorien an, die du willst (Retros, Standups, Planning Poker, Action Items, Suche), und der Token ist auf diese begrenzt. Ein Team, das nur will, dass sein PM Retro-Action-Items über Claude entwirft, muss keinen Standup- oder Poker-Zugriff gewähren. Ein Widerruf aus den Nutzereinstellungen heraus kappt ihn, egal ob du einer Kategorie oder allen zugestimmt hast. Der Token nennt außerdem eine konkrete Kollabe-Organisation. Wenn du mehreren Orgs angehörst, wählst du im Consent-Screen aus, welche, und der Token agiert als du, nur in dieser Org. Org wechseln, neu verbinden.

Was das am Retro-Board bedeutet

Ein Nutzer, der Kollabe mit seinem KI-Client verbunden hat, kann jetzt eine Unterhaltung führen, die so aussieht — wobei das Modell die Beinarbeit macht:
  1. Das Board vorbereiten
    "Öffne das Retro dieses Sprints und füge Items aus den Postmortems hinzu, die wir die letzten zwei Wochen in Linear geschrieben haben, eins pro Vorfall, in der Spalte What Could Improve." Das Modell legt die Items an, markiert sie anonym, wo das Quell-Ticket es war, und hört auf.
  2. Kontext aus alten Retros finden
    "Haben wir schon mal über CI-Flakiness gesprochen?" Semantische Suche liefert die drei Retros, in denen es aufkam, und die Action Items, die daraus entstanden sind — in einem Aufruf.
  3. Diskussion in Action Items übersetzen
    "Mach aus den drei meistgewählten Items auf dem Board Action Items, weise sie jeweils der Person zu, die sie geschrieben hat, fällig Freitag." retro_list_items und dann ein paar action_item_create-Aufrufe. Das Modell macht die Zuweisung über den Item-Autor.
  4. Kudos per Namen vergeben
    "Gib Priya Kudos dafür, dass sie die Migration entblockt hat." Das Modell ruft organization_list_users mit einer Suche nach "Priya" auf und hängt dann die Kudos an.
Nichts davon ist ein neues Feature. Jeder einzelne dieser Aufrufe entspricht einem REST-Endpunkt, der seit Monaten live ist. Die MCP-Schicht ist der Unterschied zwischen "die API existiert" und "das Modell kann die API benutzen".

Was wir wieder so machen würden, was wir uns sparen würden

Wir würden das Toggle-Pattern ab Tag eins bauen. Wir würden die querverweisenden Hinweise ab Tag eins in die Beschreibungen schreiben. Wir würden semantische Suche vor jedem einzelnen List-Endpunkt ausliefern, weil das das Tool ist, das das Modell tatsächlich will. Was wir uns sparen würden, ist die Versuchung, MCP "reichhaltiger" zu machen als REST. Wir haben kurz versucht, Auto-Zusammenfassungen ins retro_get-Tool einzubacken. Modelle haben dann die Zusammenfassung zusammengefasst, und die Latenz verdreifachte sich. Langweilig hat gewonnen. Das MCP-Tool gibt dieselbe Form zurück wie der REST-Endpunkt. KI obendrauf ist Sache des Nutzers per Prompt, nicht etwas, was wir ins Protokoll einbacken. Wenn du das an deinen eigenen Retros ausprobieren willst, ist die Setup-Anleitung sechzig Sekunden OAuth. Der tiefere Hintergrund zum Protokoll steht in unserem MCP-Erklärartikel. Und wenn du lieber sehen willst, wie KI zu einem Retro passt, bevor du ein Modell verkabelst, ist unser Retrospektive-Template-Generator ein unverbindlicher Einstieg.

Nein. Der MCP-Server ist ein dünner Adapter über denselben /api/v1/-Handlern. Die interessante Arbeit steckt in den Tool-Definitionen: Benennung, Gruppierung, Hinweise und welche Aktionen zu einem einzigen Toggle zusammengelegt werden. Die Backend-Logik ist geteilt.

Ja. retro_create_item akzeptiert ein anonymous -Flag, und retro_create_item_comment auch. Wenn gesetzt, lässt die Antwort die Autor-User-ID weg, genauso wie das UI es macht. Anonymität wird auf Handler-Ebene erzwungen, nicht in der Beschreibung.

Die Tool-Beschreibung für retro_update warnt davor, dass das Löschen einer Spalte auch jedes Item darin löscht. Wir verlassen uns darauf, dass das Modell das dem Nutzer vor dem Aufruf zeigt — genauso wie ein Entwickler, der die Doku liest, die Warnung bemerken würde. Es gibt keinen separaten Bestätigungsschritt im Protokoll.

Nein. Die Zustimmung wird zum OAuth-Zeitpunkt nach Kategorie aufgeteilt. Du kannst nur Retro-Zugriff gewähren oder jede Kombination aus Retros, Standups, Planning Poker, Action Items und Suche. Tokens lassen sich aus deinen Kollabe-Einstellungen widerrufen.