Emeq MCP Laravel
](https://packagist.org/packages/emeq/emeq-mcp-laravel) ](https://packagist.org/packages/emeq/emeq-mcp-laravel)
Laravel MCP(模型上下文协议)包与Boost集成,提供辅助工具、预构建的工具/资源/提示,以及Laravel MCP-和Boost之间的无缝集成。
特性
- 助手实用程序:用于创建MCP服务器、工具、资源和提示的流利构建器
- 预构建组件:用于常见Laravel操作的现成工具、资源和提示
- 增强集成:与Laravel Boost无缝集成,用于AI指南和开发工具
- 领域驱动设计:遵循DDD原则的清洁架构
- 坚实的原则:结构良好、可维护的代码库
- 类型安全:用于增强类型安全的值对象
安装
步骤1:通过Composer安装
composer require emeq/emeq-mcp-laravel步骤2:发布配置
php artisan vendor:publish --tag="emeq-mcp-config"这创造了 config/emeq-mcp.php 您可以在其中自定义包的行为。
步骤3:发布路线
php artisan vendor:publish --tag="emeq-mcp-routes"这创造了 routes/ai.php 您可以在那里注册MCP服务器。
快速入门:创建发票服务器
让我们使用工具、资源和提示创建一个完整的发票MCP服务器,以获取和列出发票,提供模式信息,并协助发票管理。
步骤1:创建发票服务器
php artisan make:mcp-server InvoiceServer这创造了 app/Mcp/Servers/InvoiceServer.php。在创建工具、资源和提示后,我们将在步骤5中更新它。
步骤2:创建发票工具
获取发票工具
php artisan make:mcp-tool GetInvoice编辑 app/Mcp/Tools/GetInvoiceTool.php:
'object',
'properties' => [
'invoice_number' => [
'type' => 'string',
'description' => 'The invoice number (e.g., INV-2025-001)',
],
'invoice_id' => [
'type' => 'integer',
'description' => 'The invoice ID (alternative to invoice_number)',
],
],
'required' => [],
];
}
public function handle(Request $request): Response
{
$arguments = $this->validateArguments($request->arguments());
try {
$query = Invoice::query();
if (isset($arguments['invoice_number'])) {
$invoice = $query->where('invoice_number', $arguments['invoice_number'])->first();
} elseif (isset($arguments['invoice_id'])) {
$invoice = $query->find($arguments['invoice_id']);
} else {
return Response::error('Either invoice_number or invoice_id must be provided.');
}
if (!$invoice) {
return Response::error('Invoice not found. Please verify the invoice number or ID.');
}
// Load relationships
$invoice->load(['items', 'payments', 'customer']);
$result = [
'id' => $invoice->id,
'invoice_number' => $invoice->invoice_number,
'customer' => [
'id' => $invoice->customer->id,
'name' => $invoice->customer->name,
'email' => $invoice->customer->email,
],
'status' => $invoice->status,
'issue_date' => $invoice->issue_date?->toIso8601String(),
'due_date' => $invoice->due_date?->toIso8601String(),
'subtotal' => $invoice->subtotal,
'tax' => $invoice->tax,
'total' => $invoice->total,
'paid_amount' => $invoice->paid_amount,
'balance' => $invoice->balance,
'items' => $invoice->items->map(function ($item) {
return [
'description' => $item->description,
'quantity' => $item->quantity,
'unit_price' => $item->unit_price,
'total' => $item->total,
];
})->toArray(),
'payments' => $invoice->payments->map(function ($payment) {
return [
'amount' => $payment->amount,
'payment_date' => $payment->payment_date?->toIso8601String(),
'method' => $payment->method,
];
})->toArray(),
];
return Response::text(json_encode($result, JSON_PRETTY_PRINT));
} catch (\Exception $e) {
\Log::error('Get invoice error', [
'error' => $e->getMessage(),
'arguments' => $arguments,
]);
return Response::error("Failed to retrieve invoice: {$e->getMessage()}");
}
}
}列出发票工具
php artisan make:mcp-tool ListInvoices编辑 app/Mcp/Tools/ListInvoicesTool.php:
'object',
'properties' => [
'status' => [
'type' => 'string',
'enum' => ['draft', 'sent', 'paid', 'overdue', 'cancelled'],
'description' => 'Filter by invoice status',
],
'customer_id' => [
'type' => 'integer',
'description' => 'Filter by customer ID',
],
'date_from' => [
'type' => 'string',
'format' => 'date',
'description' => 'Filter invoices from this date (YYYY-MM-DD)',
],
'date_to' => [
'type' => 'string',
'format' => 'date',
'description' => 'Filter invoices to this date (YYYY-MM-DD)',
],
'limit' => [
'type' => 'integer',
'description' => 'Maximum number of invoices to return',
'minimum' => 1,
'maximum' => 100,
'default' => 20,
],
'page' => [
'type' => 'integer',
'description' => 'Page number for pagination',
'minimum' => 1,
'default' => 1,
],
],
'required' => [],
];
}
public function handle(Request $request): Response
{
$arguments = $this->validateArguments($request->arguments());
try {
$query = Invoice::query();
// Apply filters
if (isset($arguments['status'])) {
$query->where('status', $arguments['status']);
}
if (isset($arguments['customer_id'])) {
$query->where('customer_id', $arguments['customer_id']);
}
if (isset($arguments['date_from'])) {
$query->whereDate('issue_date', '>=', $arguments['date_from']);
}
if (isset($arguments['date_to'])) {
$query->whereDate('issue_date', 'with('customer')
->orderBy('issue_date', 'desc')
->paginate($limit, ['*'], 'page', $page);
$result = [
'total' => $invoices->total(),
'per_page' => $invoices->perPage(),
'current_page' => $invoices->currentPage(),
'last_page' => $invoices->lastPage(),
'invoices' => $invoices->items()->map(function ($invoice) {
return [
'id' => $invoice->id,
'invoice_number' => $invoice->invoice_number,
'customer' => $invoice->customer->name,
'status' => $invoice->status,
'issue_date' => $invoice->issue_date?->toDateString(),
'due_date' => $invoice->due_date?->toDateString(),
'total' => $invoice->total,
'balance' => $invoice->balance,
];
})->toArray(),
];
return Response::text(json_encode($result, JSON_PRETTY_PRINT));
} catch (\Exception $e) {
\Log::error('List invoices error', [
'error' => $e->getMessage(),
'arguments' => $arguments,
]);
return Response::error("Failed to list invoices: {$e->getMessage()}");
}
}
}步骤3:创建发票资源
发票架构资源
php artisan make:mcp-resource InvoiceSchema编辑 app/Mcp/Resources/InvoiceSchemaResource.php:
getInvoiceSchema();
return Response::text(json_encode($schema, JSON_PRETTY_PRINT));
} catch (\Exception $e) {
return Response::error("Failed to get invoice schema: {$e->getMessage()}");
}
}
private function getInvoiceSchema(): array
{
$model = new Invoice();
$table = $model->getTable();
return [
'model' => Invoice::class,
'table' => $table,
'fields' => [
'id' => [
'type' => 'integer',
'description' => 'Primary key',
],
'invoice_number' => [
'type' => 'string',
'description' => 'Invoice number (e.g., INV-2025-001)',
],
'customer_id' => [
'type' => 'integer',
'description' => 'Foreign key to customers table',
],
'status' => [
'type' => 'enum',
'values' => ['draft', 'sent', 'paid', 'overdue', 'cancelled'],
'description' => 'Invoice status',
],
'issue_date' => [
'type' => 'date',
'description' => 'Invoice issue date',
],
'due_date' => [
'type' => 'date',
'description' => 'Invoice due date',
],
'subtotal' => [
'type' => 'decimal',
'description' => 'Subtotal amount before tax',
],
'tax' => [
'type' => 'decimal',
'description' => 'Tax amount',
],
'total' => [
'type' => 'decimal',
'description' => 'Total invoice amount',
],
'paid_amount' => [
'type' => 'decimal',
'description' => 'Total amount paid',
],
'balance' => [
'type' => 'decimal',
'description' => 'Remaining balance (total - paid_amount)',
],
],
'relationships' => [
'customer' => [
'type' => 'BelongsTo',
'model' => 'App\Models\Customer',
'description' => 'The customer associated with this invoice',
],
'items' => [
'type' => 'HasMany',
'model' => 'App\Models\InvoiceItem',
'description' => 'Line items on the invoice',
],
'payments' => [
'type' => 'HasMany',
'model' => 'App\Models\Payment',
'description' => 'Payments made against this invoice',
],
],
'status_values' => [
'draft' => 'Invoice is in draft state',
'sent' => 'Invoice has been sent to the customer',
'paid' => 'Invoice has been fully paid',
'overdue' => 'Invoice is past its due date',
'cancelled' => 'Invoice has been cancelled',
],
];
}
}步骤4:创建发票提示
发票管理提示
php artisan make:mcp-prompt InvoiceManagement编辑 app/Mcp/Prompts/InvoiceManagementPrompt.php:
[
'type' => 'string',
'description' => 'The invoice management task (create, update, send, cancel, etc.)',
],
'context' => [
'type' => 'string',
'description' => 'Additional context or requirements for the task',
],
];
}
protected function getTemplate(): PromptTemplate
{
return new PromptTemplate(
"You are assisting with invoice management in a Laravel application.\n\n" .
"Task: {{task}}\n\n" .
"Context: {{context}}\n\n" .
"The Invoice model has the following key features:\n" .
"- Invoice numbers are formatted as INV-YYYY-SEQ (e.g., INV-2025-001)\n" .
"- Status values: draft, sent, paid, overdue, cancelled\n" .
"- Relationships: customer, items (line items), payments\n" .
"- Financial fields: subtotal, tax, total, paid_amount, balance\n" .
"- Dates: issue_date (when invoice was created), due_date (payment deadline)\n\n" .
"Provide clear, accurate guidance following Laravel best practices."
);
}
public function handle(Request $request): Response
{
$arguments = $this->validateArguments($request->arguments());
$template = $this->getTemplate();
$rendered = $template->render([
'task' => $arguments['task'] ?? 'invoice management',
'context' => $arguments['context'] ?? 'No specific context provided',
]);
return Response::text($rendered);
}
}步骤5:更新InvoiceServer以包含资源和提示
更新 app/Mcp/Servers/InvoiceServer.php 包括资源和提示:
name('My Server')
->version('1.0.0')
->instructions('Server instructions')
->withTool(YourTool::class)
->build();
// Create a tool
$tool = Mcp::tool()
->name('my-tool')
->description('Tool description')
->inputSchema([...])
->build();增强集成
Laravel Boost集成允许您的MCP提示自动包含特定于项目的指导方针和最佳实践,确保AI助手遵循您的编码标准和惯例。
安装
安装Boost集成:
php artisan mcp:boost-install此命令:
- 创建
.boost/guidelines/目录 - 在配置中启用Boost
配置
Boost是 默认启用。您可以在您的 .env 文件(如果需要):
# Boost is enabled by default, set to false to disable
EMEQ_MCP_BOOST_ENABLED=false
EMEQ_MCP_BOOST_GUIDELINES_PATH=.boost/guidelines制定指导方针
在中创建JSON指南文件 .boost/guidelines/ 目录。指导方针可以根据具体情况而定:
例子: .boost/guidelines/code-generation.json
[
{
"title": "Laravel Code Style",
"content": "Always use PSR-12 coding standards. Use type hints for all method parameters and return types.",
"context": "code-generation"
},
{
"title": "Model Conventions",
"content": "Use Eloquent relationships instead of manual joins. Always define return type hints for relationships.",
"context": "code-generation"
}
]例子: .boost/guidelines/debugging.json
[
{
"title": "Error Handling",
"content": "Always log errors with context. Use Laravel's exception handling mechanisms.",
"context": "debugging"
}
]自动集成
升压指南是 自动集成 在所有内置提示中:
- 代码生成提示:包括生成代码时的指导方针
- 调试提示:包括调试问题时的指南
- 数据库设计提示:包括设计模式时的指导方针
当您通过AI助手使用这些提示时,它们会自动包含您的项目指南。
在自定义提示中使用Boost
您可以在自定义提示中使用Boost指南,方法是扩展 BasePrompt:
getBoostGuidelines('my-context');
// Format guidelines for inclusion in prompt
$guidelinesText = $this->formatBoostGuidelines($guidelines);
// Include guidelines in your prompt
$prompt = "Your prompt text here...";
$prompt .= $guidelinesText;
return Response::text($prompt);
}
// ... other required methods
}编程访问
以编程方式访问Boost指南:
use Emeq\McpLaravel\Support\Facades\Boost;
// Get all guidelines
$guidelines = Boost::getGuidelines();
// Get guidelines for a specific context
$contextGuidelines = Boost::getGuidelinesForContext('code-generation');
// Add custom context
Boost::addContext([
'current_feature' => 'invoice-management',
'team_standards' => 'strict-typing',
]);好处
- 一致性:AI生成的代码遵循您的项目标准
- 上下文感知:针对不同场景的不同指南
- 自动:无需在每个提示中手动包含指南
- 可维护性:在一个地方更新指南,影响所有提示
命令
make:mcp-server {name}-创建新的MCP服务器make:mcp-tool {name}-创建新的MCP工具make:mcp-resource {name}-创建新的MCP资源make:mcp-prompt {name}-创建新的MCP提示mcp:boost-install-安装Boost集成mcp:list-列出所有已注册的MCP组件
建筑
该软件包遵循领域驱动设计原则:
- 域层:合同、实体、价值对象和域服务
- 基础设施层:基类、构建器和预构建组件
- 应用层:命令和应用程序服务
- 支撑层:立面和辅助功能
测试
运行测试套件:
composer test更新日志
请查看 更新日志 有关最近发生的变化的更多信息。
贡献
欢迎投稿!请随时提交拉取请求。
安全漏洞
请审阅 我们的安全政策 关于如何报告安全漏洞。
学分
许可证
MIT许可证(MIT)。请查看 许可证文件 了解更多信息。
