Ana sayfa ›
AI ile Geliştirme ›
MCP Protokolü
🔌MCP Protokolü (Model Context Protocol)
📺 Daha Fazlası İçin İzleyin
Model Context Protocol (MCP), LLM ajanlarının harici araçlara, veritabanlarına ve servislere standart bir protokol üzerinden bağlanmasını sağlar. Komtaş mimarisinde tüm araç entegrasyonları MCP üzerinden yönetilmektedir.
3.1 MCP Sunucu Geliştirme
Transport Mekanizmaları
| Transport | Açıklama | Kullanım Senaryosu | Güvenlik |
|---|---|---|---|
| stdio | Standart giriş/çıkış üzerinden iletişim | Lokal geliştirme, CLI araçları | Orta |
| HTTP/SSE | HTTP + Server-Sent Events | Uzak sunucular, cloud servisleri | Yüksek |
| In-process | Aynı süreç içinde | Monolitik uygulamalar | En Yüksek |
Python MCP Sunucu Örneği (HTTP/SSE)
from mcp.server.fastmcp import FastMCP
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
import uvicorn
# MCP server oluştur
mcp = FastMCP("Komtaş Enterprise MCP Server")
@mcp.tool()
async def search_contracts(
query: str,
customer_id: str = None,
date_from: str = None,
date_to: str = None,
limit: int = 10
) -> list[dict]:
"""
Komtaş sözleşme veritabanında arama yapar.
Args:
query: Arama terimi
customer_id: Müşteri kimliği (opsiyonel filtre)
date_from: Başlangıç tarihi ISO format (2024-01-01)
date_to: Bitiş tarihi ISO format
limit: Maksimum sonuç sayısı (1-100)
Returns:
Sözleşme listesi: id, title, customer, value, status, date
"""
# Veritabanı sorgusu
results = await db.search_contracts(
query=query,
filters={"customer_id": customer_id, "date_range": (date_from, date_to)},
limit=limit
)
return [contract.to_dict() for contract in results]
@mcp.resource("komtas://customers/{customer_id}/profile")
async def get_customer_profile(customer_id: str) -> str:
"""Müşteri profil kaynağı"""
customer = await db.get_customer(customer_id)
return customer.to_json()
@mcp.prompt()
def contract_analysis_prompt(contract_id: str) -> str:
"""Sözleşme analizi için sistem promptu"""
return f"""Sözleşme {contract_id}'yi analiz et:
1. Anahtar taahhütleri listele
2. Risk maddelerini belirle
3. Sona erme tarihlerini belirt
4. Yenileme gereksinimlerini özetle"""
# HTTP sunucu
app = Starlette()
transport = SseServerTransport("/messages/")
app.mount("/", transport)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8080)
📌 Kod Notları
- FastMCP: Anthropic'in MCP sunucu geliştirmesini basitleştiren Python dekoratör tabanlı çerçevesidir.
@mcp.tool()ile herhangi bir fonksiyon anında MCP aracına dönüşür. - SSE transport: Server-Sent Events — HTTP üzerinden tek yönlü gerçek zamanlı akış sağlar. MCP istemcisi SSE bağlantısıyla sunucuyu dinler; araç çağrısı sonuçları bu kanaldan iletilir.
- Type hints zorunlu: FastMCP, parametre ve dönüş tipi bilgilerini MCP şemasına otomatik çevirir. Type hint olmayan fonksiyonlar şema üretemez.
- Güvenlik: MCP sunucusuna ağ erişimini Kubernetes NetworkPolicy ile yalnızca izinli istemcilerle (Claude Desktop, Copilot) sınırlandırın.
3.2 MCP Güvenlik
🚨 Kritik Güvenlik Kuralı
Credential Passthrough Yasaktır. MCP sunucu, istemciden alınan token'ları başka servislere ASLA iletmemelidir. Her servis için ayrı, scope-limited credential kullanılmalıdır.
# OAuth 2.0 ile MCP güvenlik implementasyonu
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
security = HTTPBearer()
async def verify_mcp_token(
credentials: HTTPAuthorizationCredentials = Depends(security)
) -> dict:
"""MCP istek token doğrulama"""
token = credentials.credentials
try:
payload = jwt.decode(
token,
settings.JWT_PUBLIC_KEY,
algorithms=["RS256"],
audience="komtas-mcp-server"
)
# Scope kontrolü
required_scopes = ["mcp:read", "contracts:read"]
token_scopes = payload.get("scope", "").split()
if not all(s in token_scopes for s in required_scopes):
raise HTTPException(403, "Yetersiz izin")
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(401, "Token süresi dolmuş")
except jwt.InvalidTokenError:
raise HTTPException(401, "Geçersiz token")
# MCP route'larına middleware ekle
@app.middleware("http")
async def audit_mcp_calls(request, call_next):
"""Tüm MCP çağrılarını denetim günlüğüne kaydet"""
user = request.state.user if hasattr(request.state, "user") else "anonymous"
await audit_log.record(
action="mcp_call",
path=request.url.path,
user=user,
ip=request.client.host,
timestamp=datetime.utcnow()
)
response = await call_next(request)
return response
📌 Kod Notları
- Bearer token doğrulama: Her MCP çağrısında HTTP Authorization başlığındaki JWT token doğrulanmalıdır. FastAPI'nin
Depends()mekanizması bunu tüm endpoint'lere otomatik uygular. - JWK Set (JWKS): Token imzasını doğrulamak için kullanılan açık anahtarların JSON listesidir. Sağlayıcının JWKS URL'ini önbelleğe alın (TTL: 1 saat); her istekte çekmek gecikmeye neden olur.
- Scope kontrolü: Token kapsamı (
scope) kullanıcının hangi araçları çağırabileceğini belirler. MCP sunucusunda her araç için gerekli scope tanımlanmalıdır. - Token yenileme: JWT süresi dolduğunda istemci refresh token ile yeni token almalıdır. MCP istemcisinin bu akışı desteklediğinden emin olun.
3.3 Entegrasyon Senaryoları
n8n MCP Entegrasyonu
# n8n'de MCP araçlarını kullanma
# n8n workflow JSON konfigürasyonu (AI Agent Node)
{
"nodes": [{
"name": "AI Agent",
"type": "n8n-nodes-langchain.agent",
"parameters": {
"agent": "toolsAgent",
"promptType": "define",
"text": "={{ $json.user_query }}",
"options": {
"systemMessage": "Sen Komtaş asistanısın. MCP araçlarını kullanarak müşteri sorularını yanıtla."
}
}
}, {
"name": "MCP Client",
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"parameters": {
"serverUrl": "http://komtas-mcp:8080/sse",
"authentication": "bearerToken",
"credentials": "komtas_mcp_creds"
}
}]
}
Dataiku Analytics MCP
# Dataiku'dan MCP sunucusu olarak yayınlama
# dataiku/mcp_server.py
from mcp.server.fastmcp import FastMCP
import dataiku
mcp = FastMCP("Dataiku Analytics MCP")
@mcp.tool()
async def run_recipe(recipe_name: str, params: dict = {}) -> dict:
"""Dataiku recipe'sini çalıştır"""
client = dataiku.api_client()
project = client.get_project("KOMTAS_COPILOT")
recipe = project.get_recipe(recipe_name)
result = recipe.run(params)
return {"status": result.status, "outputs": result.outputs}
@mcp.tool()
async def query_dataset(dataset_name: str, query: str, limit: int = 1000) -> list:
"""Dataiku dataset'inde SQL sorgusu çalıştır"""
ds = dataiku.Dataset(dataset_name)
df = ds.get_dataframe(filter=query, limit=limit)
return df.to_dict('records')
📌 Kod Notları
- Dataiku MCP entegrasyonu: Dataiku recipe'lerini ve dataset'lerini MCP araçları olarak yayınlamak, Claude ve diğer MCP istemcilerinin Dataiku'ya doğrudan doğal dil komutuyla erişmesini sağlar.
- run_recipe(): Dataiku'nun proje tabanlı pipeline yönetimini API üzerinden tetikler. Uzun süren recipe'ler için sonucu beklemek yerine polling veya webhook tabanlı tamamlanma bildirimi kullanın.
- get_dataframe(filter, limit): Büyük dataset'lerde
limitparametresi kritiktir. Limitsiz çekme, bellek sorunlarına ve uzun yanıt sürelerine yol açar. MCP aracında sensible default tanımlayın.
📘 Geliştirici Referansı
Bu bölümün teknik API detayları için Claude API Geliştirici Referansı'na bakın. İlgili alt bölümler: MCP, Tool Use.