内容
# 核心
[](https://crates.io/crates/cortex) [](https://github.com/jmagar/cortex/pkgs/container/cortex)
用于家庭实验室日志智能的 Rust syslog 接收器和 MCP 服务器。通过 UDP 和 TCP 接收 syslog,存储在 SQLite 中,并具有 FTS5 全文索引,通过 MCP、REST 和 CLI 适配器提供基于操作的日志搜索、库存、关联、状态和分析工具。
核心还维护用于调查图的派生投影表。这些图表将源 IP、声称的主机、应用程序、规范服务、容器、AI 项目/会话和错误签名与证据连接起来,但原始日志、心跳、库存、签名和会话行仍然是真相的来源。图形投影是可重建的,意意没有摄入触发器。图形重建使用暂存表和短序列交换,并记录明确的投影状态、源水印、行计数、运行时指标和降级故障状态。
服务身份是解析器支持的:搜索 `plex` 首先解析逻辑服务(`logical_service:plex`),然后是具体的服务实例,如 `service_instance:tootie/plex`。核心不再将 `tootie:plex` 或 `tootie:plex:plex` 视为规范的服务身份 - 那些旧式形状被拒绝并带有 `rejected_legacy_shape`(参见 `openwiki/inventory-graph.md`,“规范解析器证明:Plex”)。
## 目录
- [命名](#命名)
- [功能和边界](#功能和边界)
- [安装](#安装)
- [快速入门](#快速入门)
- [客户端配置](#客户端配置)
- [运行时界面](#运行时界面)
- [MCP 工具参考](#mcp-工具参考)
- [CLI 参考](#cli-参考)
- [配置](#配置)
- [身份验证](#身份验证)
- [安全和信任模型](#安全和信任模型)
- [架构](#架构)
- [分发合约](#分发合约)
- [开发](#开发)
- [验证](#验证)
- [部署](#部署)
- [故障排除](#故障排除)
- [文档](#文档)
- [相关服务器](#相关服务器)
- [许可证](#许可证)
## 命名
核心将其存储库和 CLI 名称保留为 `cortex`。npm 包是 `cortex-rmcp`,因为核心不仅仅是一个 MCP 服务器。MCP 注册表名称是 `tv.tootie/cortex`,Docker 镜像是 `ghcr.io/jmagar/cortex:v<version>`。
大多数此工作区中的小型 Rust MCP 服务器都使用 `<service>-rmcp` 存储库 / `r<service>` 二进制 / `<service>-rmcp` npm 模式。核心是刻意的例外:存储库 `cortex`,CLI `cortex`,npm 包 `cortex-rmcp`。
## 功能和边界
核心将 syslog、OTLP、Docker、托管文件尾部、库存、心跳和 AI 会话信号摄入到 SQLite,然后通过 MCP、REST 和 CLI 适配器提供有界的调查操作。
主要功能:
- 端口 `1514` 上的 UDP 和 TCP syslog 接收器。
- 带有保留和存储预算控制的 SQLite + FTS5 日志存储。
- 用于搜索、过滤、时间线、错误、上下文、库存、图形、AI 会话关联和事件证据包的 MCP 操作表面。
- 用于操作工作流和本地自动化的 REST 和 CLI 适配器。
- 用于支持 UI 资源的 MCP 主机的可选 MCP 应用程序查询小部件。
- 用于拓扑和调查工作流的派生图投影表。
**不适用于:** 替换 SIEM,从代理接收任意未经审计的日志突变,或在没有受信任的部署边界的情况下暴露 Docker/admin 操作。核心是一个具有有界操作表面和明确管理员门的家庭实验室日志智能服务。
MCP 调用者永远不会提供凭证、令牌、密钥或秘密作为操作参数。身份验证令牌、上游通知秘密、文件尾部根目录和 API 管理员凭证存储在服务器配置或环境变量中。
## 安装
使用 npm 启动器进行本地 MCP 客户端和快速 CLI 访问:
```bash
npx -y cortex-rmcp --help
npx -y cortex-rmcp mcp
```
要安装一个永久命令,请全局安装启动器:
```bash
npm i -g cortex-rmcp
cortex --version
```
该软件包在 `postinstall` 期间下载与 GitHub Release 二进制文件匹配的 `cortex` 二进制文件。对于源代码构建:
```bash
cargo build --release
```
## 快速入门
第一个屏幕 30 秒路径是一个指向启动器的 stdio MCP 客户端:
```json
{
"mcpServers": {
"cortex": {
"command": "npx",
"args": ["-y", "cortex-rmcp", "mcp"]
}
}
}
```
然后请求一个廉价的读取操作:
```json
{"action":"status"}
```
对于带有 syslog 监听器的 HTTP 服务器:
```bash
export CORTEX_API_TOKEN=change-me
export CORTEX_TOKEN=change-me
cortex serve mcp
```
## 客户端配置
stdio 启动一个仅限查询的 MCP 进程,该进程读取配置的数据库,而不启动网络监听器:
```json
{
"mcpServers": {
"cortex": {
"command": "cortex",
"args": ["mcp"]
}
}
}
```
可流式 HTTP 使用持久服务器上的 `/mcp`:
```json
{
"mcpServers": {
"cortex": {
"url": "http://127.0.0.1:3100/mcp",
"headers": {
"Authorization": "Bearer ${CORTEX_TOKEN}"
}
}
}
}
```
纯 JSON REST API 安装在同一 HTTP 监听器下的 `/api/*` 上,并使用 `CORTEX_API_TOKEN` 而不是 `CORTEX_TOKEN`。
## 运行时界面
| 界面 | 状态 | 目的 |
| --- | ---: | --- |
| Syslog | 守护进程摄入所需 | UDP/TCP `1514` 接收器用于网络日志 |
| MCP | 必需 | `cortex` 操作调度工具,通过 stdio 或 Streamable HTTP |
| CLI | 必需 | 操作命令、本地查询工作流、设置和管理摄入 |
| REST | 守护进程模式下必需 | `/api/*` 下的 JSON API,具有单独的 bearer auth |
| MCP 应用程序 | 可选 | 查询小部件资源,用于支持 UI 资源的 MCP 主机 |
| Web 仪表盘 | 未发货 | 核心不提供独立的浏览器应用程序 |
## MCP 工具参考
核心公开了一个名为 `cortex` 的 MCP 工具。所需的 `action` 参数选择操作;每个操作的参数验证发生在处理程序和服务层中。
常见的第一步操作是 `status`、`errors`、`tail`、`search`、`timeline` 和 `context`。昂贵或写入/管理员操作应该只在查询范围内使用。
有关完整的操作表和参数参考,请参见 [`docs/mcp/SCHEMA.md`](docs/mcp/SCHEMA.md)。该文档是从运行时模式中整理的,并受漂移测试保护;生成的运行时模式和 Rust `ACTION_SPECS` 表是它们不一致时的真相来源。
## CLI 参考
CLI 镜像了 MCP 和 REST 使用的同一个服务层:
```bash
cortex stats
cortex status
cortex search "error" --limit 20
cortex ingest inventory refresh --json
cortex ingest filetail list
cortex setup repair
cortex serve mcp
cortex mcp
```
使用 `cortex --help` 和子命令帮助获取完整命令树。CLI 是本地设置、修复和管理员维护的首选界面。
## 安全和信任模型
核心分离了读取、管理员和传输信任边界:
- MCP 读取使用 `cortex:read`;管理员突变需要 `cortex:admin`。
- HTTP MCP 使用 `CORTEX_TOKEN`。
- REST 使用 `CORTEX_API_TOKEN`;REST 管理员突变还需要 `X-Cortex-Admin-Token: $CORTEX_API_ADMIN_TOKEN`。
- 非环回 MCP 绑定需要 bearer auth、OAuth 或显式受信任网关配置。
- 文件尾部管理拒绝敏感的安装并要求允许列出的根目录。
- 库存和图形操作返回有界、编辑的证据,而不是原始的凭证承载配置体。
生成的运行时模式和整理的文档应保持一致,但操作策略应位于 Rust 服务层中,而不是仅限于 MCP 的粘合剂中。
## 架构
守护进程监听 UDP/TCP syslog,规范输入,通过批处理 SQLite 写入器写入,并通过共享的核心服务模型公开 MCP/REST/CLI 适配器。派生的图形投影表可从原始日志、心跳、库存、签名和会话行中重建;它们不是真相的来源。
详细的架构图和摄入说明继续在 [概述](#overview)、[家庭实验室库存](#homelab-inventory) 和下面的摄入部分中。
## 分发合约
发布身份的真相来源是 `Cargo.toml`、`lockfile`、发布元数据、包启动器元数据、插件/注册表元数据和容器镜像标签共享的版本。
分发/版本不变式:
- `cortex-rmcp` npm 包版本必须与其下载的 GitHub Release 二进制文件版本匹配。
- `server.json` 必须指向当前的 `ghcr.io/jmagar/cortex:v<version>` 镜像。
- 插件清单在 marketplace 从提交 SHA 推导出标识时保持无版本。
- 生成的运行时 MCP 模式来自 Rust 源代码,而不是手写的文档。
- 整理的 README/docs 内容应指向源代码真实性的文档,而不是复制每个操作参数。
生成的工件包括服务器返回的实时 MCP 模式和通过 MCP 公开的模式资源。整理的工件包括此 README 和 `docs/` 中的人为参考。
## 部署
当核心应该接收 syslog 并提供 HTTP MCP/REST 时,部署守护进程模式:
```bash
CORTEX_RECEIVER_HOST=0.0.0.0 \
CORTEX_RECEIVER_PORT=1514 \
CORTEX_HOST=0.0.0.0 \
CORTEX_PORT=3100 \
CORTEX_API_TOKEN=change-me \
CORTEX_TOKEN=change-me \
cortex serve mcp
```
容器和多主机部署说明在 [安装](#installation)、[多主机部署](#multi-host-deployment) 和 [HTTPS / 反向代理](#https--reverse-proxy) 中。
## 故障排除
- `/mcp` 返回 `401` 或 `403`:检查 `CORTEX_TOKEN`、OAuth 和受信任网关设置。
- `/api/*` 失败,而 `/mcp` 有效:检查 `CORTEX_API_TOKEN`;REST 有自己的 bearer 令牌。
- 没有 syslog 行到达:验证 UDP/TCP `1514`、发送者转发规则和 `CORTEX_RECEIVER_HOST`。
- `map` 报告丢失缓存:运行 `cortex ingest inventory refresh --json`。
- 文件尾部添加失败:确认路径在 `CORTEX_FILE_TAIL_ALLOWED_ROOTS` 下且不是符号链接或敏感安装。
- 昂贵操作慢:首先使用 `status`、`errors`、`tail` 或作用域 `search`,然后在 `patterns`、`anomalies` 或 `compose_doctor` 之前缩小范围。
## npm / npx
在没有手动二进制安装的情况下运行 stdio MCP 服务器或 CLI:
```bash
npx -y cortex-rmcp --help
```
MCP 客户端可以使用相同的启动器:
```json
{
"mcpServers": {
"cortex": {
"command": "npx",
"args": ["-y", "cortex-rmcp", "mcp"]
}
}
}
```
npm 包在 `postinstall` 期间从 GitHub Releases 下载 `cortex` 二进制文件。核心将其存储库和 CLI 名称保留为 `cortex`;npm 包是 `cortex-rmcp`,因为核心不仅仅是一个 MCP 服务器。
## Rust MCP 命名模式
大多数 Rust MCP 服务器使用:
- 存储库:`<service>-rmcp`
- CLI 别名:`r<service>`
- npm 包:`<service>-rmcp`
核心是例外:存储库 `cortex`,CLI `cortex`,npm 包 `cortex-rmcp`。
## 概述
```
┌─────────────────────────────────┐
rsyslog/syslog-ng ─▶ UDP :1514 / TCP :1514 │
网络设备 ─▶ ┌──────────────────────────┐ │
│ │ 解析 → 批处理写入器 │ │
│ │ SQLite + FTS5 (WAL 模式) │ │
│ └──────────────────────────┘ │
Claude / MCP ◀──── ▶ RMCP HTTP :3100/mcp │
本地 MCP 客户端 ◀──▶ syslog mcp 查询进程 │
└─────────────────────────────────┘
```
守护进程监听单个端口的 UDP 和 TCP syslog(默认 `1514`)。所有入站消息都被解析、批处理并写入 SQLite,并具有全文索引。MCP HTTP 服务器在单独的端口(默认 `3100`)上运行,并在无状态 JSON 响应模式下使用 RMCP Streamable HTTP。本地仅限 stdio 的 MCP 客户端可以启动 `cortex mcp`,这是一个仅限查询的 MCP 进程,它读取同一个 SQLite 数据库,而不启动 syslog 监听器或 HTTP 服务器。
MCP 是一个暴露接口,而不是日志智能业务策略的所有者。共享的默认值、限制、验证、审计身份、关联行为和安全门应该位于 `SyslogService` 或服务拥有的操作模型中,以便 MCP、REST 和 CLI 保持一致。
---
## 工具
公开一个 MCP 工具,`cortex`。使用所需的 `action` 参数运行 `search`、`filter`、`tail`、`errors`、`hosts`、`map`、`sessions`、`search_sessions`、`abuse`、`abuse_incidents`、`abuse_investigate`、`ai_correlate`、`topic_correlate`、`usage_blocks`、`project_context`、`list_ai_tools`、`list_ai_projects`、`correlate`、`stats`、`status`、`apps`、`source_ips`、`timeline`、`patterns`、`context`、`get`、`ingest_rate`、`silent_hosts`、`clock_skew`、`anomalies`、`compare`、`compose_status`、`compose_doctor`、`unaddressed_errors`、`ack_error`、`unack_error`、`notifications_recent`、`notifications_test`、`llm_invocations`、`similar_incidents`、`incident_context`、`graph`、`skill_events`、`skill_incidents`、`skill_investigate`、`mcp_events`、`mcp_incidents`、`mcp_investigate`、`hook_events`、`hook_incidents`、`hook_investigate` 或 `help`。
有关每个操作的参数参考,请参见 [`docs/mcp/SCHEMA.md`](docs/mcp/SCHEMA.md)。有关关联行为和 AI/非 AI 包含规则,请参见 [`docs/mcp/CORRELATION.md`](docs/mcp/CORRELATION.md)。
| 操作 | 目的 |
| --- | --- |
| `search` | 具有过滤器的全文搜索 |
| `filter` | 仅限结构化筛选日志检索 |
| `tail` | 最近的日志条目 |
| `errors` | 按主机和严重程度划分的错误/警告摘要 |
| `hosts` | 具有首次/最后看到的主机注册表 |
| `map` | 缓存的家庭实验室库存加上图形支持的拓扑答案 |
| `sessions` | 按项目划分的 AI 转录会话 |
| `search_sessions` | 排名分组会话搜索 |
| `abuse` | AI 转录中的滥用命中,具有相同会话上下文 |
| `abuse_incidents` | 将滥用命中分组为得分的事件候选 |
| `abuse_investigate` | 将事件扩展为确定的证据包 |
| `ai_correlate` | AI 转录锚点与非 AI 日志的交叉引用 |
| `topic_correlate` | 将主题解析为图实体并关联所有相关日志到统一的时间线 |
| `usage_blocks` | 5 小时 UTC 窗口中的 AI 活动 |
| `project_context` | 一个 AI 项目路径的摘要 |
| `list_ai_tools` | 不同的 AI 工具计数 |
| `list_ai_projects` | 不同的 AI 项目计数 |
| `correlate` | 交叉主机事件关联时间窗口;省略 reference_time 并传递查询以从匹配的 AI 会话中派生锚点 |
| `stats` | 数据库统计和存储健康 |
| `status` | 轻量级运行时和 DB 健康 |
| `apps` | 不同的应用程序名称与日志和主机计数 |
| `source_ips` | 不同的源标识符与主机名分解 |
| `timeline` | 按时间分桶计数 |
| `patterns` | 近似重复消息模板集群 |
| `context` | 日志 ID 或时间戳周围的周围日志 |
| `get` | 日志条目 ID,包括原始帧 |
| `ingest_rate` | 最近的摄入吞吐量和写块状态 |
| `silent_hosts` | 主机 last_seen 旧于阈值 |
| `clock_skew` | 每主机接收_at 减去 timestamp 分布 |
| `anomalies` | 最近与基线相比的容量/错误比较 |
| `compare` | 两个时间范围的并排比较 |
| `compose_status` | 减少 Compose 部署诊断 |
| `compose_doctor` | 严格的 Compose 部署健康诊断 |
| `unaddressed_errors` | 重复的未确认错误签名 |
| `ack_error` | 确认错误签名 |
| `unack_error` | 撤销错误确认 |
| `notifications_recent` | 最近的通知触发 |
| `notifications_test` | 通过 Apprise 发送测试通知 |
| `llm_invocations` | 最近的 LLM 调用审计记录(包括并发/速率限制/断路器拒绝) |
| `similar_incidents` | 历史系统日志的 FTS5 集群搜索 |
| `incident_context` | 一个已知时间窗口的完整上下文包 |
| `graph` | 解析图实体、邻域和基于证据的解释 |
| `skill_events` | 提取的 AI 技能调用事件列表 |
| `skill_incidents` | 将技能调用后的负面信号命中分组为得分的事件候选 |
| `skill_investigate` | 扩展技能使用事件为基于证据的包,优先考虑技能 |
| `mcp_events` | 提取的 AI MCP 工具调用事件列表 |
| `mcp_incidents` | 将 MCP 工具调用后的负面信号命中分组为得分的事件候选 |
| `mcp_investigate` | 扩展 MCP 使用事件为基于证据的包,优先考虑服务器/工具 |
| `hook_events` | 提取/收集的 AI hook 事件列表(运行时执行和配置库存) |
| `hook_incidents` | 将 hook 失败/超时和其他负面信号分组为得分的事件候选 |
| `hook_investigate` | 扩展 hook 使用事件为基于证据的包,优先考虑 hook |
| `help` | 所有操作的 Markdown 引用 |
## 主机库存
`cortex ingest inventory refresh --json` 收集原生 Rust 库存到 `~/.cortex/inventory` 并写入:
- `normalized/homelab.json` — 类型化的 `cortex.homelab_inventory.v1` 缓存
- `collection-state.json` — 每个收集器的状态、警告、时间记录和工件引用
- `raw/<run_id>/*.txt` — 原始但已编辑的 Compose 和反向代理工件
`cortex ingest inventory status --json` 报告缓存新鲜度和警告,而无需打开 SQLite。MCP 的 `map` 操作是只读的:它读取规范化的缓存并覆盖有界的实时 Cortex 主机/心跳数据,但从不触发刷新或返回原始工件体。
`map` 默认使用库存快照。基于图的模式添加一个类型化的 `graph_answer` 信封,包含 `answer_status`、`rows` 有界拓扑、`safe` 证据样本、`map` 跟进查询和图证明查询:
```json
{"action":"map","mode":"host_services","host":"squirts"}
{"action":"map","mode":"domain_routes","domain":"adguard.tootie.tv"}
{"action":"map","mode":"service_dependencies","host":"squirts","service":"swag"}
{"action":"map","mode":"findings","finding_types":["potential_public_route","risky_mounts","collector_health"]}
```
`mode=findings` 返回基于图的拓扑风险和卫生状况发现,这些发现源自规范化的库存/缓存状态。发现结果包括严重性、置信度、原因代码、受影响的实体、安全证据 ID/摘录和补救提示。它们故意避免原始配置内容、原始工件或缓存路径、包含凭据的上游 URL 和原始收集器警告文本;`potential_public_route` 指的是配置的反向代理路由,而不是未经身份验证的公共互联网暴露证明。
当服务器运行时,库存刷新还会将拓扑证据投射到调查图中。基线刷新间隔为 5 分钟,本地 Compose/代理配置监视器作为低延迟刷新触发器。远程 Docker `events` 流通过 SSH 是可选的,通过设置 `CORTEX_INVENTORY_REMOTE_DOCKER_EVENTS=true` 启用。
在第一次运行时,在 `normalized/homelab.json` 存在之前,`map` 和 `cortex ingest inventory status --json` 报告 `cache_status: "missing"`。运行 `cortex ingest inventory refresh --json` 以播种 `~/.cortex/inventory` 并清除缺失缓存状态。
## 提示
MCP 服务器还为常见的基础设施调试工作流提供了可重用的提示:`infra.incident-triage`、`infra.host-health`、`infra.service-outage`、`infra.security-auth-review`、`infra.noise-reduction` 和 `infra.agent-change-correlation`。
有关提示目录和参数参考,请参见 [`docs/mcp/PROMPTS.md`](docs/mcp/PROMPTS.md)。
## MCP 应用查询小部件
Cortex 配备了一个交互式 UI 表面作为渐进式增强:一个简单的日志搜索小部件,用于支持 MCP 应用的 MCP 主机 [`MCP Apps`](https://modelcontextprotocol.io/extensions/apps/overview) / MCP-UI (`_meta.ui.resourceUri`)。它是一个单独的自包含 HTML 资源 - 无需浏览器构建步骤,无外部依赖,无新服务器路由。
- **资源 URI:** `ui://cortex/query-widget`
- **MIME 类型:** `text/html;profile=mcp-app`
- `cortex` 工具通过 `_meta.ui.resourceUri` 广告宣传它;小部件通过主机桥调用相同的 `cortex` 工具,带有 `action=search` 并在紧凑的表格中渲染行。
- 它是一个**简单的搜索 UI,而不是仪表盘** - 查询(FTS5)加主机、严重性和限制过滤器。
**非 UI 主机不受影响**。普通的 MCP 客户端继续读取正常的文本/JSON 工具结果;只有检测到 `_meta.ui.resourceUri` 的主机才获取和渲染 `ui://` 资源。
使用原始 JSON-RPC(无需 UI 主机)确认线路合约:
```bash
# 小部件资源被列出
curl -s -X POST http://localhost:3100/mcp \
-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/list","params":{}}'
# 小部件 HTML 使用 MCP 应用 MIME 类型提供
curl -s -X POST http://localhost:3100/mcp \
-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"resources/read","params":{"uri":"ui://cortex/query-widget"}}'
# 搜索返回结构化内容(用于 UI 行)和文本(用于普通客户端)
curl -s -X POST http://localhost:3100/mcp \
-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"cortex","arguments":{"action":"search","query":"error","limit":5}}}'
```
如果设置了 `CORTEX_TOKEN`,请添加 `-H "Authorization: Bearer $CORTEX_TOKEN"`。
`scripts/smoke-test.sh` 自动运行这些相同的检查。对于线路格式详细信息,请参见 [`docs/mcp/MCPUI.md`](docs/mcp/MCPUI.md)。
### `cortex search`
对所有 syslog 消息进行全文搜索,可选过滤器。使用 SQLite FTS5 和波特词干提取。
**参数**
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|-----------|------|----------|---------|-------------|
| `query` | 字符串 | 否 | — | FTS5 查询(参见 [FTS5 查询语法](#fts5-查询语法)) |
| `host` | 字符串 | 否 | — | 精确的主机名匹配。使用 `cortex` 和 `action: "hosts"` 来枚举。 |
| `source` | 字符串 | 否 | — | 精确的源标识符。Syslog 条目使用验证的网络发送者地址(`IP:port`);OTLP 行使用验证的对等 IP;Docker 提取流行使用 `docker://host/container/stream`;Docker 生命周期事件行使用 `docker-event://host/container/action`。 |
| `severity` | 字符串 | 否 | — | 以下之一:`emerg alert crit err warning notice info debug` |
| `app` | 字符串 | 否 | — | 应用程序名称,例如 `sshd`、`dockerd`、`kernel` |
| `since` | 字符串 | 否 | — | 时间范围起点(相对如 `1h`/`yesterday`,或 ISO 8601 / RFC 3339,例如 `2025-01-15T00:00:00Z`) |
| `until` | 字符串 | 否 | — | 时间范围终点(相对或 ISO 8601) |
| `limit` | 整数 | 否 | 100 | 最大结果数(上限:1000) |
**响应**
```json
{
"count": 3,
"logs": [
{
"id": 12345,
"timestamp": "2025-01-15T14:30:00Z",
"hostname": "router",
"facility": "kern",
"severity": "err",
"app_name": "kernel",
"process_id": null,
"message": "kernel panic: unable to mount root",
"received_at": "2025-01-15T14:30:01.123Z",
"source_ip": "10.0.0.1:51234"
}
]
}
```
**FTS5 示例**
```
query: "kernel panic" # 隐含 AND:两个术语必须同时出现
query: "OOM AND killer" # 显式 AND
query: "sshd OR pam" # 布尔 OR
query: "failed NOT sudo" # 布尔 NOT
query: '"connection refused"' # 精确短语(绕过词干提取)
query: "error*" # 前缀通配符
query: "restart*" # 匹配 restart、restarted、restarting
```
### `cortex filter`
用于关联工作流的结构化筛选器检索。此操作拒绝 `query`;使用 `search` 进行 FTS5 消息体搜索。
常见筛选器与 `search` 匹配:`host`、`source`、`severity`、`app`、`facility`、`exclude_facility`、`process_id`、`since`、`until`、`received_since`、`received_until` 和 `limit`。
关联别名包括 `source_kind`(`docker-stream`、`docker-event`、`agent-command`、`shell-history`、`transcript`、`claude`、`codex`、`gemini`),以及 `tool`、`project`、`session_id`、`container`、`docker_host`、`stream` 和 `event_action`。
`source_kind=file-tail` 筛选托管文件尾行(`source_ip` 前缀 `file-tail://`)。
---
### `cortex tail`
返回 N 条最近的日志条目。等效于 `tail -f` 跨所有主机。
**参数**
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|-----------|------|----------|---------|-------------|
| `host` | 字符串 | 否 | — | 过滤到特定主机 |
| `source` | 字符串 | 否 | — | 过滤到精确的源标识符。Syslog 条目使用验证的网络发送者地址(`IP:port`);OTLP 行使用验证的对等 IP;Docker 提取流行使用 `docker://host/container/stream`;Docker 生命周期事件行使用 `docker-event://host/container/action`。 |
| `app` | 字符串 | 否 | — | 过滤到特定应用程序 |
| `n` | 整数 | 否 | 50 | 最近条目数(上限:500) |
**响应**
与 `cortex search` 相同结构: `{ "count": N, "logs": [...] }`.
---
### `cortex analysis errors`
汇总所有主机上的警告和错误,时间窗口内分组,按主机名和严重程度显示计数。用于快速健康评估。
**参数**
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|-----------|------|----------|---------|-------------|
| `since` | 字符串 | 否 | 所有时间 | 时间范围起点(ISO 8601) |
| `until` | 字符串 | 否 | 现在 | 时间范围终点(ISO 8601) |
包含的严重程度:`emerg`、`alert`、`crit`、`err`、`warning`.
**响应**
```json
{
"summary": [
{ "hostname": "router", "severity": "err", "count": 42 },
{ "hostname": "router", "severity": "warning", "count": 17 },
{ "hostname": "storage", "severity": "crit", "count": 3 }
]
}
```
---
### `cortex hosts`
列出所有已发送 syslog 消息的主机,并附有首次/最后一次看到的时间戳和总日志计数。
**参数:** 无
**响应**
```json
{
"hosts": [
{
"hostname": "router",
"first_seen": "2025-01-01T00:00:00.000Z",
"last_seen": "2025-01-15T14:30:00.000Z",
"log_count": 18432
}
]
}
```
---
### `cortex sessions`
按项目、工具、会话和主机分组列出 AI 转录会话。
**参数**
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|-----------|------|----------|---------|-------------|
| `project` | 字符串 | 否 | — | 精确的项目路径,例如 `/home/jmagar/workspace/cortex` |
| `tool` | 字符串 | 否 | — | AI 工具筛选器:`claude`、`codex` 或 `gemini` |
| `host` | 字符串 | 否 | — | 限制为主机 |
| `since` | 字符串 | 否 | — | 时间范围起点(ISO 8601) |
| `until` | 字符串 | 否 | — | 时间范围终点(ISO 8601) |
| `limit` | 整数 | 否 | 100 | 最大会话数(上限:1000) |
**响应**
```json
{
"count": 1,
"sessions": [
{
"project": "/home/jmagar/workspace/cortex",
"tool": "codex",
"session_id": "019e1506-dc81-7881-9926-4d6d4efda1ac",
"hostname": "dookie",
"first_seen": "2026-05-11T03:13:51.745Z",
"last_seen": "2026-05-11T04:10:00.000Z",
"event_count": 42
}
]
}
```
---
### `cortex correlate events`
在参考时间戳周围的 ±N 分钟窗口内搜索相关事件。适用于调试级联故障。结果按主机分组并按时间排序。
**参数**
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|-----------|------|----------|---------|-------------|
| `reference_time` | 字符串 | **是** | — | 中心时间戳(ISO 8601,例如 `2025-01-15T14:30:00Z`) |
| `window_minutes` | 整数 | 否 | 5 | `reference_time` 之前和之后分钟数(最大 60) |
| `severity_min` | 字符串 | 否 | `warning` | 要包含的最低严重性。`warning` 返回 `warning/err/crit/alert/emerg`。`debug` 返回所有内容。 |
| `host` | 字符串 | 否 | — | 限制关联到一个主机 |
| `source` | 字符串 | 否 | — | 限制关联到精确的源标识符。Syslog 条目使用验证的网络发送者地址(`IP:port`);OTLP 行使用验证的对等 IP;Docker 提取流行使用 `docker://host/container/stream`;Docker 生命周期事件行使用 `docker-event://host/container/action`。 |
| `query` | 字符串 | 否 | — | FTS5 查询以缩小结果 |
| `limit` | 整数 | 否 | 500 | 最大事件总数(上限:999) |
**响应**
```json
{
"reference_time": "2025-01-15T14:30:00Z",
"window_minutes": 5,
"window_from": "2025-01-15T14:25:00+00:00",
"window_to": "2025-01-15T14:35:00+00:00",
"severity_min": "warning",
"total_events": 12,
"truncated": false,
"hosts_count": 3,
"hosts": [
{
"hostname": "router",
"event_count": 7,
"events": [...]
}
]
}
```
**注意时钟偏移:`cortex correlate events` 使用 syslog 消息中的 `timestamp` 字段,该字段反映发送设备的时钟。如果设备时钟偏移,事件可能落在关联窗口之外。参见 [时间同步](#time-synchronization).
---
### `cortex stats`
返回数据库统计信息,包括总日志数、总主机数、涵盖的时间范围、逻辑和物理数据库大小、空磁盘、配置的阈值、当前写阻塞状态和运行时摄入可观察性。
**参数:** 无
**响应**
```json
{
"total_logs": 284917,
"total_hosts": 12,
"oldest_log": "2024-10-15T00:00:01Z",
"newest_log": "2025-01-15T14:30:00Z",
"logical_db_size_mb": "312.45",
"physical_db_size_mb": "328.00",
"free_disk_mb": "14200.00",
"max_db_size_mb": 1024,
"min_free_disk_mb": 0,
"write_blocked": false,
"runtime_observability": {
"syslog_udp_packets_received": 280000,
"syslog_tcp_connections_active": 3,
"ingest_entries_enqueued": 284917,
"ingest_queue_depth": 0,
"ingest_queue_capacity": 10000,
"ingest_queue_utilization_pct": "0.00",
"writer_batches_flushed": 2850,
"writer_logs_written": 284917,
"writer_flush_failures": 0,
"writer_logs_retained": 0,
"writer_logs_discarded": 0,
"writer_storage_blocked": false,
"last_ingest_at": "2025-01-15T14:30:05.123Z",
"last_write_at": "2025-01-15T14:30:05.400Z",
"last_error_at": null
},
"otlp": {
"logs_received": 42,
"decode_errors": 0
}
}
```
`write_blocked: true` 表示存储预算超额,暂停新的日志摄入。参见 [存储预算强制](#storage-budget-enforcement).
---
### `cortex status`
返回轻量级运行时状态,无需执行较重的 DB 统计信息查询。在需要当前队列深度、背压、写入失败/丢弃状态、侦听器计数器和上次活动时间戳的仪表板和医生检查中使用此功能。
**参数:** 无
---
### `cortex help`
返回此工具集中所有工具的 Markdown 文档。
**参数:** 无
---
本节中仅详细记录了最常见的操作。有关完整的 45 个操作接口及其参数,请参见 [`docs/mcp/SCHEMA.md`](docs/mcp/SCHEMA.md) 或对正在运行的服务器调用 `action=help`。
---
## FTS5 查询语法
`cortex search` 和 `cortex correlate` 操作使用带有波特词干提取的 SQLite FTS5(`tokenize='porter unicode61'`)。有效的查询形式:
| 语法 | 示例 | 匹配 |
|--------|---------|---------|
| 单个术语 | `panic` | 任何包含“panic”或词干变体的消息 |
| 波特词干提取 | `restart` | restart、restarted、restarting、restarts |
| AND(默认) | `disk error` 或 `disk AND error` | 两个术语同时存在 |
| OR | `sshd OR pam` | 任一术语存在 |
| NOT | `failed NOT sudo` | 存在“failed”,不存在“sudo” |
| 短语 | `"connection refused"` | 精确短语(绕过词干提取) |
| 前缀通配符 | `error*` | 任何以“error”开头的单词 |
| 分组 | `(kernel OR oom) AND panic` | 分组布尔逻辑 |
**限制:** 最大 512 个字符,最大 16 个空格分隔的术语。
**波特词干提取** 表示 `connect`、`connected`、`connecting` 和 `connection` 都与查询 `connect` 匹配。短语查询 (`"..."`) 绕过词干提取并需要确切的令牌顺序。
---
## 日志模式
每个存储的日志条目都有以下字段:
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `id` | 整数 | 自动递增主键 |
| `timestamp` | 文本 | 消息时间戳(RFC 3339,UTC)。来自 syslog 消息头。 |
| `hostname` | 文本 | syslog 消息中的主机名(用户控制的,未验证) |
| `facility` | 文本\|空 | syslog 设施名称(参见下面的设施) |
| `severity` | 文本 | syslog 严重程度级别名称 |
| `app_name` | 文本\|空 | syslog 消息中的应用程序/进程名称 |
| `process_id` | 文本\|空 | syslog 消息中的 PID |
| `message` | 文本 | 日志消息体(FTS5 索引) |
| `received_at` | 文本 | 服务器端接收时间戳(RFC 3339,UTC)。用于保留。 |
| `source_ip` | 文本 | 源标识符。syslog 条目使用精确的网络发送者地址 (`IP:port`) 捕获的包/连接对等方的 IP。OTLP 行使用对等 IP 而不是临时源端口。Docker 提取流行使用 `docker://host/container/stream`;Docker 生命周期事件行使用 `docker-event://host/container/action`。 |
| `ai_tool` | 文本\|空 | AI 工具名称(例如 `claude`、`codex`、`gemini`) |
| `ai_project` | 文本\|空 | AI 项目路径 |
| `ai_session_id` | 文本\|空 | AI 会话唯一标识符 |
| `ai_transcript_path` | 文本\|空 | 源转录文件路径 |
| `metadata_json` | 文本\|空 | 源特定 JSON 元数据。syslog 行包括解析器/源出处;OTLP 行包括资源/日志属性以及跟踪/范围 ID;Docker 行包括主机/容器/映像/操作详细信息;转录行包括源类型、文件路径、行号、记录键和净化状态。 |
### AI 转录索引
`cortex sessions index` 扫描默认的本地转录根目录 `~/.claude/projects`、`~/.codex/sessions` 和 `~/.gemini/tmp`;`cortex sessions index --path PATH` 可以扫描一个已知的转录目录或一个明确支持的转录文件,而 `cortex sessions add --file FILE` 则导入一个文件。递归扫描仅限于 `~/.claude/projects`、`~/.codex/sessions`、`~/.gemini/tmp` 或其子目录;诸如 `/`、`$HOME` 和当前仓库根目录等广泛的根目录在遍历前会被拒绝。扫描器跳过符号链接,不解析不支持的文件,并以有界的 SQLite 数据块流式传输 JSONL 转录文件。Gemini 聊天文件从 `~/.gemini/tmp/*/chats/session-*.json` 导入;当 Gemini 文件仅有 `projectHash` 时,Cortex 将项目存储为 `gemini://project/<hash>`,以便会话库存保持可查询。使用 `--force` 可以从头开始重新导入转录路径,`--since RFC3339` 仅扫描最近修改的文件,而 `cortex sessions checkpoints --errors` 加上 `cortex sessions errors` 用于检查结构化的扫描器失败。
对于实时本地 Claude/Codex/Gemini 转录摄入,安装主机本地的监视服务:
```bash
cortex setup sessionswatch install
cortex setup sessionswatch check
cortex setup sessionswatch remove
```
监视器在 Docker 外部运行,因为它需要访问主机上的 `~/.claude/projects`、`~/.codex/sessions` 和 `~/.gemini/tmp`。它写入配置的实时 SQLite 数据库,并将每个稳定更改的支持转录文件委托给与 `cortex sessions add --file FILE` 相同的扫描器路径;Gemini `session-*.json` 聊天文件使用相同的检查点和重复抑制路径。安装监视器会禁用较旧的轮询计时器,以免两个辅助程序扫描相同的文件。
**这会写入本地 SQLite 文件。** 只有当服务器也运行在同一主机上时,它才会到达舰队的共享 Cortex 服务器。当服务器运行在其他地方(常见情况 - 服务器通常运行在一台专用主机上,而 Claude/Codex/Gemini 运行在开发工作站上)时,请在 `cortex heartbeat agent` 上启用 AI 转录转发:`--ai-transcripts` / `CORTEX_AGENT_AI_TRANSCRIPTS=true`。这添加了一个受监督的流(与 `--docker`/`--journald` 一起),每 15 秒轮询相同的转录根目录,并将新行 POST 到服务器的 `POST /v1/ai-transcripts`(带有 bearer 身份验证,与心跳相同的令牌),使用本地检查点文件(`CORTEX_AGENT_AI_TRANSCRIPT_CHECKPOINT`,默认为 `<cortex home>/ai-transcript-forward-checkpoint.json`),因此它永远不会重新发送已经转发的行。Gemini 会话当前不受转发器的支持(整个文件的 JSON,而不是像 Claude/Codex 那样基于行的)- 今天只有 Claude 和 Codex 转录转发。本地监视服务和代理转发器可以同时运行而不会冲突;它们只读取转录文件,永远不会写入它们。
可选的轮询回退仍然可用:
```bash
cortex setup sessionstimer install
cortex setup sessionstimer check
cortex setup sessionstimer remove
```
两个辅助程序都故意不在 Docker 容器中。Docker Compose 只拥有服务器/查询运行时。
导入的 AI 转录消息在存储和全文索引之前会清除已知的凭据/令牌模式。行仍然存在于主 `logs` 表中,因此诸如 `search`、`tail`、`context` 和 `get` 等原始操作可以在转录写入后几秒内返回清除的转录文本和本地 `ai_transcript_path` 值。清除是一种尽力而为的,不是合规边界。如果存储防护措施无法恢复足够的空间,则索引会在提交额外块之前失败。
### Shell 和代理命令历史
本地命令历史可以与系统日志相关联,无需引入单独的表:
```bash
cortex ingest shell user index --path ~/.zsh_history --shell zsh
cortex setup shell agent install
export CLAUDE_CODE_SHELL_PREFIX="$HOME/.local/bin/cortex-agent-command-wrapper"
cortex ingest shell agent index ~/.local/state/cortex/agent-command.jsonl
```
`cortex ingest shell agent index` 还接受 `--server URL`/`--token TOKEN` 以将 spool 转发到远程 Cortex 的 `POST /v1/agent-commands` 端点,而不是写入本地数据库 - 只有在成功转发后才会截断 spool。删除的拼写会失败,并带有规范替换指导;没有兼容性别名。
`cortex ingest shell user index` 导入具有时间戳和持续时间的 zsh 扩展历史行,作为 `source_kind="shell-history"` 行。普通的无时间戳历史记录被跳过,因为它不支持时间窗口关联。
`cortex setup shell agent install` 编写了一个小的本地包装器,用于 Claude Code 的 `CLAUDE_CODE_SHELL_PREFIX`。Claude Code 为启动的 shell 命令调用该前缀,包括 Bash 工具调用、钩子命令和 stdio MCP 服务器启动命令。包装器保留 stdio 和退出代码,追加一个清除的 JSONL 记录到 `~/.local/state/cortex/` 下,并将这些记录导入为 `source_kind="agent-command"` 行,然后在成功导入后截断锁定 spool。包装器记录命令文本、cwd、持续时间、退出状态、代理名称、PID、主机/用户和 `CLAUDE_CODE_SESSION_ID`(如果存在)。它默认不捕获环境变量、stdout 或 stderr。
两个命令导入路径都运行 AI 清除器以及用于令牌标志、敏感赋值、授权标头、URL 用户信息、`curl -u` 和私钥块的命令特定编辑后存储。清除是尽力而为的,不是合规边界。
**重要:** `hostname` 取自 syslog 消息体,任何 LAN 设备都可以通过 UDP 将其设置为任意值。对于 syslog 条目,`source_ip` 是唯一的受信任网络标识符。对于当前主机本地 Cortex 代理的 Docker 日志条目,信任遵循部署的代理主机及其本地 Docker 套接字访问。对于遗留中央拉取条目,`source_ip` 标识配置的 Docker 主机/容器/流,应该仅信任明确的远程 Docker 引擎端点和网络路径。`metadata_json` 保留源特定的上下文用于调试和关联,但它不是授权边界。保留截止日期使用 `received_at`(服务器时钟),以便时钟配置错误的设备不会导致过早或无限期日志保留。
### 严重程度级别
从最严重到最不严重排序:
| 级别 | 数值 | 含义 |
| --- | --- | --- |
| `emerg` | 0 | 系统无法使用 |
| `alert` | 1 | 必须立即采取行动 |
| `crit` | 2 | 关键条件 |
| `err` | 3 | 错误条件 |
| `warning` | 4 | 警告条件 |
| `notice` | 5 | 正常但重要的条件 |
| `info` | 6 | 信息消息 |
| `debug` | 7 | 调试级别的消息 |
### 设施
`kern`、`user`、`mail`、`daemon`、`auth`、`cortex`、`lpr`、`news`、`uucp`、`cron`、`authpriv`、`ftp`、`ntp`、`audit`、`alert`、`clock`、`local0`–`local7`。
---
## 安装
### 一键安装程序
```bash
curl -fsSL https://raw.githubusercontent.com/jmagar/cortex/main/install.sh | sh
```
安装程序将主机 `cortex` 二进制文件放在 `~/.local/bin` 中,然后运行 `cortex setup`。设置是幂等的,并拥有共享主机布局:
- `~/.cortex/.env` - 机密、端口、Compose 插值、运行时值
- `~/.cortex/compose/docker-compose.yml` - Docker Compose 部署资产
- `~/.cortex/data/cortex.db` - SQLite 数据库和 WAL/SHM 边车
设置写入由共享主机部署使用的 Compose 项目名称。现有的安装可能仍使用旧的 `syslog-jmagar-lab` 项目名称进行容器标签兼容性;请优先使用 `cortex compose ...` 命令,因为它们在修改堆栈之前解析活动所有者。
有用的安装程序控件:
```bash
CORTEX_INSTALL_DRY_RUN=1 ./install.sh
CORTEX_INSTALL_PREFIX=/opt/cortex ./install.sh
CORTEX_VERSION=<version> ./install.sh
CORTEX_INSTALL_SKIP_SETUP=1 ./install.sh
```
有用的设置命令:
```bash
cortex setup # 首次运行或正常修复
cortex setup check # 仅检查;不会修改文件或启动服务
cortex setup repair # 修复环境/资产并重启 Docker 堆栈
cortex setup deploy preflight # 使用设置资产进行部署预检
cortex setup deploy local # 本地 Compose 部署/协调命令
cortex setup deploy local --dry-run # 在不修改 Docker 的情况下运行部署预检
cortex setup sessionswatch install # 主机本地实时转录监视器
cortex doctor binary # 检查主机/容器二进制文件新鲜度
```
### Claude Code 插件(推荐)
作为 Claude Code 插件安装。插件自动处理部署 - 您可以选择服务器模式(此机器托管 syslog 接收器 + MCP 服务器)和客户端模式(连接到远程服务器)。
**安装时提示(通过 `userConfig`):**
| 字段 | 必需 | 默认值 | 备注 |
| --- | --- | --- | --- |
| `is_server` | 是 | `true` | 服务器模式托管接收器;客户端模式连接到远程服务器 |
| `server_url` | 否 | `http://localhost:3100` | 服务器模式:保留默认值。客户端模式:远程主机 URL(例如 `http://shart:3100`) |
| `api_token` | 是 | - | 插件 MCP 客户端使用的 bearer 令牌。服务器模式:此令牌成为服务器强制执行的令牌,除非 `no_auth=true`。客户端模式:服务器管理员的令牌。存储在系统密钥链中。 |
| `syslog_host` / `syslog_port` | 否 | `0.0.0.0` / `1514` | Syslog 监听器绑定(服务器模式) |
| `mcp_host` / `mcp_port` | 否 | `0.0.0.0` / `3100` | MCP HTTP 服务器绑定(服务器模式) |
| `data_dir` | 否 | `~/.cortex/data` | 可选 SQLite 目录覆盖;默认共享设置数据保留在插件缓存之外 |
| `max_db_size_mb` | 否 | `8192` | 数据库大小上限;超过时删除最旧的日志 |
| `retention_days` | 否 | `90` | `0` = 永久保留 |
| `batch_size` | 否 | `100` | 解析的消息数/ SQLite 批次 |
| `write_channel_capacity` | 否 | `10000` | 内部解析消息队列容量,在监听器背压之前 |
| `docker_ingest_enabled` | 否 | `false` | 显式远程 Docker 引擎端点的旧中央拉取兼容性模式;当前部署使用主机本地代理 |
| `fleet_hosts` | 否 | - | SSH 别名。用于 Docker 摄入 - 启用后,每个成为 `http://<alias>:2375` |
**会话启动钩子自动化(服务器模式):**
- 确保主机 `cortex` 二进制文件在 `PATH` 上;安装程序默认为 `~/.local/bin`
- 将插件 `userConfig` 作为 `CORTEX_*` / `CORTEX_*` 环境值导出
- 运行 `cortex setup repair`,与一键安装程序使用的相同设置路径
- 修复 `~/.cortex` 下的共享资产,并删除旧插件版本留下的过时用户级 `cortex.service` 单元/下拉项
- 幂等 - 可以在每次会话安全运行
**捆绑技能(共 13 个,来自 `plugins/cortex/skills/`):
- `cortex` - 主要的日志智能技能:搜索、尾部、错误、关联、统计等 MCP 操作界面
- `frustration-assessment` - 分析 `abuse_investigate` 证据包以生成挫折/滥用报告
- `mcp-friction-assessment` - 分析 `mcp_investigate` 证据包以查找 MCP 工具可靠性问题
- `hook-friction-assessment` - 分析 `hook_investigate` 证据包以查找钩子可靠性问题
- `skill-improvement-assessment` - 分析 `skill_investigate` 证据包以查找技能质量问题
- `incidents` - 分类未确认的错误签名、通知、以前的事件和事件上下文
- `topology` - 通过 `map`/`host_state`/`fleet_state`/`correlate`/`graph` 进行 homelab 拓扑和跨主机关联
- `session-search` - 搜索和探索 AI 转录会话
- `logs` - Docker Compose 服务日志尾部(服务的 stdout/stderr,而非客户端 syslog)
- `redeploy` - 在配置或插件更改后重新运行插件设置
- `report` - 有时间限制的 homelab 健康/日志分析 Markdown 报告
- `troubleshoot` - 诊断连接失败、丢失日志、不健康的容器和重启循环
- `version-check` - 检查运行的 Docker 容器是否与本地 Compose 镜像匹配;添加 `--pull` 以先拉取,否则仅检查本地镜像缓存
插件通过与一键安装程序相同的 `cortex setup` 路径部署服务器与 Docker Compose。您仍然可以为开发构建和运行二进制文件,但自动化部署仅限于 Compose。
`cortex setup deploy local` 是操作员面向的名称,用于相同的本地 Compose 支持的协调路径。它存在,以便部署工作流保留在设置命名空间下,而不直接调用名为 `setup repair` 的命令。
### Docker
```bash
git clone https://github.com/jmagar/cortex
cd cortex
cp .env.example .env
# 编辑 .env - 至少设置 CORTEX_TOKEN
docker compose up -d
```
容器绑定:
- `UDP :1514` 和 `TCP :1514` 用于 syslog 摄入(发布到所有接口 - 发送者必须到达)
- `TCP :3100` 用于 MCP HTTP API,默认仅在 `127.0.0.1` 上发布。设置 `CORTEX_MCP_BIND=0.0.0.0` (以及 `CORTEX_TOKEN`)以公开它;同一 Docker 网络上的容器(例如 Labby 网关)可以通过 `http://cortex:3100` 访问
### 本地构建
需要 Rust 1.86+。
```bash
cargo build --release
./target/release/cortex serve mcp
```
---
## 身份验证
Cortex 支持两种身份验证模式,可通过 `CORTEX_AUTH_MODE` 选择。
**仅限 Bearer(默认)** - 设置 `CORTEX_TOKEN` 和所有 `/mcp` 请求必须将该令牌作为 `Authorization: Bearer <token>` 呈现。没有 OAuth 路由被挂载。
**循环回路无身份验证** - 仅在循环回路绑定上设置 `CORTEX_NO_AUTH=true`。
**网关保护的无身份验证(TrustedGatewayUnscoped)** - 在非循环绑定上,同时设置 `CORTEX_NO_AUTH=true` 和 `CORTEX_TRUSTED_GATEWAY_NO_AUTH=true`,前提是上游网关或反向代理在流量到达 Cortex 之前执行身份验证。这故意禁用服务本地的 MCP 身份验证 **和读取/管理员范围门控** - 每个调用者都可以运行 `ack_error`、`unack_error` 和 `notifications_test`。 **切勿将此模式与主机发布的端口结合使用**;保持 `CORTEX_MCP_BIND=127.0.0.1`(默认值),以便只有网关的 Docker 网络路径到达 Cortex。参见 [docs/SECURITY.md](docs/SECURITY.md)。
**OAuth(Google)** - 设置 `CORTEX_AUTH_MODE=oauth`、OAuth 提供者环境变量和允许的管理员电子邮件列表。服务器在用户通过 Google 身份验证后颁发 RS256 JWT。Bearer 令牌和 OAuth JWT 可以共存(OAuth 模式默认禁用静态令牌;设置 `CORTEX_AUTH_DISABLE_STATIC_TOKEN_WITH_OAUTH=false` 或 `disable_static_token_with_oauth = false` 在 `config.toml` 中进行故障排除)。
两种模式都留下 `/health` 未认证,以便健康探测始终有效。
参见 [docs/OAUTH.md](docs/OAUTH.md) 以获取完整的设置说明、架构图和操作员 FAQ。
---
## 配置
配置从三个来源按优先级顺序加载(最高优先级获胜):
1. 环境变量
2. `config.toml`(如果存在)
3. 内置默认值
### 环境变量
#### MCP 服务器
| 变量 | 必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `CORTEX_TOKEN` | 否 | --- |
| `CORTEX_HOST` | 否 | `127.0.0.1` | MCP HTTP 服务器绑定主机(默认循环访问) |
| `CORTEX_PORT` | 否 | `3100` | MCP HTTP 服务器绑定端口 |
| `CORTEX_MCP_BIND` | 否 | `127.0.0.1` | 仅限 Docker Compose:端口 3100 发布到的主机接口。将其设置为 `0.0.0.0` 和 `CORTEX_TOKEN` 以公开它。 |
| `CORTEX_ALLOWED_HOSTS` | 否 | - | RMCP 主机头验证接受的额外逗号分隔主机头值 |
| `CORTEX_ALLOWED_ORIGINS` | 否 | - | RMCP 源验证接受的额外逗号分隔浏览器源 |
#### 非 MCP API
纯 JSON API 始终挂载在 `/api/*` 下,使用相同的 HTTP 监听器,需要自己的 bearer 令牌 - 服务器在启动时(在服务器路径上)失败,没有它。`cortex setup repair` 在缺少时生成一个。
| 变量 | 必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `CORTEX_API_TOKEN` | 是 | - | `/api/*` 路由的 bearer 令牌 |
#### Syslog 监听器
| 变量 | 必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `CORTEX_RECEIVER_HOST` | 否 | `0.0.0.0` | UDP + TCP syslog 监听器绑定主机 |
| `CORTEX_RECEIVER_PORT` | 否 | `1514` | UDP + TCP syslog 监听器绑定端口 |
| `CORTEX_RECEIVER_HOST_PORT` | 否 | `1514` | Docker Compose 容器端口 1514 发布到的主机端口 |
| `CORTEX_MAX_MESSAGE_SIZE` | 否 | `8192` | UDP 数据报或换行分隔 TCP 帧的最大字节数。超过大小限制的换行分隔 TCP 帧将被丢弃,连接保持打开;超过大小限制的无终止帧将被丢弃,连接将被关闭。 |
| `CORTEX_MAX_TCP_CONNECTIONS` | 否 | `512` | 同时运行的最大 TCP syslog 连接数 |
| `CORTEX_TCP_IDLE_TIMEOUT_SECS` | 否 | `300` | TCP 读取空闲超时秒数,用于关闭非活动连接 |
| `CORTEX_BATCH_SIZE` | 否 | `100` | 每批消息数 |
| `CORTEX_FLUSH_INTERVAL` | 否 | `500` | 批量刷新间隔(毫秒) |
| `CORTEX_WRITE_CHANNEL_CAPACITY` | 否 | `10000` | 内部解析消息队列容量 |
#### Docker 日志摄入
当前部署路径是主机本地的 cortex 代理。每个部署的代理从该主机的本地 Docker 套接字(`unix:///var/run/docker.sock`)读取 Docker 日志,并将规范化的行转发到 cortex。这保持了 Docker 正常的本地日志行为,避免了守护进程级别的 syslog 驱动程序,并且不需要在网络上暴露 Docker API 端点。
`CORTEX_DOCKER_*` 设置在下面作为遗留的中心拉取兼容性模式保留,用于显式的远程 Docker 引擎 HTTP 端点。在需要 cortex 自身连接到兼容 Docker 的 API 的情况下,可以使用它们进行夹具或过渡部署。旧部署使用 `docker-socket-proxy` 作为此端点,但这不再是推荐的 homelab 路径。
| 变量 | 是否必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `CORTEX_DOCKER_INGEST_ENABLED` | 否 | `false` | 启用遗留中心拉取 Docker 日志摄入 |
| `CORTEX_DOCKER_HOSTS` | 两者之一 | - | 以逗号分隔的主机名;每个主机名成为 `http://<name>:2375`,且 `allow_insecure_http = true`。优先级高于 `CORTEX_DOCKER_HOSTS_FILE`。 |
| `CORTEX_DOCKER_HOSTS_FILE` | 两者之一 | - | 指向一个包含 `[[hosts]]` 数组的 TOML 文件的路径(用于需要每台主机 `base_url` 或 TLS 的情况)。如果文件不存在,则记录警告并且不加载主机 - 容器不会崩溃。将文件挂载到容器中(例如,通过 `CORTEX_HOME_VOLUME` 挂载到 `/cortex-home`)。 |
| `CORTEX_DOCKER_RECONNECT_INITIAL_MS` | 否 | `1000` | 主机流故障后的初始重新连接延迟 |
| `CORTEX_DOCKER_RECONNECT_MAX_MS` | 否 | `30000` | 重复故障后最大重新连接延迟 |
主机文件使用以下格式:
```toml
[[hosts]]
name = "edge-host-a"
base_url = "http://edge-host-a:2375"
allow_insecure_http = true
[[hosts]]
name = "app-host-b"
base_url = "http://app-host-b:2375"
allow_insecure_http = true
```
如果此遗留拉取路径指向 `docker-socket-proxy`,则代理端只需要对容器、事件、ping 和版本端点的读取访问:`CONTAINERS=1`、`EVENTS=1`、`PING=1`、`VERSION=1`、`POST=0`。`CONTAINERS=1` 将更广泛的只读 Docker 容器 API 公开给任何可以访问代理的东西,因此请仅在受信任的私有网络上绑定它,为 cortex 设置防火墙规则,或将其放在经过身份验证的 TLS 后面。纯 `http://` 端点需要主机文件中 `allow_insecure_http = true`,以便此信任决策是明确的。
Docker 日志摄入有两个测试边界:代理对等测试验证已部署的代理保留本地 Docker 套接字流,而遗留中心拉取客户端具有模拟的 Docker HTTP 夹具。默认烟雾测试仅关注实时 UDP/TCP syslog、MCP/REST 操作、CLI 对等和托管文件尾部摄入。为了进行完整的遗留拉取集成检查,请使用 `CORTEX_DOCKER_INGEST_ENABLED=true` 运行 cortex 针对可丢弃的 Docker 兼容 HTTP 夹具,发出一个短暂容器的唯一行,然后使用 `cortex search` 或 `mcporter call ... action=search` 验证它。容器 stdout/stderr 行使用 `source_ip=docker://<host>/<container>/<stream>`。容器生命周期行用于 `create`、`start`、`restart`、`die`、`stop`、`destroy`、`rename`、`oom` 和 `health_status:*` 等操作,使用 `source_ip=docker-event://<host>/<container>/<sanitized-action>`、`facility=docker`,并保留原始 Docker 事件 JSON。
#### 托管文件尾部摄入
Cortex可以直接跟踪本地文件,而无需 rsyslog `imfile` 插件。在 Docker 中,将主机日志树以只读方式挂载到 `/file-tail-root`,并使用 `CORTEX_FILE_TAIL_LOG_VOLUME` 注册该路径。源存储在 SQLite 数据库旁边的 `file-tails.json` 中,通过 `cortex ingest filetail ...`、`REST POST /api/file-tails`(需要 `Authorization: Bearer $CORTEX_API_TOKEN` 和 `X-Cortex-Admin-Token: $CORTEX_API_ADMIN_TOKEN`)或 MCP 操作 `file_tails` 进行管理,并作为 `source_kind="file-tail"` 行发出。行元数据包括 `file_tail_id`、`tag` 和 `path_basename`,而不是完整的文件系统路径。文档中推荐的安全默认设置是将托管尾部保留在 `/file-tail-root` 内。仅当操作员已挂载并审查了更广泛的只读根目录(例如 `/var/log` 或 `/logs`)时,才显式设置 `CORTEX_FILE_TAIL_ALLOWED_ROOTS`。Compose 服务还添加了 `CORTEX_FILE_TAIL_GROUP`(默认为 `adm`)作为辅助组,以便非根 `cortex` 进程可以读取常见的组拥有的日志,例如 `/var/log/auth.log`;将其设置为数字 gid(如果主机使用不同的日志读取组)。
```bash
cortex ingest filetail add /file-tail-root/swag/log/nginx/access.log
cortex ingest filetail add /file-tail-root/swag/log/nginx/error.log --severity warning
cortex ingest filetail add /file-tail-root/swag/log/fail2ban/fail2ban.log --facility local5
cortex ingest filetail add /file-tail-root/authelia/logs/authelia.log --facility local5
cortex ingest filetail add /file-tail-root/adguard/var/data/querylog.json --facility local6
```
文件名提供默认的 id 和标签,运行时提供默认的主机名,跟踪从文件结束处(EOF)开始。如果需要,可以添加覆盖项。使用 `--from-start` 仅在您故意想要回填当前文件内容时使用。启动后,Cortex 在 `file-tails.json` 中检查 `dev`/`inode`/偏移量,从该光标恢复,并重新打开文件进行重命名/创建旋转或截断。行由 `CORTEX_MAX_MESSAGE_SIZE` 界定;超大记录在排队前被截断。
#### 存储
| 变量 | 是否必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `CORTEX_DB_PATH` | 否 | `/data/cortex.db` | SQLite 数据库路径 |
| `CORTEX_POOL_SIZE` | 否 | `8` | SQLite 连接池大小。MCP/REST 读取获得 `pool_size - 1` 个许可;一个连接为摄入写入保留。 |
| `CORTEX_SQLITE_PAGE_CACHE_MB` | 否 | `128` | 跨池的 SQLite 页面缓存总预算;在 `PRAGMA cache_size` 之前除以 `pool_size`。 |
| `CORTEX_SQLITE_MMAP_MB` | 否 | `256` | 有界 SQLite mmap 大小。常驻映射页面仍可能计入 cgroup 内存。 |
| `CORTEX_HEAVY_READ_CONCURRENCY` | 否 | `1` | 昂贵读取操作的共享服务层限制器。 |
| `CORTEX_WAL_CHECKPOINT_MB` | 否 | `256` | 有界 PASSIVE 检查点尝试的 WAL 大小阈值。 |
| `CORTEX_RETENTION_DAYS` | 否 | `90` | 保留日志的天数。`0` = 永久保留。清除运行每小时运行一次;错误 + 严重性除外(参见 [保留策略](#retention-policy))。 |
| `CORTEX_MAX_DB_SIZE_MB` | 否 | `1024` | 逻辑 DB 大小触发器:违规删除最旧的日志。`0` = 禁用。 |
| `CORTEX_RECOVERY_DB_SIZE_MB` | 否 | `900` | DB 大小触发器后的清理目标。必须小于最大值。 |
| `CORTEX_MIN_FREE_DISK_MB` | 否 | `0` | 空闲磁盘阈值。**默认禁用**。违规阻止写入(不删除数据)。 |
| `CORTEX_RECOVERY_FREE_DISK_MB` | 否 | `0` | 在写入恢复后磁盘空闲的滞后目标。必须大于启用时的最小值。 |
| `CORTEX_CLEANUP_INTERVAL_SECS` | 否 | `60` | 存储预算强制执行间隔。最小值为 `5`。 |
| `CORTEX_CLEANUP_CHUNK_SIZE` | 否 | `2000` | 每次强制执行删除的行数 |
| `CORTEX_ERR_FLOOR_WINDOW_HOURS` | 否 | `24` | 在此窗口内收到的错误 + 行受到保护,不会被磁盘压力删除。`0` = 禁用地板。 |
| `CORTEX_ERR_FLOOR_PER_SOURCE_CAP` | 否 | `10000` | 每个源 IP 在窗口内的最大保护错误 + 行数。`0` = 禁用地板。 |
#### 容器
| 变量 | 是否必需 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `CORTEX_UID` | 否 | `1000` | 数据卷所有者的容器用户 ID |
| `CORTEX_GID` | 否 | `1000` | 数据卷所有者的容器组 ID |
| `CORTEX_DATA_VOLUME` | 否 | `cortex-data` | Docker 卷名或绑定挂载路径 |
| `CORTEX_HOME_VOLUME` | 否 | `~/.cortex` | 共享的 cortex 主目录(库存缓存、设置环境)挂载在 `/cortex-home` |
| `CORTEX_SSH_VOLUME` | 否 | `~/.cortex/ssh` | 专用 SSH 密钥目录,只读挂载在 `/home/cortex/.ssh`。永远不要指向 `~/.ssh` - 参见安全模型 |
| `DOCKER_NETWORK` | 否 | `cortex` | Docker 网络名称(必须存在) |
| `RUST_LOG` | 否 | `info` | 日志级别(`trace`、`debug`、`info`、`warn`、`error`) |
| `TZ` | 否 | `UTC` | 容器时区 |
### config.toml
将 `config.toml` 放在二进制文件旁边(或工作目录中)。环境变量覆盖此处设置的值。
```toml
[syslog]
host = "0.0.0.0"
port = 1514
max_message_size = 8192
max_tcp_connections = 512
tcp_idle_timeout_secs = 300
[storage]
db_path = "data/cortex.db"
pool_size = 8
sqlite_page_cache_mb = 128
sqlite_mmap_mb = 256
heavy_read_concurrency = 1
wal_checkpoint_mb = 256
retention_days = 90 # 0 = keep forever
wal_mode = true
max_db_size_mb = 1024
recovery_db_size_mb = 900
min_free_disk_mb = 0 # 0 = free-disk guard disabled (default)
recovery_free_disk_mb = 0
cleanup_interval_secs = 60
[mcp]
host = "127.0.0.1"
port = 3100
server_name = "cortex"
# api_token = "your-secret-token"
[docker_ingest]
enabled = false
reconnect_initial_ms = 1000
reconnect_max_ms = 30000
[[docker_ingest.hosts]]
name = "edge-host-a"
base_url = "http://edge-host-a:2375"
allow_insecure_http = true
```
---
## 安全模型
### Syslog 摄入默认无身份验证
UDP 和 TCP Syslog 监听器(端口 1514)接受来自 **任何可达主机** 的日志帧,无需身份验证。这符合 RFC 3164/5424 Syslog 协议设计,适用于网络周界是信任边界的 homelab 部署。
后果:
- 存储记录中的 **`hostname` 由供应商格式(CEF/UniFi)控制**。任何主机都可以声称任何主机名。使用 `source_ip` 进行受信任的源识别。
- **日志注入可能** 来自可以通过端口 1514 达到的任何主机。除非使用网络级访问控制,否则不要将 cortex 用于安全关键的审计轨迹。
- **保留豁免**:`severity=err` 及以上级别的日志免受基于时间的清除。主机以高严重性帧泛滥可能会耗尽磁盘空间。
**缓解措施**:将 Syslog 端口绑定到特定接口,使用防火墙规则限制源,或设置 `CORTEX_ALLOWED_SOURCE_CIDRS`(逗号分隔的 CIDR 列表)来允许发送主机。
### MCP API 身份验证
MCP 查询 API(端口 3100,默认环回)支持两种身份验证模式:
| 模式 | 配置 | 效果 |
| --- | --- | --- |
| Bearer Token | `CORTEX_TOKEN=<token>` | 静态令牌默认为 `cortex:read`;设置 `CORTEX_STATIC_TOKEN_ADMIN=true` 也授予 `cortex:admin` |
| Google OAuth | `CORTEX_AUTH_MODE=oauth` | 通过 `CORTEX_AUTH_ADMIN_EMAIL` 进行 OAuth 用户身份验证 |
**重要**:诸如 `ack_error`、`unack_error`、`notifications_test` 和 `llm_invocations` 等管理员操作需要 `cortex:admin`。静态承载令牌默认情况下仅限读取,除非显式设置 `CORTEX_STATIC_TOKEN_ADMIN=true`。
MCP 端口默认为 `127.0.0.1:3100`(仅限环回),Docker Compose 文件默认发布容器端口 3100 到 `127.0.0.1`(`CORTEX_MCP_BIND` 覆盖主机接口)。Labby 网关通过 Docker 网络在 `http://cortex:3100` 访问 cortex,而不管主机发布地址如何。要在网络接口上公开端口 3100,请设置 `CORTEX_MCP_BIND=0.0.0.0`(Compose)或 `CORTEX_HOST=0.0.0.0`(裸二进制),**设置 `CORTEX_TOKEN`**,并在它前面放置一个 TLS 终止的反向代理。
### SSH 密钥暴露(库存挂载)
Compose 文件将 SSH 密钥目录只读挂载在 `/home/cortex/.ssh` 以用于舰队库存收集器。默认源是 **专用密钥目录 `~/.cortex/ssh`**(使用 `CORTEX_SSH_VOLUME` 覆盖)。**永远不要将 `CORTEX_SSH_VOLUME` 指向 `~/.ssh`** - 挂载您的个人 SSH 目录会赋予容器您拥有的每个身份,并创建跨舰队的横向移动路径。
配置一个特权最低的部署密钥:`~/.cortex/ssh` 中生成专用密钥对,编写一个仅列出 cortex 应收集的主机的 `config`,策划一个 `known_hosts` 文件(`ssh-keyscan`),并在每个主机上限制密钥的 `authorized_keys` 条目,低权限用户。完整演走:[docs/SECURITY.md](docs/SECURITY.md) "SSH 密钥暴露"。---
## 命令模式
```bash
cortex serve mcp # UDP/TCP Syslog 摄入加上 /mcp 上的 HTTP MCP
cortex mcp # 查询仅限 MCP stdio 传输
cortex setup # 安装/修复共享的 ~/.cortex Docker Compose 设置
cortex setup deploy preflight # 检查部署先决条件而不会改变 Docker
cortex setup deploy local # 协调本地 Compose 部署
cortex stats # 直接从 CLI 查询 SQLite DB
cortex db status # 检查 SQLite 维护状态
cortex db backup # 创建 WAL 安全的 SQLite 备份
cortex compose doctor # 诊断实时 Compose/listner 所有权
cortex compose status --json # 检查规范的 cortex 容器/项目
```
两种模式使用相同的配置和环境变量加载器。`cortex mcp` 用于本地子进程 MCP 客户端,可以读取 `CORTEX_DB_PATH`;它不绑定网络端口或运行保留/存储清理作业。
直接 CLI 使用与 MCP 工具共享相同的共享服务层,因此结果和验证与 MCP 操作匹配,无需 MCP 客户端:
```bash
cortex search "oom killer" # 裸查询;默认限制 50
cortex tail dookie # 裸定位 → --host;默认 n=50
cortex analysis errors
cortex analysis errors # 默认情况下为最后1小时
cortex state host tootie # 裸定位 → --host;默认 n=50
cortex search 'error AND nginx' --host proxy --limit 10
cortex tail -n 20 --app kernel
cortex analysis errors --since 2026-01-01T00:00:00Z
cortex hosts
cortex correlate events --reference-time 2026-01-01T12:00:00Z --window-minutes 10 --severity-min warning
cortex entity host tootie
cortex graph around host tootie --limit 25
cortex graph explain host tootie --depth 2
cortex stats --json
cortex db integrity # 运行 PRAGMA integrity_check
cortex db checkpoint full
cortex db vacuum --pages 1000
cortex compose pull # 为已解析的 Compose 项目拉取镜像
cortex compose up # 为已解析的服务运行 docker compose up -d
cortex compose restart # 重启已解析的服务
cortex compose logs --tail 20 # 有界限的 Compose 日志
cortex compose logs cortex --tail 20 # 单个服务的限定日志
# 表面对齐(2026-05-22)- 每个都有一个文档化的 REST 路由
cortex hosts sources --limit 50
cortex hosts silent --silent-minutes 60
cortex state clockskew --since 2026-05-20T00:00:00Z
cortex analysis anomalies --recent-minutes 30 --baseline-minutes 720
cortex analysis compare --a-from 2026-05-20T00:00:00Z --a-to 2026-05-20T23:59:59Z \
--b-from 2026-05-21T00:00:00Z --b-to 2026-05-21T23:59:59Z
cortex apps --host dookie --limit 50
```
### 技能、MCP、滥用和钩子评估 (`cortex assess`)
`cortex assess` 是用于 LLM 防守的事件评估的主要 UX。它运行通过 LLM 调用守卫(`LlmRunner` - 速率限制、断路器保护、`llm_invocations` 中完全审计),并为 `assess skill`/`assess mcp`/`assess hooks` 获取证据,使用 `investigate_ai_skill_incidents`/`investigate_ai_mcp_incidents`/`investigate_ai_hook_incidents` - 专用事件检测器,而不是重用滥用事件搜索。
```bash
# 评估给定技能的优先级最高的事件
cortex assess skill frustration-assessment
# 按工具/项目/时间窗口缩小范围
cortex assess skill frustration-assessment --since 7d --tool codex --project /home/jmagar/workspace/cortex
# 评估每个匹配的技能事件,而不仅仅是排名靠前的事件
cortex assess skill frustration-assessment --all
cortex assess skill frustration-assessment --limit 5
# 按插件过滤而不是单个技能名称
cortex assess skill --plugin lavra --since 7d
# 仅确定性发现 - 无 Gemini 调用,安全用于脚本/自动化
cortex assess skill frustration-assessment --no-llm
# 评估给定 MCP 服务器/工具的优先级最高的事件
cortex assess mcp labby
cortex assess mcp --tool-name mcp__labby__search --since 7d
# 评估每个匹配的 MCP 事件,而不仅仅是排名靠前的事件
cortex assess mcp labby --all
cortex assess mcp labby --no-llm
# 滥用事件评估:自动选择匹配的优先级最高的事件
cortex assess abuse
# 或评估特定事件 ID
cortex assess abuse --incident-id <id>
# 钩子评估:自动选择匹配的优先级最高的钩子事件
cortex assess hooks
# 缩小到已知钩子名称/钩子事件
cortex assess hooks --hook format-on-save --since 24h
cortex assess hooks --hook-event PostToolUse --since 7d
# 从本地主机收集新的钩子配置/信任状态清单 **BEFORE** 评估(~/.claude/settings.json,~/.codex/hooks.json,~/.codex/config.toml [hooks.state]),以便在运行时评估期间提供配置/信任证据
cortex assess hooks --collect-config
```
# 确定性发现
cortex assess hooks --hook format-on-save --no-llm
`assess skill`、`assess mcp`、`assess abuse` 和 `assess hooks` 默认情况下都会运行受保护的 Gemini 评估步骤(与 `cortex sessions assess` 现有行为相匹配)— 传 `--no-llm` 以获取确定性发现结果。LLM 步骤是 **仅限本地 CLI**:`--http` 模式被拒绝,除非同时传递 `--no-llm`,因为它通过 `LlmRunner` 在本地主机上启动了一个 Gemini 子进程。
钩子评估发现结果始终包含一个 `evidence_basis` 字段,说明事件是否有已证明的 `runtime_transcript` 钩子执行(Claude 转录 `attachment.type = hook_*` 行)或仅有 `config_inventory`/`trusted_hash_state` 证据(来自 `~/.claude/settings.json`、`~/.codex/hooks.json` 或 `~/.codex/config.toml [hooks.state]` 的已配置/受信任的钩子)— 已配置的钩子永远不会被视为其执行的证据。Codex 尚未观察到运行时钩子执行的形状,因此 Codex 钩子评估仅限于配置/信任状态证据,直到确认实际结构化运行时事件形状。
相关命令:
- `cortex sessions assess <incident_id>` — 通过明确的事件 ID 进行滥用事件评估(无需自动选择)。
- `cortex sessions skillassess <skill>` — 与 `cortex assess skill` 相同。
- `cortex sessions skillinvestigate <skill>` — 确定性技能事件证据命令(无 LLM 步骤);使用此命令在决定是否花费 `assess skill` 调用之前检查证据。
- `cortex sessions mcpassess <server-or-tool>` — 与 `cortex assess mcp` 相同。
- `cortex sessions mcpinvestigate <server-or-tool>` — 确定性 MCP 事件证据命令(无 LLM 步骤);使用此命令在决定是否花费 `assess mcp` 调用之前检查证据。
- `cortex sessions mcpevents` / `cortex sessions mcpincidents` — 列出原始 MCP 工具调用事件 / 分组事件候选,无证据包。
- `cortex sessions hookevents [--hook NAME] [--hook-event EVENT]` —
列出原始 `ai_hook_events` 行(运行时 + 配置清单)。
- `cortex sessions hookincidents [HOOK]` / `cortex sessions hookinvestigate HOOK` —
列出和调查钩子执行周围的负面信号。
- `cortex sessions hooksbackfill [--since TIME] [--dry-run]` —
有界、幂等的 Claude 运行时钩子事件回填(不回填配置清单行 — 它们是通过 `--collect-config` 进行的单点主机读取)。
### REST 端点(2026-05-22 版本)
12 个新路由一一映射现有的 MCP 操作。所有路由都需要 `CORTEX_API_TOKEN` 承载令牌;带有 `terms[]=` 参数的 AI 端点通过 `serde_qs` 提供服务,以处理重复键。
```
GET /api/silent-hosts?silent_minutes=60
GET /api/clock-skew?since=<RFC3339>
GET /api/anomalies?recent_minutes=15&baseline_minutes=360
GET /api/compare?a_from=...&a_to=...&b_from=...&b_to=...
GET /api/apps?hostname=&from=&to=&limit=&offset=
GET /api/similar-incidents?query=...&window_minutes=30
GET /api/incident-context?from=...&to=...
GET /api/sessions/incidents?terms[]=foo&terms[]=bar
GET /api/sessions/investigate?correlation_window_minutes=30
GET /api/graph/entity?entity_type=host&key=tootie
GET /api/graph/around?entity_type=host&key=tootie&depth=1
GET /api/graph/explain?entity_type=host&key=tootie&depth=2
GET /api/compose/status
GET /api/compose/doctor
```
`/api/compose/status` 是一个只读的删减投影,可能在容器内无法从 Docker 检测中报告 `runtime_state="docker_unavailable"`。`/api/compose/doctor` 更严格:未准备好的 Docker、所有权或运行时状态返回 HTTP 503 以及相同的结构化投影。
`cortex compose` 命令在变异前解析实时 Compose 所有者。它们拒绝模糊的 cwd 回退、过时的 Compose 标签、监听器冲突和破坏性的 `down` 操作(无需 `--yes`)。
参见 [docs/CLI.md](docs/CLI.md) 以获取完整的直接 CLI 参考,包括标志、JSON 输出以及 CLI 命令如何映射到 MCP 操作。
---
## Syslog 转发器设置
服务器默认监听端口 `1514`。配置发送者转发到此端口。如果设备无法使用非特权端口,请参见 [暴露端口 514](#暴露端口-514)。
### rsyslog
在每个主机上创建 `/etc/rsyslog.d/99-remote.conf`:
```conf
# TCP(可靠,建议用于持久连接)
*.* @@CORTEX_SERVER:1514
# UDP(较低开销,无交付保证)
# *.* @CORTEX_SERVER:1514
```
重启:`sudo systemctl restart rsyslog`
对于仅运行 journald 而没有 rsyslog 的主机,首先在 `/etc/systemd/journald.conf` 中启用转发:
```ini
[Journal]
ForwardToSyslog=yes
```
然后安装并配置 rsyslog 如上所述。
### syslog-ng
添加到 `/etc/syslog-ng/conf.d/remote.conf`:
```conf
destination d_remote_tcp {
network("CORTEX_SERVER"
port(1514)
transport("tcp")
);
};
destination d_remote_udp {
network("CORTEX_SERVER"
port(1514)
transport("udp")
);
};
log {
source(s_src);
destination(d_remote_tcp);
};
```
重启:`sudo systemctl restart syslog-ng`
### WSL2(启用 systemd)
在 `/etc/wsl.conf` 中启用 systemd:
```ini
[boot]
systemd=true
```
安装 rsyslog 并使用上面的 rsyslog 配置。使用 cortex 主机的 Tailscale IP 地址 — WSL 有自己的网络命名空间,无法直接访问 Docker 主机 IP 地址。
### UniFi 云网关
选项 A — 通过 SSH:
```bash
ssh admin@<gateway-ip>
# 创建 /etc/rsyslog.d/remote.conf(在新固件上保留):
echo "*.* @CORTEX_SERVER:1514" | sudo tee /etc/rsyslog.d/remote.conf
sudo systemctl restart rsyslog
```
选项 B — 通过 UI(固件更新后存活):
设置 → 系统 → 高级 → 远程 Syslog 服务器。设置主机和端口 `1514`。
### 路由器和设备(仅支持 UDP)
在设备的 Syslog 设置中将 Syslog 服务器地址设置为您的 `CORTEX_SERVER`,端口设置为 `1514`。大多数消费者路由器和网络设备在诊断或日志记录设置下公开此选项。
### 暴露端口 514
Syslog 的特权端口 514 需要 root 或 `CAP_NET_BIND_SERVICE`。推荐的方法是在主机上使用 iptables 进行重定向:
```bash
# 将 UDP 和 TCP 514 重定向到 1514
sudo iptables -t nat -A PREROUTING -p udp --dport 514 -j REDIRECT --to-port 1514
sudo iptables -t nat -A PREROUTING -p tcp --dport 514 -j REDIRECT --to-port 1514
# 持久化重启(Debian/Ubuntu)
sudo apt install iptables-persistent
sudo netfilter-persistent save
```
对于 Docker Compose,设置 `CORTEX_RECEIVER_HOST_PORT=514` 以发布主机端口 `514`,同时容器保持绑定非特权端口 `1514`。在 Unraid 上,为 Docker 模板中的 UDP 和 TCP 映射主机端口 `514` 到容器端口 `1514`(`514:1514/udp` 和 `514:1514/tcp`)。
### 防火墙规则
在 Docker 主机防火墙上打开 Syslog 端口:
```bash
# ufw
sudo ufw allow 1514/udp
sudo ufw allow 1514/tcp
# firewalld
sudo firewall-cmd --permanent --add-port=1514/udp
sudo firewall-cmd --permanent --add-port=1514/tcp
sudo firewall-cmd --reload
```
---
## 心跳
心跳代理是一个小型主机本地循环(相同的 `cortex` 二进制文件),它收集有限的系统状态(负载、内存、磁盘、顶部进程)并每 30 秒将数据发送到服务器的 `POST /v1/heartbeats` 端点。心跳行会提供 `host_state`、`fleet_state` 和 `correlate_state` MCP 操作,并保留 14 天。
将其作为用户 systemd 服务安装在每个舰队主机上:
```bash
cortex setup heartbeatagent install # 编写并启用 systemd 单元
cortex setup heartbeatagent check # 检查单元/环境状态
cortex setup heartbeatagent remove # 删除单元
cortex heartbeat agent --once --emit # 一次性前台运行用于调试
```
配置:
- `CORTEX_HEARTBEAT_TARGET` — 服务器基准 URL(默认为 `http://127.0.0.1:3100`;回退到 `CORTEX_URL`)
- `CORTEX_HEARTBEAT_TOKEN` — 每次 POST 发送的承载令牌(回退到 `CORTEX_TOKEN`)
当服务器设置 `CORTEX_TOKEN` 时,心跳 POST 必须携带该令牌;在未经身份验证的仅环回服务器上不需要令牌。
---
## OTLP 采集
共享的 HTTP 监听器在端口 3100 上也接受 OpenTelemetry 日志,位于 `POST /v1/logs`(仅限日志 — `/v1/metrics` 和 `/v1/traces` 返回 404)。端点解码 **二进制 protobuf** (`ExportLogsServiceRequest`;不支持 OTLP/JSON)并强制执行 **4 MiB** 请求体限制(413 响应包含 `Retry-After: 86400`)。
身份验证与 MCP 匹配:当设置 `CORTEX_TOKEN` 时,请求需要 `Authorization: Bearer <token>`。在非环回绑定上公开 `/v1/logs` 且没有静态承载令牌的权限会被启动时阻止(今天,OAuth JWT 不会授权 OTLP 采集)。
最小的 OpenTelemetry 收集器导出程序配置:
```yaml
exporters:
otlphttp/cortex:
endpoint: http://CORTEX_SERVER:3100
encoding: proto
headers:
Authorization: "Bearer ${env:CORTEX_TOKEN}"
service:
pipelines:
logs:
exporters: [otlphttp/cortex]
```
---
## 保留策略
日志保留 `CORTEX_RETENTION_DAYS` 天(默认为 `90`)。设置为 `0` 以禁用全局基于年龄的清除(仍然适用 AdGuard 和心跳上限)。
保留清除每小时运行一次(单独的存储预算强制循环在 `CORTEX_CLEANUP_INTERVAL_SECS` 上运行)。它以 10,000 行的块删除日志,释放块之间的写锁,以便继续收集。保留截止日期使用 `received_at`(服务器端收集时间戳),而不是消息中的 `timestamp`。这可以防止时钟配置错误的设备导致过早或无限期保留。
严重性基于豁免和按来源限制:
- **err+ 豁免** — `severity IN (err, crit, alert, emerg)` 的行永远不会被保留期限老化删除。它们仍然可以在数据库大小压力下被删除,但仅在 err+ 底线之外(`CORTEX_ERR_FLOOR_WINDOW_HOURS=24`,`CORTEX_ERR_FLOOR_PER_SOURCE_CAP=10000`)。
- **AdGuard 标签** — `adguard-allowed` / `adguard-query` / `adguard-rewrite` 行硬上限为 **7 天**,无论 `retention_days` 为何(DNS 查询量否则会主导全文索引)。
- **心跳** — 心跳遥测行上限为 **14 天**。
在大型删除后,会运行增量 FTS5 合并以利用索引空间而无需长时间写锁持续时间。
---
## 存储预算强制执行
两个独立的防护措施保护免受磁盘耗尽:
**数据库大小防护**(`CORTEX_MAX_DB_SIZE_MB`,默认为 1024 MB - 启用)
当逻辑 SQLite 数据库大小超过 `max_db_size_mb` 时,最旧的日志将被删除,块大小为 `CORTEX_CLEANUP_CHUNK_SIZE` 行,直到大小降至 `recovery_db_size_mb` 以下。严重性高的行在 err+ 底线内(`CORTEX_ERR_FLOOR_WINDOW_HOURS=24`,上限 `CORTEX_ERR_FLOOR_PER_SOURCE_CAP=10000` 行/源 IP)不会被删除。
**免费磁盘防护**(`CORTEX_MIN_FREE_DISK_MB`,默认为 0 - **禁用**)
整个文件系统的可用空间是一个外部条件,cortex 无法通过删除自己的数据来修复,因此免费磁盘违规 **阻止新写入** 而不是自我修剪。写入在免费磁盘上升到 `recovery_free_disk_mb` 时恢复(滞后防止振荡)。通过设置 `min_free_disk_mb` 和更高的 `recovery_free_disk_mb` 启用。
**写阻塞行为**
如果强制执行无法释放足够的空间(或免费磁盘防护触发),批处理写入器进入写阻塞状态。新日志消息累积在一个内存缓冲区中(`CORTEX_WRITE_CHANNEL_CAPACITY`,默认为 10,000 条消息)。写入在空间恢复后自动恢复。`write_blocked` 字段在 `cortex stats` 中反映当前状态。
禁用任一防护措施,将其触发器设置为 `0`(也将恢复目标设置为 `0`)。
### 大型 SQLite 迁移
大多数模式设置在启动期间自动运行。大型迁移,例如在已填充的多百万行 `logs` 表上创建新索引,可能在 `/health` 可用之前持有 SQLite 的写锁达数分钟之久。在此期间,TCP 发送器可能会备份,而 UDP 数据包可能会被内核缓冲区丢弃。
在升级填充的数据库之前:
1. 使用 `scripts/backup.sh` 或 `sqlite3 /data/cortex.db ".backup /data/syslog-pre-upgrade.db"` 进行 WAL 安全备份。
2. 为大型数据库安排一个短暂的收集维护窗口。
3. 启动新版本并监视日志中的 `Migration N: starting ...` 和 `Migration N: ... created`。
4. 保留以前的镜像或二进制文件,直到 `/health` 返回 `ok` 且 `cortex stats` 报告合理的计数。
5. **升级跨迁移 41(规范实体解析):** 库存图投影被标记为过时,并且遗留 `service` 实体被修剪。运行 `cortex graph rebuild`(或当 `CORTEX_GRAPH_REFRESH_INTERVAL_SECS > 0` 时等待投影调度器)以期望 `topic_correlate` 服务结果 — 直到重建,解析的逻辑服务没有实例报告 `resolver_status: degraded`,并且服务时间线为空。
参见 [docs/RELEASE.md](docs/RELEASE.md) 以获取当前发布和部署检查清单。
---
## 批处理写入器
批处理写入器通过在写入 SQLite 之前将解析的 Syslog 消息收集到批处理中来提高吞吐量。
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `CORTEX_BATCH_SIZE` | `100` | 当收集到这么多消息时写入 |
| `CORTEX_FLUSH_INTERVAL` | `500` 毫秒 | 每 N 毫秒写入,即使批处理不满 |
| `CORTEX_WRITE_CHANNEL_CAPACITY` | `10000` | 解析消息队列容量,监听器背压之前 |
批处理在单个 SQLite 交易中写入。如果数据库忙(锁定),写入器会重试最多 3 次,并具有指数退避(25 毫秒、100 毫秒、250 毫秒)。插入失败的批处理保留在内存中,并在下一个刷新周期重试。如果保留的批处理增长超过 1,000 条记录,则丢弃以防止无界内存增长。
内部写通道最多可容纳 `CORTEX_WRITE_CHANNEL_CAPACITY` 个解析消息。当通道已满时,监听器会记录背压,UDP/TCP 接收方会阻塞,直到空间可用。
---
## 多主机部署
将多个主机指向相同的 cortex 实例。每个发送者的 `hostname` 字段(Syslog 消息)被记录并索引。使用 `cortex hosts` 查看所有发送者。按 `hostname` 过滤 `cortex search` 和 `cortex tail`。
对于大型舰队,请考虑:
* 增加 `CORTEX_POOL_SIZE`(默认为 8)以获得更高的读取并发性
* 增加 `CORTEX_BATCH_SIZE` 和 `CORTEX_FLUSH_INTERVAL` 以减少写入开销
* 将 `CORTEX_RETENTION_DAYS` 设置为平衡历史深度与磁盘成本
---
## 时间同步
所有时间戳均存储为 UTC。`cortex correlate events` 使用 Syslog 消息中的 `timestamp` 字段,该字段反映发送设备的时钟。具有漂移时钟的设备将相对于关联窗口偏移其事件。所有发送者都运行 NTP 以最小化偏差。`received_at`(服务器端收集时间)不受发送者时钟漂移的影响,并用于保留。
---
## HTTPS / 反向代理
添加一个 SWAG 代理配置以通过 TLS 公开 MCP API:
```nginx
# /config/nginx/proxy-confs/cortex.subdomain.conf
server {
listen 443 ssl;
server_name cortex.*;
include /config/nginx/ssl.conf;
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
# RMCP 流式 HTTP 以无状态 JSON 响应模式提供。
# 客户端使用 POST /mcp;不支持 GET/DELETE /mcp。
proxy_http_version 1.1;
set $upstream_app cortex;
set $upstream_port 3100;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```
---
## 开发
```bash
just dev # cargo run -- serve mcp
just check # cargo check
just lint # cargo clippy -- -D warnings
just fmt # cargo fmt
just test # cargo test
just build # cargo build
just release # cargo build --release
```
Docker:
```bash
just up # docker compose up -d
just logs # docker compose logs -f
just down # docker compose down
just restart # docker compose restart
cortex compose doctor
cortex compose status --json
cortex compose logs --tail 20
```
生成承载令牌:
```bash
just gen-token # openssl rand -hex 32
```
---
## 验证
部署后验证堆栈:
```bash
# 健康探测(无需身份验证)
curl -sf http://localhost:3100/health | jq .
# → {"status":"ok"}
# 从任何 Linux 主机发送测试消息
logger -n CORTEX_SERVER -P 1514 --tcp "test from $(hostname)"
# 通过 MCP 尾随最近的日志(如果启用身份验证,请替换令牌)
curl -s -X POST http://localhost:3100/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "cortex",
"arguments": {"action": "tail", "n": 1}
}
}' | jq .
```
# 数据库统计
```bash
curl -s -X POST http://localhost:3100/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {"name": "cortex", "arguments": {"action": "stats"}}
}' | jq .result.content[0].text | jq -r . | jq .
```
运行完整的测试套件:
```bash
just check
just lint
just test
```
运行实时烟雾测试:
```bash
bash scripts/smoke-test.sh
```
烟雾测试会发送UDP和TCP syslog消息,并验证MCP搜索/尾部结果。Docker日志覆盖率按路径划分:主机本地代理一致性由代理部署测试覆盖,默认实时烟雾覆盖文件-尾部/REST/CLI路径,遗留中心拉取覆盖使用模拟Docker HTTP固定装置或显式Docker兼容端点。
---
## 性能
在典型的家庭实验室规模(1-20台主机,每天数千条消息):
- SQLite with WAL模式在不发生争用的情况下处理并发读取和写入
- 批量写入器在普通硬件上可持续处理数千条消息/秒
- FTS5 with porter stemming 在普通SQL查询上增加了最小的开销
- `PRAGMA cache_size=-64000` 为每个连接分配约64 MB的页面缓存
- `PRAGMA synchronous=NORMAL` 在耐用性和吞吐量之间取得平衡
- 连接池(默认为8)满足并发MCP请求而不阻塞
对于更高的摄入率(IoT,高流量网络设备):
- 增加 `CORTEX_BATCH_SIZE` (例如 `500`)以减少事务开销
- 增加 `CORTEX_FLUSH_INTERVAL` (例如 `1000` 毫秒)以扩大批处理窗口
- 增加 `CORTEX_WRITE_CHANNEL_CAPACITY` (例如 `100000`)以吸收突发流量
- 增加 `CORTEX_POOL_SIZE` (例如 `8`)以实现更多的读取并发
- 将数据库放在SSD或tmpfs支持的卷上
---
## MCP传输
守护进程通过RMCP Streamable HTTP以无状态JSON响应模式实现了MCP。
- `POST /mcp` — RMCP Streamable HTTP请求/响应端点
- `GET /mcp` 和 `DELETE /mcp` — 在无状态模式下返回`405 Method Not Allowed`
- `GET /health` — 无身份验证的健康探测
- `cortex mcp` — 本地查询-仅stdio MCP模式,适用于启动MCP服务器作为子进程的客户端
当设置 `CORTEX_TOKEN` 时,`/mcp` 需要:
```
Authorization: Bearer <token>
```
`/health` 始终是未经身份验证的(适用于Docker健康检查和反向代理探测)。
_stdio 模式不使用 bearer auth,因为它是本地子进程访问。它确实需要 `CORTEX_DB_PATH` 指向同一个 SQLite 数据库,由守护进程填充:
```json
{
"mcpServers": {
"cortex": {
"command": "/path/to/cortex",
"args": ["mcp"],
"env": {
"CORTEX_DB_PATH": "/data/cortex.db",
"RUST_LOG": "warn"
}
}
}
}
```
当数据库只能通过正在运行的HTTP守护进程或反向代理访问时,请使用 `mcp-remote` 代替直接_stdio。
Docker镜像仍然专注于守护进程,并通过 `cortex serve mcp` 暴露HTTP MCP;在可以读取SQLite数据库的主机上使用 `cortex mcp` 进行直接本地_stdio。
---
## 文档
本README用于首次运行的介绍。源文档和代码按责任分开:
| 文件 | 描述 |
|------|-------------|
| `Cargo.toml` | 依赖库元数据和依赖关系 |
| `config.toml` | 默认运行时配置 |
| `.env.example` | 环境变量参考 |
| `docs/CONFIG.md` | 完整配置和环境参考 |
| `docs/mcp/SCHEMA.md` | 运行时模式测试支持的精选操作参考 |
| `docs/mcp/CORRELATION.md` | 相关性行为和AI/非AI包含规则 |
| `docs/mcp/MCPUI.md` | MCP应用查询小部件线缆合同 |
| `docs/SETUP.md` | 每台设备的syslog转发器设置说明 |
| `CHANGELOG.md` | 发布历史 |
| `config/Dockerfile` | 容器镜像定义 |
| `docker-compose.yml` | Docker Compose堆栈 |
| `Justfile` | 开发命令快捷方式 |
| `src/main.rs` | `cortex`二进制HTTP和_stdio MCP模式入口点 |
| `src/lib.rs` | 可重用的库边界 |
| `src/app/` | 共享类型日志应用服务 |
| `src/runtime.rs` | 配置、数据库、syslog和维护编排 |
| `src/api.rs` | 始终在线的非MCP JSON API路由( `/api/*` ,令牌保护) |
| `src/config.rs` | 配置加载和验证 |
| `src/db.rs` + `src/db/` | SQLite模式,FTS5,保留,存储预算 |
| `src/syslog.rs` + `src/syslog/` | UDP/TCP监听器,syslog解析器,批量写入器 |
| `src/mcp.rs` + `src/mcp/` | MCP HTTP服务器,RMCP适配器,身份验证中间件,工具,健康端点 |
| `.claude-plugin/plugin.json` | Claude插件清单 |
---
## 相关插件
| 插件 | 类别 | 描述 |
|--------|----------|-------------|
| [homelab-core](https://github.com/jmagar/claude-homelab) | 核心 | 核心代理、命令、技能和设置/健康工作流,用于家庭实验室管理。 |
| [overseerr-mcp](https://github.com/jmagar/overseerr-mcp) | 媒体 | 搜索电影和电视节目,提交请求,监控失败的请求通过Overseerr。 |
| [unraid-rmcp](https://github.com/jmagar/unraid-rmcp) | 基础设施 | 查询,监控和管理Unraid服务器:Docker,VM,阵列,奇偶校验和实时遥测。 |
| [unifi-rmcp](https://github.com/jmagar/unifi-rmcp) | 基础设施 | 监控和管理UniFi设备,客户端,防火墙规则和网络健康状况。 |
| [gotify-rmcp](https://github.com/jmagar/gotify-rmcp) | 实用工具 | 通过自托管的Gotify服务器发送和管理推送通知。 |
| [swag-mcp](https://github.com/jmagar/swag-mcp) | 基础设施 | 创建,编辑和管理SWAG nginx反向代理配置。 |
| [synapse-rmcp](https://github.com/jmagar/synapse-rmcp) | 基础设施 | Docker管理(Flux)和SSH远程操作(Scout)跨家庭实验室主机。 |
| [arcane-rmcp](https://github.com/jmagar/arcane-rmcp) | 基础设施 | 通过Arcane管理和Docker环境,容器,镜像,卷,网络和GitOps。 |
| [plugin-lab](https://github.com/jmagar/plugin-lab) | 开发工具 | 为具有代理和规范模板的家庭实验室MCP插件提供脚手架,审查,调整和部署。 |
## 相关服务器
- [soma](https://github.com/jmagar/soma) - 提供商支持的MCP服务器的RMCP运行时。
- [unifi-rmcp](https://github.com/jmagar/unifi-rmcp) - UniFi控制器REST API桥接。
- [tailscale-rmcp](https://github.com/jmagar/tailscale-rmcp) - 设备,用户和尾网操作的Tailscale API桥接。
- [unraid-rmcp](https://github.com/jmagar/unraid-rmcp) - Unraid GraphQL桥接,用于NAS和服务器管理。
- [apprise-rmcp](https://github.com/jmagar/apprise-rmcp) - Apprise通知分发桥接,用于许多交付后端。
- [gotify-rmcp](https://github.com/jmagar/gotify-rmcp) - Gotify推送通知桥接,用于发送,消息,应用程序和客户端。
- [arcane-rmcp](https://github.com/jmagar/arcane-rmcp) - Arcane Docker管理桥接,用于容器和相关资源。
- [yarr](https://github.com/jmagar/yarr) - 媒体堆栈桥接,用于Sonarr,Radarr,Prowlarr,Plex和相关服务。
- [ytdl-rmcp](https://github.com/jmagar/ytdl-rmcp) - 媒体下载和元数据工作流服务器。
- [synapse-rmcp](https://github.com/jmagar/synapse-rmcp) - 本地Synapse工作流服务器,用于侦察和通量操作。
- [axon](https://github.com/jmagar/axon) - RAG,爬取,抓取,提取和语义搜索项目。
- [labby](https://github.com/jmagar/labby) - 家庭实验室控制平面和MCP网关项目。
- [lumen](https://github.com/jmagar/lumen) - 本地语义代码搜索MCP服务器。
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器