nikogura/diagnostic-bot
GitHub: nikogura/diagnostic-bot
基于 MCP 协议的 AI 驱动基础设施诊断平台,通过 Slack 机器人或 MCP 客户端实现对话式故障排查与根因分析。
Stars: 0 | Forks: 0
# 诊断 Bot
一个将 Claude Code 与 Kubernetes、Loki 及可观测性工具集成的诊断自动化平台。通过基于 YAML 的模板和自定义 MCP 工具提供自主调查能力,并生成专业的 PDF 报告。包含一个用于对话式访问的 Slack 机器人,以及一个支持 Streamable HTTP 和 SSE 传输协议的 MCP 服务器,可与 Claude Code、Claude Desktop、OpenAI、Devin 及其他兼容 MCP 的客户端配合使用。
## 功能
- **Claude Code 集成**:使用带有 MCP 服务器的 Claude Code CLI 实现高级工具调用能力
- **MCP 服务器**:提供用于 Loki 查询、K8s 访问、GitHub 集成、ECR 扫描和 PDF 生成的自定义工具
- **第三方 API 集成**:通过 YAML 添加只读 API 集成的配置驱动系统——无需编写 Go 代码
- **调查技能**:基于 YAML 的模板,用于定义结构化的调查工作流
- **Kubernetes 访问**:对 pods、日志、ConfigMaps、Deployments 和 Flux CRDs 的只读访问
- **PDF 报告生成**:通过 Pandoc + LaTeX 自动生成带有公司品牌的专业报告
- **日志脱敏**:全面的 PII 和密钥遮蔽(13 种正则表达式模式)
- **Slack Socket Mode**:支持应用提及、线程和对话式跟进
- **会话状态**:具有 24 小时过期时间和自动文件清理的内存跟踪
- **Prometheus 指标**:全面的可观测性,包含调查、API 调用、K8s 查询和工具使用的计数器
## 代码质量
- **Linter 合规性**:100% 干净 - 所有 golangci-lint 和 namedreturns 检查均通过
- **测试覆盖率**:带有竞态检测的单元测试,覆盖率报告上传至 Codecov
- **CI/CD**:通过 GitHub Actions 自动执行 linting、测试、Docker 构建和安全扫描
- **多架构支持**:支持 amd64 和 arm64 架构的 Docker 镜像
- **安全扫描**:使用 Trivy 进行漏洞扫描并上传 SARIF 报告
## 项目结构
```
diagnostic-bot/
├── cmd/
│ ├── bot/main.go # Main Slack bot entry point
│ └── mcp-server/main.go # MCP server for Claude Code tools
├── pkg/
│ ├── bot/ # Slack bot logic
│ │ ├── bot.go # Core bot initialization
│ │ ├── handlers.go # Event handlers
│ │ ├── claudecode.go # Claude Code CLI integration
│ │ ├── tools.go # Dynamic tool availability config
│ │ └── state.go # Conversation state management
│ ├── claude/ # Direct Claude API integration (legacy)
│ │ ├── client.go # API client with tool use support
│ │ ├── tools.go # Tool definitions for Claude
│ │ └── prompts.go # System prompt construction
│ ├── investigations/ # Investigation skill system
│ │ ├── template.go # Skill data structures and loading
│ │ └── matcher.go # Message matching logic
│ ├── k8s/ # Kubernetes and Loki clients
│ │ ├── agent.go # K8s resource access
│ │ ├── loki.go # Loki log query client
│ │ └── sanitizer.go # Log sanitization
│ ├── apiconfig/ # Third-party API integration framework
│ │ ├── config.go # YAML config schema and loader
│ │ ├── client.go # Generic HTTP client (auth, retry, rate limiting)
│ │ ├── validate.go # Path parameter validation (traversal, injection)
│ │ ├── redact.go # PII field redaction from JSON responses
│ │ └── tools.go # MCP tool generation and dispatch
│ ├── mcp/ # MCP server implementation
│ │ ├── server.go # Tool handlers and legacy protocol
│ │ ├── sdk_server.go # MCP SDK integration (Streamable HTTP + SSE + stdio)
│ │ ├── types.go # MCP protocol types
│ │ ├── cloudwatch.go # CloudWatch Logs tools
│ │ ├── prometheus.go # Prometheus/PromQL tools
│ │ ├── grafana.go # Grafana dashboard tools
│ │ ├── database.go # Database query tools
│ │ ├── ecr.go # ECR vulnerability scanning
│ │ └── auth/ # MCP server authentication
│ └── metrics/ # Prometheus metrics
│ ├── metrics.go # Metric definitions
│ └── server.go # HTTP metrics server
├── apis/ # Third-party API configs (YAML)
│ └── bitgo.yaml # Example: BitGo read-only wallet API
├── investigations/ # YAML investigation skills
│ ├── modsecurity-block.yaml
│ ├── atlas-migration.yaml
│ ├── general-diagnostic.yaml
│ └── ecr-vulnerability-scan.yaml
├── latex-templates/ # PDF report templates
├── docs/
│ ├── ECR_INTEGRATION.md # ECR vulnerability scanning guide
│ └── PROJECT_SPEC.md # Original project specification
├── .github/workflows/ # CI/CD pipelines
│ ├── ci.yaml # Lint, test, build, Docker push
│ └── release.yaml # GoReleaser for versioned releases
├── Dockerfile # Multi-stage Alpine build
├── Makefile # Build and lint targets
├── .golangci.yml # Linter configuration (strict enforcement)
├── .mcp.json # MCP server configuration
└── go.mod # Go module dependencies
```
## 调查技能
该机器人在 `investigations/` 目录中包含示例调查技能。这些是带有替换变量的通用示例,可适应您的环境。
### 包含的示例
#### ModSecurity WAF 拦截诊断
调查 Web 应用防火墙拦截事件,具备以下功能:
- 查询 Loki 获取 ModSecurity 审计日志
- 分析 OWASP CRS 规则触发情况
- 对拦截进行分类(误报与合法拦截)
- 提供带有规则 ID 和配置片段的精确修复方案
- 通过 whois 执行 IP 地理定位
**触发模式**:`modsec`、`modsecurity`、`waf blocked`、`403.*waf`
#### Atlas 迁移故障排除
诊断在 GitOps 环境中 Atlas 迁移未应用的原因:
- 检查 AtlasMigration CRD 状态
- 验证 GitRepository 版本固定
- 检查 ConfigMap 内容
- 分析 Flux Kustomization 协调情况
- 识别根本原因(标签固定、ConfigMap 未重新生成等)
**触发模式**:`atlas.*migration`、`migration.*not.*applied`、`migration.*failure`
#### 常规诊断调查
针对常规生产问题的系统化方法:
- 定义调查阶段(范围确定、上下文收集、假设形成、定向调查、根因分析、修复)
- 提供查询 Prometheus、Thanos、Loki 和 Alertmanager 的示例
- 涵盖常见模式(WAF 拦截、数据库迁移、Flux 故障、Pod 崩溃)
- 强调安全优先和 GitOps 原则
**触发模式**:`investigate`、`diagnostic`、`troubleshoot`、`issue`、`problem`、`error`
## 创建新调查
### 调查 YAML 结构
调查在 YAML 文件中定义,结构如下:
```
name: "Investigation Name"
description: "Brief description of what this investigation does"
trigger_patterns:
- "pattern1"
- "pattern2.*regex"
- "specific phrase"
initial_prompt: |
Multi-line prompt that Claude will use as context for this investigation.
This should include:
- Role definition ("You are a diagnostic agent for...")
- Core principles (security, read-only, systematic approach)
- Investigation methodology (phases, steps)
- Available tools and when to use them
- Output format expectations
- Critical patterns to recognize
- Communication style guidelines
kubernetes_resources:
- type: "pod"
namespace: "namespace-name"
selector: "app=component"
container: "container-name"
since: "1h"
grep: "ERROR"
tail_lines: 500
require_approval: false
```
### 字段说明
- **name**:在 Slack 中显示的易读名称
- **description**:简要描述(如果是用于自定义的模板,请添加 "EXAMPLE:" 前缀)
- **trigger_patterns**:与用户消息匹配的正则表达式模式。更具体的模式(较长的纯文本模式长度)优先。
- **initial_prompt**:Claude 接收到的系统提示。这是您调查工作流的核心。
- **kubernetes_resources**:(可选)要预获取的 K8s 资源列表。适用于常见查询。
- **require_approval**:(可选)如果为 true,机器人会在开始调查前请求用户确认。
### 替换变量
使用 `{{VARIABLE_NAME}}` 语法表示在投入生产部署时需要自定义的环境特定值:
```
initial_prompt: |
Query Prometheus at {{PROMETHEUS_URL}} for metrics.
Check Loki at {{LOKI_URL}} for logs.
The application runs in namespace {{APP_NAMESPACE}}.
```
**常见替换变量:**
- `{{PROMETHEUS_URL}}` - Prometheus 端点
- `{{THANOS_URL}}` - Thanos 查询端点(联邦指标)
- `{{LOKI_URL}}` - Loki 日志聚合端点
- `{{ALERTMANAGER_URL}}` - Alertmanager 端点
- `{{REALM}}` - 环境名称 (prod, staging, dev)
- `{{NAMESPACE}}` - Kubernetes 命名空间
- `{{DOMAIN}}` - 应用程序域
- `{{GH_ORG}}` - GitHub 组织
- `{{GH_REPO}}` - GitHub 仓库名称
### 触发模式特异性
机器人使用特异性算法来选择最佳匹配的调查:
1. 模式按顺序与用户消息进行匹配
2. 如果多个模式匹配,最具体的模式获胜
3. 特异性 = 最长纯文本模式的长度(非正则表达式字符)
**示例:**
- `"atlas.*migration"` → 特异性 = 5 (最长纯文本:"atlas")
- `"migration.*not.*applied"` → 特异性 = 9 (最长纯文本:"migration")
- `"database migration failure"` → 特异性 = 25 (整个短语为纯文本)
**最佳实践:**
- 对狭窄的调查使用具体的短语
- 在特定领域内使用正则表达式模式以增加灵活性
- 较长的纯文本模式在平局时胜出
### 可用的 Claude 工具 (通过 MCP 服务器)
您的调查提示应引用 Claude 可以自主使用的这些 MCP 工具名称。工具可用性是动态的——只有配置了支持服务的工具才会被注册并显示在提示中。
**日志 (Loki)** — 需要 `LOKI_ENDPOINT`:
- `query_loki` — 使用 LogQL 语法查询 Loki 获取集群日志
参数:query, start, end (可选), limit (可选)
**CloudWatch Logs** — 需要 `CLOUDWATCH_ACCOUNTS` 或 `CLOUDWATCH_ASSUME_ROLE`:
- `cloudwatch_logs_query` — 跨日志组执行 CloudWatch Logs Insights 查询
参数:query, log_groups, start_time, end_time (可选), region (可选), limit (可选), accounts (可选)
- `cloudwatch_logs_list_groups` — 列出可用的 CloudWatch 日志组
参数:prefix (可选), region (可选), limit (可选), accounts (可选)
- `cloudwatch_logs_get_events` — 从特定日志流获取日志事件
参数:log_group, log_stream, start_time (可选), end_time (可选), limit (可选), accounts (可选)
当 `CLOUDWATCH_ACCOUNTS` 配置了多个账户时,`accounts` 参数用于过滤要查询的账户。如果省略,将查询所有已配置的账户,并按账户标记结果。
**Prometheus/Metrics** — 需要 `PROMETHEUS_URL` 或 `PROMETHEUS__URL`:
- `prometheus_query` — 执行即时 PromQL 查询
- `prometheus_query_range` — 执行范围 PromQL 查询用于趋势分析
- `prometheus_series` — 查找匹配标签选择器的时间序列
- `prometheus_label_values` — 获取给定标签名称的所有值
- `prometheus_list_endpoints` — 列出已配置的 Prometheus 端点
**Grafana** — 需要 `GRAFANA_URL` + `GRAFANA_API_KEY`:
- `grafana_list_dashboards` — 列出所有 Grafana 仪表板
- `grafana_get_dashboard` — 通过 UID 获取特定仪表板
- `grafana_create_dashboard` — 从查询创建新仪表板
- `grafana_update_dashboard` — 更新现有仪表板
- `grafana_delete_dashboard` — 删除仪表板
**Database** — 需要 `DATABASE_URL` 或 `DATABASE__URL`:
- `database_query` — 执行只读 SQL 查询 (SELECT, SHOW, DESCRIBE, EXPLAIN)
- `database_list` — 列出可用数据库
**GitHub** — 需要 `GITHUB_TOKEN`:
- `github_get_file` — 从 GitHub 仓库获取文件
- `github_list_directory` — 列出仓库目录中的文件
- `github_search_code` — 跨仓库搜索代码
**ECR (容器安全)** — 需要 `AWS_REGION` 或 `AWS_DEFAULT_REGION`:
- `ecr_scan_results` — 查询 ECR 获取容器镜像漏洞扫描结果
**第三方 API** — 从 `apis/` 目录的 YAML 配置动态加载:
- 工具命名为 `{api_name}_{endpoint_name}`(例如:`bitgo_list_wallets`)
- 仅在 API 的身份验证 token 环境变量设置后可用
- 详情请参见 [第三方 API 集成](#third-party-api-integration)
**实用工具** — 始终可用:
- `whois_lookup` — IP 地理定位、ISP、ASN 查询
- `generate_pdf` — 从 Markdown 内容生成 PDF 报告(自动上传至 Slack)
**注意:** 传统的直接 K8s 工具调用(`get_k8s_pod_logs`、`get_k8s_resource` 等)已弃用,取而代之的是 MCP 服务器架构。调查模板应使用上述 MCP 工具。
### 调查提示指南
您的 `initial_prompt` 应该:
1. **明确定义角色**:"你是一个针对 X 平台的诊断代理,正在调查 Y 问题..."
2. **设定边界**:强调只读访问、安全注意事项和 GitOps 原则
3. **提供方法论**:分步骤的调查阶段或决策树
4. **按名称引用 MCP 工具**:告诉 Claude 使用哪些 MCP 工具以及何时使用。使用上面“可用的 Claude 工具”部分中的确切工具名称(例如,`cloudwatch_logs_query`、`query_loki`、`prometheus_query`)。切勿引用 `aws`、`kubectl`、`psql` 等外部 CLI。
5. **定义输出格式**:指定结构(总结、时间线、根因、修复、预防)
6. **包含关键模式**:已知问题、误报指标、常见根因
7. **设定沟通风格**:技术深度、简洁明了、使用严重性标签
8. **记录替换变量**:在末尾列出所有 `{{VARIABLES}}` 及其描述
### 本地测试
1. **在 `investigations/my-investigation.yaml` 中创建您的调查 YAML**
2. **替换变量**以便进行本地测试:
# 使用 sed 或您的编辑器将 {{VARIABLES}} 替换为实际值
sed -e 's|{{LOKI_URL}}|http://localhost:3100|g' \
-e 's|{{NAMESPACE}}|default|g' \
investigations/my-investigation.yaml > /tmp/test-investigation.yaml
3. **运行验证测试**:
# 测试验证 YAML 结构和模式匹配
go test ./pkg/investigations/... -v
4. **在本地使用机器人测试**:
export INVESTIGATION_DIR=/tmp
export SLACK_BOT_TOKEN=xoxb-your-token
export SLACK_APP_TOKEN=xapp-your-token
export ANTHROPIC_API_KEY=sk-your-key
export LOKI_ENDPOINT=http://localhost:3100
go run cmd/bot/main.go
5. **在 Slack 中发送与您的触发模式匹配的测试消息**
### 部署到生产环境
要使用 Vault 支持的密钥进行生产部署:
1. **在您的调查 YAML 中替换生产值**(替换所有 `{{VARIABLES}}`)
2. **存储在 Vault 中**(HashiCorp Vault 示例):
vault kv put infra/diagnostic-bot-inv-myinvestigation \
my-investigation.yaml=@investigations/my-investigation.yaml
3. **创建 VaultStaticSecret 清单**:
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: diagnostic-bot-inv-myinvestigation
namespace: diagnostic-bot
spec:
type: kv-v2
mount: infra
path: diagnostic-bot-inv-myinvestigation
destination:
name: diagnostic-bot-inv-myinvestigation
create: true
refreshAfter:30s
vaultAuthRef: diagnostic-bot
rolloutRestartTargets:
- kind: Deployment
name: diagnostic-bot
4. **在 Deployment 中挂载密钥**:
volumeMounts:
- name: inv-myinvestigation
mountPath: /app/investigations/my-investigation.yaml
subPath: my-investigation.yaml
readOnly: true
volumes:
- name: inv-myinvestigation
secret:
secretName: diagnostic-bot-inv-myinvestigation
5. **使用 GitOps 应用** - 提交清单并让 Flux 进行协调
### 示例:创建自定义调查
让我们为 Nginx Ingress Controller 问题创建一个调查:
```
name: "Nginx Ingress Troubleshooting"
description: "Diagnoses Nginx ingress controller issues (502/504, SSL, routing)"
trigger_patterns:
- "nginx.*ingress"
- "502.*bad.*gateway"
- "504.*gateway.*timeout"
- "ingress.*not.*working"
initial_prompt: |
You are diagnosing Nginx ingress controller issues in a Kubernetes environment.
## Investigation Steps
1. **Check ingress controller pods**:
- Use list_k8s_pods with namespace={{INGRESS_NAMESPACE}}, selector="app.kubernetes.io/name=ingress-nginx"
- Look for restarts, OOMKilled, CrashLoopBackOff
2. **Query recent logs**:
- Use query_loki with: {namespace="{{INGRESS_NAMESPACE}}"} |= "error" or "warn"
- Time range: last 1 hour
- Look for upstream errors, SSL handshake failures, timeout messages
3. **Check ingress resource**:
- Use get_k8s_resource for the specific Ingress
- Verify: backend service name, port, TLS config, annotations
4. **Check backend pods**:
- Use list_k8s_pods for backend service namespace
- Verify pods are Running and Ready
5. **Analyze error patterns**:
- 502: Backend not responding (pod down, wrong service/port)
- 504: Backend timeout (slow response, deadlock)
- SSL errors: Certificate issues, TLS version mismatch
## Output Format
```
## 问题摘要
[一行描述]
## 症状
[用户遇到的情况]
## 根本原因
[确定的具体原因]
## 修复方案
[包含命令/配置的精确修复步骤]
```
## Substitution Variables
- {{INGRESS_NAMESPACE}}: Namespace where ingress controller runs (e.g., "ingress-nginx")
kubernetes_resources:
- type: "pod"
namespace: "{{INGRESS_NAMESPACE}}"
selector: "app.kubernetes.io/name=ingress-nginx"
container: "controller"
since: "1h"
grep: "error"
tail_lines: 200
require_approval: false
```
创建完成后,在部署到生产环境之前,请将 `{{INGRESS_NAMESPACE}}` 替换为您的实际命名空间。
## 通过 MCP 服务器使用 Claude 工具
该机器人使用带有自定义 MCP(模型上下文协议)服务器的 Claude Code CLI,该服务器提供用于自主调查的工具。工具可用性是动态的——仅注册由已配置服务支持的工具。
### 工具类别
| 类别 | 所需环境变量 | 工具 |
|----------|-----------------|-------|
| Loki (日志) | `LOKI_ENDPOINT` | `query_loki` |
| CloudWatch Logs | `CLOUDWATCH_ACCOUNTS` 或 `CLOUDWATCH_ASSUME_ROLE` | `cloudwatch_logs_query`, `cloudwatch_logs_list_groups`, `cloudwatch_logs_get_events` |
| Prometheus | `PROMETHEUS_URL` 或 `PROMETHEUS__URL` | `prometheus_query`, `prometheus_query_range`, `prometheus_series`, `prometheus_label_values`, `prometheus_list_endpoints` |
| Grafana | `GRAFANA_URL` + `GRAFANA_API_KEY` | `grafana_list_dashboards`, `grafana_get_dashboard`, `grafana_create_dashboard`, `grafana_update_dashboard`, `grafana_delete_dashboard` |
| Database | `DATABASE_URL` 或 `DATABASE__URL` | `database_query`, `database_list` |
| GitHub | `GITHUB_TOKEN` | `github_get_file`, `github_list_directory`, `github_search_code` |
| ECR | `AWS_REGION` 或 `AWS_DEFAULT_REGION` | `ecr_scan_results` |
| 第三方 API | 每个 API 的 token 环境变量 (例如:`BITGO_ACCESS_TOKEN`) | 从 `apis/` 目录中的 YAML 配置动态生成 |
| 实用工具 | *(始终可用)* | `whois_lookup`, `generate_pdf` |
请参阅 `pkg/bot/tools.go` 了解环境变量检测逻辑,参阅 `pkg/mcp/server.go` 了解条件工具注册。
### 架构
MCP 服务器支持三种传输协议,均提供相同的工具:
1. **Stdio**(用于 Claude Code 子进程):Claude Code 在 `--print` 模式下运行,该模式不会加载通过 `claude mcp add` 注册的 MCP 服务器。相反,机器人传递带有使用 stdio 传输的 `/app/mcp-server` 二进制文件的 `--mcp-config`。这会为每次调查生成一个专用的 MCP 服务器进程。
2. **Streamable HTTP**(用于外部客户端——推荐):当设置 `MCP_HTTP_ENABLED=true` 时,机器人会在配置的端口(默认 8090)的 `/mcp` 路径下提供 Streamable HTTP 服务。这是当前的 MCP 标准(规范 2025-03-26),OpenAI、Devin 和 Claude Desktop 均要求使用此协议。
3. **SSE**(旧版,为了向后兼容):同样在同一端口的 `/sse` 路径下提供服务。使用 SSE 的现有客户端可继续正常工作。
### 通过 `.mcp.json` 连接
要将 Claude Code(或其他 MCP 客户端)连接到正在运行的实例,请在您的项目根目录中添加一个 `.mcp.json` 文件:
**Streamable HTTP(推荐):**
```
{
"mcpServers": {
"diagnostic": {
"type": "http",
"url": "https://your-host:8090/mcp"
}
}
}
```
**SSE(旧版):**
```
{
"mcpServers": {
"diagnostic": {
"type": "sse",
"url": "https://your-host:8090/sse"
}
}
}
```
**同时使用两种传输协议:**
```
{
"mcpServers": {
"diagnostic-http": {
"type": "http",
"url": "https://your-host:8090/mcp"
},
"diagnostic-sse": {
"type": "sse",
"url": "https://your-host:8090/sse"
}
}
}
```
**注意:** 对于 Claude Code,传输类型为 `"http"`(而不是 `"streamable-http"`)。两种传输协议暴露相同的工具——使用您的客户端支持的那一种即可。
## 配置
机器人通过环境变量进行配置:
**必需:**
- `SLACK_BOT_TOKEN` - Bot OAuth token (xoxb-...)
- `SLACK_APP_TOKEN` - Socket Mode 的 App 级别 token (xapp-...)
- `ANTHROPIC_API_KEY` - Claude API 密钥 (sk-ant-...)
**可选:**
- `KUBECONFIG` - kubeconfig 路径(默认:使用集群内配置)
- `INVESTIGATION_DIR` - 调查技能路径(默认:`./investigations`)
- `CLAUDE_MD_PATH` - 工程标准路径(默认:`./docs/CLAUDE.md`)
- `COMPANY_NAME` - PDF 报告品牌的公司名称(默认:`Company`)
- `FILE_RETENTION` - 文件清理间隔(默认:`24h`)
- `MCP_HTTP_ENABLED` - 启用 HTTP/SSE MCP 服务器(默认:`false`,生产环境请设置为 `true`)
- `MCP_HTTP_PORT` - HTTP MCP 服务器的端口(默认:`8090`)
**MCP 服务器认证**(支持多种方法,配置一个或多个):
- `MCP_AUTH_TOKEN` - 用于简单认证的静态 bearer token(默认:空 = 无认证)
- `MCP_JWT_SECRET` - 用于 JWT bearer token 认证的 JWT 签名密钥
- `MCP_JWT_ALGORITHM` - JWT 算法(默认:`HS256`,也支持 `RS256`)
- `MCP_API_KEYS` - API 密钥认证,格式为 `key1:user1,key2:user2`
- `MCP_OIDC_ISSUER_URL` - 用于 token 验证的 OIDC issuer URL(例如,Dex 端点)
- `MCP_OIDC_AUDIENCE` - 预期的 OIDC audience 声明
- `MCP_OIDC_ALLOWED_GROUPS` - 逗号分隔的授权组列表
- `MCP_OIDC_SKIP_ISSUER_VERIFY` - 跳过 issuer 验证(默认:`false`,仅在测试时使用)
- `MCP_MTLS_CA_CERT_PATH` - 用于双向 TLS 认证的 CA 证书路径
- `MCP_MTLS_VERIFY_CLIENT` - 根据 CA 验证客户端证书(默认:`true`)
**工具支持服务**(每个都启用一组 MCP 工具——参见 [工具类别](#tool-categories)):
- `LOKI_ENDPOINT` - Loki 网关端点(启用 `query_loki`)
- `CLOUDWATCH_ACCOUNTS` - 友好名称到完整 IAM 角色 ARN 的 JSON 映射,用于多账户 CloudWatch 访问(启用 CloudWatch 工具)。示例:`{"dev":"arn:aws:iam::111:role/dev-reader","prod":"arn:aws:iam::222:role/prod-reader"}`
- `CLOUDWATCH_ASSUME_ROLE` - 用于单账户 CloudWatch 查询的 IAM 角色 ARN(旧版,启用 CloudWatch 工具)。请使用 `CLOUDWATCH_ACCOUNTS` 以支持多账户。
- `CLOUDWATCH_EXTERNAL_ID` - 用于跨账户角色假设的外部 ID(可选,与 `CLOUDWATCH_ACCOUNTS` 和 `CLOUDWATCH_ASSUME_ROLE` 一起使用)
- `PROMETHEUS_URL` - Prometheus 端点(启用 Prometheus 工具)。多端点:使用 `PROMETHEUS__URL` 模式
- `GRAFANA_URL` - Grafana 实例 URL(需要 `GRAFANA_API_KEY`)
- `GRAFANA_API_KEY` - Grafana API 密钥(与 `GRAFANA_URL` 一起必需,启用 Grafana 工具)
- `DATABASE_URL` - 数据库连接字符串(启用数据库工具)。多数据库:使用 `DATABASE__URL` 模式
- `GITHUB_TOKEN` - GitHub 工具的个人访问令牌
- `AWS_REGION` 或 `AWS_DEFAULT_REGION` - AWS 区域(启用 ECR 工具)
- `AWS_*` - 用于 ECR 漏洞扫描的标准 AWS 凭证
- `API_CONFIG_DIR` - 包含第三方 API YAML 配置的目录(默认:`./apis`)
## 第三方 API 集成
该机器人支持通过 YAML 配置文件添加只读 API 集成——无需编写 Go 代码。只需在 `apis/` 目录中放入一个 YAML 文件,设置身份验证 token 环境变量,MCP 服务器就会自动将端点注册为 Claude 可以调用的工具。
### 工作原理
1. 启动时,MCP 服务器从 `API_CONFIG_DIR`(默认 `./apis/`)加载所有 `.yaml` 文件
2. 每个配置定义了一个包含端点、参数、身份验证和速率限制的 API
3. 端点成为名为 `{api_name}_{endpoint_name}` 的 MCP 工具(例如:`bitgo_list_wallets`)
4. 如果身份验证 token 环境变量未设置,该 API 的工具将被静默跳过
5. Claude 可以像调用内置工具一样在调查期间调用这些工具
### API 配置 YAML 结构
```
name: myapi # API name (used as tool name prefix)
description: "My API description"
base_url: https://api.example.com
auth:
type: bearer # "bearer", "header", or "none"
token_env: MY_API_TOKEN # env var containing the auth token
headers: # optional custom headers
User-Agent: "diagnostic-bot/1.0"
rate_limit:
max_concurrent: 5 # semaphore size (default: 5)
retry_on_429: true # honor Retry-After header (default: true)
max_retries: 3 # max 429 retries (default: 3)
defaults:
limit: 25 # default pagination limit
max_limit: 100 # server-enforced max limit
endpoints:
- name: list_items # becomes tool "myapi_list_items"
description: "List all items"
method: GET
path: /api/v1/items
params:
- name: status
type: string
description: "Filter by status"
required: false
redact_fields: [email, phone] # PII fields to redact from responses
- name: get_item
description: "Get item by ID"
method: GET
path: /api/v1/items/{item_id} # path parameters use {placeholder} syntax
params:
- name: item_id
type: string
description: "Item ID"
required: true
in: path # "path" or "query" (default: "query")
validate: "[a-f0-9]{24,}" # regex validation pattern
redact_fields: [email, phone, ssn]
```
### 安全特性
- **只读**:仅支持 GET 请求
- **路径遍历保护**:所有路径参数都会针对 `../` 和 `\..` 模式进行验证
- **查询注入保护**:阻止路径参数包含 `?`、`&`、`#`
- **正则表达式验证**:每个参数的正则表达式模式在发出任何 HTTP 请求之前拒绝无效输入
- **PII 遮蔽**:可配置的字段级别遮蔽遍历嵌套的 JSON 并用 `[redacted]` 替换敏感值
- **速率限制**:基于信号量的并发控制,防止 Claude 的扇出调用压垮 API
- **429 重试**:遵循 `Retry-After` 标头并带有指数退避(上限 30 秒)
- **响应大小上限**:响应限制为 5MB
- **优雅降级**:缺少身份验证 token 意味着工具被隐藏,而不是引发错误
### 添加新 API
1. 在 `apis/` 中创建一个 YAML 文件(例如:`apis/fireblocks.yaml`)
2. 在您的部署中设置身份验证 token 环境变量(例如:`FIREBLOCKS_API_TOKEN`)
3. 部署——工具会自动出现在 Claude 的工具列表中
无需向核心仓库提交 PR。调查技能可以立即引用新工具。
### 包含的示例:BitGo
`apis/bitgo.yaml` 配置提供了对 BitGo 托管钱包 API 的只读访问:
| 工具 | 描述 |
|------|-------------|
| `bitgo_list_enterprises` | 列出可访问的企业 |
| `bitgo_list_wallets` | 列出带有过滤器的钱包 |
| `bitgo_get_wallet` | 获取钱包详情 |
| `bitgo_get_wallet_balance` | 获取特定币种的余额 |
| `bitgo_list_wallet_addresses` | 列出接收地址 |
| `bitgo_list_wallet_transfers` | 列出带有过滤器的转账 |
| `bitgo_get_transfer` | 获取转账详情 |
| `bitgo_list_enterprise_transfers` | 企业范围的转账 |
| `bitgo_list_pending_approvals` | 列出待处理的多签审批 |
| `bitgo_get_pending_approval` | 获取待处理的审批详情 |
需要 `BITGO_ACCESS_TOKEN` 环境变量。所有端点都会遮蔽电子邮件、电话和 IP 地址字段。
## 构建
```
# 运行 linters
make lint
# 运行测试
make test
# 构建 binary
make build
# 构建 Docker 镜像
make docker-build
```
## 用法
### Slack 命令
- `@bot help` - 列出可用的调查类型
- `@bot <问题描述>` - 开始调查
- 在线程中回复以继续对话
### 示例交互
**ModSecurity 调查:**
```
User: @bot I'm getting 403 errors from the WAF
Bot: 🔍 Starting ModSecurity WAF Block Diagnosis investigation...
Bot: [Queries Loki for recent 403s, analyzes rules, categorizes blocks]
Bot: Found 3 blocked requests in the last hour. Rule 930120 (OS File Access Attempt)
triggered on cookie data. This appears to be a FALSE POSITIVE - the session
cookie contains Base64 data that matches the pattern.
Recommended fix:
```nginx
SecRuleUpdateTargetById 930120 "!REQUEST_COOKIES:/__Secure-session-token/"
```
User: Can you check if this is happening in staging too?
Bot: [Queries Loki for staging realm, analyzes results]
```
**Atlas 迁移调查:**
```
User: @bot migration 20251029093301 not showing up in dev-01
Bot: 🔍 Starting Atlas Migration Troubleshooting investigation...
Bot: [Checks GitRepository, ConfigMap, AtlasMigration CRD]
Bot: Root cause identified:
dev-01 environment is pinned to tag 0.0.667 in control-kubernetes
Migration 20251029093301 was added in tag 0.0.673
Resolution: Update config to reference tag 0.0.673
```
## 安全性
- **只读访问**:机器人没有对 Kubernetes 的写入权限
- **日志脱敏**:所有日志在发送到 Claude API 之前都会进行脱敏处理
- API 密钥、令牌、密码被遮蔽
- JWT 令牌被遮蔽
- 电子邮件地址被遮蔽
- 信用卡号被遮蔽
- 私钥被遮蔽
- **审计跟踪**:所有 K8s 查询和 Claude API 调用都会被记录
- **GitOps 原则**:从不建议直接修改集群
## 部署
部署为 Kubernetes Deployment,包含:
- 单副本(内存状态)
- 非根容器用户 (UID 0)
- 具有最小 RBAC 权限的 ServiceAccount:
- 对 pods、pods/log、configmaps、services 的 `get`、`list` 权限
- 对 deployments 的 `get`、`list` 权限
- 对 Flux CRDs (gitrepositories, kustomizations) 的 `get`、`list` 权限
- 对 Atlas CRDs (atlasmigrations) 的 `get`、`list` 权限
### RBAC 要求
```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: diagnostic-bot
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "configmaps", "services"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
- apiGroups: ["source.toolkit.fluxcd.io"]
resources: ["gitrepositories"]
verbs: ["get", "list"]
- apiGroups: ["kustomize.toolkit.fluxcd.io"]
resources: ["kustomizations"]
verbs: ["get", "list"]
- apiGroups: ["db.atlasgo.io"]
resources: ["atlasmigrations"]
verbs: ["get", "list"]
```
## 可观测性
该机器人在端口 `:9090` 上暴露 Prometheus 指标以供抓取:
### 指标
- `investigations_started_total{type}` - 按模板类型发起的调查总数
- `investigations_resolved_total{type}` - 完成的调查总数
- `claude_api_calls_total{status}` - Claude API 调用计数 (成功/错误)
- `claude_api_tokens_total{type="input|output"}` - Token 使用追踪
- `k8s_queries_total{namespace,resource_type}` - Kubernetes 查询审计跟踪
- `loki_queries_total{status}` - Loki 查询追踪
- `tool_executions_total{tool_name,status}` - MCP 工具使用统计
- `conversations_active` - 当前活动对话数量 (仪表盘)
### 日志记录
通过 `log/slog` 进行结构化 JSON 日志记录,包含:
- 严重性级别 (Debug, Info, Warn, Error)
- 上下文感知日志记录 (对话 ID、用户 ID)
- 调查的自动关联
## 容器镜像
Docker 镜像会自动构建并发布到 GitHub Container Registry:
```
# 拉取最新镜像
docker pull ghcr.io/nikogura/diagnostic-bot:latest
# 拉取特定版本
docker pull ghcr.io/nikogura/diagnostic-bot:v1.0.0
# 本地运行
docker run -e SLACK_BOT_TOKEN=xoxb-... \
-e SLACK_APP_TOKEN=xapp-... \
-e ANTHROPIC_API_KEY=sk-... \
ghcr.io/nikogura/diagnostic-bot:latest
```
## CI/CD
该项目使用 GitHub Actions 进行持续集成和部署:
- **CI 流水线** (`.github/workflows/ci.yaml`):
- 在每次推送和拉取请求时运行
- Linting (golangci-lint + namedreturns)
- 带有竞态检测和覆盖率的测试
- 二进制构建
- 多架构 Docker 镜像构建 (amd64, arm64)
- 使用 Trivy 进行安全扫描
- 发布至 `ghcr.io/nikogura/diagnostic-bot`
- **发布流水线** (`.github/workflows/release.yaml`):
- 在版本标签 (`v*`) 上触发
- GoReleaser 用于多平台二进制文件
- 带有语义版本控制的 Docker 镜像
- 自动变更日志生成
- GitHub Release 创建
- **Dependabot** (`.github/dependabot.yml`):
- 每周依赖项更新
- 针对 AWS SDK 和 Kubernetes 的分组更新
## 许可证
Apache License 2.0
## 贡献
欢迎贡献!请:
1. Fork 此仓库
2. 创建一个特性分支
3. 进行您的更改
4. 运行测试和 linter:`make test && make lint`
5. 提交拉取请求
## 维护者
[Nik Ogura](https://github.com/nikogura)
标签:AIOps, AI运维, API集成, Claude集成, DNS解析, Docker, ECR镜像扫描, EVTX分析, GitHub Actions, Github集成, Golang, Go语言, Loki, MCP协议, MCP服务器, NIDS, PDF报告生成, PII过滤, Prometheus监控, SARIF, SlackBot, Slack机器人, SRE, StruQ, 偏差过滤, 可观测性, 基础设施诊断, 多架构镜像, 子域名突变, 安全合规, 安全编程, 安全防御评估, 容器化, 开源项目, 故障排查, 日志审计, 日志脱敏, 日志追踪, 根因分析, 程序破解, 网络代理, 自动化运维, 自动笔记, 自定义请求头, 请求拦截