aliyun-sls-codex
README.md
# Aliyun SLS Codex 插件
这是一个固定范围、只读的 Codex 插件,用于调查阿里云日志服务(SLS)中的应用故障。它通过 MCP 暴露日志搜索、上下文查询和连接检查,并附带一个有查询预算的调查 Skill。
固定资源如下,不能通过工具参数切换:
- 地域:`cn-beijing`
- Project:`taient-rpa`
- Logstore:`node-rpa`
## 架构与文件逻辑
- [`src/domain.ts`](src/domain.ts):固定资源、查询上限和领域类型。
- [`src/config.ts`](src/config.ts):读取两个凭据环境变量;资源仍由代码固定。
- [`src/query.ts`](src/query.ts):限制时间范围并安全构造 SLS 查询。
- [`src/logs.ts`](src/logs.ts):保留原始字段、规范化时间、排序和精确去重。
- [`src/errors.ts`](src/errors.ts):把 SDK 错误映射为不泄密的公共错误。
- [`src/sls-client.ts`](src/sls-client.ts):唯一的阿里云 SDK 边界,仅调用 `GetLogsV2` 和 `GetLogStore`。
- [`src/service.ts`](src/service.ts):组合搜索、上下文和连接检查策略。
- [`src/server.ts`](src/server.ts):声明并注册三个 MCP 工具及输入校验。
- [`src/index.ts`](src/index.ts):stdio 入口;stdout 仅承载 MCP 协议。
- [`skills/aliyun-sls-investigation/SKILL.md`](skills/aliyun-sls-investigation/SKILL.md):最多三次日志调用的调查流程。
代码在固定资源、区间语义、转义、去重、错误脱敏和 MCP 边界处保留了简洁的中文注释;其余代码尽量由命名和类型表达。
## 前置条件与构建
需要 Node.js 22+、npm,以及对目标 Logstore 的只读 RAM 凭据。仓库忽略 `dist/`,所以在启用插件前必须先完成本地构建和检查:
```bash
npm install
npm run build
npm run check
```
发布或安装前建议执行完整预检:
```bash
npm run preflight
```
它依次运行类型检查、全部测试、MCP smoke test 和 `git diff --check`。smoke test 只列出工具,不访问 SLS。
## 最小 RAM 权限
建议为插件创建独立的只读 RAM 用户,并绑定如下策略:
```json
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"log:GetLogStore",
"log:GetLogStoreLogs"
],
"Resource": "acs:log:cn-beijing:*:project/taient-rpa/logstore/node-rpa"
}
]
}
```
资源 ARN 中的账户通配符 `*` 可能需要按 RAM 控制台要求替换为明确的阿里云账户 ID。不要授予写日志、修改索引或管理 Project 的权限。
在启动 Codex 前注入凭据;不要把真实值写入仓库文件:
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID="replace-with-read-only-ram-access-key-id"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="replace-with-read-only-ram-access-key-secret"
```
## 本地插件启用
本仓库是插件源码,不会自动修改个人 Codex 配置。个人 Marketplace 文件 `~/.agents/plugins/marketplace.json` 中的 `./plugins/aliyun-sls-codex` 会解析为 `~/plugins/aliyun-sls-codex`。`codex plugin add` 只从 Marketplace 注册该位置,不会把任意仓库目录复制过去。
### 首次安装
仅当个人 Marketplace 中还没有该条目、且 `~/plugins/aliyun-sls-codex` 不存在时,运行一次官方脚手架:
```bash
python3 ~/.codex/skills/.system/plugin-creator/scripts/create_basic_plugin.py \
aliyun-sls-codex --with-skills --with-mcp --with-marketplace
```
不要在已有目录或已有条目上重复执行脚手架,也不要手工编辑 marketplace.json。先在源码仓库执行完整预检,再把源码同步到脚手架目录;将 `<repo-root>` 替换为本仓库绝对路径:
```bash
cd <repo-root>
npm run preflight
rsync -a --exclude .git --exclude node_modules --exclude dist --exclude .env \
<repo-root>/ ~/plugins/aliyun-sls-codex/
cd ~/plugins/aliyun-sls-codex
npm install
npm run build
npm run check
npm run smoke:mcp
```
这里不使用 `--delete`,避免移除目标目录中用户自行保留的文件;`.env` 明确不复制。凭据本来就应来自环境变量,而不是插件文件。源码目录的 `preflight` 需要 Git 元数据;安装目录排除了 `.git`,因此在那里分别运行构建、检查和 smoke test。构建必须在安装后的 `~/plugins/aliyun-sls-codex` 路径执行,因为 [`.mcp.json`](.mcp.json) 从该目录启动 `dist/src/index.js`。
读取实际 Marketplace 名称,再安装插件:
```bash
python3 ~/.codex/skills/.system/plugin-creator/scripts/read_marketplace_name.py
codex plugin add aliyun-sls-codex@personal
```
第二条命令中的 `personal` 是默认个人 Marketplace 的字面示例;如果读取脚本输出其他名称,就将 `personal` 替换为该名称。安装完成后启动新的 Codex 任务,让新插件和 Skill 被重新发现。
### 更新已安装插件
更新时不要重新运行首次脚手架,也不要手工编辑 marketplace.json。先用上面的非破坏性 `rsync` 命令同步源码,然后:
```bash
cd ~/plugins/aliyun-sls-codex
npm install
npm run build
npm run check
npm run smoke:mcp
python3 ~/.codex/skills/.system/plugin-creator/scripts/update_plugin_cachebuster.py \
~/plugins/aliyun-sls-codex
python3 ~/.codex/skills/.system/plugin-creator/scripts/read_marketplace_name.py
codex plugin add aliyun-sls-codex@personal
```
若读取到的 Marketplace 名称不是 `personal`,同样替换命令后缀。重新安装后启动新的 Codex 任务;旧任务不会自动拾取更新后的插件内容。
若暂时不用 Marketplace,可把本仓库的 [`.mcp.json`](.mcp.json) 作为 MCP 配置参考,并单独加载 [`SKILL.md`](skills/aliyun-sls-investigation/SKILL.md)。此回退方式仍要求工作目录指向已构建的仓库,且两个环境变量由启动 Codex 的环境提供。
## 使用
插件提供:
- `search_logs`:按关键词搜索;默认最近 12 小时、默认 `AND`、最多 1000 条、按时间倒序。
- `get_context_logs`:围绕锚点获取上下文;默认前后各 300 秒、最多 24 小时、最多 1000 条、按时间正序。
- `check_connection`:只检查固定 Logstore 的可读性,不查询日志内容。
搜索和上下文工具的完整 JSON 结果上限为 5 MiB。超过上限时返回 `RESULT_TOO_LARGE`,不会返回局部日志;请缩小时间范围或增加更具体的关键词。
先检查连接:
> 调用 `check_connection`,确认只读 SLS 连接可用。
示例查询:
> 使用 `search_logs` 搜索关键词 `task-42` 和 `失败`,默认使用 AND 查询最近 12 小时,并解释时间线。
调查 Skill 最多进行 3 次日志调用。首次命中后通常查询前后 5 分钟上下文;AND 无结果时不会静默改为 OR。输出包括摘要、时间线、根因与置信度、原始证据、其他解释、验证建议和查询记录,并区分事实与推断。
## 错误与排查
- `AUTHENTICATION_FAILED`:检查 AccessKey 是否正确、是否启用,以及签名时间是否正常。
- `PERMISSION_DENIED`:确认 RAM 策略包含 `log:GetLogStore` 和 `log:GetLogStoreLogs`,资源 ARN 与固定范围一致。
- `RESOURCE_NOT_FOUND`:确认 `cn-beijing`、`taient-rpa`、`node-rpa` 存在且拼写一致。
- `INVALID_QUERY`:缩短时间范围并检查关键词;查询跨度不得超过 24 小时。
- `RATE_LIMITED`:稍后重试,不要添加并发或自动重试风暴。
- `NETWORK_ERROR`:检查 DNS、代理和到阿里云 SLS 的网络连接。
- Node 18 可能启动部分依赖,但本项目只支持 Node.js 22+;看到 engine 警告时升级 Node 后重新 `npm install` 和构建。
## 数据安全
原始日志会进入当前 Codex 会话,而且不会脱敏。日志可能包含用户标识、请求参数或内部错误细节;仅查询调查所需的最小范围,并遵守公司数据政策、访问控制和保留要求。
不要提交 `.env`、真实 AccessKey、复制出的日志、故障导出或包含凭据的终端输出。不要把凭据放进 `plugin.json`、`.mcp.json`、Skill、提示词或聊天消息;`.mcp.json` 只声明环境变量名称。
提交前运行凭据扫描,并逐项确认命中的是占位符。示例:先搜索 `LTAI` 形式的 AccessKey ID,再搜索 `ALIBABA_CLOUD_ACCESS_KEY_SECRET=`;README 和 `.env.example` 中的 `replace-with-...` 占位符是预期命中,任何其他赋值都必须在提交前移除并轮换相关凭据。
TDQS
A3.6/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a clear, distinct purpose: search by keywords, fetch context around a timestamp, and verify connectivity. There is no overlap or ambiguity between them.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern: search_logs, get_context_logs, check_connection. The naming is uniform and predictable.
Tool Count5/5
With 3 tools, the server is well-scoped for a focused log-searching utility. Each tool is essential to the core workflow of finding and examining logs.
Completeness4/5
The tools cover the main workflow of searching logs and retrieving surrounding context, but lack explicit time-range controls or the ability to list available log stores. These are minor gaps that can be worked around with existing parameters or configuration.
Maintenance
ActivitySlowing
ResponsivenessNo issues