Bu rehber bir MCP sunucusunu sıfırdan ayağa kaldırıp aide.tr taramasında proto-mcp-server kontrolünü PASS hale getirmenizi sağlar. Konseptsel açıklama yerine çalışan kod vereceğiz: minimum 80 satır Python, bir Caddy/Nginx parçası, bir manifesto JSON'u.
Bağlam: AIDE bu kontrolde tam olarak neye bakıyor?
proto-mcp-server check'i şu üçlüyü doğrular:
https://<domain>/.well-known/mcp.jsonHTTP 200 dönüyor mu?- JSON şeması içinde
transport,endpoint,authalanları doğru tipte mi? endpointURL'sine bir JSON-RPC 2.0initializeisteği gönderildiğinde sunucu spec'e uygun cevap dönüyor mu?
Üçü de geçtiğinde kontrol PASS — biri eksikse WARNING ya da FAIL gelir. Bu yüzden bu rehber tam olarak bu üç adımı sırayla çözer.
Adım 1 — .well-known/mcp.json yayınlama
Manifesto, ajanın sunucunuzu nasıl bulacağını anlatır. AIDE bu dosyayı en başta okur; URL'i ve auth yöntemini buradan öğrenir.
{
"mcp_version": "2025-03-26",
"transport": "streamable_http",
"endpoint": "https://mcp.aide.tr/v1/rpc",
"name": "AIDE Scan",
"description": "AIDE tarama motoru — URL gönder, AI hazırlık skoru al.",
"auth": {
"type": "bearer",
"token_url": "https://aide.tr/account/api-keys",
"scopes": ["scan:create", "scan:read"]
},
"capabilities": {
"tools": true,
"resources": false,
"prompts": false
}
}
transport: "streamable_http" 2025-Q2 spec'inin önerdiği akış; eski stdio veya sse transport'ları tarayıcı/cloud ajanları tarafından her zaman desteklenmiyor. endpoint kesinlikle HTTPS olmalı — AIDE HTTP cevabı reddediyor.
Adım 2 — FastMCP ile sunucu
Python tarafında FastMCP en hızlı yol. Decorator ile araç tanımlıyorsunuz, FastMCP JSON-RPC 2.0 wire protokolünü, capability negotiation'ı ve hata serileştirmeyi otomatik halledebiliyor.
# mcp_server.py
import os
from fastmcp import FastMCP, Context
from pydantic import BaseModel, Field
import httpx
mcp = FastMCP("AIDE Scan")
class ScanInput(BaseModel):
url: str = Field(..., description="Taranacak site URL'i")
profile: str = Field(default="ai_ready", description="Tarama profili")
@mcp.tool()
async def scan_site(payload: ScanInput, ctx: Context) -> dict:
"""Bir siteyi tarat ve skorunu döndür."""
api_key = ctx.request_context.headers.get("authorization", "").removeprefix("Bearer ")
if not api_key:
raise ValueError("AIDE API anahtarı gerekiyor")
async with httpx.AsyncClient(timeout=60) as client:
resp = await client.post(
"https://api.aide.tr/v1/scans",
json={"url": payload.url, "profile": payload.profile},
headers={"Authorization": f"Bearer {api_key}"},
)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
mcp.run(transport="streamable-http", host="0.0.0.0", port=8001, path="/v1/rpc")
Bu sunucu tek bir araç (scan_site) export eder. Claude Desktop bağlandığında bu aracı görüp kullanıcı niyetine göre çağırabilir.
Adım 3 — Reverse proxy + TLS
MCP istemcileri (Claude Desktop, mcp-inspector, OpenAI sandbox) HTTP/2 + TLS 1.3 bekliyor. Caddy ile en basit yapı:
mcp.aide.tr {
encode gzip zstd
# MCP streamable_http transport SSE benzeri akış kullanıyor —
# proxy buffering kapalı olmalı, yoksa cevaplar gecikiyor.
@rpc path /v1/rpc*
reverse_proxy @rpc localhost:8001 {
flush_interval -1
transport http {
read_timeout 30m
}
}
}
flush_interval -1 parametresi proxy'nin buffer'lamadan body'yi akıtmasını söyler. Bu yapılmazsa AIDE'nin testi 30 saniye timeout'a düşer ve check WARNING olur.
Adım 4 — initialize testi
Sunucu ayağa kalktıktan sonra AIDE'nin yapacağı şeyi yapın:
curl -X POST https://mcp.aide.tr/v1/rpc \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AIDE_API_KEY" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {},
"clientInfo": {"name": "smoke-test", "version": "1.0"}
}
}'
Beklenen cevap:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-03-26",
"capabilities": {"tools": {"listChanged": true}},
"serverInfo": {"name": "AIDE Scan", "version": "0.1.0"}
}
}
protocolVersion istediğinizden farklı dönerse client uyumsuz değil — sunucunuz desteklediği en yüksek sürümü dönmüş demektir. AIDE bunu PASS sayar.
Yaygın hatalar
| Hata | Belirti | Çözüm |
|---|---|---|
| well-known dosyası 200 yerine 404 | AIDE WARNING; "manifest bulunamadı" mesajı | public/.well-known/mcp.json Next.js'de değil, root'tan serve edin (Caddy handle_path veya Nginx location ile) |
| Bearer token istemiyorum dedim ama sunucu yine 401 atıyor | Authorization header zorunlu sanılıyor | auth: { "type": "none" } yazıp middleware'de unauthenticated path bırakın |
| Accept: text/event-stream olmadan 406 dönüyor | streamable_http transport SSE muhasebesi yapıyor | Client tarafına Accept: application/json, text/event-stream zorunlu eklenmeli — manifest'te belirtin |
| Cloudflare cache RPC cevaplarını cache'liyor | İkinci istek stale cevap dönüyor | Cache-Control: no-store header'ı sunucu cevabına ekleyin |
Production için
- Rate limit: RPC endpoint'i (özellikle pahalı tool çağrıları) per-API-key sınırlama gerek.
slowapiveyafastapi-limiterekleyin. - Tool granularity: Tek bir
scan_sitearacı yerinestart_scan+get_scan_resultayrı verirseniz ajan kontrol akışını paralelleştirebilir. - Capability negotiation: Yeni tool eklediğinizde
notifications/tools/list_changedevent'i gönderin — Claude Desktop araç listesini canlıda yeniler. - Observability: OpenTelemetry instrumentation ekleyin —
mcp.tool.invocationsmetriği üzerinden hangi aracın hangi sıklıkla çağrıldığını görürsünüz.
Doğrulama: AIDE taraması
Yukarıdaki üç adımı tamamladıktan sonra:
curl -X POST https://api.aide.tr/v1/scans \
-H 'Content-Type: application/json' \
-d '{"url":"https://siteniz.com","profile":"ai_ready"}'
proto-mcp-server check'i status: pass dönmeli. Hâlâ WARNING geliyorsa evidence alanına bakın — hangi alt-adımın eksik olduğunu yazıyor.
İlgili kaynaklar
- MCP Spec 2025-03-26
- FastMCP GitHub
- Claude Desktop MCP Setup
- AIDE check detayı:
/learn/mcp-server-nedir