
![]()
Diş kliniğinin resepsiyonunda çalıştığınızı hayal edin. Telefon çalıyor, hasta randevu istiyor. Siz ajandayı açıyor, boş slotu buluyor, hastanın adını yazıyor, e-posta gönderiyorsunuz. Gün içinde bunu 30-40 kez tekrar ediyorsunuz. Peki bütün bunları doğal dilde — “Fatma Hanım’a cuma 14:00’e temizlik için randevu ver” der gibi — konuşarak yapabilseydik? Hem de Google Takvim (Google Calendar) ile tam entegre çalışsaydı?
Bu yazıda tam olarak bunu yapan bir sistem kuracağız. Model Context Protocol (MCP) sunucusuyla Google Calendar’ı bir yapay zeka asistanına bağlayacağız; LangChain ile konuşabilen bir ajan (agent) yazacağız; hepsini Docker içinde çalıştıracağız. Sonunda elimizde, metin kutusuna yazdığınız komutlarla randevu oluşturan, iptal eden, erteleyen, müsait saatleri kontrol eden bir asistanımız olacak.
Kodu parça parça açıklayacağım, her kararın nedenini göreceğiz. Başlayalım.
MCP Nedir ve Neden Derdimize Derman?
Model Context Protocol, Anthropic’in Kasım 2024’te açık standart olarak duyurduğu bir protokol [1][2]. Amaç basit: yapay zeka modelleriyle dış dünyadaki araç ve veri kaynakları arasında standart bir iletişim katmanı kurmak.
MCP’den önce durum neydi? Her entegrasyon için ayrı kod yazıyorduk. Gmail için ayrı, Slack için ayrı, takvim için ayrı… Anthropic bu duruma “N×M entegrasyon problemi” diyor [3]. M tane yapay zeka uygulamanız ve N tane veri kaynağınız varsa, M×N tane tekil bağlayıcı (connector) yazmak zorunda kalıyorsunuz. MCP bunu “USB-C for AI” mantığıyla çözüyor — tek bir standart, her iki tarafta bir kez yazılıyor ve herhangi bir uyumlu istemci (client) herhangi bir uyumlu sunucuya (server) bağlanabiliyor [3].
Benimsemesi de hızlı oldu. Mart 2025’te OpenAI kendi ürünlerine MCP desteği ekledi, Nisan 2025’te Google DeepMind Gemini için MCP desteğini doğruladı, Mayıs 2025’te Microsoft Build konferansında Windows 11’in MCP’yi kucakladığı duyuruldu [4][5]. Aralık 2025’te ise Anthropic, MCP’yi Linux Foundation altındaki Agentic AI Foundation’a (AAIF) bağışladı; proje artık Block, OpenAI, Google, Microsoft, AWS, Cloudflare ve Bloomberg’in desteklediği topluluk yönetimli bir standart [6]. Python ve TypeScript SDK’ları için aylık 97 milyon indirme yapıldığını söylüyor Anthropic [6] — yani artık deneysel bir şey değil, altyapı haline gelmiş durumda.
MCP teknik olarak JSON-RPC 2.0 üstünde çalışıyor ve üç temel bileşen sunuyor [7][8]:
- Tools (Araçlar): Modelin çağırabildiği fonksiyonlar (veri çekme, işlem yapma)
- Resources (Kaynaklar): Modelin okuyabildiği salt-okunur veriler
- Prompts (İstemler): Yeniden kullanılabilir şablonlar
Bizim diş kliniği projemizde hepsini Tools olarak kullanacağız: listele, oluştur, iptal et, ertele, müsaitlik kontrol et.
Mimari: İki Kutu, Bir Protokol
Projemizin mimarisi şöyle:
┌─────────────────┐ HTTP/MCP ┌───────────────────┐ API ┌─────────────┐ │ LangChain Agent │ ────────────► │ MCP Server │ ─────────► │ Google │ │ (agent.py) │ ◄──────────── │ (Docker:8000/mcp) │ ◄───────── │ Calendar │ └─────────────────┘ └───────────────────┘ └─────────────┘
Sol tarafta bizim sohbet eden ajanımız (agent) — kullanıcı ile konuşuyor, dil modelini yönetiyor. Sağ tarafta Docker konteynerı içinde koşan MCP sunucusu — Google Calendar’a konuşuyor. Arada ise HTTP üzerinden Streamable HTTP taşıma katmanı (transport).
Bu mimariyi seçmenin bir sebebi var: MCP’de üç taşıma seçeneği var — stdio, SSE (Server-Sent Events) ve Streamable HTTP [9][10]. stdio yerel kullanım için (Claude Desktop gibi), SSE ise 2025-03-26 spesifikasyonundan beri artık eskimiş (deprecated) durumda [11][12]. Yeni uygulamalar için Streamable HTTP öneriliyor; tek bir HTTP uç noktası (endpoint) üzerinden hem istek hem yanıt akışı yönetiliyor, oturum (session) yönetimi ve bağlantı kopuklukları sonrasında yeniden başlatma destekleniyor [11]. Biz de Docker içinde HTTP sunucusu çalıştıracağımız için bu bize tam uyuyor.
Gereksinimler ve Kurulum Hazırlığı
Projede kullanacağımız paketler:
MCP sunucusu tarafında:
fastmcp>=2.0.0 google-api-python-client>=2.100.0 google-auth-httplib2>=0.2.0 google-auth-oauthlib>=1.2.0
Ajan tarafında:
langchain>=0.3.17 langchain-openai>=0.3.0 langchain-mcp-adapters>=0.1.0 python-dotenv>=1.0.1
FastMCP, MCP protokolünü Python’da yazarken tüm boilerplate’i (JSON-RPC, oturum yönetimi, şema üretimi) sizden saklayan bir çerçeve (framework) [13][14]. FastMCP’nin 1.0 sürümü 2024’te resmi MCP Python SDK’sına dahil edilmiş; bağımsız proje ise bugün günde bir milyon indirme alıyor ve tüm dillerde MCP sunucularının yaklaşık %70’i bir FastMCP sürümü ile çalışıyor [13]. Karar kolay: FastMCP kullanacağız.
langchain-mcp-adapters ise LangChain ekibinin Mart 2025’te yayımladığı paket [15][16]. MCP araçlarını LangChain/LangGraph araçlarına çeviriyor, birden fazla MCP sunucusuna aynı anda bağlanmamızı sağlayan MultiServerMCPClient sunuyor. Tam bize göre.
Adım 1: Google Cloud Tarafında Kimlik Doğrulama
Google Calendar’a Python’dan konuşabilmek için OAuth 2.0 kimlik bilgilerine ihtiyacımız var [17][18]. Şu adımları izleyeceğiz:
- Google Cloud Console‘a giriyoruz
- Yeni bir proje oluşturup Google Calendar API‘yi arama çubuğundan bulup etkinleştiriyoruz
- APIs & Services → Credentials altından + Create credentials → OAuth client ID diyoruz

- İlk seferinde OAuth consent screen yapılandırmamız isteniyor: “External” seçip uygulama adı ve e-posta giriyoruz

- Application type olarak Desktop app seçiyoruz (yerel geliştirme için en pratiği bu)

- İndirdiğimiz
credentials.jsondosyasını projemizindata/klasörüne koyuyoruz

Bu dosya, OAuth akışını başlatmak için kullanacağımız istemci bilgilerini içeriyor. Sunucu ilk çalıştığında tarayıcı açılıp bizden izin isteyecek, onayladıktan sonra uzun ömürlü bir token.json üretilecek ve bir daha genelde elle bir şey yapmamıza gerek kalmayacak. Token süresi dolduğunda refresh_token ile kendi kendine yenileniyor [18][19].
Not: “Google hasn’t verified this app” uyarısı görürseniz panik yapmayın — Advanced → Go to <app name> (unsafe) deyip geçebilirsiniz. Uygulamayı yayınlamıyoruz, sadece kendi hesabımızda test ediyoruz.
credentials.json oluşturma:
python -c " import server server.CREDENTIALS_PATH = '../data/credentials.json' server.TOKEN_PATH = '../data/token.json' service = server.get_calendar_service() print('Authenticated successfully!')
Adım 2: FastMCP ile Sunucuyu Yazalım
Şimdi işin keyifli kısmına geldik. mcp_server/server.py dosyasında önce importları ve OAuth boilerplate’ini yazıyoruz [17]:
import os
import json
from datetime import datetime, timedelta
from fastmcp import FastMCP
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
SCOPES = ["https://www.googleapis.com/auth/calendar"]
CALENDAR_ID = os.getenv("GOOGLE_CALENDAR_ID", "primary")
TOKEN_PATH = "/app/data/token.json"
CREDENTIALS_PATH = "/app/data/credentials.json"
mcp = FastMCP("DentistAppointmentManager")
SCOPES olarak tam calendar yetkisini istiyoruz çünkü sadece okumayacağız, yazacağız da. Eğer sadece okuma gerekiyorsa calendar.readonly yeterli olurdu [17]. Google, “tam olarak ihtiyacınız kadar scope isteyin” diyor [18] — biz CRUD yaptığımız için tam yetki makul.
Sonra Google Calendar servisini döndüren yardımcı fonksiyon:
def get_calendar_service():
creds = None
if os.path.exists(TOKEN_PATH):
creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_PATH, SCOPES)
creds = flow.run_local_server(port=0)
with open(TOKEN_PATH, "w") as token:
token.write(creds.to_json())
return build("calendar", "v3", credentials=creds)
Bu, Google’ın kendi quickstart’ında önerdiği klasik desen [17]. Token varsa kullan, süresi dolmuşsa yenile, yoksa yeniden OAuth akışını başlat. Sonraki sefere sormuyor bile, tak-çalıştır.
Aracı Tanımlamak: @mcp.tool Dekoratörü
FastMCP’nin güzelliği burada ortaya çıkıyor. Araç (tool) yazmak için sıradan bir Python fonksiyonu yazıyor, üstüne @mcp.tool() dekoratörü koyuyoruz [20][21]. FastMCP gerisini hallediyor: fonksiyon adını araç adı yapıyor, docstring’i açıklama olarak alıyor, tip ipuçlarından (type hints) JSON şemasını otomatik üretiyor [14][22].
İlk aracımız, yaklaşan randevuları listelemek:
@mcp.tool()
async def list_appointments(days_ahead: int = 7) -> str:
"""List upcoming dentist appointments for the next N days.
Args:
days_ahead: Number of days to look ahead (default 7)
"""
service = get_calendar_service()
now = datetime.utcnow()
time_min = now.isoformat() + "Z"
time_max = (now + timedelta(days=days_ahead)).isoformat() + "Z"
events = service.events().list(
calendarId=CALENDAR_ID,
timeMin=time_min,
timeMax=time_max,
singleEvents=True,
orderBy="startTime",
).execute()
items = events.get("items", [])
if not items:
return f"No appointments found in the next {days_ahead} days."
results = []
for event in items:
start = event["start"].get("dateTime", event["start"].get("date"))
end = event["end"].get("dateTime", event["end"].get("date"))
results.append({
"id": event["id"],
"summary": event.get("summary", "No title"),
"start": start,
"end": end,
"description": event.get("description", ""),
"attendees": [a.get("email") for a in event.get("attendees", [])],
})
return json.dumps(results, indent=2)
Dikkat ettiyseniz docstring’i İngilizce tuttuk. Dil modeline (LLM) hangi durumda bu aracı çağırması gerektiğini anlatan açıklama bu — model İngilizce verilerle eğitildiği için İngilizce yazılmış araç açıklamaları tutarlı sonuç veriyor. Parametrelerin Args: bölümünde açıklanması ise modele argümanları doğru yorumlaması için yardım ediyor.
Randevu Oluşturma: İşin Kalbi
@mcp.tool()
async def create_appointment(
patient_name: str,
patient_email: str,
date: str,
start_time: str,
duration_minutes: int = 30,
treatment_type: str = "General Checkup",
notes: str = "",
) -> str:
"""Create a new dentist appointment on Google Calendar.
Args:
patient_name: Full name of the patient
patient_email: Email address of the patient
date: Appointment date in YYYY-MM-DD format
start_time: Start time in HH:MM format (24h)
duration_minutes: Duration in minutes (default 30)
treatment_type: Type of treatment
notes: Additional notes for the appointment
"""
service = get_calendar_service()
start_dt = datetime.strptime(f"{date} {start_time}", "%Y-%m-%d %H:%M")
end_dt = start_dt + timedelta(minutes=duration_minutes)
timezone = os.getenv("TIMEZONE", "Europe/Istanbul")
event = {
"summary": f"Dentist: {treatment_type} - {patient_name}",
"description": f"Patient: {patient_name}\nTreatment: {treatment_type}\nNotes: {notes}",
"start": {"dateTime": start_dt.strftime("%Y-%m-%dT%H:%M:%S"), "timeZone": timezone},
"end": {"dateTime": end_dt.strftime("%Y-%m-%dT%H:%M:%S"), "timeZone": timezone},
"attendees": [{"email": patient_email}],
"reminders": {
"useDefault": False,
"overrides": [
{"method": "email", "minutes": 24 * 60},
{"method": "popup", "minutes": 30},
],
},
}
created = service.events().insert(
calendarId=CALENDAR_ID, body=event, sendUpdates="all"
).execute()
return json.dumps({
"status": "created",
"event_id": created["id"],
"summary": created["summary"],
"start": created["start"]["dateTime"],
"end": created["end"]["dateTime"],
"link": created.get("htmlLink", ""),
}, indent=2)
Birkaç önemli detay:
sendUpdates="all"parametresi — hastaya otomatik e-posta daveti gönderiliyor. Hasta daveti onayladığında Google Meet linkini de otomatik alıyor.remindersbloğu — e-posta hatırlatması 24 saat önce, pop-up hatırlatması 30 dakika önce.- Saat dilimini (time zone)
Europe/Istanbulvarsayılan olarak alıyoruz, istersek ortam değişkeninden (environment variable) değiştirebiliriz. - Fonksiyon JSON döndürüyor; dil modeli bu yapılandırılmış veriyi okuyup kullanıcıya uygun şekilde anlatıyor.
İptal, Erteleme ve Müsaitlik Kontrolü
cancel_appointment ve reschedule_appointment araçları benzer mantıkla çalışıyor — event_id alıyor, service.events().delete() veya service.events().update() çağrısını yapıyor. check_availability ise biraz daha ilginç, Google Calendar’ın FreeBusy API‘sini kullanıyor:
@mcp.tool()
async def check_availability(date: str, start_time: str = "09:00", end_time: str = "18:00") -> str:
"""Check available time slots on a given date."""
service = get_calendar_service()
timezone = os.getenv("TIMEZONE", "Europe/Istanbul")
body = {
"timeMin": f"{date}T{start_time}:00+03:00",
"timeMax": f"{date}T{end_time}:00+03:00",
"timeZone": timezone,
"items": [{"id": CALENDAR_ID}],
}
freebusy = service.freebusy().query(body=body).execute()
busy_slots = freebusy["calendars"][CALENDAR_ID]["busy"]
# 30 dakikalık slotları üret, meşgul olanları işaretle, boşları döndür
FreeBusy API meşgul olan zaman aralıklarını döndürüyor, biz 30 dakikalık dilimlere bölüp çakışanları eliyoruz. Model kullanıcıya “cuma 14:00, 14:30 ve 15:00 boş” diye cevap verebiliyor.
Sunucuyu Çalıştırmak
Dosyanın sonunda:
if __name__ == "__main__":
mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
Bir satır. FastMCP Streamable HTTP taşıma katmanını başlatıyor, /mcp uç noktasını açıyor [14][21]. Docker konteyneri içinde 0.0.0.0 dinlemek zorundayız çünkü dışarıdan bağlanılacak.
Adım 3: Docker ile Paketleme
Neden Docker? Sunucu sürekli çalışması gereken bir servis ve bağımlılıkları (Google kütüphaneleri) izole tutmak istiyoruz. Ayrıca data/ dizinini volume olarak bağlayınca token ve credentials kalıcı oluyor.
mcp_server/Dockerfile:
FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY server.py . EXPOSE 8000 CMD ["python", "server.py"]
docker-compose.yml:
services:
mcp-server:
build:
context: ./mcp_server
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- ./data:/app/data
environment:
- GOOGLE_CALENDAR_ID=${GOOGLE_CALENDAR_ID:-primary}
- TIMEZONE=${TIMEZONE:-Europe/Istanbul}
restart: unless-stopped
Volume mount’u çok önemli: ./data:/app/data sayesinde konteyner yeniden başlatıldığında bile OAuth token’ımız kaybolmuyor.
Küçük bir hatırlatma: İlk OAuth akışını konteyner içinde çalıştırmak zor çünkü tarayıcı açılamaz. Bu yüzden
token.json‘ı önce yerel makinede üretip sonradata/klasörüne koyuyoruz. README’dekipython -c "import server; ..."komutu tam bunun için.
Sonra:
docker compose up -d
Sunucumuz http://localhost:8000/mcp adresinde hazır.
Adım 4: LangChain Ajanı
Şimdi asıl konuşma tarafına geçtik. agent.py‘de MultiServerMCPClient ile sunucumuza bağlanacağız [15][16]:
import asyncio
import os
from dotenv import load_dotenv
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
load_dotenv()
MCP_SERVER_URL = os.getenv("MCP_SERVER_URL", "http://localhost:8000/mcp")
Modeli Seçmek: OpenRouter Üzerinden
Dil modelini OpenRouter üzerinden alıyoruz. OpenRouter, tek API anahtarıyla 300+ modele erişim sağlıyor [23][24]. Şu an LangChain’in resmi langchain-openrouter entegrasyonu var [25], ama projemiz OpenAI uyumlu endpoint’i kullanıyor (bu da çalışıyor çünkü OpenRouter OpenAI API’siyle uyumlu):
model = ChatOpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
model="nvidia/nemotron-3-super-120b-a12b:free",
temperature=0,
)
temperature=0 seçmemizin nedeni: randevu yönetimi deterministik olmalı, yaratıcılık değil doğruluk istiyoruz. Model “Cuma 14:00” dediğinde hep aynı şekilde yorumlamalı.
İpucu: Üretime (production) alırken
:freemodelleri yerine ücretli bir Claude Sonnet veya GPT-4.1 gibi araç kullanımında (tool calling) daha tutarlı çalışan modelleri tercih edin. Ücretsiz modellerin tool calling başarısı değişkenlik gösterebiliyor.
Sistem İstemi (System Prompt)
SYSTEM_PROMPT = """You are a helpful dental clinic assistant managing Dr. Smith's appointment calendar. You can: - List upcoming appointments - Create new appointments for patients - Cancel existing appointments - Reschedule appointments to a new date/time - Check available time slots on any date Always confirm details with the user before creating or modifying appointments. When creating appointments, ask for: patient name, email, preferred date/time, and treatment type. Working hours are 09:00-18:00, Monday to Friday. Each slot is 30 minutes by default. Be polite, professional, and efficient."""
Sistem istemi (system prompt) modele rolünü, neler yapabildiğini ve davranış kurallarını öğretiyor. “Always confirm details before creating” kısmı kritik — model yanlış anladığında hata yapmasın diye sürekli onay almaya yönlendiriyoruz.
Ajanı Oluşturmak
async def main():
client = MultiServerMCPClient({
"dentist_calendar": {
"transport": "http",
"url": MCP_SERVER_URL,
}
})
tools = await client.get_tools()
agent = create_agent(model=model, tools=tools)
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
while True:
user_input = input("You: ").strip()
if user_input.lower() in ("quit", "exit", "q"):
break
if not user_input:
continue
messages.append({"role": "user", "content": user_input})
result = await agent.ainvoke({"messages": messages})
assistant_message = result["messages"][-1]
print(f"\nAssistant: {assistant_message.content}\n")
messages = result["messages"]
if __name__ == "__main__":
asyncio.run(main())
Burada olan bitenleri açıklayayım [15][16][26]:
MultiServerMCPClienttek bir sözlükle birden fazla MCP sunucusuna bağlanabilir; biz şimdilik sadecedentist_calendar‘ı bağladık.await client.get_tools()— sunucudaki tüm araçları LangChain araçlarına çeviriyor. MCP’nin keşif (discovery) özelliği burada devreye giriyor; elle araç listesi yazmıyoruz, sunucu ne sunuyorsa onu alıyoruz.create_agent(model, tools)— modern LangChain API’si. Eskidencreate_react_agentkullanıyorduk, artıklangchain.agents.create_agentstandart [27]. Arka planda LangGraph ile bir ajan grafiği oluşturuyor.- Döngü içinde konuşma geçmişini (
messages) manuel olarak yönetiyoruz. Bu hafıza (memory) anlamında önemli — ajan önceki mesajları hatırlamalı ki “o randevuyu iptal et” dediğimizde neden bahsettiğimizi bilebilsin.
Adım 5: Çalıştıralım ve Konuşalım
Sunucumuz zaten Docker’da dönüyor. Ajanı başlatmak için:
pip install -r requirements.txt python agent.py
Ve işte örnek bir diyalog:
You: What appointments do we have this week? Assistant: Let me check... You have 3 appointments scheduled: 1. General Checkup - Ahmet Yilmaz (Mon 10:00) 2. Cleaning - Ayse Demir (Tue 14:00) 3. Root Canal - Mehmet Kaya (Thu 09:30) You: Is Friday afternoon available? Assistant: Checking availability for Friday... Yes, these slots are open: - 13:00-13:30, 13:30-14:00, 14:00-14:30, 15:00-15:30, 16:00-16:30 You: Book Fatma Ozturk (fatma@email.com) for a cleaning at 14:00 on Friday Assistant: Appointment created! Fatma Ozturk - Cleaning on Friday at 14:00. A calendar invite has been sent to fatma@email.com.
Arkada olan şey: model list_appointments aracını çağırıyor, sonucu alıyor, doğal dilde özetliyor. check_availability ile boş slotları buluyor, create_appointment ile randevuyu açıyor. Her adımda MCP sunucusu Google Calendar’a istek atıyor, cevabı alıp modele geri döndürüyor.
Öğrendiklerimiz ve Dikkat Edilmesi Gerekenler
Bu projede birkaç önemli kalıbı görmüş olduk:
Mimari kararlar önce, kod sonra. MCP + Docker + ajan üçlüsü, sunucu mantığını kullanıcı arayüzünden ve model seçiminden ayrıştırıyor. Yarın modeli değiştirmek istersek sadece agent.py‘ye dokunuyoruz; yarın Outlook takvimi eklemek istersek ikinci bir MCP sunucusu yazıp istemciye ekliyoruz — ajan ikisini de aynı anda kullanabiliyor.
Güvenlik önemli. Nisan 2025’te güvenlik araştırmacıları MCP’de prompt injection, araç izinleri (tool permissions) ve sahte araç (lookalike tools) gibi sorunları raporladı [2]. Üretime alırken mutlaka: kimlik doğrulama (authentication) ekleyin, sendUpdates="all" gibi e-posta gönderen çağrıları dikkatli kullanın, sunucunuzun çıktılarını loglayın. Ayrıca MCP spesifikasyonu artık OAuth Resource Server sınıflandırması ve erişim belirteçlerinin sunucular arası yeniden kullanımını engelleyen resource indicators gibi güvenlik en iyi pratiklerini içeriyor [28].
Araç açıklamaları model için yazılır. Kullanıcıya değil. Modele açıkça “bu aracı ne zaman çağırmalısın, parametreler ne anlama geliyor” anlatın. Zayıf docstring = modelin yanlış araç seçmesi = kötü deneyim.
Transport katmanı doğru seçilmeli. Yerelde Claude Desktop için stdio, üretimde uzaktan erişim için Streamable HTTP. SSE artık eskimiş, yeni proje yazıyorsanız direkt Streamable HTTP ile başlayın [9][10][11].
MCP’nin ekosistem boyutu büyük. Aralık 2025 itibarıyla Claude’un 75’ten fazla resmi bağlayıcısı var, ayda 10.000’den fazla aktif MCP sunucusu üretimde kullanılıyor [6][29]. Yazdığınız sunucuyu başkalarının da kullanabileceği resmi MCP Registry’ye yayınlayabilirsiniz [6].
Projeye kolayca: SMS bildirimi için Twilio aracı, hasta veritabanı için PostgreSQL aracı, ödeme için Stripe aracı ekleyebilirsiniz — her biri ayrı bir MCP sunucusu olarak. Ajan hepsine aynı anda bağlanır, siz sadece doğal dilde isteğinizi söylersiniz. Randevu yönetiminden başlayıp bütün bir klinik operasyonunu otomatikleştirmek artık protokol katmanında zor değil.
Kodla oynamak, kendi klinik veya başka bir kullanım senaryosuna uyarlamak size kalıyor. Uğraşmayım yapılmışını kullanayım derseniz: https://app.chatbu.io. Kolay gelsin!
Kaynaklar
[1] Anthropic. “Introducing the Model Context Protocol.” https://www.anthropic.com/news/model-context-protocol
[2] Wikipedia. “Model Context Protocol.” https://en.wikipedia.org/wiki/Model_Context_Protocol
[3] ByteBridge. “Model Context Protocol (MCP): Evolution, Capabilities, and the Rise of Peta.” Medium, January 2026. https://bytebridge.medium.com/model-context-protocol-mcp-evolution-capabilities-and-the-rise-of-peta-ff2967b45d48
[4] Pento. “A Year of MCP: From Internal Experiment to Industry Standard.” https://www.pento.ai/blog/a-year-of-mcp-2025-review
[5] The New Stack. “Why the Model Context Protocol Won.” December 2025. https://thenewstack.io/why-the-model-context-protocol-won/
[6] Anthropic. “Donating the Model Context Protocol and establishing the Agentic AI Foundation.” December 2025. https://www.anthropic.com/news/donating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation
[7] IBM. “What is Model Context Protocol (MCP)?” https://www.ibm.com/think/topics/model-context-protocol
[8] Model Context Protocol Specification. https://modelcontextprotocol.io/specification/2025-11-25
[9] MCPcat. “MCP Transport Protocols: stdio vs SSE vs StreamableHTTP.” https://mcpcat.io/guides/comparing-stdio-sse-streamablehttp/
[10] Roo Code Documentation. “MCP Server Transports: STDIO, Streamable HTTP & SSE.” https://docs.roocode.com/features/mcp/server-transports
[11] Model Context Protocol. “Transports.” https://modelcontextprotocol.io/specification/2025-03-26/basic/transports
[12] fka.dev. “Why MCP Deprecated SSE and Went with Streamable HTTP.” June 2025. https://blog.fka.dev/blog/2025-06-06-why-mcp-deprecated-sse-and-go-with-streamable-http/
[13] FastMCP GitHub Repository. https://github.com/jlowin/fastmcp
[14] gofastmcp.com. “How to Create an MCP Server in Python.” https://gofastmcp.com/tutorials/create-mcp-server
[15] LangChain MCP Adapters GitHub. https://github.com/langchain-ai/langchain-mcp-adapters
[16] LangChain Documentation. “Model Context Protocol (MCP).” https://docs.langchain.com/oss/python/langchain/mcp
[17] Google for Developers. “Python quickstart | Google Calendar.” https://developers.google.com/workspace/calendar/api/quickstart/python
[18] Google for Developers. “Using OAuth 2.0 to Access Google APIs.” https://developers.google.com/identity/protocols/oauth2
[19] Unified.to. “How to Integrate with Google Calendar API: A Step-by-Step Guide for Developers.” https://unified.to/blog/how_to_integrate_with_google_calendar_api_a_step_by_step_guide_for_developers
[20] Firecrawl. “How to Build MCP Servers in Python: Complete FastMCP Tutorial for AI Developers.” https://www.firecrawl.dev/blog/fastmcp-tutorial-building-mcp-servers-python
[21] MCPcat. “Build MCP Servers in Python with FastMCP – Complete Guide.” https://mcpcat.io/guides/building-mcp-server-python-fastmcp/
[22] KDnuggets. “FastMCP: The Pythonic Way to Build MCP Servers and Clients.” February 2026. https://www.kdnuggets.com/fastmcp-the-pythonic-way-to-build-mcp-servers-and-clients
[23] OpenRouter Documentation. “LangChain Integration.” https://openrouter.ai/docs/guides/community/langchain
[24] OpenRouter Documentation. “Quickstart.” https://openrouter.ai/docs/quickstart
[25] langchain-openrouter on PyPI. https://pypi.org/project/langchain-openrouter/
[26] langchain-mcp-adapters on PyPI. https://pypi.org/project/langchain-mcp-adapters/
[27] LangChain Changelog. “MCP Adapters for LangChain and LangGraph.” March 2025. https://changelog.langchain.com/announcements/mcp-adapters-for-langchain-and-langgraph
[28] DataCamp. “Building an MCP Server and Client with FastMCP 2.0.” https://www.datacamp.com/tutorial/building-mcp-server-client-fastmcp
[29] Klavis AI. “LangChain MCP Adapters: Building Production-Ready AI Agents with Unified Tool Access.” https://www.klavis.ai/use-case/langchain-mcp-adapters-building-production-ready-ai-agents-with-unified-tool-access
[30] CircleCI. “Building and deploying a Python MCP server with FastMCP and CircleCI.” October 2025. https://circleci.com/blog/building-and-deploying-a-python-mcp-server-with-fastmcp/