Bu sayfada
8 Haziran 2026’da Anthropic, Claude dizinindeki bağlayıcıların sahiplerine bir pano verdi. Pano aktif kullanıcıları, toplam araç çağrılarını ve dizin sıralamasını gösteriyor. Ayrıca “bir bakışta sağlık puanı, hata oranları ve gecikme, neyin başarısız olduğunu tam olarak bulmak için araç bazında hata dökümleriyle” gösteriyor.
Bir yıl önce Weights & Biases’tan Alex Volkov aynı sorunu öbür uçtan anlatmıştı. Ajanı araçları MCP üzerinden çağırmaya başlayınca “kendi kodum baştan sona çalışırken alıştığım tüm o gözlemlenebilirlik biraz karardı”. Konuşmayı birlikte yaptığı Dylibso’dan Benjamin Eckel nedenini gösterdi. Uzak bir MCP sunucusu, çağıranın kontrolü dışında çalıştığı için “izde bize tek bir servis span’i olarak görünüyor”.
İki bakış açısı da sunucunun dışında duruyor. İstemci tek bir opak span görür. Dizin toplamları görür. Hiçbiri sunucudan ne istendiğini, neyi reddettiğini ve neye dokunduğunu görmedi. Bunu yalnızca sunucu gördü; dolayısıyla yalnızca sunucu bunu kayda geçirebilir.
Tajo’nun MCP sunucularının kayda geçirdiği şey bu: onları çalıştıran koddan okunmuş ve dokümantasyonda belirtilmiş haliyle. MCP sunucusu nedir protokolü anlatır. Bu yazı ise satırı anlatıyor.
Çağrı başına bir satır
Pano, liman başkanının bakış açısıdır: giren gemiler, çıkan gemiler, hangilerinin geciktiği. İstek günlüğü ise geminin kendi seyir defteridir, o anda gemide yazılır.
Tajo’nun çalışma alanı sunucusundaki ve her bağlayıcı sunucusundaki her tools/call tek bir satırla sonuçlanır. Satır, yanıt ne olursa olsun, yanıt oluşturulduktan sonra yazılır. Anahtarın yazma yetkisi olmadığı ya da uç noktanın salt okunur olduğu için reddedilen bir çağrı da diğerleri gibi bir satır alır. Var olmayan bir araca yapılan çağrı da öyle.
Satırın neleri tuttuğu ve neleri tutmayı reddettiği şöyle.
| Alan | Saklanan | Saklanmayan |
|---|---|---|
| Kim | Çağıran API anahtarının kimliği. OAuth ile oturum açmadan gelen bir token da bir anahtardır. | Anahtarın gizli değeri ya da öneki. |
| Nerede | Çalışma alanı sunucusu ya da bir bağlayıcı sunucusu, bağlayıcısı ve profiliyle birlikte. | |
| Araç | Sunucuda o adda bir araç varsa adı. | İstemcinin gönderdiği başka herhangi bir ad: (unknown) olarak saklanır. |
| Etki | read, write, send ya da destructive: çağrının sahip olabileceği en ağır etki. | |
| Sonuç | ok ya da unknown_tool gibi kısa, snake_case bir hata kodu. | Hata metni: kod olmayan her şey tool_error olarak saklanır. |
| Süre ve boyut | Gelişten yanıta kadar geçen milisaniye ve çağıranın aldığı bayt. | |
| İzleme kimliği | İsteğin kimliği; x-request-id, x-trace-id ya da W3C traceparent başlığından, yoksa yeni bir tane. | Onaltılık ya da UUID olmayan bir başlık değeri. |
| Kayıtlar | Çağrının adını verdiği ya da ürettiği kayıtların en fazla 20 kimliği: bir kişi, bir mesaj, bir onay. | Kayıtların kendisi. |
| Gövdeler | Argümanlar ve yanıt, temizlenmiş, her biri en fazla 4 KB. | Gizli bilgiler, serbest metin ve aşağıda listelenen kişisel veriler. |
Bu reddedişlerden üçü veriyle değil istemciyle ilgili. Araç adı, hata kodu ve izleme kimliği dışarıdan gelir. Her biri yalnızca sunucunun kefil olabileceği bir biçimde saklanır. Çağıranın gönderdiği her şeyi saklayan bir günlük her şeyle doldurulabilir; araç adı sütununda bir müşterinin e-posta adresi bile olabilir.
Benjamin Eckel’in konuşmanın sonundaki açık sorusu, bir toplayıcının “bunun hata içeren bir MCP araç çağrısı olduğunu” nasıl bileceğiydi. Tek bir sunucuda cevap bir sütundur. ok false’tur ve kod hangi hata olduğunu söyler.
Argümanlar: tersine çevirdiğimiz bir kural
İtiraz yerinde ve bize ait. Argümanları loglarsanız müşterilerinizin verilerinin, hiçbir silme talebinin ulaşamadığı ikinci bir kopyasını oluşturmuş olursunuz. 18 Ekim 2026’ya kadar bu bizim kendi kuralımızdı. Günlük ne argümanları ne de sonuç gövdesini tutuyordu, çünkü ikisi de kişisel veri taşıyabilir.
Bu yanlış bir takastı. Neyin gönderildiğini ve neyin geri geldiğini gösteremeyen bir istek günlüğü, var olma nedeni olan tek soruyu yanıtlayamaz: ajanımın çağrısı neden başarısız oldu?
Bu yüzden gövdeler saklanıyor ve saklanmamalarının nedeni başka bir yolla karşılanıyor. Her gövde kuyruğa alınmadan önce tek bir deterministik geçişten geçer.
- Hiçbir gizli bilgi kalmaz. Adı token, password, secret, signature, cookie, session ya da benzeri yaklaşık yirmi kelimeden birini içeren bir alan yalnızca
[secret]tutar. Bilinen bir kimlik bilgisi biçimindeki bir değer de, nerede görünürse görünsün, aynı şekilde işlenir. Buna bearer token’lar, JWT’ler, özel anahtarlar, parola içeren URL’ler ve 40 ya da daha fazla anahtar karakterinden oluşan her opak dizi dahildir. - Düz metin hiç saklanmaz. Adı
html,text,body,markdownya dacontentolan bir alan yalnızca[redacted]tutar. Düz metin, hiçbir kalıbın bulamayacağı adları ve sokak adreslerini içerir. - Kişisel veriler kalıcı olarak maskelenir. Adı e-posta, telefon, ad, adres ya da not gibi kişisel veriyi belirten bir alan yalnızca
[redacted]tutar. Başka herhangi bir dizenin içindeki e-posta adresi, telefon numarası, kart ya da IBAN maskelenir. - Gövdeler küçük kalır. Dizeler 512 karakterde kesilir, listeler 20 öğede, nesneler 50 anahtarda ve iç içelik 6 düzeyde. Gövdenin tamamı 4 KB’ta kesilir ve kırpıldı olarak işaretlenir.
İki tür çağrı daha azını tutar. Bir kişinin sohbetinin başka bir uygulamadan getirdiği kişiler bir işaret ve bir sayı olarak loglanır, asla gövde olarak değil. Günlüğü okuyan bir çağrı yanıt tutmaz, çünkü yanıt yalnızca başka günlük satırlarından ibaret olurdu.
Şimdi bedeli. Maskeleme kalıcıdır; birinin elinde anahtarı duran bir şifreleme değildir. Günlük size geri dönen e-posta adresini gösteremez. Size kişinin kimliğini gösterir ve kişi, kendi kurallarıyla, bir çağrı uzaklıktadır. Günlük, çalışma alanının silme taramasının dışında durur; bu yüzden maskeleme o taramayı bekleyemez.
Günlük neden denetim izi değil
Tajo’nun zaten yalnızca ekleme yapılabilen bir denetim günlüğü var. Her satır kendinden önceki satırın bir hash’ini taşır, bu yüzden herhangi bir yerdeki düzenleme zinciri bozar. Araç çağrıları neden oraya yazılmasın?
Çünkü zincirin bir bedeli var. Her ekleme, çalışma alanı başına bir kilit alır ve zinciri uzatmak için önceki satırı okur. Her okumayı oradan geçirmek, bir çalışma alanının çağrılarını tek bir kilidin arkasında sıraya dizerdi. Ayrıca denetim günlüğünün göstermek için var olduğu durum değişikliklerini binlerce okumanın altına gömerdi.
Bu yüzden iki kayıt soruya göre ayrılır. İstek günlüğü bir ajanın ne istediğini ve ne olduğunu 30 gün boyunca söyler. Denetim günlüğü neyin değiştiğini, buna kimin izin verdiğini ve o zamandan beri kaydı birinin düzenleyip düzenlemediğini söyler.
Onaylar denetim tarafında durur. Tajo’nun bağlayıcı profillerinde bir propose aracı beyan edilmiş bir işlemi hazırlar, bir apply aracı da onaylandığında onu çalıştırır. Öneri bir kişi ya da çalışma alanının açtığı bir kural tarafından onaylanana kadar sağlayıcıya hiçbir şey ulaşmaz. Propose çağrısının satırı, oluşturduğu onayı kayıtları arasında adlandırır. Onayın kendisi, tam girdinin SHA-256 özetine bağlıdır. Bir onay, gördüğünüz tam girdiyi kapsar: tek bir alanı değiştirin, artık eşleşmez. Yazma işlemi gerçekleştiğinde, denetim satırı girdi özetini ve sağlayıcının yanıtının bir özetini tutar, asla yanıtın değerlerini değil.
Satırın maliyeti
Bir satır bir veritabanı yazma işlemidir ve yazma işleminin bir commit’i vardır. 8 Ekim 2026’ya kadar her çağrı yanıttan önce kendi commit’ini bekliyordu; bu bizim sunucumuzda yaklaşık 2,6 ms sürüyordu. Bir istemci için bu, küçük bir araç çağrısının dörtte biriydi.
Artık satır çağrı bittiğinde oluşturulup kuyruğa alınıyor. Bir boşaltma işlemi kuyruğu en geç 100 ms sonra, çalışma alanı başına tek bir işlemle yazar; böylece birçok çağrı tek bir commit’i paylaşır. Satırla ilgili hiçbir şey, zaman damgası dahil, değişmez. 5.000 satır bekliyorsa, bir sonraki çağrı bir satırı düşürmek yerine boşaltmayı bekler.
Kayıt tutmak hiçbir zaman bir çağrıyı başarısız kılmaz. Başarısız olan bir yazma işlemi satır satır yeniden denenir, ardından loglanıp düşürülür. Sürecin sert biçimde öldürülmesinin kaybettirdiği şey kuyrukta bekleyenlerdir: en fazla son 100 ms’lik çağrılar.
Geri okuma
logs.list, çalışma alanının çağrılarını en yeniden başlayarak, gövdeler olmadan döndürür. Zamana, sonuca ya da HTTP durumuna, kaynağa (MCP ya da aynı tabloyu paylaşan REST API) ve API anahtarına göre filtreler. Varsayılan olarak sayfa başına 50, en fazla 100 satır döndürür. logs.get tek bir çağrıyı; anahtarın güncel adı, durumu, süresi, temizlenmiş istek ve yanıt ve dokunduğu kayıtlarla birlikte döndürür.
İkisi de yalnızca çağıranın çalışma alanını okur. Başka bir çalışma alanına ait satır kimliği bulunamaz.
Bir araç hatası istek kimliğini taşır. Bu kimliği sunucu oluşturduysa ya da onaltılık veya UUID olarak geldiyse, o satırın izleme kimliğidir. Hata alan bir ajan, bir kişiye çağrıyı adlandıran o tek değeri verebilir.
Neler yapıldı, neler yapılmadı
Bu yazı itibarıyla yapılanlar:
- Çalışma alanı sunucusunda ve her bağlayıcı sunucusunda, reddedilen ve bilinmeyen çağrılar dahil, her
tools/calliçin bir satır. - Anahtar kimliği, sunucu, bağlayıcı, profil, araç, etki, sonuç, süre, sonuç boyutu, izleme kimliği ve dokunulan en fazla 20 kayıt.
- Her biri en fazla 4 KB olan temizlenmiş argümanlar ve yanıtlar.
- Çalışma alanıyla sınırlı, 30 gün saklamalı
logs.listvelogs.get. - Bir girdi özetine bağlı onaylar ve hash zincirli denetim günlüğünde girdi ve çıktı özetleriyle kaydedilen uygulanmış yazma işlemleri.
Yapılmayanlar; bunlara güvenmeden önce bilmeye değer:
- Sağlık puanı yok, araç bazında grafik yok ve artan hata oranı için uyarı yok. Çağrıları, hataları ve en yavaş süreleri içeren araç bazında bir özet Tajo’nun operatörleri için var, sizin açabileceğiniz hiçbir yüzeyde değil.
logs.listaraç adına ya da izleme kimliğine göre filtreleyemez. Bir istek kimliğinin arkasındaki satırı bulmak için zamana ve anahtara göre daraltın.- Satırlar sizin çalıştırdığınız bir izleme sistemine aktarılmaz. İzleme kimliği yalnızca HTTP başlıklarından okunur; konuşmada izleme bağlamını taşımak için kullanılan MCP
_metaalanından okunmaz. - 30 gün sonra bir satır silinir. Arşiv ya da dışa aktarma yoktur.
- Maskelenen şey günlükten geri getirilemez.
- Sert bir öldürme son 100 ms’lik satırları kaybettirebilir.
Konuşma, MCP’deki gözlemlenebilirliğin “eşit dağılmadığı” tespitiyle kapandı. Akışın aşağısındaki bir pano bunu düzeltemez; sunucunun kapısında duran bir iz de düzeltemez. Başarısız olan bir senkronizasyonun kendi kaydına ihtiyacı vardır; bir şey isteyen her çağrının da öyle.
Çağrıyı sunucu gördü. Başka kimse görmedi. Onu orada kayda geçirin.
Sık Sorulan Sorular
Bir MCP sunucusu her araç çağrısı için neyi loglamalı?
Sunucunun yazdığı, çağrı başına bir satır: hangi API anahtarının çağırdığı, hangi sunucu ve bağlayıcı, araç varsa aracın adı, etki sınıfı, ok ya da kısa bir hata kodu, süre, sonuç boyutu, isteğin izleme kimliği, çağrının adını verdiği ya da ürettiği kayıtların kimlikleri ve gizli bilgilerle kişisel verileri temizlenmiş argümanlar ile yanıt. Tajo'nun MCP sunucuları reddedilen çağrılar dahil her tools/call için bu satırı yazar ve 30 gün saklar.
Bir MCP istek günlüğü araç argümanlarını saklamalı mı?
Evet, temizlenmiş olarak. Argümanları olmayan bir günlük, bir çağrının neden başarısız olduğunu söyleyemez. Tajo 18 Ekim 2026'ya kadar hiçbir gövde saklamıyordu; artık ikisini de tek bir deterministik geçişten sonra saklıyor: gizli bilgiler [secret] olur, serbest metin ve kişisel alanlar [redacted] olur, e-posta adresleri, telefonlar, kartlar ve IBAN'lar maskelenir ve her gövde 4 KB'ta kesilir. Maskeleme kalıcıdır; bu yüzden günlük kaydı kopyalamak yerine ona kimliğiyle işaret eder.
MCP araç çağrısı günlüğü neden denetim günlüğünden ayrı tutulmalı?
Çünkü farklı soruları farklı maliyetlerle yanıtlarlar. Tajo'nun denetim günlüğü durum değişikliklerinden oluşan bir hash zinciridir ve her ekleme, zinciri uzatmak için çalışma alanı başına bir kilit alır. Her okumayı oradan geçirmek, bir çalışma alanının çağrılarını bu kilidin arkasında sıraya sokar ve değişiklikleri okumaların arasına gömer. Araç çağrıları 30 gün saklanan, zincirsiz ayrı bir tabloya gider; bir çağrının hazırladığı yazma işlemleri yine kendi denetim satırlarını bırakır.