Model Context Protocol (MCP)

MCP İstemcileri Oluşturma: LLM'leri Yerel Ekosisteminize Bağlama

Model Bağlam Protokolü (MCP), Büyük Dil Modellerini (LLM) harici veri kaynaklarına ve araçlara bağlamak için fiili standart haline geliyor. Erken dönem tartışmalarının çoğu belirli yetenekleri açığa çıkaran MCP *Sunucuları* oluşturmaya odaklansa da, ekosistemin gerçek gücü MCP İstemcisi'nde yatıyor. İstemci, uygulamanızın veya IDE'nizin bu sunucuları sorunsuz bir şekilde keşfetmesine, onlara bağlanmasına ve etkileşime girmesini sağlayan köprüdür.

Bu yazıda, bir MCP istemcisinin mimarisini, taşıma katmanlarını nasıl işlediğini ve sıfırdan bir tane oluşturmak için pratik kod örneklerini inceleyeceğiz.

İstemci-Sunucu İlişkisini Anlama

Temelinde, bir MCP istemcisi kullanıcının arayüzü (örneğin bir LLM uygulaması) ile çeşitli MCP sunucuları arasında bir aracı olarak görev yapar. İstemcinin sorumlulukları şunlardır:

  • Keşif: Bağlı sunucuların açığa çıkardığı kullanılabilir araçları ve kaynakları bulma.
  • İletişim: JSON-RPC 2.0 mesaj geçişini de dahil olmak üzere bağlantı yaşam döngüsünü yönetme.
  • Yürütme: Araç çağrılarını başlatma ve sunucu tarafından döndürülen sonuçları işleme.

Geleneksel API istemcilerinin aksine, MCP istemcileri sunucunun belirli işlevselliğine kayıtsızdır. Sunucunun çalışma zamanında ne sunduğunu anlamak için standart bir şemaya güvenirler. Bu "dinamik keşif" deseni, tek bir istemcinin, her biri için sabit kodlanmış mantık gerektirmeden aynı anda bir dosya sistemi sunucusuna, bir GitHub sunucusuna ve bir veritabanı sunucusuna bağlanmasını sağlar.

Taşıma Katmanları: Nasıl Konuşurlar

MCP spesifikasyonu, istemciler için iki temel taşıma mekanizması tanımlar:

  1. Standart Girdi/Çıktı (Stdio): Yerel iletişim için kullanılır. İstemci, sunucuyu bir alt süreç olarak başlatır ve standart akışlar üzerinden iletişim kurar. Bu, yerel geliştirme ve masaüstü uygulamaları için en yaygın yöntemdir.
  2. Sunucu Tarafından Gönderilen Olaylar (SSE): HTTP üzerinden uzaktan iletişim için kullanılır. Sunucu, istemciye olayları akış halinde ileten bir uç nokta açığa çıkarır; bu da ağ sınırları boyunca kalıcı bağlantılara olanak tanır.

Çoğu yerel öncelikli uygulama için, basitliği ve ağ yükünün olmaması nedeniyle Stdio tercih edilir. İstemcinin yalnızca süreç yaşam döngüsünü yönetmesi ve JSON mesajlarını akış halinde iletmesi yeterlidir.

TypeScript ile Temel Bir MCP İstemcisi Uygulama

MCP SDK'ları yüksek düzeyde sarmalayıcılar sağlasa da, düşük düzeydeki etkileşimi anlamak, hata ayıklama ve davranışı özelleştirme konusunda yardımcı olur. Aşağıda, TypeScript SDK kullanarak bir istemcinin bağlantıyı nasıl başlattığı ve kullanılabilir araçları nasıl listelediğine dair basitleştirilmiş bir örnek bulunmaktadır.

import { Client } from "@modelcontextprotocol/sdk/client";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio";

const main = async () => {
  // 1. Taşıma katmanını tanımla
  const transport = new StdioClientTransport({
    command: "node",
    args: ["path/to/mcp/server.js"],
  });

  // 2. İstemciyi örnekleyin
  const client = new Client(
    {
      name: "MyAdvancedClient",
      version: "1.0.0",
    },
    {
      capabilities: {
        // İstemcinin desteklediklerini belirtin (ör. istemler, kökler)
        prompts: {},
        roots: {},
      },
    }
  );

  try {
    // 3. Sunucuya bağlan
    await client.connect(transport);
    console.log("Connected to MCP server");

    // 4. Kullanılabilir araçları keşfet
    const toolsResponse = await client.listTools();
    console.log("Available Tools:");
    toolsResponse.tools.forEach((tool) => {
      console.log(`- ${tool.name}: ${tool.description}`);
    });

    // 5. Bir aracı çağır (örnek)
    // const result = await client.callTool({ name: "search", arguments: { query: "test" } });
    // console.log(result.content);

  } catch (error) {
    console.error("Error:", error);
  } finally {
    // 6. Bağlantıyı temizle
    await client.close();
  }
};

main();

Temel Çıkarım: Client ve Transport arasındaki açık ayrımı not edin. Bu tasarım, istemci uygulamanızın çekirdek mantığını değiştirmeden iletişim yöntemini (örneğin Stdio'dan SSE'ye) değiştirmenizi sağlar.

İstemler ve Kökleri İşleme

Modern MCP istemcileri yalnızca araçlar çağırmaz; aynı zamanda İstemleri (Prompts) ve Kökleri (Roots) de işler.

  • İstemler (Prompts): Bunlar, sunucu tarafından sunulan önceden tanımlanmış şablonlardır. İstemci bunları alabilir ve LLM bağlamına enjekte edebilir. Örneğin, bir hukuki belge sunucusu, belirli talimatları ve biçimlendirme kurallarını içeren bir "Sözleşme İncelemesi" istemi sunabilir.
  • Kökler (Roots): Bunlar, istemcinin sunucuya hangi dosyaların veya dizinlerin mevcut olduğunu bildirmesini sağlar. Bu, dosya sistemi sunucuları için kritiktir. İstemci, kök URI listesini gönderir ve sunucu, güvenlik ve ilgili alanı sağlamak için işlemlerini bu kapsamla sınırlamak için bunu kullanır.

Doğru Kök işlemenin uygulanması güvenlik açısından kritiktir. Asla tüm dosya sistemini bir MCP sunucusuna açmayın. İstemcinin köklerini her zaman belirli proje dizinleriyle sınırlayın.

İstemci Geliştirme İçin En İyi Uygulamalar

  1. Hata Dayanıklılığı: MCP sunucuları çökebilir veya zaman aşımına uğrayabilir. Bağlantı mantığını her zaman try-catch blokları içinde sarın ve geçici arızalar için yeniden deneme mekanizmaları uygulayın.
  2. Yetenek Müzakeresi: Başlatma aşamasında, istemci ve sunucu yeteneklerini değiştirir. Beklenmedik hatalardan kaçınmak için istemcinizin yalnızca gerçekten desteklediklerini bildirdiğinden emin olun.
  3. Asenkron Yönetim: Araç çağrıları uzun sürebildiği için (örneğin, bir veritabanı sorgusu yürütme), async/await desenlerini sıkı bir şekilde kullanın. Asla ana iş parçacığını bloklamayın.
  4. Günlük Kaydı (Logging): JSON-RPC mesajları için ayrıntılı günlük kaydı uygulayın. MCP çift yönlü bir akış kullandığı için, karmaşık etkileşimleri hata ayıklamak için hem gönderilen hem de alınan mesajların günlüğünü tutmak hayati önem taşır.

Sonuç

Bir MCP istemcisi oluşturmak, yalnızca HTTP istekleri göndermekten ibaret değildir; yapay zeka uygulamanız ile gerçek dünya arasında dinamik, güvenli ve standart bir arayüz orkestrasyonudur. SDK'ları kullanarak ve protokolün taşıma ve yetenek modellerine uyarak, hem genişletilebilir hem de sürdürülebilir sağlam uygulamalar oluşturabilirsiniz.

Ekosistem olgunlaştıkça, tek bir istemcinin onlarca uzmanlaşmış sunucuya bağlantıları yönettiği ve LLM için birleşik bir bağlam penceresi sağladığı çoklu sunucu birleştirme gibi daha gelişmiş istemci özelliklerini görmeyi bekleyin. İstemcinizi bugün oluşturmaya başlayın ve Model Bağlam Protokolünün tam potansiyelini ortaya çıkarın.

Share: