PHP uygulamaları içinde iş mantığını (business logic) koruyarak yıllarınızı geçirdiyseniz, Model Context Protocol eğitimlerini izlemek kilitli bir kapının dışında beklemek gibi hissettirebilir. Neredeyse her kılavuz TypeScript veya Python kullandığınızı varsayar. Resmi SDK'lar, npm kurulumları ve pip paketleri üzerinden ilerlerler. Bu durum; müşteri kayıtları, sipariş geçmişleri ve envanter sistemleri gibi devasa miktardaki iş verisinin, mevcut yapay zeka araçları dalgası için görünmez görünen PHP kod tabanlarında öylece kalmasına neden olur.

İyi haber şu ki, MCP'nin hiçbir parçası bu SDK'lara ihtiyaç duymaz. MCP bir kütüphane değildir. Bir iletişim protokolüdür (wire protocol). Eğer çalışma ortamınız (runtime) standart girdiden (standard input) bir metin satırı okuyabiliyor, JSON ayrıştırabiliyor (parse) ve tekrar JSON yazabiliyorsa, bu protokolü konuşabilir. PHP, LLM'ler var olmadan çok uzun zamandır tam olarak bunu yapmaktadır.

MCP Aslında Nedir

MCP, Model Context Protocol'ün kısaltmasıdır. Özünde, yapay zeka asistanlarını verilere, araçlara ve harici API'lere bağlamak için kullanılan açık bir standarttır. Her asistan veya model için özel bir entegrasyon oluşturmak yerine, uyumlu tek bir arayüz oluşturursunuz. MCP'yi anlayan herhangi bir istemci (client), PHP, Laravel veya özel veritabanı şemanız hakkında hiçbir şey bilmeden sunucunuzla iletişim kurabilir.

Altta yatan yapıda MCP, JSON-RPC 2.0 kullanır. Bu, her isteğin bir metot adı, parametreler ve bir ID içeren basit bir JSON nesnesi olduğu anlamına gelir. Sunucu, bir sonuç veya bir hata taşıyan başka bir JSON nesnesi ile yanıt verir.

Bir sunucu üç temel yapı (primitive) sunar:

  • Araçlar (Tools): Modelin çağırabileceği eylemler. Bir araç bir veritabanını sorgulayabilir, bir durumu güncelleyebilir veya üçüncü taraf bir API'yi çağırabilir.
  • Kaynaklar (Resources): Modelin bir URI aracılığıyla referans verebileceği statik veya yarı statik veriler. Dosyalar, yapılandırma belgeleri veya referans veri setlerini düşünebilirsiniz.
  • İstemler (Prompts): Kullanıcının sistemle etkileşime girmesine yardımcı olan önceden tanımlanmış şablonlar.

Unutulmaması gereken önemli bir kontrol ayrımı vardır. Araçlar model tarafından kontrol edilir; asistan, bir aracı ne zaman çağıracağına kendisi karar verir. Kaynaklar ise uygulama tarafından kontrol edilir; hangi verilerin mevcut olduğuna sunucu karar verir ve model sadece sunulanı okur. Bunu doğru kurgulamak, mimarinizin öngörülebilir kalmasını sağlar. Bir modelin, araç olması gereken kaynakları aramaya çalışmasını veya tam tersini istemezsiniz.

Taşıma (Transport) Nasıl Çalışır

MCP iki taşıma yöntemi tanımlar ve seçiminiz, PHP tarafını nasıl yazacağınızı şekillendirir.

stdio en basit olanıdır. MCP istemcisi, PHP betiğinizi bir alt süreç (subprocess) olarak başlatır. İstemci, JSON-RPC mesajlarını betiğinizin standart girdisine (standard input) yazar ve betiğiniz de yanıtları standart çıktıya (standard output) yazar. Yönetilecek soketler, açılacak portlar veya ayrıştırılacak kimlik doğrulama başlıkları yoktur. Eğer aracınız ve istemciniz aynı makinede bulunuyorsa, başlamak için genellikle en doğru yer burasıdır.

stdio üzerinden çalıştırmak, PHP süreciniz üzerinde iki katı kural dayatır. İlk olarak, uygulamanız asla stdout'a protokol dışı veri yazmamalıdır. Eğer bir hata ayıklama (debug) ifadesini echo ile yazdırırsanız veya bir PHP uyarısının (notice) sızmasına izin verirseniz, istemcinin ayrıştırıcısını (parser) bozarsınız. Tüm günlükleme (logging) ve teşhis işlemlerini stderr'e yönlendirin. İkinci olarak, çıktı tamponlamayı (output buffering) tamamen devre dışı bırakın. PHP, özellikle CGI veya web bağlamlarında stdout'u tamponlamayı sever, ancak CLI betikleri bile veri tutabilir. Her yanıtı anında boşaltın (flush). Eğer akışlar (streams) kullanıyorsanız, stream_set_write_buffer(STDOUT, 0) komutunu ayarlayın veya istemcinin yeni satırı gönderdiğiniz anda alabilmesi için örtük tamponlamayı kapatın.

Streamable HTTP farklı çalışır. PHP uygulamanız, genellikle POST istekleri aracılığıyla erişilen kalıcı bir HTTP uç noktası (endpoint) olarak çalışır. Bu, sunucu farklı bir ana makinede (host) olduğunda veya birden fazla istemcinin erişebileceği uzun süre çalışan bir daemon istediğinizde kullanışlıdır. PHP'de bu, genellikle her çağrıdan sonra sona eren geleneksel istek-yanıt döngüsü yerine RoadRunner, FrankenPHP veya benzeri bir süreç yöneticisi altında çalıştırmak anlamına gelir.

PHP ile İnşa Etmek

Başlamak için bir framework'e ihtiyacınız yok. PHP'de minimal bir MCP sunucusu; STDIN'den okuyan, JSON'u çözen, bir işleyiciye (handler) yönlendiren ve sonucu kodlayan bir döngüdür.

while ($line = fgets(STDIN)) {
    $request = json_decode($line, true);
    // route to tool or resource handler
    // write JSON-RPC response to STDOUT
}

Bu döngünün içinde asıl iş, bir model için anlamlı olan arayüzleri oluşturmaktır.

Araç şemalarını koddan oluşturun. Sorun çıkarmanın en hızlı yollarından biri, araç parametreleriniz için JSON Şemalarını elle yazmak ve bunların gerçek doğrulama mantığınızla senkronizasyonunun bozulmasına izin vermektir. PHP, zengin yansıma (reflection) yeteneklerine sahiptir. Metot imzalarınızı inceleyin, formlarınızdan veya komut nesnelerinizden mevcut doğrulama kurallarını okuyun ve şemayı bu kısıtlamalardan oluşturun. Eğer dahili kodunuz geçerli bir e-posta formatı gerektiriyorsa, MCP şemanız da aynı şeyi söylemelidir. Doğrulama kuralları değiştiğinde şema otomatik olarak güncellenir. Senkronizasyon kaybı yok, sessiz hatalar yok.

Protokol hatalarını araç hatalarından ayırın. JSON-RPC'nin kendine ait bir hata alanı vardır. Bunu bozuk protokoller için kullanın: hatalı JSON, bilinmeyen metotlar veya eksik istek kimlikleri (request IDs). Bir araç doğru şekilde çalışıyor ancak bir iş problemiyle karşılaşıyorsa, payload içinde bir hata bayrağı bulunan normal bir sonuç döndürün. Eğer bir müşteri arama aracı eşleşen bir kayıt bulamazsa, bu bir protokol çökmesi değildir. {"found": false} gibi yapılandırılmış bir sonuç döndürmek, modelin ne olduğunu anlamasını ve bir sonraki adımı seçmesini sağlar. Daha geniş bir arama yapmayı deneyebilir veya kullanıcıdan açıklama isteyebilir. Bunun yerine bir JSON-RPC hatası fırlatırsanız, model genellikle bağlamı kaybeder.

Uzun süren işler için plan yapın. PHP, kısa istekler için tasarlanmıştır. Bir web isteği otuz saniye içinde zaman aşımına uğrayabilir ve CLI betikleri bile belleği veya sabrı tüketebilir. Eğer bir aracın tamamlanması dakikalar sürüyorsa —belki büyük bir rapor derliyor veya sistemler arasında veri senkronize ediyordur— modeli bekletmeyin. Hemen bir iş tanımlayıcısı (job identifier) döndürün. Ardından, bu ID ile durumu kontrol etmek için ikinci bir araç sunun. İlerlemeyi Redis'te, bir veritabanı tablosunda ve hatta hacim düşükse düz bir dosyada (flat file) saklayabilirsiniz. Model ID'yi alır, daha sonra tekrar kontrol eder ve sonunda tamamlanmış sonucu alır.

Model Anahtarlara Sahip Olduğunda Güvenlik

Bir yapay zeka modeline bir araca erişim vermek, bunu bir insan kullanıcıya vermek gibi değildir. Bir model kelimenin tam anlamıyla hızlı hareket eder ve açıklamaları yanlış yorumlayabilir. Maruz bırakılan her aracı bir yetki yükseltme (privilege escalation) riski olarak değerlendirin.

Kapsamı agresif bir şekilde sınırlayın. Asla genel bir run_sql aracı sunmayın. find_customer_by_email veya update_order_status gibi spesifik ve dar kapsamlı araçlar oluşturun. Model, yalnızca tanımladığınız parametrelerle ve tam olarak adlandırdığınız şeyi yapabilmelidir.

Okuma ve yazma yollarını ayırın. Salt okunur araçlar daha düşük risk taşır. Herhangi bir yıkıcı işlemi açık bir onay mekanizmasının arkasına koyun veya tamamen ikinci bir sunucuyla sınırlandırın. İstemciniz destekliyorsa, bir yazma aracı yürütülmeden önce bir insan onayı adımı gerektirin.

Araç açıklamalarını sanki ek talimatlarmış gibi yazın, çünkü öyledirler. Modelin bir aracı ne zaman çağırması gerektiği konusunda kesin olun. Eğer bir araç fiyat araştırması yapıyorsa, bunu belirtin. Eğer yalnızca müşteri kimliği doğrulandıktan sonra kullanılmalıysa, bunu açıkça ifade edin. Belirsiz açıklamalar belirsiz davranışlara yol açar.

Çıktınızı filtreleyin. Tüm bir Eloquent modelini veya Doctrine varlığını (entity) serileştirip sonucu içine boşaltmayın. Yalnızca modelin gerçekten ihtiyaç duyduğu alanları döndürün. Dahili alanlar —maliyet fiyatları, çalışan notları, dahili kalması gereken veritabanı kimlikleri— veri hattını (wire) geçmemelidir. Döndürdüğünüz veri yapısı (return shape) konusunda açık olun.

Son olarak, her şeyi günlüğe kaydedin (log). Araç adını, iletilen argümanları ve sonucu kaydedin. Eğer bir model maliyetli bir sorguda döngüye girmeye başlarsa veya araçları beklenmedik bir sırayla yoklamaya başlarsa, bunu görmenizin tek yolu günlüklerinizdir.

Nereden Başlamalı

PHP uygulamanızı bir yapay zeka asistanına bağlamak için bir SDK yöneticisinden izin almanıza gerek yok. JSON-RPC'ye, bir döngüye ve stdout konusunda biraz disipline ihtiyacınız var.

İlk günden tüm API'nizi MCP araçları olarak yeniden inşa etme dürtüsüne karşı koyun. Kuruluşunuzdaki birinin gerçekten defalarca sorduğu üç salt okunur işlem seçin. Belki bir sipariş durumunu kontrol etmek, bir müşteri özetini çekmek veya son faturaları listelemektir. Bunları araç olarak paketleyin, stdio üzerinden sunun ve bir meslektaşınızın kullanmasına izin verin. Modelin neleri iyi yaptığını ve nerede tökezlediğini izleyin. Bu üç araçtan, otuz tanesini planlamaktan daha çok şey öğreneceksiniz.

MCP bir köprüdür, uygulamanızın yerini almaz. PHP kodunuz işinizi zaten biliyor. Protokol, modelin karşıya geçip ona sorular sormasına olanak tanır.