内容
# FSR Playbook 框架 (`fsrpb`)
YAML → FortiSOAR Playbook 编译器和参考存储,具有 Svelte 可视化编辑器和 MCP 服务器,用于从简单的、人类可读的 IR 中编写、验证和运行 FortiSOAR Playbook,而不是手动编写 Playbook JSON。
它包含三个部分:
- **编译器 + 解析器** (`fsr_playbooks`, `python/`) — 将简化的 YAML IR 转换为 FortiSOAR Playbook JSON,具有类型化的遍历器,可以解析变量连接和类型检查源 → 目标。
- **参考存储** (`store/fsr_reference.db`) — 连接器、操作、参数、步骤类型、Jinja 过滤器/宏和步骤示例的 SQLite 目录,编译器和代理查询以确定每个步骤。
- **Playbook Studio** (`web/`) — 具有 FastAPI 后端和 Svelte 5 可视化编辑器的 Playbook 构建、调试和逐步执行工具,以及 **MCP 服务器**,提供相同的编写/验证/运行工具给代理。
## 目录
- [布局](#布局) · [参考存储](#参考存储-sqlite-first) · [设置](#设置) · [常用命令](#常用命令)
- [MCP 服务器](#mcp-服务器)
- [故障排除 → 构建 Playbook](#故障排除-→-构建-playbook-claude-desktop--claude-code) — **选择你的前端:**
- [原生路径 — Claude Desktop / Claude Code,无 API 密钥](#原生路径--claude-desktop--claude-code-无-api-密钥)
- [打包路径 — FortiSOAR 小部件 / 无头](#打包路径--fortisoar-小部件--无头)
- [Claude Desktop 配置 + 环境变量](#claude-desktop-配置--环境变量)
## 布局
```
fsr_playbooks/ 编译器、解析器、类型化遍历器、MCP 服务器(与连接器共享)
python/ CLI(fsrpb)、构建参考数据库的探测器、额外 MCP 服务器、测试
web/ FastAPI 后端(:47821)+ Svelte 5 Studio 编辑器(:47822)
ts/ TypeScript 编译器(小部件可运行;使用 fsr_reference.json)
store/ 模式 + 参考数据库 + 代理 .md 参考导出
examples/ YAML 固定装置 + 预期 Playbook JSON
e2e/ 实时端到端测试框架(examples/*.test.yaml 对抗真实的 FSR)
```
## 参考存储(SQLite-first)
`store/fsr_reference.db` 是代理或编译器需要的一切的单一真实来源 — 所有内容都可以通过 SQL 查询。`store/fsr_reference.json` 是 TypeScript 编译器/小部件的派生导出。`fsrpb refresh` 从探测器输出重建存储。
> 已发布的构建提供了一个精简的目录(步骤类型、Jinja 参考和连接器操作主体)。运行 `fsrpb refresh` 以填充特定于实例的模块、字段和选择列表。
## 设置
依赖项使用 [uv](https://docs.astral.sh/uv/) 进行管理。Python **3.11+**。
```sh
make bootstrap # 新克隆 -> 绿色、可测试状态(创建 .venv、安装依赖项)
# 或:
make sync # 创建 .venv 并通过 uv 安装所有可编辑依赖项
```
`fsr_playbooks` 也被移植到平台连接器中,其运行时为 Python 3.9 — 保持 `fsr_playbooks` 3.9 清洁(无模块级 PEP 604 联盟)。
## 常用命令
```sh
make verify # 离线绿色检查:fsr_playbooks + 连接器测试套件
make tests # 快速 pytest(排除实时 + 慢速),包括离线黄金跟踪销
make dev # 一起运行后端(:47821)+ 前端(:47822)
make e2e # 运行每个 examples/*.test.yaml 对抗实时 FSR
make lint # ruff 检查 fsr_playbooks + python
fsrpb --help # CLI(编译、验证、解析、刷新、查询存储)
```
## MCP 服务器
三个 MCP 服务器(参见 `.mcp.json`)向代理/Claude Code 公开工具集:
- **`fsrpb`** (`fsr_playbooks.mcp_server`) — 编写:编译/验证/解析 YAML,查找连接器/操作,获取步骤模式,调试会话。
- **`fsr-read`** (`python/fsr_read_mcp.py`) — 只读实时 FortiSOAR 查询(记录、选择列表、运行操作、验证 Playbook)。
- **`fsr-deploy`** (`python/fsr_deploy_mcp.py`) — 连接器构建/部署助手。
### 故障排除 → 构建 Playbook(Claude Desktop / Claude Code)
`fsrpb` 服务器允许助手调查事件、阶段控制并从其执行的操作中编译可重放的 Playbook — 无需 FortiSOAR UI。有 **两种** 方法驱动它;按前端选择:
| 前端 | 路径 | 内部模型? | 需要密钥 |
|---|---|---|---|
| **Claude Desktop / Claude Code** | [原生 — 自己驱动](#原生路径--claude-desktop--claude-code-无-api-密钥) | 否 — 助手 *是* Claude | `FSR_BASE_URL` + `FSR_API_KEY` |
| **FortiSOAR 小部件 / cron / 无头** | [打包路径](#打包路径--fortisoar-小部件--无头) | 是 — 自带 LLM | + `OPENAI_*`(默认)**或** `ANTHROPIC_API_KEY` |
#### 原生路径 — Claude Desktop / Claude Code,无 API 密钥
Claude Desktop 和 Claude Code **已经是 Claude**,因此它们使用粒度 `fsrpb` 工具自行运行故障排除循环。没有第二个模型和 `ANTHROPIC_API_KEY` — 助手只需要一种方式来(a)记录其运行的操作和(b)继承调校的故障排除纪律。三个基本操作提供:
1. `triage_session_start(entity?)` — 开始记录(调用一次,在开始时)。
2. 驱动工作:`run_op` 用于只读增强,`emit_action_card` **阶段** 控制(永远不要默默运行),`get_record` / `search_module_records` 用于跳转。`run_op` 自动记录到会话中。
3. `build_playbook_from_trace()` — 无参数;编译记录的操作到 Playbook。**仅提供** — 显式调用 `push_playbook` 以保存到 FSR。
`triage_guidance()` (和 MCP `triage` 提示)返回调校的指令表,以便助手遵循与打包代理相同的纪律(只读调查、关联警报 *和* 事件、阶段 — 不要运行 — 控制)。`triage_session_state()` 显示已捕获的内容。
只需自然地询问 — *"故障排除最新的高严重性事件并从中构建控制 Playbook"* — 助手就会按顺序调用这些。
#### 打包路径 — FortiSOAR 小部件 / 无头
`triage_build_turn` / `triage_build_resume` 在单个工具调用中运行 **整个** 循环,使用它们自己的内部 LLM。此功能适用于不是模型的 frontend(FortiSOAR 小部件;cron/无头)。内部模型由 `FSR_LLM_PROVIDER` 设置 — **默认为 `openai`** (gpt-oss 网关),或 `anthropic` (直接使用 `ANTHROPIC_API_KEY` 调用 Anthropic API — 服务器 **无法** 重用 Claude Desktop 的订阅)。对于 Claude Desktop / Code,请优先使用上述原生基本操作并跳过此功能。
#### Claude Desktop 配置 + 环境变量
配置文件(macOS):`~/Library/Application Support/Claude/claude_desktop_config.json`。使用 `uv run --directory <repo>` 启动,以便项目解析并服务器自动加载此存储库的 `.env`。对于原生路径,您不需要任何 LLM 密钥 — 仅需 `run_op` 的实时 FSR 访问。
如果您的 `.env` 已经填充,**省略 `env` 块**。仅在需要显式设置凭据时包含它(例如,没有此存储库的 `.env` 的机器,或覆盖它 — `env` 块优先):
```jsonc
{
"mcpServers": {
"fsrpb": {
"command": "uv",
"args": ["run", "--directory",
"/absolute/path/to/fsr-playbook-framework",
"python", "-m", "fsr_playbooks.mcp_server"],
"env": {
"FSR_BASE_URL": "https://your-instance.fortisoar.example.com",
"FSR_API_KEY": "<scoped FortiSOAR API key>"
// — 或 username/password 而非 FSR_API_KEY(不推荐):
// "FSR_USERNAME": "<your-FortiSOAR-username>",
// "FSR_PASSWORD": "<password>",
// — 打包路径仅需(原生路径不需要):
// "FSR_LLM_PROVIDER": "openai",
// "OPENAI_ENDPOINT": "https://your-gateway/v1",
// "OPENAI_MODEL": "gpt-oss-120b",
// "OPENAI_API_KEY": "<gateway key>"
}
}
}
}
```
> JSON 本身没有注释;上面的 `//` 行仅用于说明 — 在实际文件中删除它们(和未使用的密钥)。最小原生路径 `env` 仅需 `FSR_BASE_URL` + `FSR_API_KEY`。
**配置界面。** 所有环境变量;每个服务器的 **`env` 块优先于存储库 `.env`** (使用 `setdefault` 加载)。将 `.env` 用作开发默认值,将 `env` 块用于可移植配置。
| 变量 | 用途 |
|---|---|
| `FSR_BASE_URL` | 实时 FortiSOAR 基本 URL(用于 `run_op` 增强) |
| **`FSR_API_KEY`** | **首选** FortiSOAR 认证(作用域 + 可撤销) |
| `FSR_USERNAME` / `FSR_PASSWORD` | 备用认证,仅当没有 `FSR_API_KEY` |
| `FSR_LLM_PROVIDER` | *仅打包路径* — 内部模型:`openai`(默认)或 `anthropic` |
| `OPENAI_ENDPOINT` / `OPENAI_MODEL` / `OPENAI_API_KEY` | *仅打包路径* — gpt-oss 网关 |
| `ANTHROPIC_API_KEY` | *仅打包路径*,且仅当 `FSR_LLM_PROVIDER=anthropic` |
**优先使用 API 密钥而不是用户名/密码。** 生成一个最小权限 FortiSOAR API 密钥(只读权限就足够 — 两个路径都不推送除非您调用 `push_playbook`)并设置 `FSR_API_KEY`;身份验证层(`probes._env`)使用它覆盖用户名/密码。`.env` 和 Desktop 配置文件都是纯文本,因此可撤销的作用域密钥包含一个泄漏 — 将 `.env` 设为 gitignored 并将配置文件 `chmod 600`。
编辑配置文件后重启 Claude Desktop — 它只在启动时读取配置文件。
**在没有 GUI 的情况下测试原生路径**(不需要 LLM 密钥):
```bash
.venv/bin/python - <<'PY'
from fsr_playbooks.mcp_server import tools_agent as ta
from fsr_playbooks.mcp_server.tools_execution import run_op
from fsr_playbooks.mcp_server.tools_compile import build_playbook_from_trace
ta.triage_session_start(entity={"module": "incidents"})
run_op(connector="virustotal", operation="query_ip", params={"ip": "8.8.8.8"})
print("recorded:", ta.triage_session_state()["count"])
print("built:", build_playbook_from_trace(name="Smoke PB")["ok"])
PY
```
参见 [`docs/ARCHITECTURE_AGENT_LOOP.md`](docs/ARCHITECTURE_AGENT_LOOP.md),了解所有三个前端(小部件、Web 应用程序、MCP)如何共享相同的 `fsr_playbooks.llm` 连接。