Laravel MCP 1.0 Resmi Stabil: Bikin Server MCP Sendiri di Aplikasi Laravel
Laravel MCP 1.0 akhirnya stabil (tag v1.0.0, 14 September 2026): dukungan protokol revisi 2026-07-28, server stateless, katalog tool yang bisa dicari, cache hints, dan OAuth yang mewajibkan PKCE. Ini rangkuman perubahannya plus cara bikin server MCP pertama di aplikasi Laravel 13.

Bulan September 2026 jadi bulan yang ramai buat ekosistem Laravel — dan hampir semuanya soal AI. Setelah Laravel 13 membawa AI SDK bawaan sejak Maret, sekarang giliran laravel/mcp yang mencapai versi stabil 1.0. Tag v1.0.0 dirilis 14 September 2026, dan Laravel News mengabarkannya sehari setelahnya.
Kalau kamu penasaran bagaimana aplikasi Laravel bisa langsung "dipakai" oleh AI agent seperti Claude Code, Cursor, atau Claude Desktop, Laravel MCP adalah jawaban first-party-nya. Tulisan ini merangkum apa yang baru di 1.0 plus contoh bikin server MCP pertama.
Apa itu MCP dan kenapa perlu dipedulikan
MCP (Model Context Protocol) adalah protokol terbuka yang mendefinisikan bagaimana AI client berkomunikasi dengan sebuah server untuk memakai kapabilitas aplikasi. Di Laravel MCP, ada tiga hal yang bisa diekspos:
- Tools — aksi yang bisa dipanggil model, misalnya "buat draft artikel" atau "ambil data pesanan".
- Prompts — template prompt yang disediakan aplikasi, misalnya "review migration ini".
- Resources — data read-only yang bisa dibaca model, misalnya panduan gaya penulisan.
Bedanya dengan bikin endpoint API biasa: client MCP sudah tahu cara menemukan tool, membaca skema inputnya, dan memanggilnya, tanpa kamu menulis dokumentasi manual untuk tiap agent.
Setup: tiga perintah
composer require laravel/mcp
# bikin file routes/ai.php tempat server didaftarkan
php artisan vendor:publish --tag=ai-routes
# generate class server (masuk ke app/Mcp/Servers)
php artisan make:mcp-server WeatherServer
Server hasil generate extends Laravel\Mcp\Server dan dikonfigurasi lewat atribut:
#[Name('Weather Server')]
#[Version('1.0.0')]
#[Instructions('Server ini menyediakan data cuaca dan prakiraan.')]
class WeatherServer extends Server
{
protected array $tools = [
// GetCurrentWeatherTool::class,
];
}
Pendaftarannya di routes/ai.php. Ada dua mode:
use Laravel\Mcp\Facades\Mcp;
// HTTP — cocok untuk agent remote
Mcp::web('/mcp/weather', WeatherServer::class)->middleware(['throttle:mcp']);
// Lokal — dijalankan sebagai Artisan command via stdio
Mcp::local('weather', WeatherServer::class);
Bikin tool pertama
php artisan make:mcp-tool CurrentWeatherTool
Tool pada dasarnya cuma class dengan dua method: handle() untuk logika, schema() untuk kontrak input.
#[Description('Mengambil prakiraan cuaca untuk lokasi tertentu.')]
class CurrentWeatherTool extends Tool
{
public function handle(Request $request): Response
{
$location = $request->get('location');
// ...ambil data cuaca
return Response::text("Cuaca di {$location} sedang cerah.");
}
public function schema(JsonSchema $schema): array
{
return [
'location' => $schema->string()
->description('Lokasi yang dicari.')
->required(),
];
}
}
Skema inilah yang dikirim ke model, jadi tulis deskripsinya sejelas mungkin — agent tidak bisa menebak maksud parameter yang ambigu.
Yang baru di Laravel MCP 1.0
1. Dukungan protokol revisi 2026-07-28
Revisi terbaru MCP memakai server/discover sebagai ganti pertukaran initialize di awal koneksi. Client lama tetap jalan: server akan menjawab dengan versi protokol 2025-11-25 atau 2025-06-18 sesuai yang diminta client.
2. Server stateless
Di protokol baru, setiap request diproses secara independen. Konsekuensinya, header MCP-Session-Id, method Request::sessionId() dan Request::setSessionId(), serta event SessionInitialized dihapus. Kalau butuh mengaitkan beberapa call, kirim identifier sendiri lewat argument atau _meta.
3. Katalog tool yang bisa dicari
Setiap definisi tool memakan ruang context window. Dengan ToolSearch, tool yang jarang dipakai tidak perlu ikut di daftar utama:
protected array $tools = [
CurrentWeatherTool::class, // selalu tersedia
ToolSearch::class => [ // dicari hanya saat dibutuhkan
HistoricalWeatherTool::class,
WeatherAlertsTool::class,
],
];
Package menyediakan dua tool bawaan: search_tools (cari berdasarkan query dan limit) serta execute_tools (jalankan satu atau beberapa tool berdasarkan nama).
4. Cache hints
Server bisa memberi tahu client respons mana yang boleh di-cache dan berapa lama:
#[Cacheable(ttlMs: 60_000, scope: CacheScope::Public)]
class WeatherServer extends Server
{
protected function cacheHints(): array
{
return [
'tools/list' => new Cacheable(ttlMs: 30_000, scope: CacheScope::Public),
];
}
}
Default-nya respons ditandai private dengan TTL 0 ms — artinya tidak di-cache. CacheScope::Private membatasi cache ke konteks otorisasi yang sama, sedangkan Public boleh dibagi antar user. Hint ini sifatnya saran; client atau host yang memutuskan eksekusinya. Tool call sendiri tidak pernah di-cache.
5. OAuth lebih ketat
OAuth sekarang mewajibkan PKCE: kalau authorization server tidak mencantumkan code_challenge_methods_supported di metadata-nya, OAuthClient::redirect() akan melempar OAuthException. Ada juga dukungan Client ID Metadata Documents — client_id-nya berupa URL HTTPS ke dokumen JSON yang disajikan otomatis di GET /mcp/oauth/{client}/client-metadata.json. Dynamic Client Registration yang lama sudah deprecated di revisi 2026-07-28. Satu catatan teknis: kalau memakai metadata document, $token->clientSecret bernilai null, jadi kolom database penampungnya harus nullable. Ada juga perbaikan bug yang sebelumnya membuat client baru terdaftar ke authorization server setiap kali redirect() dipanggil.
Kalau upgrade dari 0.9
Ada middleware baru ValidateMcpHeaders yang jalan di setiap route yang didaftarkan lewat Mcp::web(). Artinya request POST wajib membawa header MCP-Protocol-Version dan Mcp-Method yang cocok dengan body; untuk tools/call, prompts/get, dan resources/read wajib ada Mcp-Name sesuai nama tool, prompt, atau URI resource. Kalau tidak cocok, server balas HTTP 400 dengan error JSON-RPC -32020. Test yang memakai postJson() juga harus mengirim header dan params._meta tersebut. Client lama yang masih memakai initialize tanpa metadata _meta dikecualikan dari validasi ini.
Daftar lengkapnya — termasuk perubahan error code dan konstanta Server::CAPABILITY_UI yang dihapus — ada di file UPGRADE.md repo laravel/mcp.
Cara nge-tes server-nya
Dua jalur yang paling praktis:
# server web
php artisan mcp:inspector mcp/weather
# server lokal bernama "weather"
php artisan mcp:inspector weather
Dan unit test tanpa perlu client sungguhan:
test('tool cuaca', function () {
$response = WeatherServer::tool(CurrentWeatherTool::class, [
'location' => 'Makassar',
]);
$response->assertOk()->assertSee('cerah');
});
Bonus: Laravel AI SDK 1.0
Di minggu yang sama, Laravel AI SDK (laravel/ai) juga naik ke 1.0. Dua hal yang menarik: kapabilitas Classification (tipe pertanyaan Boolean, Choice, dan Score) untuk keputusan cepat seperti routing tiket support, plus Approvable tool calls — tool yang menunggu persetujuan manusia sebelum dijalankan. Kombinasi ini pas dengan server MCP: agent boleh mengusulkan aksi, tapi eksekusinya tetap menunggu keputusan manusia.
Penutup
Yang paling menarik dari Laravel MCP 1.0 bukan fitur yang paling ramai dibicarakan, tapi arahnya: protokol AI jadi warga kelas satu di framework, lengkap dengan atribut, generator Artisan, dan pola testing yang sudah familier. Kalau mau mulai, jangan langsung mengekspos 20 tool — mulai dari satu atau dua tool kecil yang benar-benar dipakai, tulis deskripsi skemanya dengan rapi, lalu tambahkan cache hints begitu listing-nya terasa berat.