28 Temmuz 2026'da Model Context Protocol, spesifikasyonunun yeni bir sürümünü yayımladı. Değişiklik günlüğü, her uzak sunucunun çalışma biçimini değiştiren iki maddeyle açılıyor: protokol düzeyindeki oturumlar kaldırıldı, initialize el sıkışması da öyle. Artık her istek, sunucunun ona yanıt vermek için ihtiyaç duyduğu her şeyi kendi içinde taşıyor.

Birçok sunucu için bu bir geçiş işi demek. Kimlik belgesi okuyan bir sunucu içinse daha çok bir onay sayılır, çünkü bu tür bir sunucunun zaten durumsuz olması için iyi nedenleri vardı. Bu yazı sürümü bir araç sunucusunun gözünden ele alıyor: hangi değişiklikleri görmezden gelebilir, hangilerini yapmak zorunda ve hangilerini erkenden benimsemeye değer. Örnekler kendi çalıştırdığımız bir sunucudan geliyor, dolayısıyla aşağıda adı geçen eksikler bizim de eksiklerimiz.

Bu, önünde bir MCP sunucusu bulunan bir pasaport ve kimlik kartı OCR API'si olan doc.cheap'in blogu. Ürünle ilgili bölümleri bunu göz önünde tutarak okuyun.

Kısa özet

2026-07-28'deki değişiklik Durumsuz bir araç sunucusunun yaptığı
Mcp-Session-Id yok, oturum yok Hiç tutmadıysa hiçbir şey
initialize el sıkışması yok; sürüm ve yetenekler her isteğin _meta alanında Bunları her istekte oku, MCP-Protocol-Version başlığıyla karşılaştır
server/discover Uygula: bu bir MUST
Mcp-Method ve Mcp-Name başlıkları zorunlu Gövdeyle eşleştiklerini kontrol et
Her sonuçta resultType "complete" gönder
Liste ve okuma sonuçlarında ttlMs ve cacheScope Bir önbellek süresi ve kapsam seç
Araçlar belirlenimci bir sırada Kayıt sırasını sabit tut
HTTP GET akışı ve sürdürülebilirlik kaldırıldı GET ve DELETE'e 405 ile yanıt ver
Roots, Sampling ve Logging kullanımdan kaldırılıyor Dosyaları araç argümanı olarak al, stderr'e veya OpenTelemetry'ye logla

Yazının geri kalanı her satırı ve bunun belge işleyen bir sunucu için neden daha önemli olduğunu açıklıyor.

Oturumlar gitti ve bu belge sunucularına uyuyor

Değişiklik günlüğünün ilk maddesi "protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport" ifadesiyle protokol düzeyindeki oturumları ve bu başlığı kaldırıyor. tools/list gibi liste uç noktaları "no longer vary per-connection", yani artık bağlantıya göre değişmiyor; çağrılar arasında durum tutması gereken sunucular ise "use explicit, server-minted handles passed as ordinary tool arguments": sunucunun ürettiği ve sıradan araç argümanı olarak geçirilen açık tanıtıcılar kullanıyor.

Bir belge sunucusu zaten nadiren oturum ister. Bir oturumun ne tutacağını düşünün: bir API anahtarı, belki okunmayı bekleyen bir görüntü, belki son sonuç. Bunların hepsi, çağrılar arasında bir sürecin belleğinde tutmak istemeyeceğiniz verilerdir; orada bir hata onları bir sonraki çağırana verebilir.

https://mcp.doc.cheap/mcp adresindeki barındırılan sunucumuz bu sürümden önce de böyle kurulmuştu. Kod, sunucunun "stateless on purpose", yani bilerek durumsuz olduğunu söylüyor: her POST yeni bir sunucu ve yeni bir transport alır, yanıt verir ve atılır; böylece "no session lives in memory, a restart loses nothing, and one caller's key can never be seen by another caller's request": bellekte hiçbir oturum yaşamaz, yeniden başlatma hiçbir şey kaybettirmez ve bir çağıranın anahtarı başka bir çağıranın isteğinde asla görülemez. Transport bir oturum kimliği üreticisi olmadan oluşturulur; TypeScript SDK'da onu durumsuz yapan budur. Yanıtlar da akış yerine düz JSON olarak döner.

Sürümün tarif ettiği tanıtıcı kalıbı da zaten mevcut. Bir agent kaydedilmiş bir sonucu geri istediğinde, onu hatırlaması için bir oturuma güvenmez. scan_document bir tarama kimliği döndürür; get_scan ve delete_scan araçları bu kimliği sıradan bir scan_id argümanı olarak alır. Kimlik, tanıtıcının kendisidir. Herhangi bir sunucu örneği ona yanıt verebilir, yarın yeniden bağlanan bir istemci de.

Sunucunuz oturum başına bir şey tutuyorsa sorulacak soru aynıdır: bu, sunucunun döndürdüğü ve istemcinin geri gönderdiği bir kimliğe dönüşebilir mi? Belge işlerinde yanıt genellikle evettir ve genellikle gizlilik açısından da bir kazançtır.

El sıkışma yok: sürüm her istekle birlikte gelir

İkinci madde MCP'yi protokol düzeyinde durumsuz yapıyor. initialize ve notifications/initialized alışverişi kaldırıldı ve "every request now carries its protocol version and client capabilities in _meta": her istek artık protokol sürümünü ve istemci yeteneklerini _meta içinde taşıyor. HTTP'de sürüm ayrıca bir başlıkta da gider. Streamable HTTP sayfası, her POST'un "MUST include an MCP-Protocol-Version header" olduğunu ve bu değerin _meta içindekiyle eşleşmesi gerektiğini söylüyor; eşleşmezse sunucu 400 ve bir HeaderMismatch hatasıyla yanıt verir.

Yeni biçimde bir belge aracına yapılan çağrı şöyle görünür. Başlıklar ve _meta anahtarları spesifikasyonun kendi örneğini izliyor; araç ve argümanları bizim, yer tutucularla:

POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: scan_document

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "scan_document",
    "arguments": { "image_base64": "<base64 image>", "retain_hours": 0 },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": { "name": "<client>", "version": "<version>" },
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

Sunucu için bu, tek bir el sıkışma yerine her istekte üç kontrol demek:

  1. Sürüm. Sunucu istenen sürümü desteklemiyorsa, desteklediği sürümleri listeleyen bir UnsupportedProtocolVersionError ile 400 yanıtı verir.
  2. Başlıklar ve gövde. Mcp-Method her istekte zorunludur, Mcp-Name ise tools/call, resources/read ve prompts/get için. Bunlar metodu ve araç adını yansıtır; bir uyuşmazlık HeaderMismatch hatasıdır.
  3. Yetenekler. Sunucunun eskiden initialize'dan hatırladığı her şeyi artık elindeki istekten okur.

Başlıklar bir belge sunucusu için göründüğünden daha önemlidir. Bir scan_document çağrısı bütün bir görüntüyü base64 olarak taşır; barındırılan sunucumuz 36 MiB'a kadar istek gövdesi kabul eder. Mcp-Method ve Mcp-Name başlıklarda olduğunda, bir ağ geçidi pahalı aracı ucuz olanlardan ayrı olarak yönlendirebilir, sayabilir veya hız sınırına tabi tutabilir ve bunu gövdeyi okumadan yapar. Spesifikasyon bu tür ağ geçitleri için bir uyarı ekliyor: kimsenin kontrol etmediği bir başlığa güvenmek yerine, sürüm başlığının başlık ve gövde doğrulaması gerektiren bir sürümü belirttiğini "SHOULD verify", yani doğrulamalı, aksi halde isteği reddetmeliler.

server/discover zorunlu

Üçüncü madde server/discover'ı ekliyor ve "servers MUST implement this RPC to advertise their supported protocol versions, capabilities, and identity": sunucular desteklenen protokol sürümlerini, yeteneklerini ve kimliklerini duyurmak için bu RPC'yi uygulamak zorunda. İstemciler bir sürüm seçmek için önce onu çağırabilir veya stdio üzerinde uyumluluk yoklaması olarak kullanabilir.

Bu, durumsuz bir sunucunun atlayamayacağı tek değişiklik. Sunucumuz GET / üzerinde hâlâ küçük bir keşif belgesi sunuyor (ad, sürüm, transport ve uç nokta), ama bu protokol metodu değil, düz bir web sayfası. 2026-07-28'i konuşmak isteyen bir sunucu server/discover'a kendisi yanıt verir.

Sonuçlar: resultType, önbellekleme ve sıra

Üç küçük madde bir sonucun görünüşünü değiştiriyor.

  • resultType. Artık her sonuç bunu taşıyor: sıradan bir yanıt için "complete", çok turlu bir isteğin ara yanıtı için "input_required". İstemciler "MUST treat results from earlier-protocol servers that omit the field as "complete"", yani alanı içermeyen eski protokol sunucularının sonuçlarını "complete" saymak zorunda; bu sayede eski bir sunucu çalışmaya devam eder, ama yeni bir sunucu alanı gönderir.
  • ttlMs ve cacheScope. tools/list, prompts/list, resources/list, resources/read ve resources/templates/list sonuçları milisaniye cinsinden bir tazelik ipucu ve "public" ya da "private" olan bir kapsam taşımalı. Araç listesi yalnızca dağıtımda değişen ve kaynakları paketlenmiş dokümantasyon olan bir sunucu için "public" ile uzun bir ttlMs doğal bir seçim. Çağıranın anahtarına bağlı bir kaynak ise "private" olur.
  • Belirlenimci araç sırası. Sunucular, istemci önbelleğine ve prompt önbellek isabetlerine yardımcı olmak için "SHOULD return tools from tools/list in a deterministic order". Araçlar kodda sabit bir sırayla kaydediliyorsa öyle kalsın; bizimki altı aracı her seferinde aynı sırayla kaydediyor.

Kullanıcıdan daha fazlasını istemek: çok turlu istekler

Eski sürümler, bir sunucunun çağrının ortasında istemciye kendi isteklerini göndermesine izin veriyordu: kullanıcıya bir şey sormak için elicitation/create, istemcinin modelini ödünç almak için sampling/createMessage, izin verilen klasörleri öğrenmek için roots/list. Sürüm bunun yerine Multi Round-Trip Requests kalıbını getiriyor. Sunucu resultType: "input_required" ve bir inputRequests listesiyle yanıt verir, istemci de özgün isteği inputResponses ile yeniden dener.

Bir belge aracı için bu, "fotoğrafın sol tarafı kesilmiş, başka bir tane gönderir misiniz?" gibi bir soru için temiz bir yer. Yeniden deneme aynı isteğin tekrarı olduğundan, iki çağrı arasında sunucuda hiçbir şey tutulmak zorunda değil. Sunucu tarafından başlatılan isteklerin hiçbirini kullanmayan bir sunucunun, bizimki gibi, burada taşıyacak bir şeyi yok.

Kullanımdan kalkanlar ve yerine ne kullanılacağı

Roots, Sampling ve Logging kullanımdan kaldırılıyor. En az on iki aylık bir geçiş süresi boyunca çalışmaya devam ediyorlar, ama "new implementations should not add support for them": yeni uygulamalar bunlara destek eklememeli. Önerilen alternatifler bir belge sunucusuna iyi uyuyor:

  • Roots yerine, dosyaları araç argümanı veya yapılandırma olarak verin. Yerel sunucumuz bir dosya yolunu yalnızca yapılandırmasında bir görüntü dizini ayarlanmışsa ve yalnızca o dizinin içinde okur; dışındaki bir yol reddedilir. Argümanı model seçer; sınırı operatör çizer.
  • Logging yerine, stderr'e veya OpenTelemetry'ye loglayın. Sürüm ayrıca logging/setLevel'ı da kaldırıyor; log seviyesi artık her istekte _meta içinde gidiyor ve sunucular istemeyen isteklere log mesajı göndermemeli. İz bağlamı (traceparent) da _meta içinde taşınabilir.

Eski istemciler çağırmaya devam edecek

İstemcilerin hepsi aynı gün geçiş yapmıyor; bu yüzden transport sayfası yalnızca 2026-07-28'i destekleyen bir sunucunun eski trafikle ne yapması gerektiğini anlatıyor:

  • MCP uç noktasına GET veya DELETE: 405 Method Not Allowed.
  • Bir Mcp-Session-Id başlığı: görmezden gel, asla üretme veya geri yansıtma.
  • Bir Last-Event-ID başlığı: görmezden gel, çünkü akışlar artık sürdürülemiyor.

Barındırılan sunucumuz uç noktasındaki GET ve DELETE'e zaten 405 ve bir Allow: POST, OPTIONS başlığıyla yanıt veriyor ve hiçbir oturum kimliği üretmiyor. Hâlâ eski bir sürümü konuşan bir istemci bunu hata gövdesinden öğrenir: spesifikasyon ona yalnızca 400 gövdesi tanınan modern bir hata değilse initialize'a geri dönmesini söylüyor.

Sunucumuz nerede duruyor

Kesin konuşmak gerekirse: barındırılan sunucu TypeScript SDK'nın 1.30.0 sürümü üzerine kurulu ve kendi kodumuz henüz hiçbir yerde 2026-07-28'den söz etmiyor. Yukarıdakilerden onun için zaten doğru olan kısımlar tasarımından gelenler: oturum yok, tanıtıcı olarak kimlikler, GET ve DELETE için 405, yapılandırmayla sınırlanan dosyalar. server/discover, başlık kontrolleri, resultType ve önbellek alanları ise geriye kalan iş. Pasaport OCR MCP sunucusu sayfası ve MCP sunucusu kılavuzu, istemcilerin bugün neye bağlandığını anlatıyor.

Agent'lar için bir belge API'si seçiyorsanız, pasaport OCR API karşılaştırması hizmetleri listeliyor; MCP tarafını her birine ayrıca sormaya değer.

Kendi araç sunucunuz için bir kontrol listesi

  • İstekler arasında hiçbir durum yaşamıyor; sonraki bir çağrının ihtiyaç duyduğu her şey sunucunun döndürdüğü bir kimlik.
  • Her isteğin sürümü MCP-Protocol-Version başlığıyla karşılaştırılıyor; desteklemediğiniz bir sürüm için UnsupportedProtocolVersionError dönüyor.
  • Mcp-Method ve Mcp-Name gövdeyle karşılaştırılıyor.
  • server/discover sürümler, yetenekler ve kimlikle yanıt veriyor.
  • Sonuçlar resultType taşıyor; liste ve okuma sonuçları ttlMs ve cacheScope taşıyor.
  • tools/list her seferinde aynı sırayı döndürüyor.
  • GET ve DELETE 405 alıyor; oturum ve olay kimliği başlıkları görmezden geliniyor.
  • Dosyalar Roots üzerinden değil, yapılandırılmış bir sınırın içinde argüman olarak geliyor.
  • Loglar istemciye değil, stderr'e veya OpenTelemetry'ye gidiyor.

Tam metin modelcontextprotocol.io adresinde, arka planı ise yayın yazısı anlatıyor. Sunucumuz hakkında daha fazlası pasaport OCR MCP sunucusu sayfasında.

Size bir soru: MCP sunucunuz bir oturumda, şimdi bir tanıtıcıya dönüştürmeniz gereken bir şey tutuyor muydu? Aşağıdaki yorumlarda bize anlatın.