laravel mcp发生器
自动生成 laravel/mcp 服务器从您现有的Laravel API路由。
运行一个Artisan命令,得到一个完全有线的MCP服务器——真正的Tool类,一个server类, 以及路由注册——所有这些都可以直接从应用程序中提取逻辑,而无需HTTP调用。
______________________________________________________________________
需求
- PHP 8.2+
- Laravel 10、11或12(任何支持
laravel/mcp) laravel/mcp安装在宿主应用程序中
______________________________________________________________________
安装
composer require stayingplus/laravel-mcp-generator发布配置文件:
php artisan vendor:publish --tag=mcp-generator-config______________________________________________________________________
用法
生成所有内容
php artisan mcp:generate这将:
- 扫描配置下的所有路由
route_prefix(默认值:api) - 为每条路线编写一个工具类→
app/Mcp/Tools/{Name}ApiTool.php - 编写服务器类→
app/Mcp/Servers/ApiServer.php - 附加路线注册→
routes/ai.php
旗帜
| 标志 | 描述 |
|---|---|
--dry-run | 预览以下所有文件 *会* 无需编写任何内容即可生成 |
--force | 覆盖现有文件而不提示 |
--only=users,orders | 生成包含这些前缀的路由名称/URI的作用域 |
--include-destructive | 包括DELETE路由(默认情况下排除在外——请参阅配置) |
示例
# Preview without writing
php artisan mcp:generate --dry-run
# Only generate tools for the "users" and "orders" route groups
php artisan mcp:generate --only=users,orders
# Include destructive (DELETE) routes for this run only
php artisan mcp:generate --include-destructive
# Regenerate everything, overwriting existing files
php artisan mcp:generate --force______________________________________________________________________
生成的文件结构
app/
└── Mcp/
├── Servers/
│ └── ApiServer.php ← extends Laravel\Mcp\Server
└── Tools/
├── GetUsersApiTool.php ← GET /api/users
├── PostUsersApiTool.php ← POST /api/users
└── GetUsersApiTool.php ← GET /api/users/{id}
routes/
└── ai.php ← Mcp::web('/mcp', ApiServer::class)生成工具示例
#[Name('get-users')]
#[Title('Get Users')]
#[Description('List all users with optional filters.')]
#[IsReadOnly(true)]
#[IsIdempotent(true)]
class GetUsersApiTool extends Tool
{
public function schema(JsonSchema $schema): array
{
return [
'status' => $schema->string()->enum(['active', 'inactive']),
];
}
public function handle(Request $request): Response
{
$status = $request->get('status');
// ...
return Response::structured($data);
}
}______________________________________________________________________
逻辑提取策略
生成器在构建每个优先级链时使用此优先级链 handle() 主体:
- 建造商注入服务/行动 --控制器的构造函数是
如果发现非原始依赖关系(服务、存储库、数据库等), 动作类),它们通过以下方式解决 app() 直接呼叫模板为 以a发射 // TODO: 指向确切方法和参数的注释。
- 回退:未实现的存根 --当未检测到可注射依赖性时
(逻辑内联在控制器中),生成一个存根:
- 控制器方法需要注意的文件 - 演示如何在提取到Action类中后直接调用它 - 投掷a RuntimeException 在运行时,间隙立即可见
> 为什么不 app()->handle()? 通过HTTP内核进行委派会重新运行完整的 > 中间件堆栈——包括 auth:sanctumCSRF和会话——这将 > 拒绝未经身份验证的MCP工具调用。生成器不再发出此模式。
世代之后, 查看每个 handle() 身体 在部署之前。生成的 代码是一个起点,而不是生产就绪的逻辑。
已知限制
生成器通过以下方式检测可注入的依赖关系 仅用于构造函数注入. 两种模式尚未被检测到,并将传递到未实现的存根:
- 内联分辨率 —
app(SomeAction::class)在控制器方法体内部调用 - 方法注入 --直接在控制器方法上暗示的动作或服务类型,
例如 public function index(ListProductsAction $action, Request $request)
在这两种情况下,存根 // TODO: 注释将命名控制器方法。提取 将逻辑放入独立的Action类中,通过构造函数注入,然后重新运行 mcp:generate --force 得到一个有线 handle() 身体。
______________________________________________________________________
描述优先级链
这 #[Description(...)] 每个工具上的属性按以下顺序解析:
- 控制器方法文档块 --第一个非-
@tag直接使用文档块中的行。 - 人性化路线名称 --例如。
api.users.index→"Users index". - HTTP动词+URI —
"Handles GET /api/users"(最后手段)。
当docblock丢失时 // SUGGESTION: 在内部添加注释 handle() 展示 确切地说,哪个控制器方法需要一个文档块,它应该是什么样子的。在...的末尾 命令run,summary列出了需要注意的所有控制器方法:
⚠ The following controller methods need docblocks for better MCP descriptions:
- App\Http\Controllers\UserController::index()
- App\Http\Controllers\OrderController::store()要消除这些警告,请在每个列出的方法中添加一个摘要文档块:
/**
* List all users with optional filters.
*/
public function index(Request $request): JsonResponse______________________________________________________________________
配置
所有选项均已启用 config/mcp-generator.php:
return [
// Only routes whose URI starts with this prefix are introspected
'route_prefix' => 'api',
// MCP server settings
'server_name' => 'API Server',
'server_path' => '/mcp',
'middleware' => ['auth:sanctum'],
'transport' => 'web', // 'web' or 'local'
// Route URI patterns to always exclude
'exclude_routes' => ['telescope', 'horizon', '_debugbar', 'sanctum'],
// Control which HTTP verb categories are generated.
// DELETE routes are excluded by default; use --include-destructive to override per run.
'generate' => [
'read' => true,
'create' => true,
'update' => true,
'destructive' => false,
],
// Output paths relative to base_path()
'output' => [
'server_dir' => 'app/Mcp/Servers',
'tools_dir' => 'app/Mcp/Tools',
],
];永久启用破坏性路线生成
集 generate.destructive 到 true 在您的配置中,如果您的项目总是需要DELETE工具:
'generate' => [
'destructive' => true,
],______________________________________________________________________
验证→ JsonSchema映射
申请表格 rules() 数组被映射到 JsonSchema 建设者:
| Laravel规则 | 生成链 |
|---|---|
string | $schema->string() |
integer | $schema->integer() |
numeric | $schema->number() |
boolean | $schema->boolean() |
required | ->required() |
nullable | 省略 ->required() |
in:a,b,c | ->enum(['a','b','c']) |
max:N (字符串) | ->description('Max N characters.') |
min:N (字符串) | ->description('Min N characters.') |
max:N (int) | ->description('Maximum value: N.') |
min:N (int) | ->description('Minimum value: N.') |
email | ->description('Must be a valid email address.') |
url | ->description('Must be a valid URL.') |
路径 {param} | 作为必填字符串字段添加 |
______________________________________________________________________
贡献
- 分叉存储库
- 创建要素分支:
git checkout -b feat/my-feature - 为您的更改编写测试
- 运行测试套件:
composer test或./vendor/bin/pest - 提交拉取请求
请遵循 约定式提交 用于提交消息。
______________________________________________________________________
许可证
麻省理工学院——见 许可证.
