
Tue Aug 04 2026

Merhaba! 🎯 Buraya gelmen için çok teşekkür ederim. Uzun süreli yapay zeka ajanlarının durum yönetimi konusunda yaşadığın zorlukları biliyorum. Bu yazıda, ajanların sürekli "hatırla" derken bozulmasına son veren stateless MCP mimarisine giriş yapacağız. Burada öğreneceğin şey, ajanlarını nasıl daha temiz, daha güvenilir ve sürdürülebilir hale getireceğin.
Peki bu başlık tam olarak ne anlama geliyor? 🔁 Geleneksel olarak, uzun ömürlü ajanlar kendi özel oturum hileleriyle durumlarını tutmaya çalışırdı. Bu da anlık hatalara, veri kayıplarına ve karmaşık hata ayıklama süreçlerine yol açardı. Stateless MCP ise tam tersini yapıyor: durumu harici tutar, ajanı ise sadece iş mantığına odaklanır.
İşte bu mimariyle birlikte kazanacağın faydalar:
Nasıl çalışıyor bunu? Hadi pratik bir örnek üzerinden anlayalım. 🧠
// Eski yaklaşım: Ajan kendi durumunu tutuyordu
let sessionState = loadSession();
if (sessionState) {
continueTask(sessionState);
} else {
startNewTask();
}
Bu kodda ne oluyor? ❗️ Ajan her zaman kendi geçmişini hatırlamaya çalışıyor. Çok fazla durum biriktirince yavaşlıyor ve hata veriyordu.
Şimdi stateless MCP yaklaşımına bakalım:
// Yeni yaklaşım: Durum harici, MCP tarafından yönetiliyor
const taskContext = await mcp.getContext(agentId);
if (taskContext) {
continueTask(taskContext);
} else {
startNewTask();
}
Bu sayede ne oluyor? 🎯 Ajan artık kendi durumunu saklamıyor. MCP, durumunuzu harici bir depolamadan (örneğin bir veritabanından) çeker ve size veriyor. Ajan sadece "ne yapacağına" karar veriyor, "nasıl hatırlayacağına" ise MCP'yi bırakıyor. Böylece özel oturum hilelerinize son veriyorsunuz ve ajanlarınız çok daha sağlam bir yapıya kavuşuyor. 🚀
Haydi, biraz samimi olsun. 🎯 Uzun süreli çalışan bir yapay zeka ajanının işi nasıl gidiyor, biliyor musun? İlk birkaç saat her şey mükemmel. Ama saatler geçtikçe, işler karışmaya başlıyor.
İşte karşılaştığımız temel engeller:
Hafıza Sızıntısı: Ajan her turda biraz daha hafıza yiyor. Başlangıçta küçük bir konuşma, sonra binlerce geçmişe ulaşıyor. Bellek tüketimi patlıyor. Ne oluyor burada? Sistemi yavaşlatıyor, bazen de tamamen çöküşe sürüküyor.
Oturum Zaman Aşımı: Uzun soluk bir iş sürecinde ajanın bağlantısı kopuyor. "Oturumun süresi doldu" diyor. 🛠 Geçici bir çözüm mü? Tabii ki, tekrar başlatmak. Ama bu durumda bağlam kaybı oluyor. Ajan ne yapıyordu, neden yapıyordu, tamamen unutuyor.
Ölçeklenebilirlik Sorunları: Bir ajan çalışıyorsa sorun yok. Ama yüzlerce ajan aynı anda çalıştığında? Her ajan kendi durumunu tutmaya çalışıyor. Kaynak çatışması ve koordinasyon felaketi başlıyor.
Geçici Çözümlere Bağımlılık: En büyük sıkıntı burası. Hafıza sızıntısını gidermek için "eski veriyi sil" işlevi yazıyoruz. Zaman aşımını çözmek için "otomatik yeniden bağlan" mantığı ekliyoruz. Bu teknik borç oluşturuyor. Kodumuzu karmaşıklaştırıyor, bakımı zor hale getiriyor.
Hadi düşünelim: Projende her ajan bir "bellek gözbebesi" gibi davranıyor ve bir gün patlıyor. ❗️ Bu soruları çözmek olmadan, ajanları gerçekten uzun vadeli görevlere veremeyiz. Nasıl aşabiliriz bunu?
Bak, senin gibi geliştiriciler bazen geçici oturum hilelerine (session hacks) başvuruyor. Özellikle uzun süreli ajanlarda — mesela arka planda çalışan servisler, cron job'lar veya enterprise entegrasyonlar — "bi' geçici çözüm" diye bir şey yaratıyorsunuz. "Sadece birkaç ay çalışacak" diye düşünüyorsunuz. Ama o küçük hileler, zamanla devasa teknik borç oluyor.
Neden bahsediyorum? Çünkü ben bunu birkaç kez gözümün önünde yaşadım. İzin ver detaylarına girelim:
Kısaca söyleyeyim: geçici bir oturum hilesi asla geçici değildir. İlk versiyonda "bir hafta sürer" demiştin. Üç yıl sonra o kod hâlâ üretimde, hâlâ korkuyla dokunuluyor, hâlâ yeni bir geliştiriciyi korkutuyor.
Kısacası: O "geçici" hileye başvurmak, gelecekteki kendine ve ekibine borçlanmak demektir. Mümkünse doğru protokolü kullan, doğru araçları seç — kısa vadeli kazanç, uzun vadete değmez.
Merhaba! Önceki yazılarda MCP protokolüne girdik. Şimdi ise bu mimarinin en temel taşlarından biri olan durumsuzluk (stateless) prensibine odaklanacağız. Hazırsan bir içme bardağı al, bu konuyu birlikte kavrayalım. 🛠
Öncelikle, "stateless" ne demek aslında?
Bu, mevcut mimariyle tam bir paradigma değişikliğidir. ❗️
Peki şimdiye kadar nasıl bir yapı kullanıyorduk?
Şimdi MCP'ye dönelim. Stateless MCP, ajanların nasıl çalıştığını tamamen farklı kılıyor:
Nasıl çalışıyor bu mantık?
Bir ajan istek gönderdiğinde, tüm bağlamı isteğin içinde taşır. Sunucu bu bilgiyi alır, işleri halleder ve cevap verir. Sonra her şey unutulur.
Bu sayede ne oluyor?
Özetle, stateless MCP, ajanları sadece "iş yapan" parçalar haline getiriyor. Bağımlılıkları azaltıyor, ölçeklenebilirliği artırıyor. Bu gerçekten büyük bir dönüşüm noktası. 💡
Hadi bu iş akışını kafanda bir film gibi canlandıralım. 🎯 Stateless MCP'de sunucu her isteği bağımsız olarak görür. Yani bir önceki isteğin hafızasında kalmıyor. Peki ya durum (state) nerede kalıyor? İşte bu noktada istekte taşınan metadata devreye giriyor.
🔁 İstek-gidenep-istek döngüsü şöyle işliyor:
❗️ Durum yönetimi burada nasıl tutarlı kalıyor? Çok basit: Kimlik ve Bağlam her istekle birlikte yolculuk ediyor. Sunucu tarafında tutarlılık, her isteğin kendini yeterince tanımlayabilmesiyle sağlanır. Yani istemci, her seferinde "Ben şu sessionId'ye aitydim ve şu noktadaydım" diyor. Sunucu buna göre işlem yapar.
Şimdi pratik bir örnekle görelim. İstek gidenep-istek döngüsünde body yapısı şöyle olmalı:
{
"sessionId": "abc-123-xyz",
"contextSnapshot": {
"previousAction": "file_uploaded",
"userRole": "admin"
},
"timestamp": "2023-10-27T10:00:00Z"
}
Bu sayede ne oluyor? 🛠 İstek gönderirken sessionId sayesinde sunucu hangi oturuma ait olduğunu anlar. contextSnapshot ise önceki işlemleri hatırlatır, böylece sunucu tekrar hesaplamaya başlamaz. timestamp ise isteğin ne zaman gönderildiğini gösterir, böylece eski ve geçersiz istekleri anında fark ederiz. ✅
Geliştirici arkadaşım, stateless MCP mimarisini projelerine nasıl taşıyacağını merak ediyorsan, doğru yerdesin. Buradan araştırma aşamasından prototipleme, ortaya koyma ve izleme sürecine kadar adım adım nasıl gideceğini anlatacağım. Hazırsan başlayalım! 🚀
Önce ne yaptığını kavramalısın. Stateless demek, her isteğin bağımsız olduğu, sunucunun geçmişi hafızada tutmadığı demek.
Karar verdiğinde, hızlıca bir kanıt kodu (PoC) yaz. Karmaşıklığa girmeden önce çalışır halini görmek önemli.
Prototip çalıştığına göre, artık bunu ölçeklenebilir hale getirmeliyiz. Docker burada asıl dostun.
.env dosyalarından al, hardcode etme!İşte stateless MCP sunucusunun ve bir ajan servisinin birlikte çalıştığı Docker Compose YAML dosyası fikri:
version: '3.8'
services:
mcp-server:
image: your-mcp-server:latest
container_name: stateless-mcp
ports:
- "8080:8080"
environment:
- MCP_TOOL_TIMEOUT=30
- DB_CONNECTION_STRING=${DB_CONN}
restart: unless-stopped
agent-service:
image: your-agent-service:latest
container_name: mcp-agent
ports:
- "9090:9090"
environment:
- MCP_SERVER_URL=http://mcp-server:8080
- AGENT_MODEL=gpt-4
depends_on:
- mcp-server
restart: unless-stopped
Bu YAML'de ne oluyor?
.env'den alıyor.MCP_SERVER_URL ile konteyner isimleriyle iletişim kuruyor (Docker network sayesinde).Çalışıyor, ama ne oluyor gerçeğini bilmiyorsan, bir gemide kâğıt gemisi çizer gibi yürüyorsun.
Şimdi elinde bir plan var. Araştırma aşamasından prototipe, ortaya koyma ve izleme sürecine kadar her adımda ne yapacağını biliyorsun. Kendi projene uyarlı ve başla!
Hadi bir senaryo üzerinden düşünelim. 🎯
Bir araştırma ajanı düşün — örneğin bir startup'ın pazar araştırması yapan bir otomasyon botu. Bu ajan:
Her adım bir MCP (Model Context Protocol) isteği tetikler. Burada önemli olan şey: sunucu tarafında hiçbir şey tutmuyoruz. Her istek bağımsız (stateless). Ancak ajan, kendi başına her adımı hatırlamak için session metadata taşıyor. 🔁
İşte burada asıl fark var:
Bu sayede:
Öncelikle genel akış:
MCP İsteği Oluştur:
1. Session metadata hazırla (sessionId, step, context)
2. Header'lar içinde metadata'yi ekle
3. MCP sunucusuna isteği gönder
4. Yanıtı al, context'i güncelle
5. Sonraki adım için tekrarla (step++)
Şimdi daha somut bir bakış:
Header yapısı şöyle görünebilir:
X-Session-Id: "research-2025-001"
X-Step-Index: 3
X-Context-Accumulated: "{ findings: [...], summary: '...' }"
X-Client-Role: "research-agent"
Burada X-Context-Accumulated alanı aslında önceki adımlardan birikim — yani ajanın "bırakmadığı hiçbir şey" durumu. Sunucu bu header'ı okur, işler, ve bir sonraki adım için aynı metadata'ı tekrar client'a döndürür. Client onu kendi başına saklar.
Aşağıda, istemcinin her MCP isteğinde session metadata'yi headers içinde taşıran basit bir Node.js snippet'i var:
// MCP Client: Stateless istekler için session metadata headers içinde taşınır
const sessionId = "research-2025-001";
let stepIndex = 0;
let accumulatedContext = { findings: [], summary: "" };
// MCP sunucusuna istek gönderen fonksiyon
async function sendMcpRequest(toolName, input) {
// Header'lar içinde session metadata'yı hazırla
const headers = {
"Content-Type": "application/json",
"X-Session-Id": sessionId,
"X-Step-Index": String(stepIndex),
"X-Context-Accumulated": JSON.stringify(accumulatedContext),
"X-Client-Role": "research-agent"
};
// MCP isteği oluştur — body'ya araç adı ve girdi verisini koy
const body = JSON.stringify({
tool: toolName,
input: input
});
// İsteği gönder — sunucu state sakmadan cevap döner
const response = await fetch("https://mcp-server.example.com/invoke", {
method: "POST",
headers: headers,
body: body
});
const result = await response.json();
// Yanıttan gelen yeni bilgiyi context'e ekle
accumulatedContext.findings.push(result.data);
stepIndex++;
return result;
}
// Kullanım örneği: 4 adımlı araştırma akışı
async function runResearchAgent() {
// Adım 1: Web'den veri çek
const step1 = await sendMcpRequest("web-scraper", { url: "https://example.com/reports" });
// Adım 2: Veriyi analiz et
const step2 = await sendMcpRequest("analyzer", { data: step1.data });
// Adım 3: Özet rapor oluştur
const step3 = await sendMcpRequest("summarizer", { analysis: step2.data });
// Adım 4: Sonuçları kaydet
const step4 = await sendMcpRequest("db-saver", { report: step3.data });
console.log("Araştırma tamamlandı:", step4);
}
runResearchAgent();
X-Session-Id → Tüm istekleri aynı oturuma bağlar, sunucu tarafında session tutmadanX-Step-Index → Hangi adımda olduğumuzu sunucuya iletir, akış kontrolü içinX-Context-Accumulated → Önceki adımlardan gelen veriyi taşır — stateless ama bağlamlıX-Client-Role → Kimin istediğini belirtir, multi-agent senaryolarında faydalıSunucu her isteği tek başına ele alır — hiçbir geçmiş bilgisini hatırlamaz. Ama client, headers aracılığıyla her seferinde yeterli bağlamı (context) ile birlikte gönderir. Böylece:
İşte stateless MCP'nin gücü: sunucu basit, client akıllı. 🎯
Hazırsan başlayalım! MCP'yi mimariyle kurarken en kritik olan şey, protokolün durumsuz (stateless) yapısını anlamak. 🎯
İşte katmanlar ve nasıl çalıştıkları:
❗️ Durumsuz Mimari ile Entegrasyon
MCP sunucuları hiçbir zaman geçmiş istekleri hafızada tutmaz. Her istek bağımsızdır. Peki durum nerede saklanır? İstemci tarafında! 🔁
arguments ve metadata alanlarını JSON payload'una yazar. Sunucu bunu okur, işler ve sonucu döner. Sonraki isteklerde aynı bilgiyi tekrar göndermelisin.Bu yüzden mimari kararlarınırken, istemcinin durumunu nasıl taşıyacağını belirlemek çok önemli. Sunucu tarafında hiçbir şey kalmaz, bu da ölçeklendirmeyi kolaylaştırır ✅.
İşte bu yapılandırmayı nasıl yapacağını gösteren basit bir örnek:
mcp-sunucu:
sunucu-adı: "belge-islemci"
mod:
durumsuz-mod: true # Stateless çalışmayı etkinleştirir
iletişim:
mesaj-formatı: "JSON-RPC"
durum-aktarımı:
mekanizma: "istemci-yükünde"
alan: "bağlam-bilgisi"
Bu sayede ne oluyor? Sunucu her isteği bağımsız olarak ele alır. Hiçbir oturum (session) durumu beklenmez. İstemci her seferında gerekli bağlamı taşır, sunucu sadece işleri ve döner. 🚀
MCP'yi stateless mimariye taşıdıktan sonra asıl iş başlıyor. Şimdi ajanlarını gerçekten ölçeklenebilir hale getirmenin zamanı. İşte benim gözümle geçilen en kritik best practice'ler:
DEBUG, üretimde INFO ve ERROR düzeyinde tut — aksi halde log dosyaları okunmaz hale gelir.Basit bir retry + backoff stratejisi şöyle görünüyor:
import time
import random
def call_with_retry(func, max_retries=3, base_delay=1):
for attempt in range(max_retries):
try:
return func()
except Exception as e:
if attempt == max_retries - 1:
raise
delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
print(f"⏳ Deneme {attempt + 1} başarısız. {delay:.2f}s sonra tekrar denenecek...")
time.sleep(delay)
Bu sayede ne oluyor? Her denemede aradaki bekleme süresi katlanarak artar — bu, sisteme çarpmayı azaltır ve "thundering herd" sorununu önler. 🎯
| Alan | Altın Kural |
|---|---|
| Ölçeklenebilirlik | Stateless + horizontal scaling, connection pooling |
| Hata Toleransı | Circuit breaker, exponential backoff, fallback |
| Loglama | Structured, correlation ID, centralized |
| State Recovery | Checkpoint, idempotent ops, durable queue |
Buraya kadar geldiğinde, asıl zorluk değil — sabır ve düzenli pratik. Küçük adımlarla başla, her bir stratejiyi tek tek test et, ve sistemin davranışını gerçek ortamda gözlemle. Doğru yoldasın, ve bu kurallar onu daha da güçlendirecek. 🚀
Hadi pratik bir örnek üzerinden Stateless MCP'i kendi ortamında denemeye başlayalım. 🛠 Burada asıl önemli olan küçük bir başlangıç yapman ve kendi hızında ilerlemen. Acele etmene gerek yok!
Stateless MCP'i denemek için basit bir CLI (komut satırı) aracı yapmak harika bir başlangıç olur. İşte adım adım nasıl ilerleyebilirsin:
server.js dosyası oluştur. Sadece bir "merhaba" döndüren bir MCP işlevi yaz.Hadi şimdi hızlıca çalıştırmak için terminalde kullanabileceğin basit bir komut dizisine bakalım:
# Stateless MCP sunucusunu hızlıca çalıştırmak için kullanılan komut dizisi
# --rm bayrağı: container kapanınca otomatik olarak silinir, sistemini temiz tutar
# -it bayrakları: etkileşimli terminal modunu aktifleştirir
docker run --rm -it mcp-quickstart:latest serve --stateless
Bu sayede ne oluyor? 🔁 Docker ile sistemine dokunmadan hızlıca izole bir ortamda MCP sunucunu çalıştırıyorsun. Hata yaparsan da container otomatik olarak yok olur, her denemede sıfırdan başlarsın.
❗️ Unutma: Kendi hızında ilerle. İlk denemde bir şey çalışmazsa, bu normal! Çözüm süreci zaten en değerli öğrenme parçası.
Sadece başla, geri kalanını MCP seninle halleder. 🚀 Küçük başarılar büyük projelerin temelini oluşturur, o yüzden şimdiden merak edip denemeye başla!
Bu yazı boyunca Stateless MCP'nin ne olduğunu, nasıl çalıştığını ve neden önemli olduğunu birlikte keşfettik. Şimdi ise bu yolculuğun ana mesajını özetleyelim. 🎯
Stateless MCP sadece bir teknik çözüm değil. Düşünün:
❗️ Dikkat etmen gereken önemli nokta: Durumsuz mimari her zaman en kolay yol değildir. Bazı senaryolarda durum yönetimi kaçınılmaz. Ama Stateless MCP, o zorluğu biliyor ve sana ona ele geçirme araçlarını veriyor.
✅ Pratik olarak şöyle düşün:
🔁 Özetle: Stateless MCP, ajan mimarilerin geleceği için sağlam bir temel. Sadece bir araç değil; düşünme biçimini değiştiren bir yaklaşım.
Hadi şimdi kendi projelerine ufak bir adım at, bir API endpoint'i durumsuz hale getir, ve farkı kendin hisset. 🛠
Bu yolculukta yanındayım. Soruların olursa, geri dönmekten çekinme — hep buradayız. 👋
Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.
All rights reserved