使用说明
Laravel MCP Server by OP.GG
Build a route-first MCP server in Laravel and Lumen
English | Português do Brasil | 한국어 | Русский | 简体中文 | 繁體中文 | Polski | Español
重大变化2.0.0
- 端点设置从配置驱动的注册转移到路由驱动的注册。
- 流式HTTP是唯一支持的传输方式。
- 服务器元数据变异体被整合到
setServerInfo(...). - 已从运行时中删除旧工具传输方法(
messageType(),ProcessMessageType::SSE).
完整迁移指南: docs/migrations/v2.0.0-migration.md
概述
Laravel MCP Server为Laravel和Lumen提供基于路由的MCP端点注册。
要点:
- 可流式HTTP传输
- 路由优先配置(
Route::mcp(...)/McpRoute::register(...)) - 每个端点的工具、资源、资源模板和提示注册
- 路由缓存兼容端点元数据
需求
- PHP>=8.2
- Laravel(发光)>=9.x
- 流明>=9.x(可选)
快速开始
1) 安装
composer require opgginc/laravel-mcp-server
2) 注册一个端点(Laravel)
use Illuminate\Support\Facades\Route;
use OPGG\LaravelMcpServer\Enums\ProtocolVersion;
use OPGG\LaravelMcpServer\Services\ToolService\Examples\HelloWorldTool;
use OPGG\LaravelMcpServer\Services\ToolService\Examples\VersionCheckTool;
Route::mcp('/mcp')
->setServerInfo(
name: 'OP.GG MCP Server',
version: '2.0.0',
)
->setConfig(
compactEnumExampleCount: 3,
)
->setProtocolVersion(ProtocolVersion::V2025_11_25)
->enabledApi()
->tools([
HelloWorldTool::class,
VersionCheckTool::class,
]);
如果您需要与不支持的客户端兼容 2025-11-25,设置:
->setProtocolVersion(ProtocolVersion::V2025_06_18)
3) 验证
php artisan route:list | grep mcp
php artisan mcp:test-tool --list --endpoint=/mcp
快速JSON-RPC检查:
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
按查询字符串进行动态工具筛选
如果一个端点需要根据传入的URL公开不同的工具集,请将动态工具解析器附加到路由。 解析器拥有端点的声明工具目录和每个请求的可见子集。
use OPGG\LaravelMcpServer\Data\ToolResolutionContext;
use OPGG\LaravelMcpServer\Routing\McpEndpointDefinition;
use OPGG\LaravelMcpServer\Services\ToolService\DynamicToolResolverInterface;
final class LolPhaseToolResolver implements DynamicToolResolverInterface
{
public function declaredTools(McpEndpointDefinition $endpoint): array
{
return [
\App\MCP\Tools\LolSearchChampionMetaTool::class,
\App\MCP\Tools\LolGetChampionAnalysisTool::class,
\App\MCP\Tools\LolGetLiveItemRecommendationsTool::class,
];
}
public function resolve(
McpEndpointDefinition $endpoint,
ToolResolutionContext $context,
): array {
return match ($context->queryParameters['phase'] ?? null) {
'lobby' => [
\App\MCP\Tools\LolSearchChampionMetaTool::class,
\App\MCP\Tools\LolGetChampionAnalysisTool::class,
],
'inprogress' => [
\App\MCP\Tools\LolGetLiveItemRecommendationsTool::class,
],
default => $this->declaredTools($endpoint),
};
}
public function consumedQueryParameters(): array
{
return ['phase'];
}
}
Route::mcp('/mcp/voice/lol/live')
->setServerInfo(
name: 'OP.GG MCP Server - Voice lol Live',
version: '1.0.0',
)
->dynamicTools(LolPhaseToolResolver::class);
请求示例:
/mcp/voice/lol/live?phase=lobby
/mcp/voice/lol/live?phase=inprogress
相同的过滤工具集一致地应用于:
tools/listtools/calltools/executePOST /tools/{tool_name}当->enabledApi()已启用
如果同一端点也使用 POST /tools/{tool_name},您可以选择公开
consumedQueryParameters(): array 只应使用查询键的解析器挂钩
用于过滤,而不是作为工具参数转发。这个钩子是一个有记录的惯例
不属于 DynamicToolResolverInterface;省略它的解析器将转发这些查询键
作为工具论证。
管腔设置
// bootstrap/app.php
$app->withFacades();
$app->withEloquent();
$app->register(OPGG\LaravelMcpServer\LaravelMcpServerServiceProvider::class);
use OPGG\LaravelMcpServer\Routing\McpRoute;
use OPGG\LaravelMcpServer\Services\ToolService\Examples\HelloWorldTool;
McpRoute::register('/mcp')
->setServerInfo(
name: 'OP.GG MCP Server',
version: '2.0.0',
)
->tools([
HelloWorldTool::class,
]);
最低安全(生产)
在MCP路由组上使用Laravel中间件。
use Illuminate\Support\Facades\Route;
Route::middleware([
'auth:sanctum',
'throttle:100,1',
])->group(function (): void {
Route::mcp('/mcp')
->setServerInfo(
name: 'Secure MCP',
version: '2.0.0',
)
->tools([
\App\MCP\Tools\MyCustomTool::class,
]);
});
v2.0.0迁移说明(从v1.0.0开始)
- MCP端点设置从配置转移到路由注册。
- 流式HTTP是唯一的传输方式。
- 服务器元数据变异体被整合到
setServerInfo(...). - 工具迁移命令可用于旧签名:
php artisan mcp:migrate-tools
完整指南: docs/migrations/v2.0.0-migration.md
高级功能(快速链接)
- 创建工具:
php artisan make:mcp-tool ToolName - 创建资源:
php artisan make:mcp-resource ResourceName - 创建资源模板:
php artisan make:mcp-resource-template TemplateName - 创建提示:
php artisan make:mcp-prompt PromptName - 创建通知:
php artisan make:mcp-notification HandlerName --method=notifications/method - 从OpenAPI生成:
php artisan make:swagger-mcp-tool <spec-url-or-file> - 将工具导出到OpenAPI:
php artisan mcp:export-openapi --output=storage/api-docs-mcp/api-docs.json
代码参考:
- 工具示例:
src/Services/ToolService/Examples/ - 资源示例:
src/Services/ResourceService/Examples/ - 及时服务:
src/Services/PromptService/ - 通知处理程序:
src/Server/Notification/ - 路线建设者:
src/Routing/McpRouteBuilder.php
Swagger/OpenAPI->MCP工具
根据Swagger/OpenAPI规范生成MCP工具:
# From URL
php artisan make:swagger-mcp-tool https://api.example.com/openapi.json
# From local file
php artisan make:swagger-mcp-tool ./specs/openapi.json
有用的选项:
php artisan make:swagger-mcp-tool ./specs/openapi.json \
--group-by=tag \
--prefix=Billing \
--test-api
--group-by:tag,path,或none--prefix:生成的工具/资源的类名前缀--test-api:生成前测试端点连接
生成行为:
- 在交互模式下,您可以为每个端点选择“工具”或“资源”。
- 在非交互模式下,
GET端点作为资源生成,其他方法作为工具生成。
增强的交互式预览
如果你运行命令时没有 --group-by,生成器在创建之前显示文件夹结构和文件计数的交互式预览。
php artisan make:swagger-mcp-tool ./specs/openapi.json
预览输出示例:
Choose how to organize your generated tools and resources:
Tag-based grouping (organize by OpenAPI tags)
Total: 25 endpoints -> 15 tools + 10 resources
Examples: Tools/Pet, Tools/Store, Tools/User
Path-based grouping (organize by API path)
Total: 25 endpoints -> 15 tools + 10 resources
Examples: Tools/Api, Tools/Users, Tools/Orders
No grouping (everything in root folder)
Total: 25 endpoints -> 15 tools + 10 resources
Examples: Tools/, Resources/
生成后,在MCP端点上注册生成的工具类:
use Illuminate\Support\Facades\Route;
Route::mcp('/mcp')
->setServerInfo(
name: 'Generated MCP Server',
version: '2.0.0',
)
->tools([
\App\MCP\Tools\Billing\CreateInvoiceTool::class,
\App\MCP\Tools\Billing\UpdateInvoiceTool::class,
]);
MCP工具->OpenAPI导出
导出所有已注册 ToolInterface 课程(通过 Route::mcp(...)->tools([...]) 或 ->dynamicTools(...))使用每个工具创建OpenAPI JSON文档 inputSchema().
只有配置了的端点 ->enabledApi() 包含在此导出中,并通过以下方式公开 POST /tools/{tool_name}.
操作按端点分组 name 使用OpenAPI tags.
如果多个端点注册了相同的工具名称,则操作将保留首次注册行为,并将所有匹配的端点名称合并到 tags.
如果缺少路线注册,该命令会自动在默认路径下发现工具: app/MCP/Tools 和 app/Tools.
# Default output: storage/api-docs-mcp/api-docs.json
php artisan mcp:export-openapi
# Custom output + metadata
php artisan mcp:export-openapi \
--output=storage/app/mcp.openapi.json \
--title="MCP Tools API" \
--api-version=2.1.0
# Limit to one endpoint (id or path)
php artisan mcp:export-openapi --endpoint=/mcp
# Discover tools from additional directory paths
php artisan mcp:export-openapi --discover-path=app/MCP/Tools
# Existing output is overwritten by default
php artisan mcp:export-openapi
启用工具API路由生成:
use Illuminate\Support\Facades\Route;
Route::mcp('/mcp')
->setServerInfo(name: 'OP.GG MCP Server', version: '2.0.0')
->enabledApi()
->tools([
\App\MCP\Tools\GreetingTool::class,
]);
Swagger UI测试提示:
- 导出操作使用
query parameters仅(否requestBody)用于更简单的手动测试。 - 每个工具的必填字段
inputSchema().required反映在Swagger参数验证中。 - 枚举字段导出时使用
schema.enum因此Swagger呈现下拉选择。 - 数组字段导出时使用
style=form+explode=true(重复密钥格式,例如。desired_output_fields=items&desired_output_fields=runes). /tools/{tool_name}参数解析更喜欢查询参数而不是正文/表单有效载荷,以避免Swagger冲突。- 无显式枚举字段
default/example从第一个枚举值(或第一个非空枚举值)自动填充。 - 具有以下描述的字符串字段
e.g., en_US, ko_KR, ja_JP自动推断第一个样本值为default和example.
工具类示例
<?php
namespace App\MCP\Tools;
use App\Enums\Platform;
use OPGG\LaravelMcpServer\JsonSchema\JsonSchema;
use OPGG\LaravelMcpServer\Services\ToolService\ToolInterface;
class GreetingTool implements ToolInterface
{
public function name(): string
{
return 'greeting-tool';
}
public function description(): string
{
return 'Return a greeting message.';
}
public function inputSchema(): array
{
return [
'name' => JsonSchema::string()
->description('Developer Name')
->required(),
'platform' => JsonSchema::string()
->enum(Platform::class)
->description('Client platform')
->compact(),
];
}
public function annotations(): array
{
return [
'readOnlyHint' => true,
'destructiveHint' => false,
];
}
public function execute(array $arguments): mixed
{
return [
'message' => 'Hello '.$arguments['name'],
];
}
}
JsonSchema生成器(Laravel风格)
此包在下面提供了自己的JsonSchema构建器 OPGG\LaravelMcpServer 命名空间。
你可以用Laravel 12风格的流畅格式定义工具模式,同时保持 inputSchema(): array.
<?php
namespace App\MCP\Tools;
use App\Enums\Platform;
use OPGG\LaravelMcpServer\JsonSchema\JsonSchema;
use OPGG\LaravelMcpServer\Services\ToolService\ToolInterface;
class WeatherTool implements ToolInterface
{
public function name(): string
{
return 'weather-tool';
}
public function description(): string
{
return 'Get weather by location.';
}
public function inputSchema(): array
{
return [
'location' => JsonSchema::string()
->description('Location to query')
->required(),
'platform' => JsonSchema::string()
->enum(Platform::class)
->description('Client platform'),
'days' => JsonSchema::integer()
->min(1)
->max(7)
->default(1),
];
}
public function annotations(): array
{
return [];
}
public function execute(array $arguments): mixed
{
return ['ok' => true];
}
}
笔记:
- 仍然支持现有的完整JSON模式数组。
enum()接受数组或BackedEnum::class.compact()之后可以用链子锁住enum()移除enum从已发出的模式中提取并附加一个简洁的提示description(compact(),compact(null),compact(3),或compact('custom hint')).- 默认压缩示例计数为
3,并且可以通过以下方式对每个端点进行覆盖Route::mcp(...)->setConfig(compactEnumExampleCount: N). - 导出时(
tools/listOpenAPI),属性映射会自动标准化为JSON模式对象格式。
提示类示例
<?php
namespace App\MCP\Prompts;
use OPGG\LaravelMcpServer\Services\PromptService\Prompt;
class WelcomePrompt extends Prompt
{
public string $name = 'welcome-user';
public ?string $description = 'Generate a welcome message.';
public array $arguments = [
[
'name' => 'username',
'description' => 'User name',
'required' => true,
],
];
public string $text = 'Welcome, {username}!';
}
示例资源类
<?php
namespace App\MCP\Resources;
use OPGG\LaravelMcpServer\Services\ResourceService\Resource;
class BuildInfoResource extends Resource
{
public string $uri = 'app://build-info';
public string $name = 'Build Info';
public ?string $mimeType = 'application/json';
public function read(): array
{
return [
'uri' => $this->uri,
'mimeType' => $this->mimeType,
'text' => json_encode([
'version' => '2.0.0',
'environment' => app()->environment(),
], JSON_THROW_ON_ERROR),
];
}
}
在路线上注册示例
use App\MCP\Prompts\WelcomePrompt;
use App\MCP\Resources\BuildInfoResource;
use App\MCP\Tools\GreetingTool;
use Illuminate\Support\Facades\Route;
Route::mcp('/mcp')
->setServerInfo(
name: 'Example MCP Server',
version: '2.0.0',
)
->tools([GreetingTool::class])
->resources([BuildInfoResource::class])
->prompts([WelcomePrompt::class]);
测试和质量命令
vendor/bin/pest
vendor/bin/phpstan analyse
vendor/bin/pint
翻译
pip install -r scripts/requirements.txt
export ANTHROPIC_API_KEY='your-api-key'
python scripts/translate_readme.py
翻译所选语言:
python scripts/translate_readme.py es ko
许可证
这个项目是在MIT许可下分发的。