mcpField
L
Laravel MCP Server by OP.GG

Laravel MCP Server by OP.GG

本地服务
op.gg开发工具3306 天前更新

关于 Laravel MCP Server by OP.GG

Laravel MCP Server 是 OP.GG 开发的 Laravel 扩展包,用于在 Laravel 和 Lumen 中通过路由注册 MCP 端点。它基于 Streamable HTTP 传输,面向需要在 PHP 项目中构建可扩展 MCP 服务的团队。

主要功能

  1. 01基于路由注册 MCP 端点
  2. 02仅支持 Streamable HTTP 传输
  3. 03按端点注册工具、资源、资源模板与提示词
  4. 04根据查询参数动态过滤工具集
  5. 05由 OpenAPI 规范生成 MCP 工具

适用场景

  1. 01在现有 Laravel 应用中提供 MCP 接口
  2. 02将 Swagger/OpenAPI 接口转换为 MCP 工具
  3. 03按 URL 参数为不同客户端暴露不同工具集

MCP 相关

作为 MCP 服务端,它将已注册的工具、资源、提示词和通知处理器通过 Route::mcp 端点暴露给 MCP 客户端,并支持路由缓存。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

OP.GG 的 Laravel MCP 服务

在 Laravel 和 Lumen 中构建路由优先的 MCP 服务

构建状态 总下载量 最新稳定版本 许可证

官方网站

English | Português do Brasil | 한국어 | Русский | 简体中文 | 繁體中文 | Polski | Español

Laravel MCP 服务演示

2.0.0 重大变更

  • 端点设置从配置驱动的注册改为路由驱动的注册。
  • 仅支持 Streamable HTTP 传输。
  • 服务元数据修改方法已合并到 setServerInfo(...)。
  • 运行时已移除旧版工具传输方法(messageType()、ProcessMessageType::SSE)。

完整迁移指南:docs/migrations/v2.0.0-migration.md

概述

Laravel MCP Server 为 Laravel 和 Lumen 提供基于路由的 MCP 端点注册。

要点:

  • Streamable HTTP 传输
  • 路由优先配置(Route::mcp(...) / McpRoute::register(...))
  • 为每个端点注册工具、资源、资源模板和提示词
  • 端点元数据兼容路由缓存

要求

  • PHP >= 8.2
  • Laravel(Illuminate)>= 9.x
  • Lumen >= 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/list
  • tools/call
  • tools/execute
  • 启用 ->enabledApi() 时的 POST /tools/{tool_name}

如果同一端点还使用 POST /tools/{tool_name},可以选择在解析器中公开一个 consumedQueryParameters(): array 钩子,指定仅用于筛选、不转发为工具参数的查询键。此钩子是文档约定, 不属于 DynamicToolResolverInterface;未实现该钩子的解析器会将这些查询键转发为工具参数。

Lumen 设置

// 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 端点设置已从配置迁移至路由注册。
  • 仅支持 Streamable 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

使用每个工具的 inputSchema(),将所有已注册的 ToolInterface 类(通过 Route::mcp(...)->tools([...]) 或 ->dynamicTools(...))导出为 OpenAPI JSON 文档。 只有配置了 ->enabledApi() 的端点才会包含在导出内容中,并通过 POST /tools/{tool_name} 对外提供。 操作会使用 OpenAPI tags 按端点 name 分组。 如果多个端点注册了同名工具,操作会保留首次注册时的行为,并将所有匹配的端点名称合并到 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} 的参数解析优先使用查询参数,而非 body/form 载荷,以避免 Swagger 冲突。
  • 未显式指定 default/example 的枚举字段会自动填入第一个枚举值(或第一个非 null 枚举值)。
  • 描述中包含 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 风格)

此软件包在 OPGG\LaravelMcpServer 命名空间下提供自己的 JsonSchema 构建器。 你可以使用 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 Schema 数组。
  • enum() 接受数组或 BackedEnum::class。
  • 在 enum() 后链式调用 compact(),可以从生成的架构中移除 enum,并在 description 中追加紧凑提示(compact()、compact(null)、compact(3) 或 compact('custom hint'))。
  • 默认紧凑示例数量为 3,也可以通过 Route::mcp(...)->setConfig(compactEnumExampleCount: N) 按端点覆盖。
  • 导出时(tools/list、OpenAPI),属性映射会自动规范化为 JSON Schema 对象格式。

示例提示词类

<?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 许可证发行。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。