> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel MCP

> Intégrez un serveur Model Context Protocol (MCP) à votre application Laravel : définissez tools, resources et prompts pour vos agents IA.

## Qu'est-ce que MCP

**Model Context Protocol (MCP)** est une spécification pour la communication standardisée entre clients IA (Claude, Cursor, GitHub Copilot…) et les applications. En implémentant un serveur MCP, votre agent IA peut accéder aux données de votre app Laravel et déclencher des actions.

<Info>
  Laravel MCP est un package officiel ajouté sous Laravel 13, disponible sous `laravel/mcp`.
</Info>

Un serveur MCP fournit trois choses :

| Fonctionnalité | Description                                                                          |
| -------------- | ------------------------------------------------------------------------------------ |
| **Tools**      | Fonctions appelables par le client IA (recherche, mise à jour, appel d'API externe…) |
| **Resources**  | Données et contexte que le client peut lire                                          |
| **Prompts**    | Modèles de prompts réutilisables                                                     |

## Installation

```shell theme={null}
composer require laravel/mcp
```

Publiez les routes AI :

```shell theme={null}
php artisan vendor:publish --tag=ai-routes
```

Le fichier `routes/ai.php` est créé.

## Créer un serveur

```shell theme={null}
php artisan make:mcp-server WeatherServer
```

`app/Mcp/Servers` :

```php theme={null}
<?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 = [
        // GetCurrentWeatherTool::class,
    ];

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

    protected array $prompts = [
        // DescribeWeatherPrompt::class,
    ];
}
```

### Enregistrer le serveur

Dans `routes/ai.php`, deux modes possibles.

#### Serveur Web

Accessible via HTTP POST. Idéal pour les clients IA distants ou les intégrations web.

```php theme={null}
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;

Mcp::web('/mcp/weather', WeatherServer::class);
```

Middlewares habituels :

```php theme={null}
Mcp::web('/mcp/weather', WeatherServer::class)
    ->middleware(['throttle:mcp']);
```

#### Serveur local

Commande Artisan. Pour les clients IA locaux comme Claude Desktop.

```php theme={null}
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;

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

<Tip>
  Le client MCP démarre habituellement la commande automatiquement. Pas besoin d'exécuter `mcp:start` manuellement.
</Tip>

## Tools

Fonctions appelables par le client IA (accès aux données, appel d'API, opérations DB…).

### Créer un tool

```shell theme={null}
php artisan make:mcp-tool CurrentWeatherTool
```

Ajoutez-le à `$tools` du serveur.

```php theme={null}
use App\Mcp\Tools\CurrentWeatherTool;
use Laravel\Mcp\Server;

class WeatherServer extends Server
{
    protected array $tools = [
        CurrentWeatherTool::class,
    ];
}
```

Implémentation :

```php theme={null}
<?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;

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

        // Récupérer la météo...

        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(),
        ];
    }
}
```

### Nom et description

Nom et titre déduits du nom de classe (`CurrentWeatherTool` → `current-weather` / `Current Weather Tool`). Personnalisez avec `Name` et `Title`.

```php theme={null}
use Laravel\Mcp\Server\Attributes\Name;
use Laravel\Mcp\Server\Attributes\Title;

#[Name('get-optimistic-weather')]
#[Title('Get Optimistic Weather Forecast')]
class CurrentWeatherTool extends Tool
{
    // ...
}
```

<Warning>
  La description (`Description`) n'est pas auto-générée. Elle est essentielle pour que le modèle comprenne l'usage — soignez-la.
</Warning>

### Schéma d'entrée

`schema()` définit les paramètres via le builder de schéma JSON.

```php theme={null}
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'),
    ];
}
```

### Schéma de sortie

`outputSchema()` structure la réponse, facilitant l'analyse par le client.

```php theme={null}
public function outputSchema(JsonSchema $schema): array
{
    return [
        'temperature' => $schema->number()
            ->description('Temperature in Celsius')
            ->required(),

        'conditions' => $schema->string()
            ->description('Weather conditions')
            ->required(),

        'humidity' => $schema->integer()
            ->description('Humidity percentage')
            ->required(),
    ];
}
```

### Validation

Utilisez la validation Laravel standard dans `handle()`.

```php theme={null}
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.',
    ]);

    // Utilisez les données validées...
}
```

<Tip>
  Les messages d'erreur sont retournés au client IA, qui peut alors reformuler l'appel.
</Tip>

### Types de réponse

`Response::text()`, `Response::error()`, `Response::json()`, `Response::structured()`.

```php theme={null}
return Response::text('Simple text response');

return Response::error('Something went wrong');

return Response::json(['data' => $data]);

return Response::structured([
    'temperature' => 22,
    'conditions' => 'sunny',
    'humidity' => 60,
]);
```

### Notifications et pagination

Pour de longs traitements, envoyez des notifications de progression :

```php theme={null}
public function handle(Request $request): Response
{
    $this->notify('progress', ['step' => 1, 'total' => 3]);

    // Traitement...

    return Response::text('Done');
}
```

## Resources

Données/contexte lisible par le client.

### Créer une resource

```shell theme={null}
php artisan make:mcp-resource WeatherGuidelinesResource
```

Ajoutez-la à `$resources`.

```php theme={null}
protected array $resources = [
    WeatherGuidelinesResource::class,
];
```

Implémentation :

```php theme={null}
<?php

namespace App\Mcp\Resources;

use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Attributes\Description;
use Laravel\Mcp\Server\Resource;

#[Description('Guidelines for interpreting weather data.')]
class WeatherGuidelinesResource extends Resource
{
    public function handle(): Response
    {
        return Response::text(file_get_contents(
            resource_path('mcp/weather-guidelines.md')
        ));
    }
}
```

## Prompts

Templates de prompts réutilisables.

### Créer un prompt

```shell theme={null}
php artisan make:mcp-prompt DescribeWeatherPrompt
```

Ajoutez-le à `$prompts`.

```php theme={null}
protected array $prompts = [
    DescribeWeatherPrompt::class,
];
```

Implémentation :

```php theme={null}
<?php

namespace App\Mcp\Prompts;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Attributes\Description;
use Laravel\Mcp\Server\Prompt;

#[Description('Prompt for describing weather conditions.')]
class DescribeWeatherPrompt extends Prompt
{
    public function handle(Request $request): Response
    {
        $location = $request->get('location');

        return Response::text("Describe the weather in {$location} using vivid imagery.");
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'location' => $schema->string()
                ->description('Location for the weather description')
                ->required(),
        ];
    }
}
```

## Authentification et autorisation

Un serveur web MCP peut utiliser les middlewares standard.

```php theme={null}
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;

Mcp::web('/mcp/weather', WeatherServer::class)
    ->middleware(['auth:sanctum']);
```

Dans un tool, contrôlez les droits :

```php theme={null}
public function handle(Request $request): Response
{
    if (! $request->user()->can('view-weather')) {
        return Response::error('Unauthorized');
    }

    // ...
}
```

## Tests

Utilisez `TestServer` pour tester votre serveur MCP.

```php theme={null}
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Testing\TestServer;

test('current weather tool returns weather', function () {
    $server = new TestServer(WeatherServer::class);

    $response = $server->tool('current-weather', [
        'location' => 'Tokyo',
    ]);

    $response->assertSuccessful();
    $response->assertContains('sunny');
});
```

Testez schémas et validation :

```php theme={null}
$server = new TestServer(WeatherServer::class);

$response = $server->tool('current-weather', []);

$response->assertFailed();
$response->assertContains('location is required');
```

## Récapitulatif

<AccordionGroup>
  <Accordion title="Composants principaux">
    | Composant | Rôle                                |
    | --------- | ----------------------------------- |
    | Server    | Point d'entrée MCP                  |
    | Tool      | Fonction appelable par le client IA |
    | Resource  | Données lisibles par le client      |
    | Prompt    | Template de prompt réutilisable     |
  </Accordion>

  <Accordion title="Web vs Local">
    * **Web** (`Mcp::web`) : HTTP POST, clients distants ou intégrations web
    * **Local** (`Mcp::local`) : Commande Artisan, clients IA locaux (Claude Desktop, etc.)
  </Accordion>

  <Accordion title="Bonnes pratiques">
    * Une description claire pour chaque tool
    * Schémas d'entrée avec `enum` / `required` / `default` pour orienter l'agent
    * Retournez des `outputSchema` structurés quand pertinent
    * Utilisez la validation Laravel pour renvoyer des erreurs compréhensibles
    * Testez avec `TestServer`
  </Accordion>
</AccordionGroup>


## Related topics

- [Créer un serveur MCP avec Laravel](/fr/advanced/mcp-server.md)
- [Laravel AI SDK](/fr/ai-sdk.md)
- [Laravel Console Starter](/fr/packages/laravel-console-starter/index.md)
- [MCP](/fr/packages/laravel-copilot-sdk/mcp.md)
- [Laravel Boost](/fr/boost.md)
