[控场AI]
· 8 分钟阅读· 4,452 字

Laravel 接入 MCP 服务器实战指南:从安装到测试

Laravel 接入 MCP 服务器实战指南:从安装到测试

Laravel 官方 MCP 包让 PHP 开发者用 Artisan 和服务容器快速搭建符合协议的 AI 工具服务器。

本文介绍了如何利用 Laravel 官方 MCP 包构建符合 Model Context Protocol 的服务器,让 AI 模型以结构化函数调用的方式与业务代码交互。文章从安装开始,覆盖了环境前提(Laravel 12/13、PHP 8.2+)、Composer 安装与 routes/ai.php 路由发布、用 Artisan 脚手架生成服务器类、通过 #[Name]/#[Version]/#[Instructions] 属性向客户端描述自身、以及 Mcp::web() 与 Mcp::local() 两种注册方式的取舍。在工具层面,强调 handle() 执行逻辑与 schema() 输入模式必须成对实现,并指出 #[Description] 与安全注解直接决定模型的调用成功率与客户端的安全策略。最后建议在接入真实客户端前,用 php artisan mcp:inspector 做交互式自测。

AI 模型与外部应用的交互方式正在从「聊天框包装」走向结构化函数调用,Model Context Protocol(MCP)就是这一转变的底层标准之一。它让模型能直接调用你的代码,而不是靠一句模糊的自然语言提示去猜测意图。对 Laravel 开发者来说,这意味着可以用熟悉的 Artisan、服务容器和验证规则来搭建 MCP 服务器,而不必从零实现协议规范。

rss source: How to Connect and Use Laravel with an MCP Server

为什么在 Laravel 里构建 MCP 服务器

MCP 的价值在于把 AI 能力嵌入既有工程体系。Laravel 的官方包把协议细节封装成框架原生概念:用 Artisan 生成脚手架、通过服务容器自动注入依赖、复用内置验证规则和认证支持。你不需要手写协议解析,只需要定义「工具」和它们接受的参数。

这种做法的直接好处是可维护性。MCP 流量和普通 Web 请求在协议预期与安全要求上并不相同,因此官方包单独生成一份 routes/ai.php,把它与 web.php、api.php 隔离,避免路由和安全策略互相污染。

什么是 Model Context Protocol(MCP)? MCP 是由 Anthropic 于 2024 年底开源的一项标准协议,用于规范 AI 模型与外部工具、数据源之间的通信方式。它采用 JSON-RPC 2.0 作为消息格式,定义了三种核心能力:Tools(模型可主动调用的函数)、Resources(模型可读取的数据)、Prompts(预设的提示模板)。与传统的「聊天框包装」不同,MCP 让模型通过结构化的 schema 精确理解每个工具接受的参数类型和约束,从而减少猜测带来的调用错误。MCP 服务器本质上是一个遵循该协议规范的服务端,客户端(如 Claude Desktop、Cursor 等)会先拉取服务器的能力清单,再按需发起调用。因为协议本身与语言无关,Laravel MCP 包所做的,就是把协议细节翻译成 PHP 开发者熟悉的 Artisan 命令、服务容器和中间件体系。

环境准备与安装

开始前需要满足几个前提:Laravel 12.x 或 13.x、PHP 8.2 以上、Composer,以及一个可测试的 MCP 客户端(例如 Claude Desktop,或使用内置的 Artisan inspector)。

安装通过 Composer 完成,随后发布专属路由配置:

composer require laravel/mcp
php artisan vendor:publish --tag=ai-routes

这一步会在应用中生成 routes/ai.php。把它当作 MCP 的「入口层」,后续所有服务器的注册都集中在这里。

创建并注册第一个 MCP 服务器

用 Artisan 脚手架生成服务器类:

php artisan make:mcp-server WeatherServer

生成的类位于 app/Mcp/Servers/WeatherServer.php,继承 Laravel MCP 的基础 Server 类。类上的 #[Name]、#[Version]、#[Instructions] 三个属性并非装饰,AI 客户端会读取它们来判断何时调用你的服务器。原文特别提醒:#[Instructions] 要写清楚用途,而不是留一个通用占位符,否则模型不知道什么时候该伸手调用它。

服务器内部有三个数组:$tools、$resources、$prompts,分别对应可执行动作、可读取资源和提示模板。

本地还是远程:两种注册方式

注册位置决定了 AI 客户端能否访问到你的服务器。

HTTP(远程/生产):使用 Mcp::web(),让托管的 AI 客户端通过 URL 端点访问:

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

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

本地开发:使用 Mcp::local(),适合客户端和服务器运行在同一台机器的场景,例如本地 AI 编程助手:

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

两种方式的取舍很直接:一旦要对外暴露给托管的 AI 客户端,就必须走 web() 并考虑限流中间件;如果只是本机调试,local() 更省事。

构建一个 AI 能调用的工具

工具(Tool)是模型可以调用的具体动作。用 Artisan 生成:

php artisan make:mcp-tool CurrentWeatherTool

工具类需要实现两部分:执行逻辑 handle() 和输入模式 schema()。

#[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');
        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(),
        ];
    }
}

描述与安全注解不是可选项

原文给出两条实践建议,值得单独拎出来。

第一,描述即接口。AI 模型读取 #[Description] 以及每个字段的 description 来决定如何调用工具。留空或写通用描述,等于让模型去猜参数含义,调用失败率会明显上升。

第二,安全注解是给客户端的信号。#[IsReadOnly]、#[IsIdempotent]、#[IsDestructive] 让客户端在执行前就知道这个工具会不会改数据、能不能重复调用。对于会修改或删除数据的工具,这类注解尤其重要。

定义完成后,把工具类加入服务器的 $tools 数组即可生效:

protected array $tools = [
    CurrentWeatherTool::class,
];

三个安全注解的具体含义。 #[IsReadOnly] 表示该工具只读取数据、不产生任何副作用,客户端可以放心地在只读上下文中调用;#[IsIdempotent] 表示无论调用多少次结果都相同,适合用于查询、计算类操作,客户端可以在重试时安全地重复调用;#[IsDestructive] 则警告该工具可能修改或删除数据,客户端通常会要求用户显式确认后才执行。这三个注解本质上是在向 AI 客户端传递「风险等级」信号,让客户端在执行前决定是否需要额外的审批步骤。从工程角度看,注解是一种轻量级的契约声明,它不替代代码层面的权限校验,而是与之互补——注解告诉客户端「这个操作有多危险」,服务端的认证和授权则决定「这个请求是否被允许执行」。

连接真实客户端前先自测

在接入 Claude Desktop 之类的真实 AI 客户端之前,用内置的 Artisan inspector 验证配置:


**MCP Inspector 的工作方式。** `php artisan mcp:inspector` 启动的交互式会话,本质上是一个内置的 MCP 客户端,它会按照协议规范向你的服务器发起握手、请求能力列表、展示每个工具的 JSON Schema,并允许你手动填入参数触发真实调用。这意味着你可以在不依赖 Claude Desktop 或任何外部 AI 客户端的情况下,独立验证服务器的协议实现是否正确。常见的排查场景包括:schema 中某个字段的 required 声明缺失导致调用被拒、描述文本过于模糊导致模型选错工具、以及 handle() 内部抛出的异常是否被正确转换为协议层的错误响应。建议把 inspector 测试作为开发流程中的固定步骤,在每次修改工具定义后先跑一遍,再接入真实客户端。
# 已注册为 Web 服务器的情况
php artisan mcp:inspector mcp/weather

# 本地服务器的情况
php artisan mcp:inspector weather

这会打开一个交互式测试会话,可以检查工具列表、查看 schema、手动触发测试调用。相比直接连接客户端后靠报错排查,这一步能更快定位 schema 定义错误或参数缺失问题。

这套方案适合谁

如果你的团队已经在用 Laravel,并且希望让 AI 助手直接读取或操作业务数据,MCP 提供了一条不必自造协议的路。它复用了你已有的验证、认证和依赖注入体系,代价是需要在 routes/ai.php 里单独管理一套入口。

需要注意的是,原文演示的天气工具只是骨架,handle() 里的数据获取逻辑被省略了。生产环境中,工具的安全注解、参数校验和权限边界都需要根据实际业务重新设计——尤其是那些会写数据的工具,#[IsDestructive] 之类的注解应当被视为最低要求,而非全部防护。

#Laravel MCP#MCP 服务器#Model Context Protocol#Laravel AI#MCP 工具开发#Artisan 命令#AI 函数调用
分享:

相关推荐