DEV Community

HostingSeekers
HostingSeekers

Posted on Originally published at hostingseekers.com

How to Connect and Use Laravel with an MCP Server

The Model Context Protocol (MCP) is an open standard that gives AI models a structured way to interact with external applications—not through a messy chatbot wrapper, but via actual function calls directly into your codebase.

Building an MCP server in Laravel lets you tap into patterns you already know. Instead of implementing a protocol spec by hand, you get Artisan scaffolding, automatic dependency injection via the service container, built-in validation rules, and authentication support.

Here is a practical guide on how to set up, build, and test an MCP server inside a Laravel application. For the full, detailed walkthrough, you can also check out the complete HostingSeekers guide on connecting Laravel with an MCP server.

Prerequisites
Before you begin, ensure your environment meets the following requirements:

Laravel 12.x or 13.x

PHP 8.2 or higher

Composer

An MCP-compatible client for testing (such as Claude Desktop) or the built-in Artisan inspector tool.

Step 1: Install the Laravel MCP Package
First, pull the official package into your project using Composer:

Bash
composer require laravel/mcp
Enter fullscreen mode Exit fullscreen mode

Next, publish the dedicated routing configuration:

Bash
php artisan vendor:publish --tag=ai-routes
Enter fullscreen mode Exit fullscreen mode

This creates a new routes/ai.php file in your application. MCP traffic has distinct protocol expectations and security requirements, so keeping it isolated here prevents it from mixing with your standard web.php or api.php routes.

Step 2: Create Your First MCP Server
Scaffold a new server using the Artisan command:

Bash
php artisan make:mcp-server WeatherServer
Enter fullscreen mode Exit fullscreen mode

This generates a server class in app/Mcp/Servers/WeatherServer.php that extends Laravel MCP's base Server class:

PHP

<?php

namespace App\Mcp\Servers;

use Laravel\Mcp\Server\Attributes\Instructions;
use Laravel\Mcp\Server\Attributes\Name;
use Laravel\Mcp\Server\Attributes\Version;
use Laravel\Mcp\Server;

#[Name('Weather Server')]
#[Version('1.0.0')]
#[Instructions('This server provides weather information and forecasts.')]
class WeatherServer extends Server
{
    protected array $tools = [
        // CurrentWeatherTool::class,
    ];

    protected array $resources = [
        // WeatherGuidelinesResource::class,
    ];

    protected array $prompts = [
        // DescribeWeatherPrompt::class,
    ];
}
Enter fullscreen mode Exit fullscreen mode

Note on #[Instructions]: The AI client reads this attribute to understand how your server should be used. Write a clear description rather than a generic placeholder so the model knows when to reach for your server.

Step 3: Register the Server in routes/ai.php
Depending on whether your client is local or remote, register your server appropriately inside routes/ai.php:

For HTTP (Remote/Production): Use Mcp::web() so hosted AI clients can reach your application over a URL endpoint.

PHP
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;

Mcp::web('/mcp/weather', WeatherServer::class)
    ->middleware(['throttle:mcp']); %}
Enter fullscreen mode Exit fullscreen mode

For Local Development: Use Mcp::local() if the client and server run on the same machine (ideal for local AI coding assistants).

PHP
Mcp::local('weather', WeatherServer::class);

Enter fullscreen mode Exit fullscreen mode

Step 4: Build a Tool the AI Can Call
Tools represent the actions a model can invoke. Scaffold a tool with Artisan:

Bash
php artisan make:mcp-tool CurrentWeatherTool
Implement the tool by defining its execution logic and input schema:

<?php

namespace 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;
use Laravel\Mcp\Server\Tools\Annotations\IsIdempotent;
use Laravel\Mcp\Server\Tools\Annotations\IsReadOnly;

#[Description('Fetches the current weather forecast for a specified location.')]
#[IsIdempotent]
#[IsReadOnly]
class CurrentWeatherTool extends Tool
{
    public function handle(Request $request): Response
    {
        $location = $request->get('location');

        // Fetch weather data...
        return Response::text("The weather in {$location} is sunny.");
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'location' => $schema->string()
                ->description('The location to get the weather for.')
                ->required(),
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

Pro-Tip on Descriptions and Safety Annotations
Descriptions a %}re interfaces: The AI model reads #[Description] and the field descriptions to determine how to call your tool. Never leave them blank or generic.

Safety Annotations: Annotations like #[IsReadOnly], #[IsIdempotent], and #[IsDestructive] help clients understand what a tool does before execution, ensuring safer interactions—especially for tools that modify or delete data.

Register the tool in your WeatherServer class:


PHP
protected array $tools = [
    CurrentWeatherTool::class,
];
Enter fullscreen mode Exit fullscreen mode

Step 5: Test Your MCP Server
Before connecting a live AI client, use the built-in Artisan inspector to verify your setup:

Bash
# For a web server registered at /mcp/weather
php artisan mcp:inspector mcp/weather
Enter fullscreen mode Exit fullscreen mode

For a local server

php artisan mcp:inspector weather
This opens an interactive testing session where you can inspect your tools, check schemas, and fire test calls manually.

Top comments (0)