Gönderiler

Retrospektifler için neden yerel bir MCP sunucusu geliştirdik

Sol tarafta bir sohbet paneline akan yapışkan notlardan oluşan bir retrospektif panosunun editoryal illüstrasyonu, yumuşak mor ve pembe geçişli, modern düz vektör tarzı, sohbet küçük bir paletten araçlar seçiyor, okunabilir metin veya UI etiketi yok
Kelly Lewandowski

Kelly Lewandowski

Son güncelleme 19/05/20267 dk okuma

OpenAPI spesifikasyonumuzu bir kod üreticisinden geçirerek bir Kollabe MCP sunucusunu bir öğleden sonrada yayına alabilirdik. Bunun yerine, araç yüzeyini elle tasarlamak için birkaç hafta harcadık. Bu kararda bizi en çok şaşırtan kısım şu: işin neredeyse tamamı retrospektifler ile ilgiliydi. Standuplar ve planlama pokeri mekaniktir. Cevap gönderirsin; oy verirsin. JSON okuyup JSON yazabilen bir model, üretilmiş bir sarmalayıcıyla gayet iyi iş çıkarır. Retrospektifler bunun tam tersi bir yapıdadır. Uzun, dağınık, kısmen anonim, oylanan, tepki verilen, gruplandırılan, özetlenen ve isimle bulamayabileceğin kişilere referans veren içeriklerdir. Denediğimiz ilk sürüm, REST'i birebir yansıtan sürüm, bir model birine takdir vermeye çalıştığı an çuvalladı.

"Yerel" demek "farklı kod" demek değil

Yerel bir MCP sunucusu ayrı bir backend değildir. Bizimki, kişisel erişim tokeni olan herkesin doğrudan çağırabildiği aynı /api/v1/ uç noktalarının üzerine ince bir katmandır. Aynı işleyiciler, aynı Zod şemaları, aynı yetki kontrolleri. Birinde bir kural değişirse diğeri de onunla birlikte değişir. Yerel olmanın gerçek anlamı şu: araç yüzeyi onu kullanan şey için tasarlandı. Bir REST API, dokümanlar açık bir geliştirici tarafından okunur. Bir MCP sunucusu ise zaten bin token sistem isteminin harcandığı, bir kullanıcının beklediği bir sohbetin ortasındaki model tarafından okunur. İki çağıran taraf aynı backendden farklı şeyler ister. Retrospektifler için dört fark önemli olmaya başladı.

Karar 1: çift yerine geçiş düğmesi olan, daha az araç

Üretilmiş bir sunucu bize bir retro_create_reaction ve bir retro_delete_reaction verirdi; REST rotalarımızın oluşturmayı silmeden ayırdığı gibi. Her emoji tepkisi başına iki araç. Bunu öğelerle ve yorumlarla çarp; model henüz faydalı bir şey yapmadan gerçek tokenleri gürültüye harcıyor olursun. Geri alınabilir her eylemi tek bir araca topladık. retro_toggle_reaction, çağıranın daha önce tepki verip vermediğine göre bir emojiyi açan ya da kapatan tek bir araçtır. Yanıtta "added" veya "removed" döner; böylece model, yalnızca silmek için ihtiyaç duyacağı tepki kimliklerini saklamak zorunda kalmadan ne olduğunu anlatabilir. Aynı mantık, öğe oylarını çift olarak tuttu (aynı öğe üzerinde birden fazla oy tutabilirsin, dolayısıyla birini kaldırmak için gerçekten bir kimliğe ihtiyacın olur) ve öğe oluşturma ile silmeyi ayrı tuttu (öğeler geri alınabilir bir durum değil, kayıtlardır). Geri alınabilirse geçiş düğmesi yap, değilse ayrı tut.

Karar 2: ipuçlarını dokümanlara değil, açıklamalara yaz

Retrospektif takdir aracı bize bunu öğretti. İlk sürüm bir userId ve bir kudoType kabul ediyor ve alanda olmayan birini geçtiğinde nazik bir hata döndürüyordu. Modeller sürekli bir kullanıcı kimliği uyduruyor, hatayla karşılaşıyor, özür diliyor ve kullanıcıdan doğru kimliği yapıştırmasını istiyordu. Faydasız. Bunu işleyiciyi değil, araç açıklamasını yeniden yazarak düzelttik:
Başka bir kullanıcıya, mevcut bir retrospektif öğesine bağlı olarak takdir ver (yoksa önce retro_create_item ile bir tane oluştur). Alıcı, retrospektifin alanının bir üyesi olmalıdır — kullanıcı kimliğini isme göre bulmak için organization_list_users kullan (arama filtresini destekler).
Aynı kod, aynı hata, ama artık model açıklamayı okuyor, kullanıcının yüksek sesle söylediği isimle organization_list_users'ı çağırıyor, kimliği alıyor ve takdiri tek seferde veriyor. İşleyici değişmedi. İpucu değişti. Sol tarafta bir sohbet baloncuğu, sağ tarafta üç adımlı küçük bir iş akışı: bir kullanıcı ara, kaydını bul, sonra bir retrospektif öğesine takdir ekle; yumuşak pastel palet, düz vektör editoryal tarzı Bunu her yerde yapmaya başladık. retro_update, açıklama içinde bir sütunu silmenin içindeki tüm öğeleri de sildiği konusunda uyarıyor. retro_cast_item_vote, pano başına ve sütun başına oy üst sınırından açıkça bahsediyor; böylece model, 400'e yakalanmadan önce kullanıcıyı uyarabiliyor. "Beni doğru çağırmak için bilmen gereken her şey" aracın içine giriyor, kimsenin okumadığı ayrı bir kılavuza değil.

Karar 3: bir liste-ve-filtrele zinciri değil, anlamsal bir arama aracı

Retrospektifler birikir. İki haftada bir retrospektif yapan bir ekibin yılda 26 panosu, bu panolarda da belki 800 öğesi olur. Birisi bir asistana "geçen çeyrek dengesiz deploylar hakkında ne demiştik" diye sorduğunda, mümkün olan en kötü cevap, modelin retro_list'i çağırması, sonra her sonuç için retro_list_items'ı çağırması ve hepsini bağlama okumasıdır. Bu, kullanıcıya para harcatan ve grep'ten daha kötü bir cevap üreten bir araç-çağrısı fırtınasıdır. Bu yüzden tüm alan genelinde anlamsal arama çalıştıran bir search aracı geliştirdik. Sorguya karşı kosinüs benzerliğine göre sıralanmış ve türe göre gruplanmış retrospektif öğelerini, yorumları, aksiyon öğelerini, standup cevaplarını, anket yanıtlarını, buz kırıcı cevaplarını ve notları döndürür. Model, yüzlerce kayıt arasında dağılmak yerine ilgili 20 sonucu tek bir çağrıda alır.

Karar 4: OAuth aşamasında özellik bazında onay

Kollabe MCP sunucusunda retrospektifler, standuplar, planlama pokeri, aksiyon öğeleri ve arama arasında yaklaşık kırk araç var. Bir kullanıcıdan kırkının hepsine tek bir ekranda onay vermesini istemek, insanların okumadan tıklayıp geçtiği türden bir karardır. Onay ekranını kategoriye göre böldük. Kollabe'yi Claude veya Cursor'a bağladığında, istediğin kategorileri işaretliyorsun (retrospektifler, standuplar, planlama pokeri, aksiyon öğeleri, arama) ve token o kategorilerle sınırlı oluyor. Yalnızca PM'inin Claude üzerinden retrospektif aksiyon öğeleri taslamasını isteyen bir ekibin, standup veya poker erişimi vermesi gerekmiyor. Kullanıcı ayarları sayfasından yapılan iptal, bir kategoriye mi yoksa hepsine mi onay verildiğini umursamadan tokeni öldürür. Token ayrıca belirli bir Kollabe organizasyonunu adlandırır. Birkaç organizasyona aitsen, onay ekranında hangisini seçeceğini belirlersin ve token yalnızca o organizasyonda, senin adına çalışır. Organizasyon değiştirirsen, yeniden bağlanırsın.

Retrospektif panosunda bu ne anlama geliyor

Kollabe'yi AI istemcisine bağlamış bir kullanıcı artık modelin tüm ağır işi yaptığı şöyle bir sohbet yapabilir:
  1. Panoyu önceden doldur
    "Bu sprintin retrospektifini aç ve bu iki haftada Linear'da yazdığımız postmortem'lerden öğeler ekle; her olay için bir tane, What Could Improve sütununa." Model öğeleri oluşturur, kaynak biletin anonim olduğu yerleri anonim olarak işaretler ve durur.
  2. Eski retrospektiflerden bağlam bul
    "Daha önce CI dengesizliği hakkında konuşmuş muyduk?" Anlamsal arama, konunun geçtiği üç retrospektifi ve onlardan çıkan aksiyon öğelerini tek bir çağrıda döndürür.
  3. Tartışmayı aksiyon öğelerine dönüştür
    "Panodaki en çok oy alan üç öğeden aksiyon öğeleri çıkar, her birini onu yazan kişiye ata, Cuma'ya teslim." retro_list_items, ardından birkaç action_item_create çağrısı. Model atamayı öğe yazarına göre yapar.
  4. İsimle takdir ver
    "Priya'ya migrasyonun önündeki engeli kaldırdığı için takdir ver." Model, organization_list_users'ı "Priya" araması ile çağırır, ardından takdiri ekler.
Bunların hiçbiri yeni bir özellik değil. Bu çağrıların her biri aylardır yayında olan bir REST uç noktasına eşleşiyor. MCP katmanı, "API var" ile "model API'yi kullanabiliyor" arasındaki farktır.

Yeniden yapacaklarımız, atlayacaklarımız

Geçiş düğmesi desenini ilk günden inşa ederdik. Çapraz referanslı ipuçlarını açıklamalara ilk günden yazardık. Anlamsal aramayı, herhangi bir tekil liste uç noktasından önce yayına alırdık; çünkü modelin gerçekten istediği araç o. Atlayacağımız şey, MCP'yi REST'ten "daha zengin" yapma cazibesi. Kısa bir süre, retro_get aracına otomatik özetler gömmeyi denedik. Modeller sonra özeti özetledi ve gecikme üçe katlandı. Sıkıcı olan kazandı. MCP aracı, REST uç noktasının döndürdüğü şekli döndürüyor. Bunun üzerine eklenecek AI, kullanıcının istem ile devreye alması içindir; bizim protokole gömmemiz için değil. Bunu kendi retrospektiflerinde denemek istersen, kurulum kılavuzu altmış saniyelik bir OAuth işlemi. Protokol hakkında daha derin arka plan MCP açıklayıcımızda var. Bir model bağlamadan önce AI'nin bir retrospektife nasıl oturduğunu görmek istersen, retrospektif şablonu oluşturucumuz bağlayıcılığı olmayan iyi bir başlangıç noktası.

Hayır. MCP sunucusu, aynı /api/v1/ işleyicileri üzerine ince bir adaptör. İlginç iş araç tanımlarında: isimlendirme, gruplama, ipuçları ve hangi eylemlerin tek bir geçiş düğmesine indirgendiği. Backend mantığı paylaşılıyor.

Evet. retro_create_item bir anonymous bayrağı kabul eder, retro_create_item_comment de öyle. Ayarlandığında, yanıt yazar kullanıcı kimliğini, UI'nin yaptığı gibi atlar. Anonimlik açıklamada değil, işleyici düzeyinde uygulanır.

retro_update için araç açıklaması, bir sütunu silmenin içindeki tüm öğeleri de sildiği konusunda uyarır. Bunu çağırmadan önce modelin kullanıcıya bildirmesine güveniyoruz; tıpkı dokümanları okuyan bir geliştirenin uyarıyı fark etmesi gibi. Protokol içinde ayrı bir onay adımı yok.

Hayır. Onay, OAuth aşamasında kategoriye göre bölünür. Yalnızca retrospektif erişimi verebilir veya retrospektifler, standuplar, planlama pokeri, aksiyon öğeleri ve aramanın herhangi bir kombinasyonunu verebilirsin. Tokenler Kollabe ayarlarından iptal edilebilir.