Ce qui se passe
L'équipe Laravel publie Laravel MCP 1.0, première version stable du paquet
qui permet d'exposer les outils et les données d'une application Laravel à des
clients IA. Elle implémente la révision de protocole 2026-07-28.
La compatibilité descendante est assurée : un client qui se connecte encore avec
initialize reçoit une réponse en 2025-11-25 ou 2025-06-18, selon ce qu'il
demande.
Serveurs sans état
Le nouveau protocole remplace l'échange initialize par server/discover, et
chaque requête — HTTP comme stdio — porte désormais elle-même la version du
protocole et les capacités du client, dans params._meta.
Conséquence directe, ces éléments disparaissent : l'en-tête
MCP-Session-Id, les méthodes Request::sessionId() et
Request::setSessionId(), et l'événement SessionInitialized. Pour relier
plusieurs appels entre eux, il faut maintenant passer son propre identifiant dans
les arguments ou dans _meta.
Catalogue d'outils cherchable
Chaque définition d'outil envoyée au modèle consomme du contexte. ToolSearch
garde les outils courants dans la liste principale et place les autres derrière
une recherche :
use Laravel\Mcp\Server;
use Laravel\Mcp\Server\Tools\ToolSearch;
class WeatherServer extends Server
{
protected array $tools = [
CurrentWeatherTool::class, // toujours exposé
ToolSearch::class => [ // cherchés à la demande
HistoricalWeatherTool::class,
WeatherAlertsTool::class,
],
];
}Le paquet enregistre alors deux outils : search_tools, qui prend une requête et
une limite et renvoie les outils correspondants avec leurs entrées attendues, et
execute_tools, qui en exécute un ou plusieurs par nom.
Indications de cache
Un serveur peut annoncer ce qui est réutilisable, combien de temps, et si le cache peut être partagé entre utilisateurs :
#[Cacheable(ttlMs: 60_000, scope: CacheScope::Public)]
class WeatherServer extends Server
{
protected function cacheHints(): array
{
return ['tools/list' => new Cacheable(ttlMs: 30_000)];
}
}Le client Laravel suit ces indications quand on active withCache(). Une réponse
sans ttlMs, ou avec ttlMs à zéro, n'est pas mise en cache — et les appels
d'outils ne le sont jamais.
Ce qui casse à la mise à jour
C'est la partie à lire avant de toucher au code. Le middleware
ValidateMcpHeaders s'applique à toutes les routes enregistrées par
Mcp::web() :
- tout POST au nouveau protocole exige
MCP-Protocol-VersionetMcp-Method, cohérents avec le corps de la requête ; tools/call,prompts/getetresources/readexigent en plusMcp-Name, qui doit correspondre au nom de l'outil, du prompt, ou à l'URI de la ressource ;- un écart renvoie HTTP 400 avec le code JSON-RPC
-32020.
Vos tests qui envoient ces requêtes par postJson() doivent donc porter ces
en-têtes, ainsi que les champs params._meta. Les anciens clients en
initialize, eux, échappent à cette validation.
Côté OAuth, PKCE devient obligatoire : OAuthClient::redirect() lève une
OAuthException si le serveur d'autorisation omet
code_challenge_methods_supported de ses métadonnées. Les Client ID Metadata
Documents arrivent en remplacement de l'enregistrement dynamique de client,
déprécié par 2026-07-28 : le client_id devient l'URL HTTPS d'un document
JSON, servi par Mcp::oAuthRoutesFor() sur
GET /mcp/oauth/{client}/client-metadata.json. Dans ce cas
$token->clientSecret vaut null — la colonne qui le stocke doit accepter
null.
À retenir
La version 1.0 fige un protocole, elle ne fige pas votre code : la migration
depuis 0.9 touche les en-têtes, les tests et le schéma de la table des jetons. Le
guide de mise à jour
liste le reste, dont les changements de codes d'erreur et la suppression de la
constante Server::CAPABILITY_UI.