---
title: 'Model Bağlam Protokolü Nedir'
source: 'https://academia.sh/tr/kurslar/mcp/model-baglam-protokolu-nedir'
course: 'Model Bağlam Protokolü ve Araç Ekosistemi'
language: tr
updated: '2026-08-17T18:06:40+00:00'
license: 'CC BY-SA 4.0'
---

# Model Bağlam Protokolü Nedir

Araç tanımının çağıran tarafın kodundan çıkıp bir sunucuya taşınmasının sayılması: üç kurgu sunucu beş araç bildirir, istemcinin izin listesi dört araç taşır ve yetenek uzlaşması sonrası anlaşılan küme üç araçta kalır. Aynı üç araçlık zincir protokolsüz tabanda 844 sonucunu sıfır mesaj, sıfır zarf belirteci ve sıfır gidiş-dönüşle üretir; protokollü kurulumda aynı 844 için 6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş ödenir. Bağlantıyı kurmak işi yapmaktan pahalıdır: el sıkışması 99 belirteç, zincirin kendisi 80 belirteç tutar ve el sıkışmasının 2 mesajı ile 2 gidiş-dönüşü hiçbir araç kazandırmayan bir sunucuya gider. Karşılığında kazanılan taşınabilirlik de sayılır: dört istemcide protokolsüz kurulum 20 araç tanımı yazdırır ve arayüz değiştiğinde dört yeri kırar, protokollü kurulum 5 tanımı tek yerde tutar ve karşılığında istemci başına 6 mesaj ile 99 zarf belirteci ister.

Yapay Zekâ Ajanları kursu yirmi iki derste bir ajanı kurdu, donattı ve ölçtü: algı ile eylemin
sırası, planlayıcı ile yürütücünün ayrılması, adım bütçesi, durdurma ölçütü, araç tanımının dört
düzeyi, bellek, yetki yüzeyi ve değerlendirme. Hepsinde bir şey sessizce varsayıldı: **her araç
ders içinde elle tanımlandı.** Tanım da yürütme de aynı elin altındaydı; aracın adı, şeması ve
örnek çağrısı ajanın kodunun yanı başında duruyordu.

Bu ders o varsayımı kaldırır ve üç soru sorar: aynı araç başka bir ajana, başka bir ekibe ya da
başka bir uygulamaya **nasıl verilir**, tanım **kimin elinde** durur ve arayüz değiştiğinde **kim
kırılır**. Model bağlam protokolü bu üç sorunun ortak yanıtıdır: araç tanımını çağıran tarafın
kodundan çıkarır, karşı tarafa bir **sunucuya** taşır ve arayı sabit bir mesaj düzeniyle bağlar.
Kazanç taşınabilirliktir. Bedeli ise sayılabilir: her mesajın bir **zarfı**, her uzak isteğin bir
**gidiş-dönüşü** vardır. Bu ders ikisini yan yana koyar.

- **PY1.** Ortam, üç sunucu ve protokol benzeticisi **kurgudur**; gerçek bir sunucu, istemci
  kitaplığı ya da çalışma zamanı çağrılmaz. 60 kurgu abone, üç kurgu sunucu, beş bildirilen araç.
  Tohum **20260218**.
- **PY2.** Benzetici protokolün kendisini uygulamaz; sözleşmenin **gözlenebilir kalemlerini** sayar:
  istek, yanıt, bildirim, zarf belirteci ve gidiş-dönüş.
- **PY3.** Zarfın **sabit bedeli sekiz belirteçtir**; gövdenin belirteçleri bunun üstüne eklenir.
- **PY4.** Taban çizgisi **protokolsüz kurulumdur**: araç çağıran tarafın içinde tanımlıdır, el
  sıkışması yoktur, zarf sayılmaz. Yapay Zekâ Ajanları kursunun bütün ölçümleri bu tabandaydı.
- **PY5.** Yerel aktarımda bir istek **bir**, uzak aktarımda **iki** gidiş-dönüş sayılır.
- **PY6.** Yetenek uzlaşması her sunucuya bir istek gönderip bir yanıt alır. Sürüm uyuşmazlığında
  sunucunun **tamamı** düşer; izin listesi dışındaki araç alınmaz.
- **PY7.** Küme küçüktür: sunucu **üç**, bildirilen araç **beş**, izin listesi **dört**. Bu kümede
  oran basan bir ölçünün en küçük adımı $1/5 = 0{,}2000$'dir ve bundan küçük fark ölçülemez. Bu
  ders oran yerine **sayım** basar.
- **PY8.** Sayımlar koşumdan bağımsızdır; benzeticide belirsiz bir bileşen yoktur. İkinci koşum
  aynı zinciri **başka bir abone** için çalıştırır.
- **PY9.** Aracın kendi doğruluğu Yapay Zekâ Ajanları kursunda ölçüldü ve **tekrarlanmaz**; şema
  eklendiğinde geçerli çağrı oranının 0,2803'ten 0,8919'a çıktığı oradan girdi alınır. Burada
  ölçülen şey tanımın **yerinin** bedelidir.

## Üç Rol ve Kurgu Ortam

Protokolün tanımladığı üçlü kursun sonuna kadar sürer. **Barındırıcı**, kullanıcıyla ve dil
modeliyle konuşan uygulamadır: bağlamı tutar, izin listesini taşır, yan etkili bir çağrıda onayı
ister. **İstemci** barındırıcının içinde yaşar ve **sunucu başına bir tanedir**: oturumu kurar,
yetenek uzlaşmasını yürütür, mesajları zarflar. **Sunucu** araç tanımını, o tanımın arkasındaki
**işleyiciyi**, varsa **kaynak** ve **istem** yeteneklerini barındırır; barındırıcıyı hiç görmez,
yalnız istemciyle konuşur.

Yapay Zekâ Ajanları kursunda bu üç rol tek bir dosyaydı. Aşağıdaki kod aynı ölçüm ağı kurgusunu
alır ve araçları üç ayrı kurgu sunucuya dağıtır: `olcum` sayaç okur ve tüketim hesaplar, `tarife`
bedeli çıkarır, `kayit` bölge özeti verir ve kayıt yazar. Her sunucunun bir **sürümü** ve bir
**aktarım** biçimi vardır. `mesaj` her istek, yanıt ve bildirimi sayan kurgu zarftır.

```python
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def belirtecle(m):
    b = []
    for s in str(m).lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


# ---- KURGU ortam: olcum aginin abone kayitlari
BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
ABONE = {}
for i in range(60):
    r = uretec(TOHUM + 31 * i)
    onceki = 10000 + int(r() * 80000)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "onceki": onceki, "simdiki": onceki + int(r() * 70)}
BASAMAK, USTU, ISYERI_KAT = ((10, 4), (25, 7), (40, 11)), 16, 2


def _bedel(m3, tip):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    return (top + kalan * USTU) * (ISYERI_KAT if tip == "isyeri" else 1)


def t_sayac(abone=None, **_):
    a = ABONE.get(abone)
    return {"hata": "abone yok"} if a is None else {
        "onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"]}


def t_tuketim(onceki=None, simdiki=None, **_):
    if onceki is None or simdiki is None:
        return {"hata": "eksik alan"}
    f = simdiki - onceki
    return {"m3": f + 100000 if f < 0 else f}


def t_tarife(m3=None, tip="mesken", **_):
    return {"hata": "eksik alan"} if m3 is None else {"tutar": _bedel(m3, tip)}


def t_bolge(bolge=None, **_):
    if bolge not in BOLGE:
        return {"hata": "bolge yok"}
    n = sum(1 for a in ABONE.values() if a["bolge"] == bolge)
    return {"bolge": bolge, "abone": n}


def t_kayit(abone=None, sutun=None, deger=None, **_):
    if not (abone and sutun and deger is not None):
        return {"hata": "eksik alan"}
    return {"yazildi": True}


# ---- KURGU sunucular: her biri yetenek bildirir
SUNUCU = {
    "olcum": {"surum": 2, "aktarim": "yerel",
              "arac": {"sayac_oku": {"islev": t_sayac, "alan": ("abone",), "yan_etki": False},
                       "tuketim": {"islev": t_tuketim, "alan": ("onceki", "simdiki"),
                                   "yan_etki": False}},
              "kaynak": ("abone_listesi",), "istem": ()},
    "tarife": {"surum": 1, "aktarim": "uzak",
               "arac": {"tarife": {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False}},
               "kaynak": ("basamak_tablosu",), "istem": ("bedel_aciklamasi",)},
    "kayit": {"surum": 3, "aktarim": "uzak",
              "arac": {"bolge_ozet": {"islev": t_bolge, "alan": ("bolge",), "yan_etki": False},
                       "kayit_yaz": {"islev": t_kayit, "alan": ("abone", "sutun", "deger"),
                                     "yan_etki": True}},
              "kaynak": (), "istem": ()},
}
ISTEMCI_SURUM = {"olcum": 2, "tarife": 1, "kayit": 2}      # kayit sunucusu ileride
IZIN = ("sayac_oku", "tuketim", "tarife", "bolge_ozet")     # kayit_yaz izin listesinde yok

SAYIM = {"istek": 0, "yanit": 0, "bildirim": 0, "belirtec": 0, "gidis_donus": 0}


def mesaj(tur, govde, aktarim="yerel"):
    """KURGU zarf. Gercek bir protokol uygulanmaz; sayilan sey zarfin bedelidir."""
    SAYIM[tur] += 1
    b = len(belirtecle(govde)) + 8                       # zarf sabiti
    SAYIM["belirtec"] += b
    if tur == "istek":
        SAYIM["gidis_donus"] += 2 if aktarim == "uzak" else 1
    return b


def elsikismasi(istemci_surum=None, izin=None):
    """Yetenek uzlasmasi: surum uyusmazligi ve izin listesi arac kumesini daraltir."""
    istemci_surum = ISTEMCI_SURUM if istemci_surum is None else istemci_surum
    izin = IZIN if izin is None else izin
    anlasilan, dusen = {}, []
    for ad, s in SUNUCU.items():
        mesaj("istek", f"yetenek sor {ad}", s["aktarim"])
        mesaj("yanit", f"yetenek bildir {ad} surum {s['surum']} "
                       + " ".join(s["arac"]) + " " + " ".join(s["kaynak"]))
        if istemci_surum.get(ad, 0) < s["surum"]:
            dusen.append((ad, "surum", s["surum"], istemci_surum.get(ad, 0)))
            continue
        for t, tan in s["arac"].items():
            if t not in izin:
                dusen.append((ad, "izin", t, None))
                continue
            anlasilan[t] = dict(tan, sunucu=ad, aktarim=s["aktarim"])
    return anlasilan, dusen


def cagir(anlasilan, ad, durum):
    if ad not in anlasilan:
        return {"hata": "arac bildirilmedi"}
    t = anlasilan[ad]
    kw = {a: durum[a] for a in t["alan"] if a in durum}
    mesaj("istek", f"{ad} " + " ".join(f"{k} {v}" for k, v in kw.items()), t["aktarim"])
    s = t["islev"](**kw)
    mesaj("yanit", " ".join(f"{k} {v}" for k, v in s.items()))
    return s


print("sunucu   surum  aktarim  arac                     kaynak  istem")
for ad, s in SUNUCU.items():
    print(f"{ad:<8} {s['surum']:>5}  {s['aktarim']:<7}  {', '.join(s['arac']):<23}"
          f" {len(s['kaynak']):>6} {len(s['istem']):>6}")
print(f"bildirilen arac {sum(len(s['arac']) for s in SUNUCU.values())}"
      f"   izin listesi {len(IZIN)}   istemcinin bildigi surum {ISTEMCI_SURUM}")
```

```
sunucu   surum  aktarim  arac                     kaynak  istem
olcum        2  yerel    sayac_oku, tuketim           1      0
tarife       1  uzak     tarife                       1      1
kayit        3  uzak     bolge_ozet, kayit_yaz        0      0
bildirilen arac 5   izin listesi 4   istemcinin bildigi surum {'olcum': 2, 'tarife': 1, 'kayit': 2}
```

Bu tablo bir **yetenek bildirimidir**: her sunucu ne sunduğunu söyler. Beş araç bildiriliyor,
istemcinin izin listesi dördünü tanıyor ve `kayit` sunucusunun sürümü üç iken istemci iki
biliyor. Bildirilen şey ile kullanılabilecek şey aynı değildir; aradaki farkı **yetenek uzlaşması**
belirler.

## Protokolsüz Taban ve Protokollü Kurulum

Ölçü için iki kurulum yan yana konur. `protokolsuz` işlevi araçları doğrudan çağırır: tanım aynı
dosyada olduğu için ne oturum kurulur ne mesaj sayılır. `protokollu` işlevi aynı işi protokol
üzerinden yapar: önce yetenek uzlaşması, sonra üç araçlık zincir. İkinci koşum aynı zinciri
başka bir abone için çalıştırır.

```python
def protokolsuz(abone):
    """Taban cizgisi: arac ders icinde tanimli, el sikismasi yok, zarf sayilmiyor."""
    a = t_sayac(abone=abone)
    m = t_tuketim(onceki=a["onceki"], simdiki=a["simdiki"])
    return t_tarife(m3=m["m3"], tip=a["tip"])["tutar"]


def protokollu(abone):
    """Ayni is, tanim karsi tarafta: once yetenek uzlasmasi, sonra zincir."""
    for k in SAYIM:
        SAYIM[k] = 0
    anlasilan, dusen = elsikismasi()
    el = dict(SAYIM)
    durum = {"abone": abone}
    for ad in ("sayac_oku", "tuketim", "tarife"):
        durum.update(cagir(anlasilan, ad, durum))
    return durum["tutar"], anlasilan, dusen, el, dict(SAYIM)


for abone in ("A017", "A031"):
    tutar, anlasilan, dusen, el, top = protokollu(abone)
    print(f"{abone}  protokolsuz taban : sonuc {protokolsuz(abone):>4}"
          f"  istek 0  yanit 0  zarf belirteci 0  gidis-donus 0")
    print(f"{abone}  el sikismasi      : istek {el['istek']}  yanit {el['yanit']}"
          f"  zarf belirteci {el['belirtec']}  gidis-donus {el['gidis_donus']}")
    print(f"{abone}  ucluk zincir      : istek {top['istek'] - el['istek']}"
          f"  yanit {top['yanit'] - el['yanit']}"
          f"  zarf belirteci {top['belirtec'] - el['belirtec']}"
          f"  gidis-donus {top['gidis_donus'] - el['gidis_donus']}")
    print(f"{abone}  protokollu toplam : sonuc {tutar:>4}  istek {top['istek']}"
          f"  yanit {top['yanit']}  zarf belirteci {top['belirtec']}"
          f"  gidis-donus {top['gidis_donus']}")
print("anlasilan arac", sorted(anlasilan), " dusen", dusen)
print("izin listesinde olmayan arac :", cagir(anlasilan, "kayit_yaz",
                                              {"abone": "A017", "sutun": "bedel", "deger": 1}))
```

```
A017  protokolsuz taban : sonuc  844  istek 0  yanit 0  zarf belirteci 0  gidis-donus 0
A017  el sikismasi      : istek 3  yanit 3  zarf belirteci 99  gidis-donus 5
A017  ucluk zincir      : istek 3  yanit 3  zarf belirteci 80  gidis-donus 4
A017  protokollu toplam : sonuc  844  istek 6  yanit 6  zarf belirteci 179  gidis-donus 9
A031  protokolsuz taban : sonuc   89  istek 0  yanit 0  zarf belirteci 0  gidis-donus 0
A031  el sikismasi      : istek 3  yanit 3  zarf belirteci 99  gidis-donus 5
A031  ucluk zincir      : istek 3  yanit 3  zarf belirteci 80  gidis-donus 4
A031  protokollu toplam : sonuc   89  istek 6  yanit 6  zarf belirteci 179  gidis-donus 9
anlasilan arac ['sayac_oku', 'tarife', 'tuketim']  dusen [('kayit', 'surum', 3, 2)]
izin listesinde olmayan arac : {'hata': 'arac bildirilmedi'}
```

İki kurulum **aynı sonucu** veriyor: A017 için 844, A031 için 89. Hesap değişmedi, araçların kodu
değişmedi, sıra değişmedi. Değişen tek şey tanımın nerede durduğu ve bunun bedeli dört sütunda
yazılı: **6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş**. Protokolsüz tabanda bu dört
sayının hepsi sıfırdır.

Bedelin dağılımı beklenenin tersidir. İşi yapan üç çağrı **80 belirteç** tutuyor, bağlantıyı kuran
el sıkışması **99 belirteç**; bağlantıyı kurmak işi yapmaktan **19 belirteç pahalı** ve dokuz
gidiş-dönüşün beşi orada harcanıyor. Nedeni el sıkışmasının **her sunucuyla ayrı ayrı**
yapılmasıdır: zincir üç araç kullanıyor, uzlaşma üç sunucuyla konuşuyor.

İki koşum aynı sayıları veriyor. Bu bir tesadüf değil, zarfın ne ölçtüğünün sonucudur: mesajın
gövdesi A017 ile A031 arasında değişiyor fakat belirteç sayısı aynı kalıyor, çünkü sayılan şey
verinin kendisi değil **sözleşmenin biçimidir**. Bir araç bağlantısının sayısı aracın sayısı değil
sözleşmenin sayısıdır; kursun kuralı budur ve on bir ders boyunca sürer.

Son iki satır ilk kayıptır. Uzlaşma sonrası anlaşılan küme **üç araçtır**, bildirilen ise beş.
`dusen` listesinde tek bir satır var: `kayit` sunucusu sürüm üç bildiriyor, istemci iki biliyor ve
sunucunun **tamamı** düşüyor. Bunun bedeli iki kez ödeniyor. Birincisi, `kayit_yaz` çağrıldığında
araç hiç yokmuş gibi davranılıyor. İkincisi ve daha sessiz olanı: el sıkışmasının **2 mesajı ve 2
gidiş-dönüşü** hiçbir araç kazandırmayan bir sunucuya gitti. Uzlaşma bedeli, uzlaşma başarısız
olsa bile ödenir.

## Taşınabilirliğin Sayısı

Ödenen bedelin karşılığı taşınabilirliktir ve o da sayılabilir. Ölçü şudur: aynı beş araç tanımı
**kaç yerde yazılır** ve arayüz değiştiğinde **kaç yer kırılır**.

```python
def tanim_metni(s):
    return " ".join(f"{a} ( {' , '.join(t['alan'])} )" for a, t in s["arac"].items())


TANIM_SATIR = sum(len(s["arac"]) for s in SUNUCU.values())
TANIM_BEL = sum(len(belirtecle(tanim_metni(s))) for s in SUNUCU.values())
for k in SAYIM:
    SAYIM[k] = 0
elsikismasi()
EL_MESAJ, EL_BEL = SAYIM["istek"] + SAYIM["yanit"], SAYIM["belirtec"]

print(f"bes arac tanimi {TANIM_SATIR} satir, {TANIM_BEL} belirtec;"
      f" bir oturumun el sikismasi {EL_MESAJ} mesaj, {EL_BEL} zarf belirteci")
print("istemci   protokolsuz: tanim  kirilan yer   protokollu: tanim  kirilan yer"
      "  mesaj  zarf belirteci")
for k in (1, 2, 3, 4):
    print(f"{k:>7}   {k * TANIM_SATIR:>18}  {k:>11}   {TANIM_SATIR:>17}  {0:>11}"
          f"  {k * EL_MESAJ:>5}  {k * EL_BEL:>14}")
```

```
bes arac tanimi 5 satir, 35 belirtec; bir oturumun el sikismasi 6 mesaj, 99 zarf belirteci
istemci   protokolsuz: tanim  kirilan yer   protokollu: tanim  kirilan yer  mesaj  zarf belirteci
      1                    5            1                   5            0      6              99
      2                   10            2                   5            0     12             198
      3                   15            3                   5            0     18             297
      4                   20            4                   5            0     24             396
```

Tek istemcide protokol **hiçbir şey kazandırmıyor**: tanım iki kurulumda da beş satır, kırılan yer
iki kurulumda da bir tane — biri istemcide, öbürü sunucuda. Eklenen tek şey altı mesaj ve doksan
dokuz belirteç. Bir araç tek bir uygulamada kullanılacaksa protokol saf bedeldir.

Fark istemci sayısıyla açılıyor. Dört istemcide protokolsüz kurulum **20 araç tanımı** yazdırıyor
ve `tuketim` aracının alan adları değiştiğinde **dört yeri** kırıyor; protokollü kurulumda tanım
**beş satır ve tek yerde** duruyor, istemcilerde kırılacak bir şey yok. Karşılığında dört istemci
**24 mesaj ve 396 zarf belirteci** ödüyor: taşınabilirliğin oturum başına sabit bir bedeli vardır
ve bu bedel istemci sayısıyla doğrusal büyür.

"Kırılan yer" sütununun sıfır olması **hata olmayacağı anlamına gelmez**. `kayit` sunucusunun sürüm
sapması bunu göstermişti: istemcide düzeltilecek bir satır yoktu ve iki araç yine de kayboldu.
Değiştiğinde kimin kırılacağı yazılmayan bir arayüz ölçülmemiş sayılır; protokol o soruyu ortadan
kaldırmaz, yalnız **tek bir yere** taşır.

## Özet

- Model bağlam protokolü üç rol tanımlar: barındırıcı bağlamı, izin listesini ve onayı tutar;
  istemci sunucu başına bir oturum kurar ve mesajları zarflar; sunucu araç tanımını ve işleyicisini
  barındırır.
- Üç kurgu sunucu beş araç bildiriyor, izin listesi dört araç taşıyor ve yetenek uzlaşması sonrası
  anlaşılan küme üç araçta kalıyor; `kayit` sunucusu sürüm sapmasıyla tamamen düşüyor.
- Aynı üç araçlık zincir protokolsüz tabanda 844 sonucunu sıfır mesajla üretir; protokollü
  kurulumda aynı sonuç 6 istek, 6 yanıt, 179 zarf belirteci ve 9 gidiş-dönüş tutar.
- Bağlantıyı kurmak işi yapmaktan pahalıdır: el sıkışması 99 belirteç, zincir 80 belirteç; el
  sıkışmasının 2 mesajı ve 2 gidiş-dönüşü hiçbir araç kazandırmayan bir sunucuya gider.
- İki farklı abonenin koşumu aynı zarf sayısını verir; sayılan şey veri değil sözleşmenin biçimidir.
- Taşınabilirlik bir sayımdır: dört istemcide protokolsüz kurulum 20 tanım yazdırır ve dört yeri
  kırar, protokollü kurulum 5 tanımı tek yerde tutar ve istemci başına 6 mesaj ile 99 zarf
  belirteci ister.

## Sonraki Adım

Bu derste üç rol adlandırıldı ve aralarındaki mesajlar sayıldı, ama hangi kalemin hangi rolde
durduğu sıralanmadı. İzin listesi barındırıcıda mı istemcide mi durur, araç tanımının tek doğru
yeri neresidir, oturumu kim tutar, onayı kim ister? Bu soruların yanıtı bir tercih değil bir
bedeldir: bir kalem yanlış rolde durduğunda iki taraf onu birbirine anlatmak zorunda kalır ve her
anlatma mesajdır. Sonraki ders on kalemi üç role dağıtır ve rol sınırını geçen her kalemin kaç
mesaj eklediğini sayar.
