Laravel v12 - The PHP Framework For Web Artisans (project, gitignored)
Comprehensive assistance with Laravel MCP (Model Context Protocol) development. Laravel MCP provides a simple and elegant way for AI clients to interact with your Laravel application through the Model Context Protocol, enabling you to define servers, tools, resources, and prompts for AI-powered interactions.
This skill should be triggered when:
MCP Server: The central communication point that exposes MCP capabilities. Each server has:
name: Server identifierversion: Server versioninstructions: Description of the server's purposetools: Array of tool classesresources: Array of resource classesprompts: Array of prompt classesTools: Enable AI clients to perform actions. Tools can:
#[IsReadOnly] and #[IsIdempotent]Prompts: Reusable prompt templates that provide a standardized way to structure common queries with argument definitions and validation.
Resources: Enable your server to expose data and content that AI clients can read, including text and blob responses with customizable MIME types and URIs.
<?php
namespace App\Mcp\Servers;
use Laravel\Mcp\Server;
class WeatherServer extends Server
{
protected string $name = 'Weather Server';
protected string $version = '1.0.0';
protected string $instructions = 'This server provides weather information and forecasts.';
protected array $tools = [
// CurrentWeatherTool::class,
];
protected array $resources = [
// WeatherGuidelinesResource::class,
];
protected array $prompts = [
// DescribeWeatherPrompt::class,
];
}
<?php
namespace App\Mcp\Tools;
use Illuminate\JsonSchema\JsonSchema;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
protected string $description = 'Fetches the current weather forecast for a specified location.';
public function handle(Request $request): Response
{
$location = $request->get('location');
// Get weather...
return Response::text('The weather is...');
}
public function schema(JsonSchema $schema): array
{
return [
'location' => $schema->string()
->description('The location to get the weather for.')
->required(),
];
}
}
public function handle(Request $request): Response
{
$validated = $request->validate([
'location' => 'required|string|max:100',
'units' => 'in:celsius,fahrenheit',
], [
'location.required' => 'You must specify a location.',
'units.in' => 'You must specify either "celsius" or "fahrenheit".',
]);
// Fetch weather data...
}
<?php
namespace App\Mcp\Tools;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
public function __construct(
protected WeatherRepository $weather,
) {}
public function handle(Request $request, WeatherRepository $weather): Response
{
$location = $request->get('location');
$forecast = $weather->getForecastFor($location);
// ...
}
}
<?php
namespace App\Mcp\Tools;
use Laravel\Mcp\Server\Tools\Annotations\IsIdempotent;
use Laravel\Mcp\Server\Tools\Annotations\IsReadOnly;
use Laravel\Mcp\Server\Tool;
#[IsIdempotent]
#[IsReadOnly]
class CurrentWeatherTool extends Tool
{
// ...
}
<?php
namespace App\Mcp\Tools;
use Generator;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
public function handle(Request $request): Generator
{
$locations = $request->array('locations');
foreach ($locations as $index => $location) {
yield Response::notification('processing/progress', [
'current' => $index + 1,
'total' => count($locations),
'location' => $location,
]);
yield Response::text($this->forecastFor($location));
}
}
}
<?php
namespace App\Mcp\Prompts;
use Laravel\Mcp\Server\Prompt;
use Laravel\Mcp\Server\Prompts\Argument;
class DescribeWeatherPrompt extends Prompt
{
protected string $description = 'Generates a natural-language explanation of the weather.';
public function arguments(): array
{
return [
new Argument(
name: 'tone',
description: 'The tone to use in the weather description.',
required: true,
),
];
}
public function handle(Request $request): array
{
$tone = $request->string('tone');
return [
Response::text("You are a weather assistant. Provide a {$tone} tone.")->asAssistant(),
Response::text("What is the current weather like in New York City?"),
];
}
}
<?php
namespace App\Mcp\Resources;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
protected string $description = 'Comprehensive guidelines for using the Weather API.';
protected string $uri = 'weather://resources/guidelines';
protected string $mimeType = 'application/pdf';
public function handle(Request $request): Response
{
return Response::text($weatherData);
}
}
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;
Mcp::web('/mcp/weather', WeatherServer::class);
// With middleware
Mcp::web('/mcp/weather', WeatherServer::class)
->middleware(['throttle:mcp']);
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;
Mcp::local('weather', WeatherServer::class);
use App\Mcp\Servers\WeatherExample;
use Laravel\Mcp\Facades\Mcp;
Mcp::oauthRoutes();
Mcp::web('/mcp/weather', WeatherExample::class)
->middleware('auth:api');
use App\Mcp\Servers\WeatherExample;
use Laravel\Mcp\Facades\Mcp;
Mcp::web('/mcp/demo', WeatherExample::class)
->middleware('auth:sanctum');
This skill includes comprehensive documentation in references/:
Use view to read specific reference files when detailed information is needed.
Start by understanding the core concepts:
composer require laravel/mcpphp artisan vendor:publish --tag=ai-routes to create routes/ai.phpphp artisan make:mcp-serverroutes/ai.php using Mcp::web() or Mcp::local()Begin with simple read-only tools using the #[IsReadOnly] annotation before moving to tools that modify data.
Focus on building robust tools:
Implement production-ready features:
#[IsIdempotent] annotationreferences/other.md for comprehensive documentation# Generate server class
php artisan make:mcp-server WeatherServer
# Edit app/Mcp/Servers/WeatherServer.php
# Add tools, resources, and prompts
# Register in routes/ai.php
Mcp::web('/mcp/weather', WeatherServer::class);
// Simple required string
'location' => $schema->string()->required()
// Optional with default
'units' => $schema->string()->default('celsius')
// Number with constraints
'temperature' => $schema->number()->minimum(0)->maximum(100)
// Array of items
'cities' => $schema->array()->items($schema->string())
// Object with properties
'forecast' => $schema->object()->properties([
'temperature' => $schema->number(),
'humidity' => $schema->number(),
])
// Text response
return Response::text('The weather is sunny');
// Multiple responses
return [
Response::text('First message'),
Response::text('Second message'),
];
// Notification (streaming)
yield Response::notification('processing/progress', ['status' => 'processing']);
composer require laravel/mcp
php artisan vendor:publish --tag=ai-routes
#[IsReadOnly]