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`、最多 5000 条、按时间倒序。
- `get_context_logs`:围绕锚点获取上下文;默认前后各 300 秒、最多 24 小时、最多 5000 条、按时间正序。
- `check_connection`:只检查固定 Logstore 的可读性,不查询日志内容。
`search_logs` 和 `get_context_logs` 都可选传入以下实例条件;它们会与关键词表达式使用 `AND` 组合:
- `hostname`:精确匹配 SLS 字段 `__tag__:__hostname__`。
- `source`:精确匹配 SLS 字段 `__source__`。
- `path`:精确匹配 SLS 字段 `__tag__:__path__`。
例如,先按任务 ID 搜索,再把命中日志里的实例字段带入上下文查询:
```json
{
"anchor_time": 1786614000,
"before_seconds": 300,
"after_seconds": 300,
"keywords": ["f48442b0-201e-43c5-81fd-1f47d6d90cdb"],
"hostname": "rk16",
"source": "192.168.31.136",
"path": "/data/deploy/logs/r02_rpa.log",
"limit": 5000
}
```
多个关键词使用 OR 时会先成组,再与实例条件做 AND,避免实例过滤只作用于最后一个关键词。
两个日志工具都支持游标分页。首次调用不传 `cursor`;当响应中 `has_more=true` 时,把 `next_cursor` 作为下一次调用的 `cursor`。翻页时必须复用上一页 `query` 中的精确起止时间、关键词、AND/OR 和实例过滤条件,只改变 `cursor`,否则倒序结果集变化可能造成重复或漏日志。
分页响应会返回:
- `returned`:本页规范化、去重后的日志条数。
- `has_more`:额外探测下一条后确认是否仍有结果。
- `next_cursor`:仅在确实存在下一页时返回。
- `truncated`:兼容旧客户端,值与 `has_more` 相同。
示例:上一页返回 `next_cursor: 5000` 后,下一页沿用相同的 `start_time`、`end_time` 和过滤条件,并传入 `"cursor": 5000`。
搜索和上下文工具的完整 JSON 结果上限为 5 MiB。超过上限时返回 `RESULT_TOO_LARGE`,不会返回局部日志;请保持关键词和实例条件不变,拆分时间范围后分别查询。
先检查连接:
> 调用 `check_connection`,确认只读 SLS 连接可用。
示例查询:
> 使用 `search_logs` 搜索关键词 `task-42` 和 `失败`,默认使用 AND 查询最近 12 小时,并解释时间线。
调查 Skill 最多进行 3 次日志调用。第一次固定按 5000 条上限搜索;底层按每页 100 条顺序分页聚合。超过 5 MiB 时按时间分段,不降低条数上限。首次命中后从日志提取实例字段,并使用业务关键词或实例精确条件查询前后 5 分钟上下文;AND 无结果时不会静默改为 OR。输出包括摘要、时间线、根因与置信度、原始证据、其他解释、验证建议和查询记录,并区分事实与推断。
插件更新后,Codex 需要启动新的任务才能重新发现更新后的 Skill。其他支持动态重载 MCP 的客户端(例如 Qoder)在同步源码并重新构建后可执行 `/mcp reload`;如果客户端没有该命令,就重启对应会话或应用。
## 错误与排查
- `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
ActivityMaintained
ResponsivenessNo issues