OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)

This commit is contained in:
wangruiguo
2026-09-03 18:49:20 +08:00
commit d647428529
3501 changed files with 1988906 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
<?php
namespace Leantime\Mcp\Servers;
use Laravel\Mcp\Server as McpServer;
use Laravel\Mcp\Server\Tool;
/**
* OneBot 的 MCP server暴露所有 Domain 下 Tools 目录里定义的 AI 工具。
*
* 采用 boot() 动态发现(扫描 app/Domain 各域的 Tools 目录),而非静态 tools 数组,
* 这样后续新增任何域的 Tool 类都会自动注册,无需改这里。
*/
class OneBotServer extends McpServer
{
public string $serverName = 'OneBot';
public string $serverVersion = '1.0.0';
public function __construct()
{
parent::__construct();
$this->instructions = implode("\n", [
'你是 OneBot 项目管理系统的 AI 助手,可通过工具直接操作系统完成用户指令。',
'',
'【身份】你有系统操作能力,但只是辅助;涉及删除、批量修改、覆盖导入等高风险写操作前,必须先列出将影响的数据并征得用户明确确认。',
'',
'【业务规则】',
'- BOM / 工艺文件 / 工具清单是「全局主数据」(跨项目共享),修改会影响所有引用它的项目。',
'- 项目对主数据是「单向引用」:项目级追加的列/值不影响全局主数据。',
'- 删除、批量修改、覆盖导入前,先列影响并确认。',
'',
'【边界】不臆造数据;工具返回错误时如实报告并给排查建议,不反复重试同一失败操作;回答用简体中文;金额用人民币。',
]);
}
/**
* 动态发现并注册所有 Domain Tools。
*/
public function boot(): void
{
$pattern = app()->basePath('app/Domain/*/Tools/*Tool.php');
$files = glob($pattern) ?: [];
foreach ($files as $file) {
$class = $this->classFromFile($file);
if ($class !== null && class_exists($class) && is_subclass_of($class, Tool::class)) {
try {
$this->addTool($class);
} catch (\Throwable $e) {
// 单个工具失败不阻断整个 server 启动
}
}
}
}
/**
* 从文件路径推导类名app/Domain/Projects/Tools/GetAllProjectsTool.php
* → Leantime\Domain\Projects\Tools\GetAllProjectsTool
*/
private function classFromFile(string $file): ?string
{
$appRoot = rtrim(app()->basePath('app'), '/\\');
if (! str_starts_with($file, $appRoot)) {
return null;
}
$relative = substr($file, strlen($appRoot));
$relative = ltrim(str_replace(['/', '\\'], '\\', $relative), '\\');
$relative = preg_replace('/\.php$/', '', $relative);
if ($relative === '' || $relative === null) {
return null;
}
return app()->getNamespace().$relative;
}
}