İçeriğe geç
26/3030 bölümden 26. bölüm

MCP Spesifikasyona Göre: Bir Sunucu Gerçekte Nedir

Bir subprocess’e tek satır JSON gönder; on üç araç tanımı gelsin. Handshake’i kaldıran 2026-07-28 revizyonuyla okuyalım.

Bu sayfada

Yayınlanmış bir MCP sunucusu kur, ona tek satır JSON gönder ve geri geleni oku.

terminalBASH
npm i @modelcontextprotocol/server-everything@2026.8.31
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  | npx @modelcontextprotocol/server-everything stdio
TEXT
{"result":{"tools":[{"name":"echo","title":"Echo Tool","description":"Echoes
back the input string","inputSchema":{"$schema":"http://json-schema.org/draft-07/
schema#","type":"object","properties":{"message":{"type":"string","description":
"Message to echo"}},"required":["message"]},"annotations":{"readOnlyHint":true,
…                                        … 7,663 bytes on one line …
"jsonrpc":"2.0","id":1}

Standart girdisinden tek satır okuyan bir process’ten, tek satırda on üç araç tanımı. Artık Model Context Protocol konuşmuş oldun; SDK yok, client kütüphanesi yok, framework yok. Hepsi bu: bir transport, bir mesaj biçimi ve küçük bir adlandırılmış yöntemler kümesi.

18. Bölüm bir aracı iki şey olarak tanımladı: modelin gördüğü bir JSON Schema ve kodunda modelin hiç görmediği bir endpoint. 23. Bölüm bunların bir kataloğunu tutan bir harness kurdu. Hiçbiri, tüm bunların yeniden kullanılabilir olup olmayacağını belirleyen soruyu yanıtlamadı: schema’yı kim yazar ve o schema, yazan kişiden senin prompt’una nasıl gelir? MCP bu soruya verilen yanıtlardan biri ve orijinalinden okumaya değer; çünkü onun hakkında yazılan neredeyse her şey artık var olmayan bir revizyonu anlatıyor.

Az önce çalıştırdığın komutla ilgili üç şey yanlıştı ve her biri bu bölümün bir kısmı. Protokol sürümü taşımıyordu, bu yüzden uyumlu bir sunucu onu reddederdi. Yine de yanıt aldı; bunun nedeni spesifikasyonun özellik değil tehlike dediği bir şey. Ve diğer ikisinin varlığını hiç keşfetmeden üç primitive’den birini istedi.

Çözdüğü problem ve spesifikasyonun bizzat kurduğu benzetme

Bölüme bağlantı: Çözdüğü problem ve spesifikasyonun bizzat kurduğu benzetme

Wire’dan önce aritmetik. Elinde NN AI uygulaması ve bunların erişebilmesi gereken MM şey var: takvim, ticket tracker, warehouse veritabanı, tasarım aracı. Ortak bir sözleşme yoksa biri N×MN \times M entegrasyon yazar; her biri de bir schema, bir endpoint, bir kimlik doğrulama hikâyesi ve bir bakım yüküdür. Ortak sözleşmeyle tool sağlayıcısı bir sunucu yazar, uygulama sağlayıcısı bir client yazar ve toplam N+MN + M olur.

Bu yeni bir gözlem değil ve spesifikasyon fikrin kimden geldiğini söylüyor:

MCP takes some inspiration from the Language Server Protocol, which standardizes how to add support for programming languages across a whole ecosystem of development tools. In a similar way, MCP standardizes how to integrate additional context and tools into the ecosystem of AI applications.1

Bu karşılaştırmayı iltifat gibi değil, kelimesi kelimesine al. O protokolden önce bir editörde bir dili desteklemek, editör başına plugin demekti; sonra bir dil ekibi tek sunucu yayınladı ve her editör onu aldı. Başarı ölçütü zarafet değildi; entegrasyon sayısının çarpılmayı bırakmasıydı. Burada da aynı şey geçerli: değer tasarımda değil, implementation sayısındadır. İki ürünün konuştuğu bir protokol, fazladan seremoni eklenmiş bir veri biçimidir.

MCP mesajları JSON-RPC 2.0’dır. Bir request; jsonrpc, bir id, bir method ve isteğe bağlı params içeren bir object’tir; response aynı id değerini ve ya result ya da error taşır; notification, id olmayan bir request’tir ve yanıt almaz. Spesifikasyon bunun üstüne üç kısıt ekler: id string veya sayı olmalı ve null olmamalıdır, uçuşta olan başka bir request ile çakışmamalıdır ve her result bir resultType alanı taşımalıdır.2

stdio transport’unda — yukarıdaki komutun kullandığı transport — framing kuralı mesaj başına bir satırdır:

Messages are delimited by newlines, and MUST NOT contain embedded newlines. […] The server MUST NOT write anything to its stdout that is not a valid MCP message.3

Bu son madde, ev yapımı bir sunucunun en sık kırıldığı yerdir ve sessizce kırılır: başıboş bir console.log, bir progress bar, bir dependency’den gelen deprecation warning’i derken client’ın satır parser’ı JSON olmayan bir şeye çarpar. Kaçış yolu aynı bölümde: sunucu stderr içine istediğini yazabilir ve client bunu hata saymamalıdır. Yukarıdaki reference server her başlatmada stderr üzerinde Starting default (STDIO) server... yazdırıyor; pipe’ın yine de çalışmasının nedeni bu.

Diğer standart transport Streamable HTTP’dir: her mesaj tek bir endpoint’e POST edilir ve yanıt ya bir JSON object ya da request-scoped bir Server-Sent Events akışıdır — 14. Bölüm’ün elle parse ettiği wire format. Semantics ikisinde de aynıdır; çünkü transport bir binding’dir: framing ve delivery tanımlar, anlamı değil.4

Yukarıdaki komut tools/list gönderdi, başka hiçbir şey göndermedi. Mevcut revizyona göre bu request malformed’dur ve uyumlu bir sunucu onu reddetmelidir.

2026-07-28 itibarıyla MCP stateless bir protokoldür ve spesifikasyon bunu hiç yumuşatmadan söyler:

The Model Context Protocol (MCP) is a stateless protocol: all the information needed to process a request is contained in the request itself. A server processes each request independently; no state should be inferred from previous requests, even those on the same connection or stream.2

Yani her request kendi protokol sürümünü ve kendi client capabilities bilgisini, params içindeki ayrılmış bir _meta object’inde taşır. Bu alanlardan ikisi her tek request’te zorunludur; ikisinden biri eksik olan request malformed’dur ve sunucu -32602 yanıtlamalıdır:2

_meta anahtarızorunlunedir
io.modelcontextprotocol/protocolVersionevetbu request’in konuştuğu revizyon, ör. "2026-07-28"
io.modelcontextprotocol/clientCapabilitiesevetclient’ın bu request’te sunucu için ne yapabildiği
io.modelcontextprotocol/clientInfohayır ama olmalıyalnızca gösterim ve loglar için client adı ve sürümü
io.modelcontextprotocol/logLevelhayırsunucunun bu request için yayması gereken minimum log seviyesi

Açık yazıldığında doğru bir tools/list budur — ve bu bölüm metadata’yı tam olarak son kez gösteriyor; çünkü bundan sonra her request’te var:

one line, split for the pageTEXT
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{"elicitation":{"form":{}}},
  "io.modelcontextprotocol/clientInfo":{"name":"bare-hands","version":"0.0.1"}}}}

Capability object negotiation’ın kendisidir. Artık ayrı bir negotiation adımı yok: client her request’te ne yapabildiğini bildirir, sunucu result içinde ne yapabildiğini bildirir ve iki taraf da diğerinin sahip olduğunu iddia etmediği bir özelliği kullanamaz. Client’ın bildirmediği bir capability’ye ihtiyaç duyan sunucu -32021 yanıtlamalı ve eksik capability’yi data.requiredCapabilities içinde adlandırmalıdır. İstenen sürümü konuşmayan sunucu -32022 yanıtlamalı ve konuştuğu sürümleri listelemelidir.2

Yanıtı baştan isteyen client’lar bunu sorabilir: server/discover, supported versions, capabilities, identity ve isteğe bağlı bir instructions bloğunu tek round trip’te döndüren zorunlu bir RPC’dir.5 Onu çağırmak isteğe bağlıdır. Onu implement etmek değildir.

Yanlış olan ikinci şey: sunucu legacy idi

Bölüme bağlantı: Yanlış olan ikinci şey: sunucu legacy idi

Komut çalıştı. Mevcut revizyona göre çalışmaması gerekirdi; çalışmasının nedeni bir paragraftan çok bir ölçümü hak ediyor, çünkü tüm ekosistemin durumunu tek satırda gösteriyor.

Reference server’ı, spesifikasyonun modern bir client’a probe etmesini söylediği şekilde probe et:

terminalBASH
echo '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{}}}}' \
  | npx @modelcontextprotocol/server-everything stdio
TEXT
{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Method not found"}}

Bu, compatibility kuralının üçüncü dalıdır: DiscoverResult modern demektir, tanınan modern bir error modern-ama-yanlış-sürüm demektir ve başka her şey-32601 dahil — legacy demektir; initialize handshake’e geri dön.3 Öyleyse current revision’ı isteyerek bunu yap:

TEXT
→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28",
   "capabilities":{},"clientInfo":{"name":"bare-hands","version":"0.0.1"}}}

← {"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true},
   "prompts":{"listChanged":true},"resources":{"subscribe":true,"listChanged":true},
   "logging":{},"tasks":{…},"completions":{}},"serverInfo":{"name":"mcp-servers/everything",
   "title":"Everything Reference Server","version":"2.0.0"},"instructions":"…"}}

Client 2026-07-28 istedi, sunucu 2025-11-25 yanıtladı. 7 Eylül 2026’da resmi reference server — npm package @modelcontextprotocol/server-everything, sürüm 2026.8.31, 31 Ağustos 2026’da yayınlanmış — current revision’ı implement etmiyor. Tarihlere bakınca, üzerine kurulu olduğu TypeScript SDK de etmiyor: 1.30.0 release’i 27 Temmuz 2026’da, revizyondan bir gün önce çıktı.

Dedikoduyu değil sonucu oku. MCP hakkında yazılan neredeyse her şey initialize handshake’i, session’ı, sunucunun client’a gönderdiği roots/list request’i ve HTTP+SSE transport’u olan bir protokolü anlatıyor. Dördü de gitti ya da gidiyor. Bu sayfa dahil MCP hakkında herhangi bir şey okurken bakacağın ilk şey revizyon numarasıdır.

Ve en baştaki komutun çalışmasının nedeni spesifikasyonda özellik değil tehlike olarak geçer:

some legacy servers do not validate that a request arrives after initialize and would process an era-ambiguous method (such as tools/call) under legacy semantics. Probing yields a deterministic failure instead.3

Ölçüldü: o sunucuya hiçbir handshake olmadan tools/list göndermek tüm kataloğu döndürüyor. Reddedilmesi gereken bir method servis edildi; spesifikasyonun, yalnızca modern sürümleri desteklesen bile önce server/discover ile probe et demesinin nedeni tam olarak bu.

Üç rol ve tüm belgeden alıntılanacak cümle

Bölüme bağlantı: Üç rol ve tüm belgeden alıntılanacak cümle

MCP’de üç taraf vardır ve insanların birbirine karıştırdığı ayrım ilk ikisi arasındadır:

Host. Uygulama: chat ürünü, editör, agent. Conversation’ı, modeli, credentials’ı ve kullanıcının consent’ini o sahiplenir. Client’lar oluşturur ve aralarındaki security boundary’yi enforce eder.

Client. Host içindeki connector. Her client tam olarak bir sunucuyla konuşur — katı bir 1:1 ilişki — ve route ettiği her request’e protocol version ile capabilities ekler.

Sunucu. Resources, araçlar ve prompts expose eden bir process veya service. Local ya da remote olabilir, bağımsız çalışır ve tüm işi tek bir odak alanıdır.6

Bu “tam olarak bir sunucu” kuralı defter tutma değildir. Aşağıdaki tasarım ilkesini uygulanabilir kılan şeydir ve spesifikasyondan tek cümle alacaksan o cümle budur:

Servers should not be able to read the whole conversation, nor "see into" other servers. Servers receive only necessary contextual information. Full conversation history stays with the host. Each server maintains isolation. Cross-server interactions are controlled by the host.6

Bu, çoğu insanın geldiği zihinsel modeli tersine çevirir. Assistant’ına bağladığın bir hava durumu sunucusu, ne sorduğunu görmez. Modelin seçtiği arguments ile bir tools/call görür, başka hiçbir şey görmez — önceki turn’leri, system prompt’unu, takvim sunucusunun az önce döndürdüğü sonuçları değil. İki sunucunun işbirliği yapması gerekiyorsa host, bir değeri birinden diğerine bilinçli olarak taşır; çünkü model bunu istemiştir. Bu yüzden isolation, 30. Bölüm’ün dayandığı security property’dir: ele geçirilmiş bir sunucunun küçük ve tanımlı bir blast radius’u vardır; bunu büyütmek host’un işbirliğini gerektirir.

Üçüncü şey: yetkinin kimde olduğuna göre sıralanan üç primitive

Bölüme bağlantı: Üçüncü şey: yetkinin kimde olduğuna göre sıralanan üç primitive

İlk komut o sunucudan araçları istedi ve on üç tane aldı. Diğer iki soruyu da sorarsan onları da yanıtlıyor: resources/list yedi, prompts/list dört döndürüyor. Hiçbiri görünmedi; çünkü hiçbir şey sormadı. Bu bizi MCP’nin pedagojik omurgasına getiriyor: spesifikasyonda duran ama neredeyse kimsenin alıntılamadığı bir tablo.

PrimitiveKontrolAçıklamaÖrnek
PromptsKullanıcı kontrollüKullanıcının seçimiyle çağrılan etkileşimli templatesSlash commands, menü seçenekleri
ResourcesUygulama kontrollüClient tarafından eklenen ve yönetilen contextual dataDosya içerikleri, git geçmişi
AraçlarModel kontrollüAksiyon almak için LLM’ye expose edilen functionsAPI POST request’leri, dosya yazma

“Bir capability expose etmenin üç yolu” değil. Bunun olmasına kim karar veriyor sorusuna üç yanıt. Model bir aracı çağırmaya karar verir. Uygulama bir resource eklemeye karar verir. Kişi bir prompt çalıştırmaya karar verir. Bunu yanlış anlarsan özellik yine çalışır ama yanlış anda ve yanlış nedenle çalışır.

Bunu hissetmenin en net yolu bir takvimdir. İşte aynı takvimi üç kez, her primitive olarak birer kez expose eden, dependency’siz yüz satırlık düz Node sunucusu:

calendar.mjs — the parts that matterJS
const TOOL = {
  name: "create_event",
  description: "Create a calendar event. Writes to the calendar.",
  inputSchema: {
    type: "object",
    properties: {
      title:    { type: "string", description: "Event title." },
      startsAt: { type: "string", format: "date-time", description: "Start, ISO 8601 UTC." },
    },
    required: ["title"],
  },
};

switch (method) {
  case "resources/read":                                          
    return ok(id, { contents: [{ uri: "calendar://week",
      mimeType: "application/json", text: JSON.stringify(EVENTS) }],
      ttlMs: 60000, cacheScope: "private" });

  case "prompts/get":                                             
    return ok(id, { description: PROMPT.description, messages: [{ role: "user",
      content: { type: "text", text: `Read calendar://week and draft a plan. ` +
        `Focus: ${params.arguments?.focus ?? "balance"}.` } }] });

  case "tools/list":                                              
    return ok(id, { tools: [TOOL], ttlMs: 300000, cacheScope: "public" });
}

Çalıştır ve üç şekilde de sor. Gerçek çıktı; wire üzerinde satır başına bir mesaj, sayfa için burada sarıldı, request _meta ve sunucunun identity block’u çıkarıldı:

TEXT
→ resources/read  {"uri":"calendar://week"}
← {"resultType":"complete","contents":[{"uri":"calendar://week",
   "mimeType":"application/json","text":"[{\"id\":\"e1\",\"title\":\"Standup\",
   \"startsAt\":\"2026-09-07T09:00:00Z\"},{\"id\":\"e2\",\"title\":\"Design review\",
   \"startsAt\":\"2026-09-09T15:00:00Z\"}]"}],"ttlMs":60000,"cacheScope":"private"}

→ prompts/get    {"name":"prepare_week","arguments":{"focus":"deep work"}}
← {"resultType":"complete","description":"Read the week and draft a plan.",
   "messages":[{"role":"user","content":{"type":"text",
   "text":"Read calendar://week and draft a plan. Focus: deep work."}}]}

→ tools/call     {"name":"create_event","arguments":{"title":"Dentist",
                  "startsAt":"2026-09-10T08:30:00Z"}}
← {"resultType":"complete","content":[{"type":"text",
   "text":"Created e3: Dentist at 2026-09-10T08:30:00Z"}],
   "structuredContent":{"id":"e3","title":"Dentist","startsAt":"2026-09-10T08:30:00Z"},
   "isError":false}

Üç method, üç shape, tek takvim. Şimdi mesele:

Bir URI ile adreslenir, inert’tir ve conversation’a eklenip eklenmeyeceğine uygulama karar verir. Protokolde modelin onu kendi başına almasına izin veren hiçbir şey yoktur. Result ttlMs ve bu revizyonda yeni olan cacheScope taşır; böylece client, polling yapmak yerine haftayı bir dakika cache’leyebilir.

Bir schema’sı vardır, side effect’leri vardır ve ne zaman çağrılacağına model karar verir. Result’ı isError taşır; bu da 18. Bölüm’ün savunduğu alandır: validation failure, protocol error olarak değil, modelin okuyup düzeltebileceği bir tool result olarak geri gelir.

Adlandırılmış, argument alan bir template’tir ve kişi çağırır — menüdeki slash command. Bir yanıt değil, messages döndürür. Sunucu yazarının, kendi araçlarıyla çalışan ifadeyi paketlemesinin yoludur; bu tam olarak sunucu yazarının bildiği ve kullanıcının bilmediği bilgidir.

Neredeyse herkes bu üçünü de araç yapar. Sonuç; uygulamanın sessizce eklemesi gereken bir read’in, approval gerektiren bir write ile modelin attention’ı için yarıştığı ve kişinin buton istediği tek şeyin schema içine gömüldüğü bir katalogdur. Doğru yapmak hiçbir şeye mal olmaz ve tek satır yazmadan önce karar verilir.

Takvim aracının bir zorunlu argument’i, title, ve isteğe bağlı bir startsAt alanı var. Ondan tarihsiz bir etkinlik oluşturmasını iste ve ilginç bir şey geri gelir:

TEXT
→ tools/call {"name":"create_event","arguments":{"title":"Dentist"}}

← {"resultType":"input_required",
   "inputRequests":{"when":{"method":"elicitation/create","params":{"mode":"form",
     "message":"When should \"Dentist\" start?",
     "requestedSchema":{"type":"object",
       "properties":{"startsAt":{"type":"string","format":"date-time"}},
       "required":["startsAt"]}}}},
   "requestState":"eyJ0aXRsZSI6IkRlbnRpc3QifQ=="}

Sunucu request göndermedi. Kendisine verilen request’e, resultType: "input_required" ve hâlâ neye ihtiyaç duyduğunun açıklamasıyla yanıt verdi. Client yanıtı kişiden toplar ve sonra original call’u yeniden gönderir — yeni bir id ile, inputResponses taşıyarak ve opaque requestState değerini geri echo ederek:

TEXT
→ tools/call {"name":"create_event","arguments":{"title":"Dentist"},
   "inputResponses":{"when":{"action":"accept",
     "content":{"startsAt":"2026-09-10T08:30:00Z"}}},
   "requestState":"eyJ0aXRsZSI6IkRlbnRpc3QifQ=="}

← {"resultType":"complete","content":[{"type":"text",
   "text":"Created e3: Dentist at 2026-09-10T08:30:00Z"}],"isError":false}

Bu, current revision’da tanıtılan Multi Round-Trip Requests’tir ve sunucuların client’lara JSON-RPC request’leri geri gönderdiği eski tasarımın yerini almıştır. Transport specification artık kuralı açıkça koyuyor: “servers do not initiate JSON-RPC requests and clients do not send JSON-RPC responses”.4 İnisiyatifin tek yönü vardır ve host’a aittir.

İki client-side özellik bu mekanizmanın üzerinde ilerler ve birinin adı seni yanıltacak.

Elicitation, sunucunun kişiden bir şey istemesidir: bilerek kısıtlanmış JSON Schema’ya sahip bir form — flat objects, primitive properties, no nesting — böylece herhangi bir client onu layout engine olmadan render edebilir. Sert bir kural taşır: sunucular “passwords, API keys, access tokens, or payment credentials” istemek için form mode’u kullanmamalıdır ve bunlar için kullanıcıyı client’ın hiç okumadığı bir sayfaya gönderen URL mode’u kullanmalıdır.7

Sampling, sunucunun host’un modelinden bir generation istemesidir; böylece sunucu API key tutmadan intelligent olabilir. Ve burada vocabulary uyarısı var; çünkü bu kelime bu kursta zaten başka bir anlama geliyor: bu, 17. Bölüm’ün sampling’i değildir. Burada temperature, top-p veya probability distribution’ın şekliyle ilgili hiçbir şey yok. Bu, protokol üzerinden geriye doğru giden nested bir model call’dur.

Ona sarılmamak için ikinci bir neden var: bu revizyon itibarıyla sampling deprecated, roots ve logging ile birlikte SEP-2577 kapsamında; önerilen migration da gayet net: “integrate directly with LLM provider APIs instead of Sampling”.8 Fikir teknik olarak başarısız olmadı; surface area’sını haklı çıkaramadı ve bir şeyleri kaldırabilen protokol, kaldıramayandan daha sağlıklıdır.

Statelessness, test edene kadar wire-format detayı gibi görünür. Yukarıdaki üç mesajlı exchange’i al ve her mesajı ayrı bir process içinde çalıştır — yepyeni bir node calendar.mjs, shared memory yok, taşınan hiçbir şey yok:

TEXT
process A   tools/call (no date)   → resultType: input_required
                                     requestState: eyJ0aXRsZSI6IkRlbnRpc3QifQ==
process B   tools/call (with the answer, same requestState)
                                   → resultType: complete
                                     "Created e3: Dentist at 2026-09-10T08:30:00Z"
process C   resources/read calendar://week
                                   → events: 2  (Standup, Design review)

Soruyu hiç görmeyen Process B, Process A’nın başlattığı multi-round-trip call’u tamamladı. requestState noktasının anlamı bu: continuation mesajın içinde seyahat eder, bu yüzden hiçbir şey process’in aynı olmasına bağlı değildir.

Process C başarısızlıktır. Etkinlik oluşturuldu ama orada değil — çünkü toy server EVENTS değerini module-level array’de tutuyor ve module-level array connection state’tir. Spesifikasyonun notu hatayı tam adıyla söyler:

an open connection, such as a STDIO process, is not a conversation or session: clients may interleave unrelated requests on the same transport, and a server must not treat connection or process identity as a proxy for conversation or session continuity.2

Önerilen düzeltme session değildir. Explicit handle’dır: creation tool opaque bir identifier döndürür ve sonraki her call bunu sıradan bir argument olarak alır. Protokolde buna dair hiç kavram yoktur — “from the wire's perspective a handle is an ordinary string in a tool result and an ordinary argument to subsequent tool calls”.9 Bu, onu taşımayı modelin sorumluluğuna verir; her tek call’da bu caller’ın onu kullanmaya izinli olduğunu validate etmeyi de sunucunun sorumluluğuna verir. Çünkü handle bir addır, permission değildir.

Bir sunucunun daha hiçbir şey yapmadan maliyeti

Bölüme bağlantı: Bir sunucunun daha hiçbir şey yapmadan maliyeti

Bir sunucunun expose ettiği her araç, her request’te prompt’una giren bir schema’dır ve 24. Bölüm bunun context window’a ne yaptığını ölçtü. MCP, gözden kaçırması kolay ikinci bir kalem ekler; bu yüzden yukarıdaki reference server’da ikisini de saymaya değer.

o200k_base tokensTEXT
13 tool definitions (name + description + inputSchema):  1,307 tokens
  cheapest tool, get-tiny-image                              52
  costliest tool, gzip-file-as-resource                     235
server `instructions`, returned by discovery:               312 tokens
                                                          ------
one server, connected, before it is used:                 1,619 tokens

İki gözlem. İlki aritmetik: bu boyutta beş sunucu bağla ve window’unun yaklaşık sekiz bin token’ı, model bunlardan herhangi birini kullansın kullanmasın, her turn’de sonsuza kadar ayrılmış olur — 24. Bölüm’ün alıntıladığı 150.000’den 2.000’e düşüşün arkasındaki mekanizma ve just-in-time tool discovery’nin varlık nedeni budur.

İkincisi accounting kostümü giymiş bir security notu. instructions, sunucu yazarı tarafından yazılmış, host’un prompt’una düşen natural-language text’tir; yanındaki tool descriptions da aynıdır. Spesifikasyon kendi security principles bölümünde bununla ilgili ne yapılacağını söyler: tool annotations ve descriptions “should be considered untrusted, unless obtained from a trusted server” ve hosts “must obtain explicit user consent before invoking any tool”.1 Bir MCP sunucusu bağlamak dependency eklemek değildir. Bir yabancıya system prompt’unun 1.619 token’ını ve çağrılma hakkını vermektir. 30. Bölüm, o yabancı hostile olduğunda olan şeydir.

Tarihli bölüm: 2026-07-28 revizyonu ve neyi kırdığı

Bölüme bağlantı: Tarihli bölüm: 2026-07-28 revizyonu ve neyi kırdığı

Bu bölümdeki her şey, 2026-07-28 protokol revizyonu için doğrudur; 7 Eylül 2026’da okunan current revision. Revizyonlar YYYY-MM-DD biçiminde tarihlenir ve tarih, backwards-incompatible bir değişikliğin en son yapıldığı zamandır.10 Normative document bir TypeScript dosyasıdır, schema/2026-07-28/schema.ts; yanındaki JSON Schema ondan generated’dır. Bu yüzden spesifikasyon burada TypeScript’ten okunur ve MCP’yi başka herhangi bir şeyden öğretmek bir translation öğretmektir.

Ne değiştiEskidenŞimdiKırdığı şey
Handshakebağlantı başına bir kez initialize + notifications/initializedkaldırıldı; her request _meta version ve capabilities taşıyorbu revizyondan önce yazılmış her client
SessionsMcp-Session-Id header, connection-scoped statekaldırıldı; state explicit, server-minted handles içinde seyahat ediyorconnection’a göre değişen list endpoints
Discoveryinitialize result’ından inferredsunucuların implement etmesi zorunlu olan server/discoverhiçbir şey, ama implement etmek artık zorunlu
Server-to-client callssunucu roots/list, sampling/createMessage, elicitation/create gönderirdiInputRequiredResult ve client retryclient’a request push eden her sunucu
Result shapeherhangi bir objectzorunlu resultType: "complete" veya "input_required"hiçbir şey: absent field "complete" olarak okunmalı
SubscriptionsHTTP GET stream, resources/subscribeopt-in types ile tek subscriptions/listen streamGET endpoint gitti
Stream resumptionStreamable HTTP üzerinde Last-Event-ID replaykaldırıldı; broken stream request’i kaybeder, yeni bir id ile yeniden gönderredelivery’ye güvenen client’lar
Rootssunucuların isteyebildiği bir client featuredeprecated (SEP-2577); path’leri tool arguments veya resource URI’leri olarak geçirhenüz hiçbir şey — on iki aylık pencere
Sampling ve loggingclient featuresdeprecated (SEP-2577)henüz hiçbir şey — on iki aylık pencere
HTTP+SSE transport2025-03-26 tarihinden beri deprecatedlifecycle policy kapsamında Deprecated (SEP-2596)Streamable HTTP’ye migrate et
Client registrationOAuth 2.0 Dynamic Client Registration, RFC 7591Client ID Metadata Documents lehine deprecatedbunları desteklemeyen authorization servers için korunuyor
Error codesresource not found için -32002-32602; -32020-32099 spec için reservedyeni kodlar -32020, -32021, -32022

Bu tablonun altındaki governance değişikliği, tek tek satırların hepsinden daha önemlidir. Bu revizyon bir feature lifecycle and deprecation policy benimsedi: features Active, Deprecated veya Removed olur; deprecated feature migration path’ini belgeler ve removal için eligible olmadan önce en az on iki ay spesifikasyonda kalır; Deprecated durumundaki her şeyi listeleyen bir registry vardır.8 Bu politikadan önce bir AI protokolünde “deprecated”, son blog post’un ne dediğine bağlıydı. Artık bir tarih demek.

Ayrıntıları göster

Extensions; yani henüz kimsenin yazmadığı kısım.

Core’un ötesinde MCP isteğe bağlı extensions tanımlar — “always opt-in and require explicit support from both client and server”; client’ın ve sunucunun capabilities içindeki extensions alanıyla bildirilir.1 Üçünü adıyla bilmeye değer:

  • Tasks (io.modelcontextprotocol/tasks), bu revizyonda core protocol’den resmi bir extension’a taşındı: long-running operations için asynchronous execution; tasks/get üzerinden polling, tasks/update üzerinden mid-flight input ve durable handles. Yirmi dakika süren bir tool’a verilen yanıttır; 23. Bölüm bunu progress event ve tool’a ulaşan signal ile ele almıştı.
  • Skills over MCP, agent skills’i — 28. Bölüm’ün konusu — protokol üzerinden discoverable ve consumable hâle getiren working group.
  • MCP Apps, conversation içinde inline render edilen interactive UI: charts, forms, video players.

Ve “negotiated”ın artık ne anlama geldiğine dikkat et: negotiation yapılacak bir initialization yok; dolayısıyla extension da her şey gibi request başına bildirilir.

MCP’nin, karıştırıldığı her şeye göre durduğu yer

Bölüme bağlantı: MCP’nin, karıştırıldığı her şeye göre durduğu yer

Bu bloktaki vocabulary tek yerde.

NedirKim kiminle konuşurNe zaman doğru yanıttır
Düz bir APIBir program için interfacekodun ↔ bir serviceCaller’ı sen yazıyorsun. Schema’yı, auth’u ve error handling’i sen kontrol ediyorsun; çözülecek discovery problemi yok.
MCPAraçları, data’yı ve templates’i bir AI uygulamasına expose eden protocolhost ↔ server, her biri için bir clientCapability’yi başkası yazdı ve birçok host onu bespoke integration olmadan kullanabilmeli.
RAGText bulup prompt’a koyma technique’ikodun ↔ index’inModelin bir şeyi bilmesi gerekiyor. 19. Bölüm. MCP retriever teslim etmenin bir yoludur; retriever değildir.
Agent skillsModelin okuduğu SKILL.md içeren bir klasörmodel ↔ bir documentKnowledge procedural’dır — bunu biz nasıl yapıyoruz — ve prose’dur, function değil. 28. Bölüm.
A2AAgent’ların peer olarak collaborate etmesi için protocolagent ↔ agentKarşı taraf bir call’a yanıt vermek yerine reasoning yapar, plan kurar ve uzun bir task boyunca state tutar.
ACPAyrı bir agent-communication protocol idiArtık canlı bir karşılaştırma değil. Aşağıya bak.

Bunlardan ikisi birer cümleyi hak ediyor; çünkü kafa karışıklığı gerçekten orada yaşıyor.

MCP ile A2A bir rekabet değildir ve iki spesifikasyon da bunu söyler. A2A documentation çizgiyi karşı uçta ne olduğuna göre çizer: MCP “defines how an AI agent interacts with and utilizes individual tools and resources, such as a database or an API”; burada tool “specific, often stateless, functions” gerçekleştirir. A2A ise agents’a, “more autonomous systems”a yöneliktir; bunlar “reason, plan, use multiple tools, maintain state over longer interactions, and engage in complex, often multi-turn dialogues” yapar. Kendi özeti hatırlanacak cümledir: “A2A is about agents partnering on tasks, while MCP is more about agents using capabilities.”11 İkisi iç içe geçer — bir uygulama başka agents’a ulaşmak için A2A kullanır; her agent kendi araçlarına ulaşmak için MCP kullanır. 25. Bölüm, aynı process içinde sub-agent’a sormak ile conversation’ı ona devretmek arasındaki çizgiyi çizmişti; A2A bunu organizasyonlar arasında çizer.

MCP ile ACP bayat bir premise’e sahip bir karşılaştırmadır; tam da bu yüzden yanıtlamaya değer. Agent Communication Protocol, agent-to-agent messaging için ayrı bir open standard’dı. Kendi documentation’ı artık şu notice ile açılıyor: “ACP is now part of A2A under the Linux Foundation!”12 Eylül 2026’da “MCP mi ACP mi?” sorusunun dürüst yanıtı, sıralama alan sayfaların ima ettiğinden bir seçenek daha az olduğudur.

Ve insanların en çok istediği karşılaştırma, mcp vs api, en az ilginç yanıta sahip: MCP bir API’dir. Eklediği şey güç değil, conventions’dır — sabit bir method names kümesi, discovery call, primitives üzerinde control hierarchy ve isolation model. Kendi interface’ini tasarlama özgürlüğünden vazgeçersin ve karşılığında protokolü konuşan her host’u alırsın; her protokolün şimdiye kadar sunduğu trade-off budur.

Artık spesifikasyonu tercümansız okuyabilir, resource ile tool ile prompt’u kimin kontrol ettiğine bakarak ayırabilir, client library sana yalan söylediğinde bir request’i elle yazabilir ve okuduğun herhangi bir MCP yazısını, hâlâ current diye öğrettiği deprecated features’a bakarak tarihleyebilirsin.

Henüz yapmadığın şey bir tane ship etmek. 27. Bölüm aynı sunucuyu iki kez yazıyor — TypeScript ve Python, yan yana; çünkü MCP bu kurstaki gerçekten bilingual tek alan ve sayılar iki yönde de bunu söylüyor. İki live transport’u doğru düzgün, inspector’ı, packaging’i ve bu bölümün bilerek kenarda bıraktığı protocol yarısını kapsıyor: authorization. Çünkü sunucun kendi laptop’ındaki bir subprocess değil de remote olduğu anda bir yabancının client’ı bir token sunacak ve spesifikasyonun onunla ne yapabileceğine dair kuralı alışılmadık derecede strict.

Bu da bir sonraki bölümün yanıtlaması gereken soruyu doğuruyor; dostça bir soru değil: sunucuna bir token gelirse ve başka birinin audience’ı için issued edilmişse, onu forward etmeni tam olarak ne durdurur?


Bu bölümdeki her quotation, method name, error code ve rule, 7 Eylül 2026 tarihinde Model Context Protocol specification’ın 2026-07-28 revizyonundan okundu. Her trace local olarak Node 22 üzerinde üretildi: toy calendar server dependency’siz 101 satırdır ve reference server aşağıda adı verilen published npm package’tır. Bu bölümü yazmak için paid API çağrılmadı — burada hiçbir şey bir model gerektirmiyor; zaten mesele de bu.

Ölçümler: @modelcontextprotocol/server-everything@2026.8.31, 31 Ağustos 2026’da yayınlandı, @modelcontextprotocol/sdk@1.30.0 üzerine kurulu, 27 Temmuz 2026’da yayınlandı — bu bölümün anlattığı revizyondan bir gün önce. server/discover isteğine -32601 yanıtlıyor, 2026-07-28 istendiğinde 2025-11-25 negotiate ediyor ve hiçbir handshake olmadan tools/list servis ediyor. Kataloğu 7.663 byte içinde 13 tool; token counts, her definition’ın name, description ve inputSchema alanları üzerinden tiktoken aracılığıyla o200k_base; bu bir provider’ın prompt’una render ettiği şeydir, JSON-RPC frame’in ağırlığı değil.

Anthropic, Code execution with MCP: building more efficient agents, 4 Kasım 2025, 150.000’den 2.000’e figürünün kaynağıdır; 24. Bölüm’de alıntılanıp kullanılmış, burada yalnızca referans verilmiştir.

  1. Specification, modelcontextprotocol.io/specification/latest (/2026-07-28 adresine redirect eder), 7 Eylül 2026’da okundu. Language Server Protocol karşılaştırmasının; specification’ın “based on the TypeScript schema in schema.ts” ifadesinin; base-protocol özetinin (“Stateless, self-contained requests”, “Per-request capability negotiation”); extension list’in (Tasks, Skills over MCP, MCP Apps) ve extensions’ın “are always opt-in and require explicit support from both client and server” olduğuna dair ifadenin; ayrıca “Hosts must obtain explicit user consent before invoking any tool” dahil Security and Trust & Safety principles’ın ve tool annotations’ın untrusted olarak ele alınmasının kaynağı. 2 3

  2. Base Protocol, modelcontextprotocol.io/specification/2026-07-28/basic. JSON-RPC kısıtlarının (non-null id, id reuse yok, zorunlu resultType); Statelessness bölümünün ve açık stdio process’in session olmadığına dair notunun; _meta reserved-key tablosunun ve her per-request field’ın required/optional durumunun; missing required field için -32602 kuralının; MissingRequiredClientCapability (-32021) kuralının; ve error-code allocation policy’nin kaynağı. 2 3 4 5

  3. stdio transport, modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio. Newline-delimited framing rules’un, stdout purity requirement’ın, stderr allowance’ın ve üç sonuçlu backward-compatibility probe’un kaynağı — bazı legacy servers’ın handshake olmadan era-ambiguous methods işlediğine dair uyarı dahil; bu bölümdeki ölçüm bunu yeniden üretir. 2 3

  4. Transports overview, modelcontextprotocol.io/specification/2026-07-28/basic/transports. “a transport is a binding” framing’inin ve sunucuların JSON-RPC request başlatmadığı, client’ların JSON-RPC response göndermediği ifadenin kaynağı. 2

  5. Discovery, modelcontextprotocol.io/specification/2026-07-28/server/discover. server/discover değerinin mandatory status’ının, DiscoverResult shape’inin ve “optional natural-language guidance for LLMs on how to use this server effectively” olarak tanımlanan instructions field’ının kaynağı.

  6. Architecture, modelcontextprotocol.io/specification/2026-07-28/architecture. Host/client/server tanımlarının, 1:1 client-to-server kuralının, dört design principle’ın — burada isolation principle beşinci bullet’ı “Host process enforces security boundaries” olmadan alıntılanmıştır — ve capability-negotiation bölümünün kaynağı. 2

  7. Elicitation, .../client/elicitation, ve Sampling, .../client/sampling. İki elicitation mode’unun ve restricted schema’sının; form mode üzerinden credentials isteme yasağının; sampling definition’ın, human-in-the-loop requirement’ının ve ona iliştirilmiş deprecation warning’in kaynağı.

  8. Key Changes, modelcontextprotocol.io/specification/2026-07-28/changelog, ve Feature lifecycle and deprecation policy, .../community/feature-lifecycle. Change table’daki her satırın kaynağı: sessions’ın ve Mcp-Session-Id header’ın removal’ı (SEP-2567); statelessness ve initialize removal’ı (SEP-2575); server/discover (SEP-2575); subscriptions/listen (SEP-2575); Multi Round-Trip Requests ve resultType (SEP-2322); stream resumability removal’ı (SEP-2575); Roots, Sampling ve Logging deprecation’ı (SEP-2577); HTTP+SSE’nin reclassification’ı (SEP-2596); Dynamic Client Registration’ın Client ID Metadata Documents lehine deprecation’ı; error-code renumbering; ve on iki aylık deprecation window. 2

  9. Tools, modelcontextprotocol.io/specification/2026-07-28/server/tools ve Server Features, .../server. Yukarıda yeniden üretilen control-hierarchy tablosunun; tools/list ve tools/call shapes’inin; protocol errors ile tool execution errors arasındaki isError ayrımının; tool-name rules’un ve “prefixing tool names with a server identifier” öneren namespace note’unun; ayrıca explicit handles üzerine non-normative “Stateful Tools” guidance’ın kaynağı.

  10. Versioning, modelcontextprotocol.io/specification/versioning. YYYY-MM-DD scheme’inin, Draft/Current/Final revision states’in, 2026-07-28’in current olduğunun confirmation’ının ve per-request negotiation rules’un kaynağı. modelcontextprotocol.io/docs/sdk adresindeki SDK tier table; TypeScript, Python, C#, Go ve Rust’ı Tier 1; Java ve Ruby’yi Tier 2; Swift, PHP ve Kotlin’i Tier 3 olarak listeler.

  11. A2A Protocol, version 1.0.0, a2a-protocol.org — specification ve A2A and MCP: Relationship and Distinction sayfası, 7 Eylül 2026’da okundu. Tools-against-agents ayrımının, iki protokolün “address distinct but highly complementary needs” ifadesinin ve partnering/using formulation’ın kaynağı.

  12. Agent Communication Protocol, agentcommunicationprotocol.dev, 7 Eylül 2026’da okundu: “ACP is now part of A2A under the Linux Foundation!”, hâlâ bütünüyle servis edilen bir specification’ın üstüne eklenmiş banner — architecture, agent manifest, agent discovery, message structure, stateful agents, run lifecycle ve REST endpoint list hâlâ 200 yanıtlıyor. Specification ortadan kalkmadı; proje kalktı.

Seçimi LIA'ya bırakmaya hazır mısın?

Tüm yapay zeka modelleriyle tek yerde üret — bugün ücretsiz başla.