内容
# Laravel Swarm MCP
[](https://github.com/builtbyberry/laravel-swarm-mcp/actions/workflows/tests.yml)
一款适用于 Laravel Swarm 的只读 Model Context Protocol 服务器,基于官方的 `laravel/mcp` 包构建。它公开了 swarm 的持久运行历史、持久运行检查和审计输出健康状况作为 MCP **资源**,因此任何与 MCP 兼容的 AI 客户端 — Claude、Cursor 等 — 都可以观察您的 swarm 运行。
> **设计为只读。** 此版本仅公开可观察性 **资源**,并且注册 **零工具**。它可以 *观察* swarm 运行,但永远不能暂停、恢复、取消或发出信号。操作员控制是一个刻意延迟的次要版本(参见[设计为只读](#读设计为只读))。
它封装了 Laravel Swarm 的公共显示读取合约(在核心 `v0.19.0` 中引入)— `ReadableRunHistoryStore`、`InspectsDurableRuns` 和 `ReadableAuditOutbox` — 因此每次读取都是 **显示解密和降级安全** 的:无法解密的字段(例如,在 `APP_KEY` 旋转后)返回 `null`,并带有 `*_available: false` 标志,而不是原始 `sw0:` 密文或失败的读取。
## 要求
- PHP `^8.5`
- `builtbyberry/laravel-swarm` `^0.19`
- `laravel/mcp` `^0.8`
## 安装
```bash
composer require builtbyberry/laravel-swarm-mcp
```
可选地发布配置文件:
```bash
php artisan vendor:publish --tag="swarm-mcp-config"
```
## 配置
`config/swarm-mcp.php`:
| 键 | 默认值 | 描述 |
|-----|---------|-------------|
| `server.enabled` | `true` | 观测服务器的总开关。 |
| `server.name` | `Laravel Swarm` | 向 MCP 客户端报告的显示名称。 |
| `transports.stdio.enabled` | `true` | 通过 stdio (本地/代理主机)公开服务器。 |
| `transports.http.enabled` | `false` | 通过网络化的 HTTP 传输公开服务器。**默认关闭。** |
| `transports.http.path` | `swarm-mcp` | HTTP 传输的路由路径。 |
| `authentication.middleware` | `['auth:sanctum']` | 应用于 HTTP 传输路由的中间件。 |
| `resources.*` | `true` | 切换各个资源组(`run_history`、`durable_inspection`、`audit_outbox`)。 |
## 连接 MCP 客户端
### stdio(默认)
服务器在句柄 `laravel-swarm` 下注册,并使用 `laravel/mcp` 命令启动:
```bash
php artisan mcp:start laravel-swarm
```
将您的 MCP 客户端指向该命令。例如,Claude Desktop 条目:
```json
{
"mcpServers": {
"laravel-swarm": {
"command": "php",
"args": ["artisan", "mcp:start", "laravel-swarm"]
}
}
}
```
### HTTP(可流式传输)
将 `transports.http.enabled` 设置为 `true`。然后,服务器在配置的路径(默认 `POST /swarm-mcp`)下可访问,并使用配置的身份验证中间件。**网络调用者必须进行身份验证** — 默认守卫是 `auth:sanctum`(您的应用程序提供 Sanctum)。参见[授权](#授权)。
## 资源
| URI | 支持 | 返回 |
|-----|-----------|---------|
| `swarm://runs` | `ReadableRunHistoryStore::query()` | 最近的运行 — 精简、无需解密的投影。 |
| `swarm://runs/{runId}` | `ReadableRunHistoryStore::findForDisplay()` | 单个运行及其步骤;密封字段按字段降级。 |
| `swarm://durable-runs/{runId}` | `InspectsDurableRuns::inspect()` | 组装的持久运行状态:等待、信号、进度、子项、分支、层次输出。 |
| `swarm://audit-outbox/health` | `ReadableAuditOutbox::healthSummary()` | 输出框可用性 + 待处理/死信/预留计数。 |
| `swarm://audit-outbox/queue/{state}` | `pending()` / `deadLettered()` | 待处理或死信队列(仅元数据和 `last_error`)。 |
| `swarm://audit-outbox/records/{id}` | `ReadableAuditOutbox::record()` | 单个输出框行及其完全显示解密的有效载荷。 |
### 显示安全读取
每个资源都解析 **绑定公共合约** — 而不是内部的 `SwarmPersistenceCipher`。密封的有效载荷通过显示路径打开,该路径遵循 `swarm.persistence.decrypt_failure_policy` 并 **按字段降级**:无法解密的值变为 `null`,并带有明确的 `*_available: false` 标志(`output_available`、`context_available`、`payload_available` 等)。旋转的 `APP_KEY` 或单个毒行永远不会引发异常、终止读取或将 `sw0:` 密文泄漏给客户端。审计输出读取是纯粹的 `SELECT` — 它们不能排空或改变输出框,`swarm:relay --type=audit` 排空。
## 设计为只读
`v0.1.0` 故意 **仅限资源**。服务器注册没有工具,因此 AI 客户端可以读取 swarm 状态但不能对其操作。向自主代理公开操作员控制动词(暂停/恢复/取消/信号)是一个微妙的接口 — 它需要每个运行的授权回调,并故意排除整个舰队的批量动词 — 并计划在明确选择加入后作为次要版本发布。在此之前,此包是进入您的 swarm 的安全、仅观察窗口。
## 授权
服务器对网络调用者进行身份验证(通过配置的 `authentication.middleware`),但 **对哪些运行调用者可以读取** 是未知的 — 将运行可见性限制在租户或用户是您应用程序的责任。此版本仅公开只读数据。
## 测试
```bash
composer test # Pest
composer analyse # PHPStan(级别 8)
composer lint # Pint
```
## 许可证
MIT 许可证(MIT)。请参阅 [许可证文件](LICENSE) 以获取更多信息。