关于 Laravel MCP
Laravel MCP 是用于在 Laravel 应用中实现 Model Context Protocol 的扩展包,面向 PHP 与 Laravel 开发者。它通过标准化接口连接 AI 模型与 Laravel 应用。
主要功能
- 01支持 HTTP、WebSocket 和 Stdio 传输
- 02提供工具注册与调用
- 03支持基于 URI 的资源管理
- 04提供提示词模板与进度跟踪
- 05提供多级别日志系统
适用场景
- 01将 Laravel 应用的功能以 MCP 工具形式提供给 AI 模型
- 02通过基于 URI 的资源向客户端暴露文件或数据
- 03构建带提示词模板的代码审查助手
MCP 相关
该项目是 MCP 服务框架,用于在 Laravel 应用中实现服务端,向 MCP 客户端暴露工具、资源和提示词。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Laravel MCP
一个用于在 Laravel 应用中实现 Model Context Protocol(MCP)的 Laravel 包。该协议通过标准化接口,促进 AI 模型与 Laravel 应用之间的通信。
:star: 我们现已在 mcphub 上精选展示
📚 查看完整文档
要求
系统要求
- PHP 8.1 或更高版本
- Laravel 10.x
- Composer 2.x
- OpenSSL PHP 扩展
- PDO PHP 扩展
- Mbstring PHP 扩展
- XML PHP 扩展
- Ctype PHP 扩展
- JSON PHP 扩展
- ReactPHP(用于 HTTP/WebSocket 传输)
- ext-json(用于 JSON 处理)
可选要求
- Redis(用于 WebSocket 扩展)
- Supervisor(用于进程管理)
- ext-pcntl(用于信号处理)
- ext-posix(用于进程管理)
功能
-
多种传输方式
- HTTP 传输(RESTful API)
- WebSocket 传输(实时)
- Stdio 传输(命令行)
- 可配置的主机和端口设置
-
服务端功能
- 工具注册和执行
- 资源管理
- 提示词处理
- 进度跟踪
- 日志系统
- 模型偏好设置
-
工具系统
- 注册带参数的自定义工具
- 处理带参数的工具调用
- 返回结构化响应
- 错误处理和验证
-
资源管理
- 基于 URI 的资源访问
- 资源模板
- 动态资源处理
- 内容类型支持
-
提示词系统
- 基于模板的提示词
- 动态参数处理
- 上下文管理
- 消息历史记录支持
-
进度跟踪
- 实时进度更新
- 基于 Token 的跟踪
- 总进度支持
- 客户端通知系统
-
日志系统
- 多种日志级别
- 日志记录器标识
- 结构化日志
- 与传输方式无关的日志记录
文档
项目为所有类和方法提供了全面的 PHPDoc 文档。文档可直接在源代码中查看,内容包括:
核心组件
-
服务端功能(
src/Capabilities/ServerCapabilities.php)- 服务端功能管理
- 实验性功能配置
- 日志配置
- 组件功能(提示词、资源、工具)
-
客户端功能(
src/Capabilities/ClientCapabilities.php)- 功能标记管理
- 根目录配置
- 状态序列化/反序列化
组件功能
-
工具功能(
src/Capabilities/ToolsCapability.php)- 工具列表变更跟踪
- 状态管理
- 变更通知支持
-
资源功能(
src/Capabilities/ResourcesCapability.php)- 资源订阅管理
- 变更跟踪
- 状态序列化
-
提示词功能(
src/Capabilities/PromptsCapability.php)- 提示词列表变更跟踪
- 状态管理
- 变更通知
-
根目录功能(
src/Capabilities/RootsCapability.php)- 根目录管理
- 目录配置
- 访问控制设置
服务端管理
- MCP 服务命令(
src/Commands/MCPServerCommand.php)- 服务启动配置
- 传输方式选择
- 信号处理
- 平稳关闭
每个组件均包含:
- 详细的类说明
- 功能和能力列表
- 配置示例
- 使用示例
- 方法文档
- 参数说明
- 返回值文档
探索文档的方式:
- 浏览
src/目录中的源文件 - 使用 IDE 的 PHPDoc 集成
- 使用 phpDocumentor 生成 HTML 文档(可选)
生成 HTML 文档:
composer require --dev phpdocumentor/phpdocumentor
vendor/bin/phpdoc -d src/ -t docs/
安装
通过 Composer 安装:
composer require laravelmcp/mcp
该包会自动注册其服务提供程序和门面。
配置
- 发布配置:
php artisan vendor:publish --provider="LaravelMCP\MCP\MCPServiceProvider" --tag="config"
- 配置环境变量:
MCP_SERVER_HOST=127.0.0.1
MCP_SERVER_PORT=8080
MCP_SERVER_TRANSPORT=http
基本用法
启动服务
# Start the server with default HTTP transport
php artisan mcp:serve
# Start with specific transport and options
php artisan mcp:serve --transport=websocket --host=0.0.0.0 --port=8081
# Start with stdio transport (useful for CLI applications)
php artisan mcp:serve --transport=stdio
服务设置
use LaravelMCP\MCP\Server\MCPServer;
use LaravelMCP\MCP\Transport\HttpTransport;
// Create and configure server
$server = new MCPServer();
// Configure transport
$transport = new HttpTransport($server, [
'host' => '127.0.0.1',
'port' => 8080
]);
$server->setTransport($transport);
$server->initialize();
// Start the server
$server->start();
使用不同的传输方式
use LaravelMCP\MCP\Transport\WebSocketTransport;
use LaravelMCP\MCP\Transport\StdioTransport;
use LaravelMCP\MCP\Transport\TransportFactory;
// Using WebSocket transport
$wsTransport = new WebSocketTransport($server, [
'host' => '0.0.0.0',
'port' => 8081
]);
// Using Stdio transport (for CLI applications)
$stdioTransport = new StdioTransport($server);
// Using transport factory
$factory = new TransportFactory();
$transport = $factory->create('http', $server, [
'host' => '127.0.0.1',
'port' => 8080
]);
注册工具
use LaravelMCP\MCP\Server\FastMCP;
use LaravelMCP\MCP\Facades\MCP;
// Using FastMCP (recommended)
$mcp = new FastMCP();
// Register a simple calculation tool
$mcp->tool('calculate', [
'num1' => ['type' => 'number', 'required' => true],
'num2' => ['type' => 'number', 'required' => true],
'operation' => ['type' => 'string', 'required' => true]
])(function ($args) {
$num1 = $args['num1'];
$num2 = $args['num2'];
$operation = $args['operation'];
return match ($operation) {
'+' => ['result' => $num1 + $num2],
'-' => ['result' => $num1 - $num2],
'*' => ['result' => $num1 * $num2],
'/' => $num2 != 0 ? ['result' => $num1 / $num2] : ['error' => 'Division by zero'],
default => ['error' => 'Invalid operation']
};
});
// Register a tool with error handling
$mcp->tool('process-data', [
'items' => ['type' => 'array', 'required' => true],
'token' => ['type' => 'string', 'required' => false]
])(function ($args) use ($mcp) {
try {
$items = $args['items'];
$token = $args['token'] ?? uniqid();
foreach ($items as $index => $item) {
// Process item
$progress = ($index + 1) / count($items);
MCP::sendProgress($progress, $token, count($items));
MCP::sendLog("Processing item {$index + 1}", 'info', 'processor');
}
return ['processed' => count($items)];
} catch (\Exception $e) {
MCP::sendLog($e->getMessage(), 'error', 'processor');
return ['error' => $e->getMessage()];
}
});
管理资源
// Register a file resource
$mcp->resource('file://{path}')(function ($matches) {
$path = $matches['path'] ?? null;
if (!$path || !file_exists($path)) {
return ['error' => 'File not found'];
}
return [
'content' => file_get_contents($path),
'metadata' => [
'size' => filesize($path),
'modified' => filemtime($path),
'mime' => mime_content_type($path)
]
];
});
// Register a database resource
$mcp->resource('db://{table}/{id}')(function ($matches) {
$table = $matches['table'] ?? null;
$id = $matches['id'] ?? null;
if (!$table || !$id) {
return ['error' => 'Invalid parameters'];
}
try {
$record = DB::table($table)->find($id);
return $record ? ['data' => $record] : ['error' => 'Record not found'];
} catch (\Exception $e) {
return ['error' => $e->getMessage()];
}
});
// Register a health check resource
$mcp->resource('/health')(function () {
return ['status' => 'ok'];
});
处理提示词
// Basic prompt template
$mcp->prompt('code-review', [
'language' => ['type' => 'string', 'required' => true],
'code' => ['type' => 'string', 'required' => true]
])(function ($args) {
return [
['role' => 'system', 'content' => 'You are a code review assistant.'],
['role' => 'user', 'content' => "Please review this {$args['language']} code:\n\n{$args['code']}"]
];
});
// Prompt with context
$mcp->prompt('chat', [
'message' => ['type' => 'string', 'required' => true],
'context' => ['type' => 'array', 'required' => false]
])(function ($args) {
$messages = $args['context'] ?? [];
$messages[] = [
'role' => 'user',
'content' => $args['message']
];
return $messages;
});
进度与日志记录
use LaravelMCP\MCP\Facades\MCP;
// Send progress updates
MCP::sendProgress(0.5, 'task_123', 1.0);
// Send logs with different levels
MCP::sendLog('Processing started', 'info', 'processor');
MCP::sendLog('Warning: Rate limit approaching', 'warning', 'rate-limiter');
MCP::sendLog('Error occurred: Invalid input', 'error', 'validator');
MCP::sendLog('Debug: Request payload', 'debug', 'http');
模型偏好
use LaravelMCP\MCP\Sampling\ModelPreferences;
// Basic model preferences
$preferences = new ModelPreferences(
costPriority: 0.5,
intelligencePriority: 0.8,
speedPriority: 0.3
);
MCP::setModelPreferences($preferences);
// Model preferences with hints
$preferences = new ModelPreferences(
costPriority: 0.7,
intelligencePriority: 0.9,
speedPriority: 0.4,
hints: ['creative', 'concise']
);
MCP::setModelPreferences($preferences);
// Create from array
$preferences = ModelPreferences::create([
'costPriority' => 0.6,
'intelligencePriority' => 0.8,
'speedPriority' => 0.5,
'hints' => ['detailed', 'technical']
]);
MCP::setModelPreferences($preferences);
错误处理
use LaravelMCP\MCP\Facades\MCP;
try {
// Initialize server
$server = new MCPServer();
if (!$server->getTransport()) {
throw new RuntimeException('Transport not initialized');
}
// Handle tool call
$result = $server->handleToolCall('test_tool', [
'param1' => 'value1',
'param2' => 'value2'
]);
// Handle resource request
$resource = $server->handleResourceRequest('test://resource');
// Handle prompt request
$prompt = $server->handlePromptRequest('test_prompt', [
'arg1' => 'value1'
]);
} catch (RuntimeException $e) {
MCP::sendLog("Runtime error: {$e->getMessage()}", 'error', 'server');
} catch (\Exception $e) {
MCP::sendLog("Unexpected error: {$e->getMessage()}", 'error', 'server');
}
趣味大模型应用:构建代码审查助手
以下是一个完整示例,展示如何构建一个能够分析代码、提出改进建议,甚至修复错误的代码审查助手:
use LaravelMCP\MCP\Server\FastMCP;
use LaravelMCP\MCP\Facades\MCP;
use Illuminate\Support\Facades\Storage;
$mcp = new FastMCP();
// Register a tool for analyzing code complexity
$mcp->tool('analyze-complexity', [
'code' => ['type' => 'string', 'required' => true],
'language' => ['type' => 'string', 'required' => true]
])(function ($args) {
// Simulate complexity analysis
$metrics = [
'cyclomatic' => random_int(1, 10),
'cognitive' => random_int(1, 15),
'lines' => count(explode("\n", $args['code']))
];
return [
'metrics' => $metrics,
'suggestion' => $metrics['cyclomatic'] > 5 ? 'Consider breaking down this function' : 'Complexity is acceptable'
];
});
// Register a code improvement prompt
$mcp->prompt('suggest-improvements', [
'code' => ['type' => 'string', 'required' => true],
'language' => ['type' => 'string', 'required' => true],
'context' => ['type' => 'string', 'required' => false]
])(function ($args) {
$messages = [
[
'role' => 'system',
'content' => "You are an expert {$args['language']} developer. Analyze the code and suggest improvements for:
1. Performance
2. Readability
3. Best practices
4. Potential bugs
Be specific and provide examples."
],
[
'role' => 'user',
'content' => "Here's the code to review:\n\n```{$args['language']}\n{$args['code']}\n```"
]
];
if (isset($args['context'])) {
$messages[] = [
'role' => 'user',
'content' => "Additional context: {$args['context']}"
];
}
return $messages;
});
// Register a resource for storing review history
$mcp->resource('reviews://{file_hash}')(function ($matches) {
$hash = $matches['file_hash'] ?? null;
if (!$hash) return ['error' => 'Invalid file hash'];
$reviewPath = "reviews/{$hash}.json";
if (!Storage::exists($reviewPath)) {
return ['error' => 'No review history found'];
}
return ['history' => json_decode(Storage::get($reviewPath), true)];
});
// Create a fun code review workflow
$mcp->tool('review-code', [
'code' => ['type' => 'string', 'required' => true],
'language' => ['type' => 'string', 'required' => true],
'style' => ['type' => 'string', 'enum' => ['serious', 'fun', 'sarcastic'], 'default' => 'serious']
])(function ($args) use ($mcp) {
$fileHash = md5($args['code']);
$reviewToken = uniqid('review_');
try {
// Step 1: Analyze complexity
MCP::sendProgress(0.2, $reviewToken, "Analyzing code complexity...");
$complexity = $mcp->call('analyze-complexity', [
'code' => $args['code'],
'language' => $args['language']
]);
// Step 2: Get improvement suggestions
MCP::sendProgress(0.5, $reviewToken, "Getting expert suggestions...");
$personality = match($args['style']) {
'fun' => "Be playful and use coding puns, but maintain professionalism.",
'sarcastic' => "Use witty, sarcastic humor (but stay constructive and kind).",
default => "Be direct and professional."
};
$suggestions = $mcp->prompt('suggest-improvements', [
'code' => $args['code'],
'language' => $args['language'],
'context' => "Please {$personality}\nComplexity metrics: " . json_encode($complexity['metrics'])
]);
// Step 3: Store review history
MCP::sendProgress(0.8, $reviewToken, "Saving review history...");
Storage::put("reviews/{$fileHash}.json", json_encode([
'timestamp' => now(),
'complexity' => $complexity,
'suggestions' => $suggestions,
'style' => $args['style']
]));
// Step 4: Format response
MCP::sendProgress(1.0, $reviewToken, "Done!");
$funnyComments = [
'fun' => [
"🎮 Game Over! Your code review is ready!",
"🎯 Hit the target! Here's your review!",
"🎪 Step right up to see your code review!"
],
'sarcastic' => [
"🎭 Oh look, another masterpiece to review...",
"🎪 Ladies and gentlemen, behold this code!",
"🎯 Well, well, well... what do we have here?"
],
'serious' => [
"✅ Code review completed",
"📋 Analysis complete",
"🔍 Review finished"
]
];
return [
'message' => $funnyComments[$args['style']][array_rand($funnyComments[$args['style']])],
'complexity' => $complexity,
'suggestions' => $suggestions,
'history_uri' => "reviews://{$fileHash}"
];
} catch (\Exception $e) {
MCP::sendLog("Review error: {$e->getMessage()}", 'error', 'reviewer');
return ['error' => "Oops! The code reviewer needs coffee! ({$e->getMessage()})"];
}
});
// Example usage:
$result = $mcp->call('review-code', [
'code' => '
function fibonacci($n) {
if ($n <= 1) return $n;
return fibonacci($n - 1) + fibonacci($n - 2);
}
',
'language' => 'php',
'style' => 'fun'
]);
// Output might include fun messages like:
// "🎮 Game Over! Your code review is ready!"
// With suggestions about using memoization for better performance
// and adding parameter validation!
此示例展示了:
- 使用复杂度分析注册工具
- 使用具有个性特色的自定义提示词模板
- 管理审查历史记录的资源
- 使用有趣的消息跟踪进度
- 以幽默的方式处理错误
- 集成多项 MCP 功能
- 真实场景中的代码改进工作流
测试
运行测试套件:
composer test
贡献
详情请参阅 CONTRIBUTING.md。
安全
如果发现任何与安全相关的问题,请发送邮件至 [email protected],而不要使用问题跟踪器。
许可证
MIT 许可证(MIT)。更多信息请参阅 许可证文件。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。