0Pricing
AI Engineering Academy · Ders

İlk MCP Sunucunuzu Oluşturma

Kaynakları, araçları ve istemleri kullanıma sunan bir sunucu oluşturmak için Python MCP SDK'sını kullanın, ardından uçtan uca çalıştığını görmek için Claude Desktop'a bağlayın.

İlk MCP Sunucunuzu Oluşturma, CoddyKit'te ücretsiz bir AI Engineering Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, AI Engineering Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. AI Engineering Academy kursu toplamda 4 dersten oluşur.

MCP Sunucusu İçin Proje Kurulumu

Python'da bir MCP sunucusu oluşturmak için mcp SDK'si ve bir Python ortamı gerekir. Claude Desktop'ın veya herhangi bir MCP istemcisinin stdio üzerinden bağlanabileceği bir sunucu oluşturacaksınız. Paketi yükleyip sunucu dosyanızı oluşturarak başlayın.

# Create a project directory
# mkdir my_mcp_server && cd my_mcp_server

# Create a virtual environment
# python -m venv venv && source venv/bin/activate

# Install the MCP SDK
# pip install mcp httpx

# Project structure:
# my_mcp_server/
#   server.py          <- Your MCP server
#   requirements.txt
#   README.md

Sunucu Nesnesi Oluşturma

mcp paketinden içe aktarma yapın ve sunucunuzun adıyla bir Server örneği oluşturun. Ad, istemcilerin MCP sunucusu listesinde gösterilir; açıklayıcı bir ad seçin. Sunucu nesnesi, tüm araçlarınızı, kaynaklarınızı ve istemlerinizi kaydetmenin başlangıç noktasıdır.

# server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import asyncio
import httpx

# Create the server — name is shown in Claude Desktop
app = Server('weather-server')

# --- Tool registrations go here ---

# Entry point
if __name__ == '__main__':
    asyncio.run(stdio_server(app))

@app.list_tools() ile Araçları Kaydetme

@app.list_tools() dekoratörü, istemci istediğinde kullanılabilir araçların listesini döndüren bir işleyiciyi kaydeder. Her araç bir ad, açıklama ve parametrelerini açıklayan JSON Şeması olan bir inputSchema ile tanımlanır. İstemci bu listeyi LLM'e göndererek hangi araçları çağırabileceğini bildirir.

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name='get_weather',
            description='Get current weather for a city. Use when the user asks about weather in a specific location.',
            inputSchema={
                'type': 'object',
                'properties': {
                    'city': {
                        'type': 'string',
                        'description': 'City name, e.g. London or New York'
                    },
                    'units': {
                        'type': 'string',
                        'enum': ['metric', 'imperial'],
                        'description': 'Temperature units. Default is metric.'
                    }
                },
                'required': ['city']
            }
        ),
        types.Tool(
            name='list_cities',
            description='Return a list of major cities the user can query weather for.',
            inputSchema={'type': 'object', 'properties': {}, 'required': []}
        )
    ]

Araç Yürütmesini Uygulama

@app.call_tool() dekoratörü araçların yürütülmesini yönetir. İstemci bir aracı çağırdığında bu işleyici, araç adını ve bağımsız değişkenleri alır. Uygun mantığı yürütün ve sonuç dizesini içeren TextContent nesnelerinden oluşan bir liste döndürün.

@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
    if name == 'list_cities':
        cities = ['London', 'New York', 'Tokyo', 'Paris', 'Sydney']
        return [types.TextContent(type='text', text=', '.join(cities))]

    if name == 'get_weather':
        city = arguments['city']
        units = arguments.get('units', 'metric')
        unit_symbol = 'C' if units == 'metric' else 'F'

        # Call real weather API (stub here)
        async with httpx.AsyncClient() as client:
            # Replace with actual API call
            result = f'{city}: 18{chr(176)}{unit_symbol}, partly cloudy, humidity 65%'

        return [types.TextContent(type='text', text=result)]

    raise ValueError(f'Unknown tool: {name}')

Kaynakları Kullanıma Sunma

Kaynaklar, modelin okuyabileceği statik veya dinamik verilerdir; bunları dosyalar gibi düşünebilirsiniz. Kaynak URI'lerini tanımlayın ve bir kaynak okuyucu uygulayın. Kaynaklar, istemcide yapay zekânın başvurabileceği öğeler olarak görünür; yapılandırma, belgeler veya sık erişilen veri anlık görüntüleri için kullanışlıdır.

@app.list_resources()
async def list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri='weather://supported-cities',
            name='Supported Cities List',
            description='Complete list of cities available in this weather server.',
            mimeType='text/plain'
        )
    ]

@app.read_resource()
async def read_resource(uri: str) -> str:
    if uri == 'weather://supported-cities':
        cities = ['London', 'New York', 'Tokyo', 'Paris', 'Sydney', 'Dubai', 'Singapore']
        return '\n'.join(cities)
    raise ValueError(f'Unknown resource URI: {uri}')

İstem Şablonlarını Kaydetme

İstemler, istemcilerin kullanıcılara eğik çizgi komutları veya hızlı işlemler olarak sunduğu yeniden kullanılabilir ileti şablonlarıdır. Parametre kabul eder ve bir görüşmenin başlangıç bağlamını oluşturan ileti listesini döndürürler. İstemler, kullanıcıların tek bir komutla tetiklediği karmaşık talimatları kodlamak için oldukça kullanışlıdır.

@app.list_prompts()
async def list_prompts() -> list[types.Prompt]:
    return [
        types.Prompt(
            name='weather-report',
            description='Generate a formatted weather report for a city.',
            arguments=[
                types.PromptArgument(name='city', description='City name', required=True)
            ]
        )
    ]

@app.get_prompt()
async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
    if name == 'weather-report':
        city = arguments.get('city', 'London')
        return types.GetPromptResult(
            description=f'Weather report for {city}',
            messages=[
                types.PromptMessage(
                    role='user',
                    content=types.TextContent(
                        type='text',
                        text=f'Use the get_weather tool to look up {city} and give me a detailed weather report including what clothing I should wear.'
                    )
                )
            ]
        )
    raise ValueError(f'Unknown prompt: {name}')

Claude Desktop'a Bağlanma

MCP sunucunuzu Claude Desktop ile kullanmak için sunucuyu Claude Desktop yapılandırma dosyasına ekleyin. macOS üzerinde bu dosya ~/Library/Application Support/Claude/claude_desktop_config.json konumundadır. Sunucunuzu başlatacak komutu ve sunucunun ihtiyaç duyduğu ortam değişkenlerini belirtin.

# ~/Library/Application Support/Claude/claude_desktop_config.json
# Add this JSON configuration:

# {
#   "mcpServers": {
#     "weather-server": {
#       "command": "/path/to/venv/bin/python",
#       "args": ["/path/to/my_mcp_server/server.py"],
#       "env": {
#         "WEATHER_API_KEY": "your_api_key_here"
#       }
#     }
#   }
# }

# After saving, restart Claude Desktop.
# Your server's tools will appear in Claude's tool list.

MCP CLI ile Sunucunuzu Sınama

Claude Desktop'a bağlanmadan önce sunucunuzu MCP denetleyicisini veya CLI araçlarını kullanarak sınayın. mcp dev komutu sunucunuzu başlatır ve tarayıcı tabanlı bir denetleyici açar. Burada araçları el ile çağırabilir ve ham protokol iletilerini görebilirsiniz; bu da sorunları ayıklamayı kolaylaştırır.

# Install the MCP development tools
# pip install 'mcp[cli]'

# Start the inspector with your server
# mcp dev server.py

# The inspector opens at http://localhost:5173
# You can:
# - See all registered tools and their schemas
# - Call tools with custom arguments
# - Browse available resources
# - Test prompt templates
# - View the full JSON-RPC message exchange

MCP Sunucularında Hataları Yönetme

MCP sunucuları hatalı girdiler nedeniyle asla çökmemelidir. Tüm araç yürütme işlemlerini try/except içine alın ve özel durumları yükseltmek yerine hata iletilerini TextContent olarak döndürün. Yapılandırma sorunları veya eksik API anahtarları gibi kritik hataları başlangıçta günlüğe kaydedin ve sunucu ana döngüsüne girmeden önce özel durum yükseltin.

@app.call_tool()
async def call_tool_safe(name: str, arguments: dict) -> list[types.TextContent]:
    try:
        if name == 'get_weather':
            city = arguments.get('city')
            if not city:
                return [types.TextContent(type='text', text='Error: city argument is required.')]
            result = await fetch_weather(city, arguments.get('units', 'metric'))
            return [types.TextContent(type='text', text=result)]
        raise ValueError(f'Unknown tool: {name}')
    except httpx.TimeoutException:
        return [types.TextContent(type='text', text='Error: Weather API timed out. Try again.')]
    except Exception as e:
        return [types.TextContent(type='text', text=f'Error: {str(e)}')]

MCP Sunucuları için Günlük Kaydı

MCP sunucuları istemciyle stdio üzerinden iletişim kurduğundan, print ifadeleri protokolü bozar. Günlük kaydı için her zaman stderr kullanın; bu, MCP ileti alışverişine müdahale etmeyen ayrı bir akışa yazılır. Python'ın günlük kaydı modülünü stderr'e yazacak şekilde yapılandırın.

import logging
import sys

# Configure logging to stderr (NOT stdout — that's the MCP channel)
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] %(message)s',
    stream=sys.stderr
)
logger = logging.getLogger('weather-server')

# In your tool handler:
# logger.info(f'Getting weather for {city}')
# logger.error(f'API call failed: {e}')

# Claude Desktop captures stderr to a log file:
# ~/Library/Logs/Claude/mcp-server-weather-server.log

MCP Sunucunuzu Paketleme

MCP sunucunuzu pyproject.toml ile paketleyip PyPI'da yayımlayarak ekiplerle paylaşın veya Docker kapsayıcısı olarak dağıtın. Tüm gizli bilgiler (API anahtarları ve veritabanı URL'leri gibi) için ortam değişkenlerini kullanın; böylece sunucu yapılandırması koddan ayrı kalır. Gerekli ortam değişkenlerini ve örnek yapılandırmayı açık bir README dosyasında belgeleyin.

Hızlı Kontrol

Python'da MCP sunucusu oluşturma konusundaki anlayışınızı sınayın.

Ders Özeti

Bu derste şunları öğrendiniz: MCP sunucuları araçları @app.list_tools() ve @app.call_tool() dekoratörleriyle kullanıma sunar, kaynaklar ve istemler sunucuyu okunabilir veriler ve yeniden kullanılabilir şablonlarla genişletir ve stdio MCP protokol kanalının bozulmasını önlemek için günlük kaydı stderr kullanılarak yapılmalıdır. Sırada bir MCP sunucusunu veritabanına bağlamak ve dinamik kaynakları sayfalandırmayla kullanıma sunmak var.

Sıkça Sorulan Sorular

“İlk MCP Sunucunuzu Oluşturma” dersi ücretsiz mi?

Evet — “İlk MCP Sunucunuzu Oluşturma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve AI Engineering Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. AI Engineering Academy kursu toplamda 4 dersten oluşur.

“İlk MCP Sunucunuzu Oluşturma” dersinde ne öğreneceğim?

Kaynakları, araçları ve istemleri kullanıma sunan bir sunucu oluşturmak için Python MCP SDK'sını kullanın, ardından uçtan uca çalıştığını görmek için Claude Desktop'a bağlayın. AI Engineering Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

AI Engineering Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te AI Engineering Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“İlk MCP Sunucunuzu Oluşturma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu AI Engineering Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her AI Engineering Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. MCP Nedir ve Neden Önemlidir
  2. İlk MCP Sunucunuzu Oluşturma
  3. MCP ile Veritabanı Kaynaklarını Kullanıma Sunma
  4. MCP Güvenliği ve Kimlik Doğrulama
← AI Engineering Academy Sayfasına Dön