← Blog'a Dön

Model Context Protocol (MCP)

Mikail Karadeniz tarafından yazılmıştır.

Bültenimize Abone Olun

Gelişmelerden haberdar olmak için e-posta adresinizi giriniz.

MCP'ye Giriş

MCP nedir ve son dönemde neden her yerde karşımıza çıkıyor? Gelin birlikte inceleyelim. Önce MCP'yi nasıl kullanacağımızı öğrenelim, sonra geliştirme aşamasına geçelim. Bu süreçte bir MCP Server ve Client oluşturup, bunları kendi uygulamamızda nasıl kullanacağımızı göreceğiz.

MCP, yapay zekaların araçlara kolayca erişmesini sağlayan, API benzeri fakat iletişim için JSON-RPC protokolünü kullanan bir protokoldür. Bu protokol sayesinde uygulamalar yapay zekalar tarafından kolayca kullanılabilir hale getirilir ve standartlaştırılır.

Figma ve Cursor Örneği

Örneğin, Figma'da bir tasarım yaptığımızı düşünelim. Bu tasarımın Cursor tarafından anlaşılabilir olmasını istiyoruz. Bunun için Figma, bir MCP Server geliştirmiş. Bu MCP server içerisinde, basitçe açıklamak gerekirse, arayüzü algılamak için gerekli araçlar (fonksiyonlar) tanımlanmış. Bu tanımlamalar MCP protokolü kullanılarak yapılmış. Cursor'a MCP server olarak Figma'yı tanımladıktan sonra (bunun için bir JSON dosyasını Cursor'a eklemeniz gerekiyor), Cursor'a Figma tasarımının konumunu verip "bu tasarımı HTML ve CSS'e dönüştür" dediğinizde, Cursor bunu yapabilir hale gelecektir. Ayrıntıya daha sonra gireceğim şimdilik olayı anlamanız için bu açıklama yeterli olacaktır. Gördüğünüz gibi, bu yapay zekanın yeteneklerini artırmak için oldukça kolay bir yöntem. Geleneksel yöntemle, Figma API'sine erişip her bir fonksiyonu ayrı ayrı araca dönüştürmeniz ve Cursor içinde kullanmak için ekstra çaba harcamanız gerekirdi. Üstelik entegre etmek istediğiniz her araç için (Figma, Slack, Discord vb.) bu süreci tekrar tekrar yaşamanız gerekecekti.

Claude MCP Entegrasyonu

Eğer Claude'a doğrudan gidip "hava kaç derece" diye sorarsanız size cevap veremeyecektir, çünkü internete erişimi yoktur. Size sadece basit bir yanıt verecektir. (Şimdiden uyarayım, Washington DC'nin hava durumunu sormamın nedeni, kuracağımız MCP'nin ABD hava durumu verilerine sahip olması. 🤭)

Gelin birlikte bir MCP indirelim ve Claude'a hava durumu sorgulama yeteneği verelim.

Python MCP Server'ı Kurulumu

Anthropic tarafından oluşturulan quickstart-resources deposunu bilgisayarınıza klonlayın. Bunun içinde weather MCP server'ı bulunuyor. Python ve typescript dillerinde yazılmış 2 örnek var. Biz Python olanı kullanacağız. Bir terminal açın ve aşağıdaki komutları çalıştırın. Bilgisayarınızda Python ve pip kurulu olduğunu varsayıyorum.

Proje boyunca kullanacağımız kodların tamamını buradan takip edebilirsiniz.

Not: Bulduğunuz her MCP server kodunu bilgisayarınızda çalıştırmayın — güvenlik riski oluşturabilir!
mkdir mcp-servers
cd mcp-servers
git clone https://github.com/modelcontextprotocol/quickstart-resources.git
cd quickstart-resources
cd weather-server-python
pip install uv

Buraya kadar olan kısımda öncelikle bir mcp-servers adında bir klasör oluşturduk. Hangi klasörde bulunuyorsanız orda oluşturacaktır. cd ile mcp-servers klasörüne giriş yaptık ve repoyu klonladık. Ardından klonlamış olduğumuz klasöre ve çalışacağımız klasöre giriş yaptık. Bu proje hızlı ve modern bir Python paket yükleyicisi olan uv kullanıyor. O sebeple uv paketini pip ile kurduk. Şimdi uv kullanarak projenin çalışabilmesi için gerekli paketleri kuralım ve bir env oluşturalım.

uv sync

Çalıştırmadan önce programı incelemek isterseniz 👇 Kodu şimdilik önemsemeyin sonrasında sıfırdan bir server da yazacağız.

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP

# Initialize FastMCP server
mcp = FastMCP("weather")

# Constants
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"

async def make_nws_request(url: str) -> dict[str, Any] | None:
    """Make a request to the NWS API with proper error handling."""
    headers = {
        "User-Agent": USER_AGENT,
        "Accept": "application/geo+json"
    }
    async with httpx.AsyncClient() as client:
        try:
            response = await client.get(url, headers=headers, timeout=30.0)
            response.raise_for_status()
            return response.json()
        except Exception:
            return None

def format_alert(feature: dict) -> str:
    """Format an alert feature into a readable string."""
    props = feature["properties"]
    return f"""
Event: {props.get('event', 'Unknown')}
Area: {props.get('areaDesc', 'Unknown')}
Severity: {props.get('severity', 'Unknown')}
Description: {props.get('description', 'No description available')}
Instructions: {props.get('instruction', 'No specific instructions provided')}
"""

@mcp.tool()
async def get_alerts(state: str) -> str:
    """Get weather alerts for a US state.

    Args:
        state: Two-letter US state code (e.g. CA, NY)
    """
    url = f"{NWS_API_BASE}/alerts/active/area/{state}"
    data = await make_nws_request(url)

    if not data or "features" not in data:
        return "Unable to fetch alerts or no alerts found."

    if not data["features"]:
        return "No active alerts for this state."

    alerts = [format_alert(feature) for feature in data["features"]]
    return "\n---\n".join(alerts)

@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """Get weather forecast for a location.

    Args:
        latitude: Latitude of the location
        longitude: Longitude of the location
    """
    # First get the forecast grid endpoint
    points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
    points_data = await make_nws_request(points_url)

    if not points_data:
        return "Unable to fetch forecast data for this location."

    # Get the forecast URL from the points response
    forecast_url = points_data["properties"]["forecast"]
    forecast_data = await make_nws_request(forecast_url)

    if not forecast_data:
        return "Unable to fetch detailed forecast."

    # Format the periods into a readable forecast
    periods = forecast_data["properties"]["periods"]
    forecasts = []
    for period in periods[:5]:  # Only show next 5 periods
        forecast = f"""
{period['name']}:
Temperature: {period['temperature']}°{period['temperatureUnit']}
Wind: {period['windSpeed']} {period['windDirection']}
Forecast: {period['detailedForecast']}
"""
        forecasts.append(forecast)

    return "\n---\n".join(forecasts)

if __name__ == "__main__":
    # Initialize and run the server
    mcp.run(transport='stdio')

Ardından programı çalıştıralım.

uv run weather.py

Herhangi bir hata almamışsanız her şey yolunda demektir.

Claude için Config Dosyası Hazırlama ve Uygulama

Şimdi Claude için bir config dosyası oluşturalım (veya düzenleyin) ve server'ımızın yolunu Claude'a gösterelim. Bu arada 2 farklı MCP türü vardır. Bunlardan biri stdio olan (standart input ve output) diğeri SSE yani uzaktan çalıştırmayı mümkün kılan protokoldür. Kodu incelediyseniz bizim stdio seçimi yaptığımızı görmüş olmalısınız.

mcp.run(transport='stdio')

Bu sebeple MCP kullanımı için programımızın dosya sistemindeki yerini Claude'a göstermeliyiz. args kısmında yer alan path weather.py dosyasının bulunduğu yerin tam olarak adresi olmalıdır. Ona dikkat edin. Aşağıdaki kodu dosya yolunu düzenleyerek claude config dosyasına ekleyeceğiz.

{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "C:\\\\ABSOLUTE\\\\PATH\\\\TO\\\\PARENT\\\\FOLDER\\\\weather",
        "run",
        "weather.py"
      ]
    }
  }
}

Eğer bilgisayarınızda Visual Studio Code kuruluysa, config dosyasını aşağıdaki komutla kolayca açabilirsiniz.

code $env:AppData\Claude\claude_desktop_config.json

Yukarıdaki komutu bir terminal'e yapıştırmanız yeterli olacaktır (Windows için).

Açılan pencereye daha önce hazırladığımız JSON kod parçasını yapıştırın kaydedin ve dosyayı kapatın. Bu şekilde Claude'a MCP server'ınızı göstermiş oldunuz. Eğer Claude açık ise sol üst köşedeki menüden exit diyin ve yeniden açın. Aşağıdaki gibi bir icon çıkmışsa MCP Serverınız ile Claude haberleşiyor demektir Tebrikler 🥳.

Claude MCP Integration Success Icon

Şimdi hava durumunu öğrenebiliriz. Hava durumunu sorguladığımızda aşağıdaki gibi bize izin soracaktır. İzne evet dediğinizde sizin için sorguyu yapacaktır.

Claude Requesting Permission for MCP Tool

Sorguyu yaptıktan sonra aşağıdaki gibi sonuçlandırılır.

Claude Weather Forecast Result

Adım Adım MCP

Peki bu süreçte neler oluyor?

  1. Biz bir prompt yazıyoruz: "Washington DC'de hava nasıl?"
  2. Claude, yazdığımız prompt içinde MCP Server tanımına uyan anlamı yakalıyor. (Fonksiyonun hemen altında yazılan açıklamayı görebilirsiniz.)
    """Get weather forecast for a location.
    
        Args:
            latitude: Latitude of the location
            longitude: Longitude of the location
        """
  3. Server'a bağlanılmadan önce MCP protokolü gereği kullanıcıdan izin isteniyor. (Her zaman olmak zorunda değil.)
  4. MCP protokolüne göre server'a bağlanıldıktan sonra server'ın özellikleri iletiliyor - mevcut toollar ve tanımları gibi. Bu tanımlar arasından en uygun araç (tool — fonksiyon) seçilip JSON-RPC haberleşme yöntemiyle çağırılıyor. Çağırma sırasında gerekli parametreleri model otomatik olarak ekliyor (latitude, longitude)
  5. MCP Server, çağırılan tool'u çalıştırıp sonucu döndürüyor.
  6. Döndürülen sonuç, model'in context'ine ekleniyor.
  7. Model, context'i yorumlayıp derleyerek bize sonucu sunuyor.

Buraya kadar MCP'nin genel yapısını anlamış olduk. Gördüğünüz gibi MCP tamamen açık bir protokoldür ve dilediğiniz şekilde kendi serverınızı oluşturabilirsiniz. Şimdi bir MCP server'ın temel özelliklerini ve nasıl yazılacağını daha detaylı inceleyelim.

Derinlemesine MCP

MCP Architecture Diagram

MCP'nin temel bileşenleri şu şekildedir: Ekranın sol tarafında client ile iletişim kuran hostlar bulunur. Bu hostlar Claude Desktop, Cursor veya herhangi bir AI aracı olabilir (kendi geliştirdiklerimiz dahil). Tek şart, MCP'nin uygulamaya entegre edilebilmesi ve protokole uygun olmasıdır. Hostların sağında MCP protokolüne erişimi sağlayan clientlar, bunların da sağında clientların haberleştiği serverlar bulunur. Her server, farklı programları ve işlevleri (veritabanları, PDF'ler ve diğer işlevsel özellikler) barındırır. Bir client yalnızca tek bir server ile haberleşebilir. Bir host'un birden fazla server ile haberleşebilmesi için her server için ayrı bir client kullanması gerekir.

Temel Bileşenler:

MCP Haberleşme Akışı

MCP Communication Flow Diagram

Başka Bir Örnek Senaryo: Türkiye'deki Hava Durumu

MCP Transport

MCP Server Giriş

MCP protokolünde server'ın üç temel konsepti bulunmaktadır:

  1. Resources: Dosya benzeri verilerdir. Bunlar client'lardan gelen API yanıtları, yüklenen PDF'ler veya vektör veritabanı gibi kaynaklardır. Bu kaynaklar server üzerinden kullanıma sunulabilir.
  2. Tools: Model tarafından çağrılabilir şekilde tasarlanmış fonksiyonlardır. Veri getirme, arama, mesaj gönderme, veritabanı güncelleme gibi işlemleri gerçekleştirir.
  3. Prompts: Model için önceden hazırlanmış prompt şablonlarıdır. Soru-cevap dokümanı, konuşma özeti, JSON formatında veri gibi çıktılar üretir.

Bu konseptler MCP SDK tarafından sağlanan dekoratörler ile uygulanır.

@mcp.tool()
@mcp.resource()
@mcp.prompt()

Bu konseptler sayesinde hem yerel ortamda (stdio) hem de sunucu olarak (HTTP, SSE (Server Sent Events) ) internet üzerinde hizmet verilebilir.

Şimdi daha önce çalıştırdığımız server'ı daha ayrıntılı inceleyelim.

Weather MCP açıklaması

Bu kod, MCP (Model Context Protocol) Python SDK kullanılarak oluşturulmuş bir hava durumu bilgi sunucusudur. Sunucu, ABD Ulusal Hava Servisi (NWS) API'sini kullanarak hava durumu verileri sağlar ve iki ana işlev sunar:

  1. Belirli bir ABD eyaleti için hava durumu uyarılarını getirme
  2. Belirtilen koordinatlar (enlem/boylam) için hava durumu tahminini getirme

Kod Yapısı

FastMCP Sunucusu

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP

# Initialize FastMCP server
mcp = FastMCP("weather")

Kod, FastMCP sınıfını kullanarak "weather" adlı bir MCP sunucusu oluşturarak başlar. FastMCP, MCP Python SDK'sının bir parçasıdır ve araçlar, kaynaklar ve komutları kolayca tanımlamak için yüksek seviyeli bir API sağlar.

Yardımcı Fonksiyonlar

async def make_nws_request(url: str) -> dict[str, Any] | None:
    """NWS API'sine doğru hata yönetimi ile istek yapar."""
    # ... (fonksiyon içeriği)

def format_alert(feature: dict) -> str:
    """Bir uyarı özelliğini okunabilir bir dizeye biçimlendirir."""
    # ... (fonksiyon içeriği)

Bu yardımcı fonksiyonlar:

MCP Araçları

@mcp.tool()
async def get_alerts(state: str) -> str:
    """Bir ABD eyaleti için hava durumu uyarılarını alır."""
    # ... (fonksiyon içeriği)

@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """Bir konum için hava durumu tahmini alır."""
    # ... (fonksiyon içeriği)

@mcp.tool() dekoratörü, bu fonksiyonları MCP araçları olarak kaydeder. MCP araçları:

Ana Uygulama Çalıştırma

if __name__ == "__main__":
    # Sunucuyu başlat ve çalıştır
    mcp.run(transport='stdio')

Bu kısım, sunucuyu 'stdio' (standart giriş/çıkış) transport mekanizmasını kullanarak başlatır. Bu, sunucunun Claude Desktop gibi MCP istemcileriyle kolayca entegre olabileceği anlamına gelir.

MCP Araçlarının Detayları

get_alerts

Bu araç, belirli bir ABD eyaleti için aktif hava durumu uyarılarını getirir:

get_forecast

Bu araç, belirli bir konum için hava durumu tahminini getirir:

Özet

Bu MCP sunucusu, MCP Python SDK kullanarak başarılı bir şekilde dış bir API ile entegre olmuş ve LLM'lerin hava durumu verilerine erişimini kolaylaştırmıştır. Kodun yapısı, MCP protokolünün temel konseptlerini (sunucu, araçlar) göstermekte ve asenkron operasyonlar kullanarak etkin bir şekilde çalışmaktadır.

Resource Kullanımı

Elimizdeki kodda tool kullanımı için güzel bir örnek var, ancak henüz resource kullanımını görmedik. Gelin bu koda bir resource ekleyelim. Mevcut kod sadece ABD'deki şehirlerin hava durumunu iletebiliyor. Bu eksiği gidermek için Türkiye'deki şehirlerin hava durumunu içeren bir JSON dosyasını Claude'a resource olarak tanıtalım ve hava durumunu öğrenelim.

Aşağıdaki adreste gerekli dosyayı bulabilirsiniz.

https://github.com/eemmikail/tr_today_weather/blob/main/tr_today_weather.json

Bu dosyayı kodun bulunduğu dizine tr_today_weather.json adında kaydedin.

Her şey yolunda gittiğinde aşağıdaki sonuçla karşılaşacaksınız. Şimdi gerekli fonksiyonları ekleyelim. Chat'e doğrudan sürükleyip bırakmak yok - unutmayın, MCP resource'u öğrenmeye çalışıyoruz 😀

Turkish Weather Resource in Claude

Şimdi koda aşağıdaki satırları ekleyelim.

@mcp.resource("resource://tr_cities_weather")
def tr_cities_weather() -> str:
    """Turkish cities current weather data in JSON format.
    Includes city name, temperature, weather description, wind speed, humidity, etc.

    Returns:
        JSON data containing current weather for Turkish cities
    """
    try:
        import json

        # JSON dosyasını oku (NDJSON formatında)
        cities_data = []
        with open("tr_today_weather.json", "r", encoding="utf-8") as f:
            for line in f:
                if line.strip():
                    cities_data.append(json.loads(line))

        # Tüm şehir verilerini bir liste olarak döndür
        return json.dumps(cities_data, ensure_ascii=False)
    except Exception as e:
        return f"Error processing weather data: {str(e)}"

tr_cities_weather Fonksiyonu - Teknik Açıklama

@mcp.resource("resource://tr_cities_weather")
def tr_cities_weather() -> str:"
try:
    import json

# JSON dosyasını oku (NDJSON formatında)
cities_data = []
with open("tr_today_weather.json", "r", encoding="utf-8") as f:
    for line in f:
        if line.strip():
            cities_data.append(json.loads(line))

# Tüm şehir verilerini bir liste olarak döndür
return json.dumps(cities_data, ensure_ascii=False)

except Exception as e:
    return f"Error processing weather data: {str(e)}"

Veri Yapısı

Döndürülen JSON verisi şu özelliklere sahip objelerin bir listesidir:

Evet şimdi bir resource fonksiyonumuz hazır. Claude'a MCP Server'ın bağlantısını daha önce gerçekleştirmiştik zaten. Yapmamız gereken Claude'a sol üst köşede bulunan ayar menüsünden settings > exit deyip Claude'u yeniden başlatmak.

Claude Settings Menu - Exit

Açtığınızda işaretlediğim yerde de göründüğü gibi yeni bir buton gelecek. Bu butona tıklayın yeni bir menü açılacak.

Claude MCP Integration Button and Menu

choose an integration diyip resource://tr_cities_weather'ı seçin.

Ve Claude'a Konyadan bir şehrin hava durumunu sorun.

Claude using Turkish Weather Resource

Gördüğünüz gibi, harici bir dosyayı MCP aracılığıyla dil modeline başarıyla ilettik. Böylece resource implementasyonunu tamamlamış olduk.

Prompt Kullanımı

Şimdi de prompt özelliğini ekleyelim ve ufaktan client tarafına geçelim.

Aşağıdaki satırları kodun en altına yerleştirin. Dosyayı kaydetmeyi unutmayın! 😄

@mcp.prompt()
def weather_prompt(city: str) -> str:
    """Get weather information for a specific city.

    Args:
        city: Name of the city to get weather information for
    """
    return f"Bu şehirde hava nasıl? Şehir: {city}"

@mcp.prompt() dekoratör'ünü kullanarak bir prompt eklemiş olduk. Şimdi Claude da karşılığına bakalım.

Claude'dan tekrar exit yapın ve tekrar açın. İşaretli yere tıklayın.

Claude MCP Integration Menu Showing Prompt

Listeye weather_prompt'un eklendiğini göreceksiniz. Ona tıklayın sizden bir şehir isteyecek.

Claude Prompt Input Request

İstediğiniz şehri girin. Ben Washington DC girdim.

Claude Prompt Input Example

Ve sonuç olarak Claude context'ine prompt eklenmiş olacak.

Claude Context with MCP Prompt

Claude'a prompt'u işleme al derseniz. Size o prompt'u işletip geri dönüş yapacaktır.

Claude Processing MCP Prompt and Result

İşaretli yerde gördüğünüz gibi diğer araçları da kullanmaya devam ediyor.

Server Özet

Böylece Server kısmındaki tüm konuları ele almış olduk.

Server'ın nasıl oluşturulacağını,

içine tool, resource ve prompt'ların nasıl entegre edileceğini

ve tüm bunların Claude'a nasıl ekleneceğini öğrendik.

MCP Client

MCP Client nedir?

Uygulamanızda (host) MCP server'ı kullanabilmek için her bir server'a karşılık bir client oluşturmanız gerekiyor. Bu, protokole uygun haberleşmeyi sağlar. Client aracılığıyla server tarafındaki tool, resource ve prompt araçlarına erişebilir, bunlardan gelen yanıtları uygulamanızda kullanabilirsiniz.

Şimdi weather.py kodumuza bağlanabilmek için weather_client.py dosyamızı oluşturalım. Aynı klasöre oluşturabilirsiniz. Oluşturduktan sonra aşağıdaki kodu kopyalayın ve içerisine yapıştırın.

import asyncio
from typing import Optional
from contextlib import AsyncExitStack
import os
from dotenv import load_dotenv
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

load_dotenv()

server_params = StdioServerParameters(
    command="uv",  # Executable
    args=["run", os.getenv("SERVER_PATH")],  # Optional command line arguments
    env=None,  # Optional environment variables
)

class MCPClientWrapper:
    def __init__(self):
        self.session: Optional[ClientSession] = None
        self.exit_stack = AsyncExitStack()

    async def connect_to_server(self):
        """
        Connect to the MCP server.
        """

        stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
        self.stdio, self.write = stdio_transport
        self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))

        await self.session.initialize()

        print("Session initialized")

    async def list_tools(self):
        """
        List all tools available on the server.
        """
        response = await self.session.list_tools()
        return response.tools

    async def list_resources(self):
        """
        List all resources available on the server.
        """
        response = await self.session.list_resources()
        return response.resources

    async def list_prompts(self):
        """
        List all prompts available on the server.
        """
        response = await self.session.list_prompts()
        return response.prompts

    async def invoke_tool(self, tool_name: str, **kwargs):
        """
        Invoke a tool with the given name and arguments.
        """
        response = await self.session.call_tool(tool_name, kwargs)
        return response

    async def cleanup(self):
        """cleanup resources"""
        await self.exit_stack.aclose()

async def initialize_client():
    client = MCPClientWrapper()
    await client.connect_to_server()
    return client

async def main():
    client = await initialize_client()
    try:
        await client.connect_to_server()
        tools = await client.list_tools()
        print(tools)
        resources = await client.list_resources()
        print(resources)
        prompts = await client.list_prompts()
        print(prompts)
        if tools:
            print("Tools available")
            print("Invoking tool")
            result = await client.invoke_tool("get_forecast", latitude=float(38.9072), longitude=float(-77.0369))
            print(result)
        else:
            print("No tools available")
    finally:
        await client.cleanup()

if __name__ == "__main__":
    asyncio.run(main())
    # Add a small delay before exiting to allow cleanup
    import time
    time.sleep(0.5)

Kodu açıklayalım.

MCP İstemci Kodu Dökümanı

Bu döküman, verilen Python kodunun adım adım Türkçe açıklamasını içermektedir. Kod, bir MCP (Modular Command Protocol) istemcisi kullanarak bir sunucuya bağlanmayı, sunucudaki araçları, kaynakları ve prompt'ları listelemeyi amaçlamaktadır. asyncio kütüphanesi ile asenkron işlemler yönetilir ve mcp modülünden çeşitli sınıflar ile fonksiyonlar kullanılır.


1. Gerekli Modüllerin İçe Aktarılması

import asyncio
from typing import Optional
from contextlib import AsyncExitStack
import os
from dotenv import load_dotenv
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


2. Ortam Değişkenlerinin Yüklenmesi

load_dotenv()


3. Sunucu Parametrelerinin Tanımlanması

server_params = StdioServerParameters(
    command="uv",  # Executable
    args=["run", os.getenv("SERVER_PATH")],  # Optional command line arguments
    env=None,  # Optional environment variables
)


4. MCPClientWrapper Sınıfının Tanımlanması

class MCPClientWrapper:
    def __init__(self):
        self.session: Optional[ClientSession] = None
        self.exit_stack = AsyncExitStack()


5. Sunucuya Bağlanma Metodu

    async def connect_to_server(self):
        """
        Connect to the MCP server.
        """
        stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
        self.stdio, self.write = stdio_transport
        self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))

        await self.session.initialize()

        print("Session initialized")


6. Araçları Listeleme Metodu

    async def list_tools(self):
        """
        List all tools available on the server.
        """
        response = await self.session.list_tools()
        return response.tools


7. Kaynakları Listeleme Metodu

    async def list_resources(self):
        """
        List all resources available on the server.
        """
        response = await self.session.list_resources()
        return response.resources


8. Prompt'ları Listeleme Metodu

    async def list_prompts(self):
        """
        List all prompts available on the server.
        """
        response = await self.session.list_prompts()
        return response.prompts


9. Aracı Çağırma Metodu

    async def invoke_tool(self, tool_name: str, **kwargs):
        """
        Invoke a tool with the given name and arguments.
        """
        response = await self.session.call_tool(tool_name, kwargs)
        return response


10. Temizleme Metodu

    async def cleanup(self):
        """cleanup resources"""
        await self.exit_stack.aclose()


11. İstemciyi Başlatma Fonksiyonu

async def initialize_client():
    client = MCPClientWrapper()
    await client.connect_to_server()
    return client


12. Ana Fonksiyon

async def main():
    client = await initialize_client()
    try:
        await client.connect_to_server()
        tools = await client.list_tools()
        print(tools)
        resources = await client.list_resources()
        print(resources)
        prompts = await client.list_prompts()
        print(prompts)
        if tools:
            print("Tools available")
            print("Invoking tool")
            result = await client.invoke_tool("get_forecast", latitude=float(38.9072), longitude=float(-77.0369))
            print(result)
        else:
            print("No tools available")
    finally:
        await client.cleanup()


13. Programın Çalıştırılması

if __name__ == "__main__":
    asyncio.run(main())
    # Add a small delay before exiting to allow cleanup
    import time
    time.sleep(0.5)

Bir .env dosyası oluşturun ve içine weather.py'ın tam dosya yolunu yapıştırın.

SERVER_PATH="C:\\ABSOLUTE\\PATH\\TO\\PARENT\\FOLDER\\weather\\weather.py"

Aşağıdaki komut ile programı çalıştırabilirsiniz.

uv run weather_client.py

Özet

Bu kod, MCP sunucusuna bağlanmak, araçları, kaynakları ve prompt'ları listelemek ve bir aracı çağırmak için bir istemci oluşturur. Asenkron programlama ile işlemler eşzamanlı yönetilir ve kaynaklar temizlenir. Kod, modüler ve genişletilebilir bir yapıya sahiptir.

Sonuç

Eveet dostlar. Bir yazımızın daha sonuna geldik. Buraya kadar okuduysanız tebrikler 🥳

Bu yazımızda MCP'i kendi uygulamalarımıza nasıl entegre edebileceğimize dair her şeyi anlattığımı düşünüyorum bir eksik olduğunu düşünüyorsanız sosyal medya hesaplarımdan bana ulaşabilirsiniz. Çok kısa sürede eksikleri tamamlayacağıma emin olabilirsiniz. Sevgilerimle Mikail Karadeniz.