Orijinal olarak hafiz.dev‘de yayımlandı
Çoğu Laravel MCP öğreticisi, bir sunucu oluşturmayı öğretir. Uygulamanızın araçlarını açarsınız, bir AI istemcisi bağlanır ve Claude veya Cursor, siparişler tablonuzu sorgulayabilir. Kullanışlıdır ve Filament ile MCP sunucusu kurmayı daha önce ele aldım.
Bu yazı, ters yönde ilerliyor. Laravel AI ajanınız istemci olur. Herhangi bir MCP sunucusuna, GitHub’a, Notion’a, Laravel Nightwatch’a veya yerel olarak çalıştırdığınız bir sunucuya bağlanır ve o sunucunun araçlarını, sanki onları elle yazmışsınız gibi kullanır. Eğer Laravel AI SDK ile bir ajan oluşturduysanız, bu, sahip olduğunuz ajana doğrudan entegre olur. Ajanınıza “uygulamadaki en son istisnayı kontrol et” dediğinizde, Nightwatch sorunlarınızı gözden geçirir, yığın izini çeker ve size geri rapor eder. Bu entegrasyon kodunun hiçbirini yazmadınız.
Laravel bu özelliği 9 Haziran 2026’da sundu. Bu, bir ajanın yalnızca kodunuzu bilmekten çıkıp, ekibinizin zaten kullandığı her araca ulaşabilmesini sağlayan parçadır. Eğer ajana Laravel Boost ve MCP ile bağlam veriyorsanız, bu tersidir: ajanın uzanması, aracın içeri girmesi yerine. İşte nasıl kuracağınız, kimlik doğrulama gereksiz bir yerel sunucudan tam OAuth akışına, artı üretim aşamasında sizi ısırabilecek tuzaklara kadar tüm detaylar.
Kutuda Gerçekten Ne Var
Kutuda Gerçekten Ne Var
Özellik, birlikte çalışan iki paketten oluşur ve ayrım önemlidir.
MCP istemcisi laravel/mcp içinde yer alır. Bir sunucuya nasıl bağlanacağını, el sıkışmayı müzakere etmeyi, kimlik doğrulama yapmayı ve araçları çağırmayı bilir. Kendi başına, bir kuyruklu işten veya bir konsol komutundan çalışır, burada hiçbir ajan görünmez.
Ince entegrasyon ise laravel/ai içindedir. Bir ajanın, değişiklik yapmadan o istemciyi kullanmasına izin verir. MCP araçlarını daha önce kullandığınız tools() dizisine yerleştirirsiniz ve SDK, her birini ajanın araç sözleşmesine uyması için sarar.
Herhangi bir koddan önce, sürümlerinizi sabitleyin. 2026 yılı Haziran ayı sonu itibarıyla:
-
laravel/mcpv0.8.1 (0.8 serisi istemciyi tanıttı; önceki sürümler yalnızca sunucu içindi) -
laravel/aiv0.8.1 - Laravel 12 veya 13
- PHP 8.3 veya üzeri
Bu PHP eşiği önemlidir. laravel/mcp kendisi PHP 8.2 toleransını kabul eder, ancak laravel/ai 8.3 gerektirir ve bunun için her ikisine de ihtiyacınız vardır. Eğer 8.2’deyseniz, Composer çözümü reddedecektir. Neye sahip olduğunuzu kontrol edin:
composer show laravel/mcp laravel/ai
İstemci Arayüzü
İstemci Arayüzü
Tüm istemci üç fiil içerir: bağlan, araçları listele, bir aracı çağır. Diğer her şey sizi rahatsız etmez.
use Laravel\Mcp\Client;
// Bir HTTP üzerinden uzaktan sunucu
$client = Client::web('https://mcp.example.com');
// Bir süreç olarak çalıştırdığınız yerel sunucu (STDIO)
$client = Client::local('php', ['artisan', 'mcp:start']);
Bu iki yapıcı, iki taşıma şeklidir. web(), ağ üzerinden eriştiğiniz uzak sunucular için akışa alınabilir HTTP kullanır. local(), aynı makinedeki bir çocuk süreç olarak çalıştırdığınız sunucular için STDIO (standart giriş/çıkış) kullanır. Seçiminiz, sunucunun nerede bulunduğuna dayalıdır, tercihinize değil.
Araçları listelemek ve çağırmak ise şöyle görünür:
$tools = $client->tools();
$result = $client->callTool('search-issues', [
'query' => ,
]);
$result->text(); // metin içeriği
$result->isError; // aracın bir hata raporlayıp raporlamadığı
$result->structuredContent; // aracın bir yapılandırılmış yük döndürdüyse
Bağlantı, ilk gerçek çağrıda tembel bir şekilde gerçekleşir, bu nedenle onu manuel olarak yönetmeniz gerekmez. Ama isterseniz yönetebilirsiniz:
$client->connect();
$client->ping();
$client->disconnect();
Bağlantı sırasında, istemci ve sunucu bir protokol sürümünü müzakere eder ve yetenekleri değiş tokuş eder, böylece her iki taraf da çalışmaya başlamadan önce kurallar üzerinde anlaşır. Bunun hiçbirini yazmıyorsunuz. Bu bir el sıkışmasıdır ve hata verirse (daha fazla bilgi için aşağıya) genellikle bir kimlik doğrulama veya sürüm uyuşmazlığı altında olur.
Adım 1: Kimlik Doğrulaması Olmadan Bir Yerel Sunucu
Adım 1: Kimlik Doğrulaması Olmadan Bir Yerel Sunucu
En basit olası durumla başlayın, böylece karmaşıklığı görürsünüz. Bir ajanı bir yerel MCP sunucusuna (sizin veya herhangi bir STDIO sunucusu) kimlik doğrulaması olmadan yönlendirin.
Ajanda, MCP araçları doğrudan tools() metoduna, el ile yazdığınız araçların yanına gider:
use App\Ai\Tools\SendSlackMessage;
use Laravel\Mcp\Client;
public function tools(): iterable
{
return [
...Client::local(, [, ])->tools(),
new SendSlackMessage,
];
}
İşte tüm entegrasyon bu. Yayılma operatörü, MCP sunucusundan her aracı dizisine atar. SDK, bunların MCP araçları olduğunu fark eder ve her birini sarar: MCP girdi şemasını Laravel’in JSON şemasına çevirir, model çağırdığında uzak aracı çağırır ve dönen sonucu modelin okuyabileceği bir sonuca normalleştirir. Model, hangi araçların MCP’den geldiğini ve hangisinin sizin yazdığınız olduğunu bilmez. Hepsi model için aynı görünür.
Bu özelliğin zihinsel modeli budur. Bir yerel sunucu bağlantısını kurabilirseniz, diğer her sunucu sadece farklı bir taşıma ve üstüne bir kimlik doğrulama katmanıdır.
Adım 2: Taşıyıcı Token Kimlik Doğrulama
Adım 2: Taşıyıcı Token Kimlik Doğrulama
En kullanışlı sunucular, kim olduğunuzu bilmek ister. Daha basit kimlik doğrulama yolu bir taşıyıcı token olan, zaten elinizde olan bir dizedir. GitHub kişisel erişim tokeni klasik bir örnektir.
use Laravel\Mcp\Client;
$client = Client::web()
->withToken($token);
Bunun yerine bir closure geçirebilirsiniz, bu da tokenin şu anda kimliğini doğrulayan kullanıcıya ait olduğunda istediğiniz bir şeydir:
$client = Client::web()
->withToken(fn () => auth()->user()->github_token);
Ajana aynı şekilde yerleştirin:
public function tools(): iterable
{
return [
...Client::web()
->withToken(fn () => auth()->user()->github_token)
->tools(),
];
}
Artık ajanın, depo araması yapabildiğini, CI loglarını okuyabildiğini, sorunları triage edebildiğini ve Dependabot uyarılarını kontrol edebildiğini görebilirsiniz. GitHub sunucusu, ajanın hiçbir şeyi değiştirmemesi için bir istekte başlıkla okuma-modu da destekler.
Adım 3: Tam OAuth (Gerçek Dünya Durumu)
Adım 3: Tam OAuth (Gerçek Dünya Durumu)
Taşıyıcı tokenlerinin elinizde olduğu durumlarda iyidir. Ancak, barındırılan sunucular, kullanıcı bir düğmeye tıkladığında, sağlayıcının sitesinde erişimi onayladığında ve geri döndüğünde tokenin app’iniz tarafından saklandığı bir OAuth kullanır. (Eğer Nightwatch’ı alternatiflerle karşılaştırıyorsanız, Telescope vs Pulse vs Nightwatch ayrı ayrı değerlendirdim.) Resmi duyuruda üzerinde durulmayan bölüm burası, bu nedenle tüm akış burada.
Adlı bir istemci kaydedin, genellikle bir hizmet sağlayıcınızın boot() metodunda:
use Laravel\Mcp\Client;
use Laravel\Mcp\Facades\Mcp;
Mcp::registerClient(, fn () => Client::web()
->withOAuth(
clientId: config(),
clientSecret: config(),
));
Eğer sunucu dinamik istemci kaydı destekliyorsa, istemci kimliğini ve gizli anahtarı tamamen atlayabilirsiniz. Bunu yapıp yapamayacağınız, sorunlar ortaya çıktığında önemli hale gelir.
Ardından, routes/ai.php dosyasında bağlantı ve geri çağırma yollarını bağlayın. Paket, her ikisini de kaydeden bir yardımcı sağlar:
use Laravel\Mcp\Client\OAuth\TokenSet;
use Laravel\Mcp\Facades\Mcp;
Mcp::oAuthRoutesFor(, function (string $client, TokenSet $token) {
auth()->user()->update([
=> $token->accessToken,
]);
return redirect();
});
Bu, iki adlandırılmış yolu kaydeder: mcp.oauth.nightwatch.connect ve mcp.oauth.nightwatch.callback. Bağlantı yönü kullanıcıyı yetkilendirme sunucusuna yönlendirir. Geri çağırma yönü yetkilendirme kodunu değiştirir ve taze bir token ile boşluğunuzu çalıtır. Yönlendirme URL’lerini veya PKCE ayrıntılarına hiç dokunmazsınız.
Ardından, Blade görünümünüzde bir düğme ile başlama yapın:
Akış sırasıyla işler: kullanıcı düğmeye tıklar, paket onları Nightwatch’a yönlendirir, oturum açarlar ve onaylarlar, Nightwatch onları geri çağırma yolunuza gönderir, closure’ınız token ile çalışır ve istediğiniz şekilde saklarsınız. Paket OAuth dansını yönetir. Uygulamanız, tokenin nerede saklanacağını belirler.
Bir noktayı netleştirmek önemli: yerleşik bir token depolama sistemi yoktur. $token->accessToken‘i kendiniz saklarsınız ve istemciyi oluşturduğunuzda yeniden okursunuz. Paket, süresi dolmuş tokenleri yeniler, ancak depolama size aittir.
Token saklandığında, ajan adlandırılmış istemciyi kullanır:
public function tools(): iterable
{
return [
...Mcp::client()->tools(),
];
}
Şimdi lütfen ajana şunu sorun: “Üretimdeki en son istisnalar nedir? Hangi düzeltmeleri önceliklendirmeliyim?” O, sorunlarınızı inceleyip yığın izlerini okuyarak yanıt verir. Ona “123 numaralı sorunu çözülmüş olarak işaretle ve düzeltmeyi özetleyen bir yorum ekle” diye söylerseniz, bunu da yapar.
Ajanın MCP Araçlarını Görmesi
Ajanın MCP Araçlarını Görmesi
İşte istemciden uzaktan bir araca ve geri dönüşe olan akış, böylece modelin bir Nightwatch aracını kullanmaya karar verdiğinde ne olduğunu bilirsiniz.
Kilidi çözmek, orta kısımda önemli bir nokta. Model, seçerken, yerel ve MCP araçları aynı listede ve aynı görünümde bulunur. Sarmalama, şema çevirisi, ağ çağrısı ve sonuç normalleştirmesi, tüm bu süreçler modelin farkında olmaksızın gerçekleşir.
Araç Listesini Önbelleğe Alma
Araç Listesini Önbelleğe Alma
Araçları listelemek, uzak bir sunucuda ağ işlemi gerektirir ve araç listesi nadiren değişir. Bu yüzden önbelleğe alın. Araçlar basit veriler olarak döndüğü için çağrıyı Laravel’in önbelleği ile sarabilir ve temiz bir şekilde yeniden oluşturabilirsiniz:
use Illuminate\Support\Facades\Cache;
$tools = Cache::remember(, now()->addHour(), function () {
return Mcp::client()->tools();
});
Bilmekte fayda var: bu, bazı tanımların ima ettiği gibi, özel bir istemci özelliği değildir. Bu, tools() çağrısına sarılmış standart Laravel önbellegelemesidir. Kazanç gerçek olsa bile: her bir istemde bir ağ gidiş gelişinden kurtulursunuz, bu da özellikle her çağrıda kimlik doğrulama yükü taşıyan OAuth güvenli uzak sunucular için önemlidir.
Canlı Sunucu Olmadan Test Etme
Canlı Sunucu Olmadan Test Etme
Test kümenizin gerçek bir MCP sunucusuna ağ üzerinden ulaşmasını istemezsiniz. Laravel AI’nın sahteleme katmanı, aletin çağrısı hala MCP katmanından geçerken modelin yanıtlarını komutlayarak çalışmanıza olanak tanır.
MCP alet isimleri mcp_tools_ şemasını takip eder. search adlı bir sunucu aracı, ajana mcp_tools_search olarak görünür. Bu yüzden aracı çağıran bir model yanıtını taklit edebilir, ardından bir son yanıtla sonlandırabilir ve sonucu doğrulayabilirsiniz:
use Laravel\Ai\Facades\Ai;
it(, function () {
Ai::fake([
Ai::toolCall(, [=> ]),
Ai::text(),
]);
$response = (new SupportAgent)->prompt();
expect((string) $response)->toContain();
});
Üretim yolunu test ediyorsunuz (ajan, bir aracı çağırıyor, sonucu okuyor, yanıt veriyor) tek bir ağ çağrısı yapmadan.
Gerçekten Sizi Isıracak Tuzaklar
Gerçekten Sizi Isıracak Tuzaklar
İyi yol temiz. İşte kötü olabilecek kısımlar, geliştiricilerin karşılaştığı gerçek sorunlardan özeldir.
OAuth el sıkışma hataları en büyük olanıdır. Belirli ajanlar aracılığıyla Nightwatch’a bağlanırken 403 Forbidden ... when send initialize request hatası fırlatıldığına dair belgelenmiş bir durum var, ve hata el sıkışması çözümleme hataları sonradan ortaya çıkıyor. Rapor edilen neden: istemci kimlik doğrulamasının gerekli olduğunu tespit edemedi ve oturum açma akışını tetiklemedi. O iptal thread’inden iki düzeltme ortaya çıktı. Ajanınız destekliyorsa, onu zorla çalıştırın. Ya da mcp-remote köprüsünden geçin, doğrudan URL’ye yönlendirmek yerine. Nightwatch’ın kendi belgeleri, birkaç istemci için bunu öneriyor. Doğrudan bağlantı başarılı olursa, el sıkışması hatasından önce köprü aracılığıyla deneyin, kodunuzun yanlış olduğunu varsaymadan önce.
Dinamik istemci kaydı evrensel değildir. OAuth adımında, istemci kimliğini ve gizli anahtarı atlayabileceğiniz durum beklemediğiniz gibi. Bu, sunucunun dinamik istemci kaydı desteklemesi durumunda geçerlidir. Birkaç sunucu, önceden kaydedilmiş bir OAuth istemcisi talep eder ve onlara otomatik kayıt denemesi, genellikle bir yetkilendirme hatası gibi görünecek bir 403 ile sonuçlanır. Hedef alacağınız mod hakkında bilgi sahibi olun: dinamik kayıt yapılmadığında, clientId ve clientSecret‘yi açıkça vermeniz gerekir.
Token saklaması sizin işinizdir ve yanlış yapması kolaydır. Paket tokenleri yeniler ama saklamaz. Ortak hata, tokeni withToken() closure’ınızın geri okuma yapmayacağı bir yerde saklamak veya hiç saklamamaktır ve her istekte kimlik doğrulaması istemeden ne olduğunu sorgulamak.
Protokol sürümü uyuşmazlıkları el sıkışma hataları olarak ortaya çıkar. Sunucular farklı MCP spesifikasyon sürüm bilgilerini duyurur. Bir sunucu yalnızca istemcinin müzakere edemediği bir sürüm konuşuyorsa, bağlantı el sıkışmasında başarısız olur. Hata her zaman “sürüm” demeyecek, bu yüzden bir bağlantı kurulamıyorsa, listeye şüphelendiğinizden emin olun.
Uzak araç hataları kodunuza atlamaz. Bir uzak araç hata oluşursa, sonuçta isError döner, bunu ajan döngüsünüze istisna olarak yükseltmez. Sarıcı, hatayı modelin okuyup tepki verebileceği bir şeye dönüştürür. Sonuçları manuel olarak işliyorsanız, isError’yi kontrol edin.
Ne Zaman Kullanmalısınız (ve Ne Zaman Kullanılmamalı)
Ne Zaman Kullanmalısınız (ve Ne Zaman Kullanılmamalı)
Artık bir MCP istemci bağlantısına başvurun, eğer araç zaten bir MCP sunucusu olarak bulunuyorsa ve aksi takdirde el ile bir API entegrasyonu yazıyor olsanız. Nightwatch, GitHub, Notion ve büyüyen bir hizmet listesi MCP sunucularını açar. Birini kullanmak birkaç satır alır; onun entegrasyonunu yeniden inşa etmek ise birkaç gün alır.
Bir veya sadece bir son noktaya ihtiyacınız varsa, basit bir API çağrısı veya kendi yazdığınız bir araç sınıfı daha basit ise bunu atlayın. Eğer bir sunucunun birden fazla yeteneğine ihtiyacınız varsa ya da araçların zengin öğeleri olması gerektiği gibi, MCP onu haklı çıkarır.
Kendi uygulamanız için araçlar oluşturuyorsanız, laravel/mcp sunucu araç sınıflarınızı doğrudan bir ajan içinde, hiç istemci olmadan bile yeniden kullanabileceğinizi unutmayın. Aracı bir kez yazın, hem dış istemciler için bir sunucu aracı olarak hem de dahili olarak yerel bir ajan aracı olarak kullanın. Bu, tüm Laravel uygulamanızı AI ajanı dostu hale getirmek için aynı içgüdüdür: yeteneği bir kez inşa edin, her yerde serbest bırakın.
SSS
SSS
Bunu kullanmak için bir MCP sunucusu oluşturmam gerekiyor mu?
Hayır. Bu, tam tersidir. Dış sunucuları bir istemci olarak tüketiyorsunuz. Hiçbir şey açmıyorsunuz. Uygulamanızın araçlarını dış AI istemcilerine açmayı da istiyorsanız, o sunucu tarafı ayrı bir kurulumdur.
İstemci hangi taşımaları destekliyor?
İki: Yerel olarak bir süreç olarak çalıştırdığınız sunucular için STDIO (Client::local(...)), ve ağ üzerinden eriştiğiniz uzak sunucular için akışa alınabilir HTTP (Client::web(...)). Seçiminiz sunucunun nerede çalıştığına göre, tercihinize dayanmaktadır.
Aynı ajan içinde birden fazla MCP sunucusuna bağlanabilir miyim?
Evet. Aynı tools() dizisine birden fazla istemci yayabilirsiniz, taşımaları ve kimlik doğrulamaları karıştırarak. Bir yerel STDIO sunucusu ve bir uzak OAuth sunucusu, kendi yazdığınız araçların yanı sıra tek bir ajana girebilir. Model, hepsini aynı düzeyde değerlendirir.
Kimlik doğrulamaya ihtiyacı olan bir sunucuya ama benim istemcim başsız çalışıyorsa ne yapmalıyım?
OAuth, bir insanın tarayıcıda erişimi onayladığı varsayımına dayanır. Arka planda veya başsız çalışmalar için bazı sunucular bir istemci kimlik bilgileri yetkisi (kullanıcı olmadan) destekler, bu paketin yönettiği bir durumdur. Diğerleri, Notion’ın uzak sunucusu gibi, açıkça başsız ajanlar için tasarlanmamıştır ve farklı bir kimlik doğrulama yolu ya da önceden verilmiş bir token talep edebilir.
Bu, Laravel 11 ile çalışıyor mu?
laravel/mcp istemcisi Laravel 11, 12 ve 13’ü destekler, ancak laravel/ai Laravel 12 veya 13 ve PHP 8.3+ gerektirir. Ajan entegrasyonu hem sürümleri gerektirdiğinden, aslında bir ajanı bir MCP istemcisi olarak kullanmak için Laravel 12 veya 13’e ihtiyacınız var.
Sonuç
Sonuç
Ajanın istemci yönü, Laravel’in MCP hikayesinin daha sessiz yarısıdır ve çoğu uygulama için daha kullanışlı olandır. Bir sunucu kurmak, uygulamanızın AI araçlarına açılmasını sağlar. Sunucuları tüketmek, ajanın zaten çalıştığınız her araca erişebilmesini sağlar ve bu da her hizmet için özel bir entegrasyon yerine birkaç satır sürebilir. Kimlik doğrulaması olmayan bir yerel sunucuyla başlayın, tools() desenine aşina olun, ardından bir taşıyıcı token ile ilerleyin ve Nightwatch gibi bir şeyi bağladığınızda tam OAuth akışını seri hale getirin. Ve sorun giderme bölümünü elinizin altında bulundurmayı unutmayın, çünkü el sıkışması ve OAuth uç noktaları gerçekte zaman alır.
Laravel uygulamanıza ajan özellikleri ekliyorsanız ve MCP katmanınızı doğru ayarlamak için yardıma ihtiyacınız varsa, görüşelim.
Kaynak: Orijinal Makale
- Kutuda Gerçekten Ne Var
- İstemci Arayüzü
- Adım 1: Kimlik Doğrulaması Olmadan Bir Yerel Sunucu
- Adım 2: Taşıyıcı Token Kimlik Doğrulama
- Adım 3: Tam OAuth (Gerçek Dünya Durumu)
- Ajanın MCP Araçlarını Görmesi
- Araç Listesini Önbelleğe Alma
- Canlı Sunucu Olmadan Test Etme
- Gerçekten Sizi Isıracak Tuzaklar
- Ne Zaman Kullanmalısınız (ve Ne Zaman Kullanılmamalı)
- SSS
- Sonuç


