Come integrare un server Model Context Protocol (MCP) in un’app Laravel. Definisci tool, resource e prompt con cui gli agenti AI possono interagire con la tua app.
Il Model Context Protocol (MCP) è una specifica che consente a client AI (Claude, Cursor, GitHub Copilot, ecc.) e alle applicazioni di comunicare tramite un protocollo standardizzato. Implementando un server MCP fai in modo che gli agenti AI possano accedere ai dati della tua app Laravel ed eseguire azioni.
Laravel MCP è il pacchetto ufficiale aggiunto in Laravel 13, laravel/mcp. Offre tutto il necessario per costruire server MCP.
Un server MCP può offrire tre tipi di funzionalità:
Funzionalità
Descrizione
Tool
Funzioni chiamabili dal client (ricerca, aggiornamento, chiamate API esterne, ecc.)
<?phpnamespace App\Mcp\Tools;use Illuminate\Contracts\JsonSchema\JsonSchema;use Laravel\Mcp\Request;use Laravel\Mcp\Response;use Laravel\Mcp\Server\Attributes\Description;use Laravel\Mcp\Server\Tool;#[Description('Fetches the current weather forecast for a specified location.')]class CurrentWeatherTool extends Tool{ public function handle(Request $request): Response { $location = $request->get('location'); // Recupero dei dati meteo... return Response::text('The weather is sunny, 22°C.'); } public function schema(JsonSchema $schema): array { return [ 'location' => $schema->string() ->description('The location to get the weather for.') ->required(), ]; }}
public function schema(JsonSchema $schema): array{ return [ 'location' => $schema->string() ->description('The location to get the weather for.') ->required(), 'units' => $schema->string() ->enum(['celsius', 'fahrenheit']) ->description('The temperature units to use.') ->default('celsius'), ];}
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. For example, "New York City" or "Tokyo".', 'units.in' => 'You must specify either "celsius" or "fahrenheit" for the units.', ]); // Elabora con i dati validati...}
Alle validation errors i client AI riprovano seguendo il messaggio: rendilo chiaro e azionabile.
<?phpnamespace App\Mcp\Prompts;use Laravel\Mcp\Server\Prompt;use Laravel\Mcp\Server\Prompts\Argument;class DescribeWeatherPrompt extends Prompt{ public function arguments(): array { return [ new Argument( name: 'tone', description: 'The tone to use in the weather description (e.g., formal, casual, humorous).', required: true, ), ]; }}
<?phpnamespace App\Mcp\Prompts;use Laravel\Mcp\Request;use Laravel\Mcp\Response;use Laravel\Mcp\Server\Prompt;class DescribeWeatherPrompt extends Prompt{ public function handle(Request $request): array { $tone = $request->string('tone'); $systemMessage = "You are a helpful weather assistant. Please provide a weather description in a {$tone} tone."; $userMessage = 'What is the current weather like in Tokyo?'; return [ Response::text($systemMessage)->asAssistant(), Response::text($userMessage), ]; }}
<?phpnamespace App\Mcp\Resources;use Laravel\Mcp\Request;use Laravel\Mcp\Response;use Laravel\Mcp\Server\Attributes\Description;use Laravel\Mcp\Server\Resource;#[Description('Comprehensive guidelines for using the Weather API.')]class WeatherGuidelinesResource extends Resource{ public function handle(Request $request): Response { $guidelines = "# Weather API Guidelines\n\n- Always specify a location..."; return Response::text($guidelines); }}
Le resource non hanno schema di input né argomenti, ma puoi accedere alle info della richiesta.
<?phpnamespace App\Mcp\Resources;use Laravel\Mcp\Request;use Laravel\Mcp\Response;use Laravel\Mcp\Server\Resource;class WeatherGuidelinesResource extends Resource{ public function handle(Request $request): Response { // Info della richiesta... }}
Laravel MCP supporta le MCP Apps: estensione del protocollo per applicazioni HTML interattive renderizzate in iframe sandbox all’interno dell’host. Puoi costruire dashboard, form, visualizzazioni.Un’app MCP ha due parti:
App resource — restituisce l’HTML autonomo
Tool — collegato alla resource con l’attribute #[RendersApp]
Crea due file: PHP in app/Mcp/Resources e vista Blade in resources/views/mcp (dedotta dal nome della classe; WeatherDashboardApp → mcp.weather-dashboard-app).
AppResource estende Resource e configura URI ui:// e MIME text/html;profile=mcp-app. Registrala nel server come le altre.La vista Blade usa <x-mcp::app>, che include l’SDK client-side MCP.
createMcpApp è fornita dall’SDK. Gestisce connessione dell’iframe, tema dell’host, helper come callServerTool, sendMessage, openLink. Vedi le specifiche MCP Apps.
Library::Tailwind, Library::Alpine ecc. hanno gli script CDN preimpostati; le origini vanno automaticamente in CSP. Permission::Camera, Microphone, Geolocation, ClipboardWrite per i permessi.
Per config dinamica, sovrascrivi appMeta sulla resource usando i builder fluenti AppMeta, Csp, Permissions in Laravel\Mcp\Server\Ui.
Laravel MCP include un riferimento di Boostmcp-development per costruire MCP Apps. L’agente può generare automaticamente app resource, viste Blade e tool collegati.Per il riferimento completo del protocollo consulta la documentazione ufficiale MCP Apps.
use App\Mcp\Servers\WeatherServer;use Laravel\Mcp\Facades\Mcp;Mcp::oauthRoutes();Mcp::web('/mcp/weather', WeatherServer::class) ->middleware('auth:api');
Pubblica le viste e configurale:
php artisan vendor:publish --tag=mcp-views
use Laravel\Passport\Passport;Passport::authorizationView(function ($parameters) { return view('mcp.authorize', $parameters);});
public function handle(Request $request): Response{ if (! $request->user()->can('read-weather')) { return Response::error('Permission denied.'); } // ...}
Oltre al server, Laravel MCP offre un client per connettersi ad altri server MCP e usare i tool esposti. Utile per fornire tool esterni ai propri agenti AI.
Registra le route OAuth in routes/ai.php con oAuthRoutesFor. La closure riceve il nome del client e il TokenSet dopo lo scambio del codice.
use Illuminate\Support\Facades\Auth;use Laravel\Mcp\Client\OAuth\TokenSet;use Laravel\Mcp\Facades\Mcp;Mcp::oAuthRoutesFor('github', function (string $client, TokenSet $token) { Auth::user()->update([ 'github_mcp_token' => $token->accessToken, ]); return redirect('/dashboard');});
Vengono create due route con nome: mcp.oauth.{client}.connect (redirect al server di autorizzazione) e mcp.oauth.{client}.callback (scambio del codice, chiamata all’handler). Usano il middleware web (sovrascrivibile via argomento middleware).Per iniziare il flow:
use Laravel\Mcp\Facades\Mcp;$result = Mcp::client('github')->readResource('weather://guidelines');$result->content();(string) $result;$result->mimeType();$result->contents;
test('tool', function () { $response = WeatherServer::tool(CurrentWeatherTool::class, [ 'location' => 'Tokyo', 'units' => 'celsius', ]); $response ->assertOk() ->assertSee('The current weather in Tokyo is 22°C and sunny.');});
public function test_tool(): void{ $response = WeatherServer::tool(CurrentWeatherTool::class, [ 'location' => 'Tokyo', 'units' => 'celsius', ]); $response ->assertOk() ->assertSee('The current weather in Tokyo is 22°C and sunny.');}
$response->assertHasErrors();$response->assertHasErrors([ 'Something went wrong.',]);$response->assertHasNoErrors();
Nome, titolo, descrizione:
$response->assertName('current-weather');$response->assertTitle('Current Weather Tool');$response->assertDescription('Fetches the current weather forecast for a specified location.');