内容
# SysRaptor MCP
用于操作 SysReptor 项目和发现结果的 FastMCP 服务器,具有防御性验证。
目标是让 Codex 和 Claude 等代理能够读取和更新 SysReptor 报告,而无需依赖隐含上下文。写入操作需要明确的 `project_id`、实时报告验证和重复确认字段,然后才能写入数据。
## 功能
- 搜索和获取 SysReptor 项目。
- 列出章节和发现结果。
- 创建发现结果。
- 更新发现结果和章节,并明确确认。
- 运行 `check_report`。
- 渲染项目 PDF 并将项目存档导出到受控输出目录。
- 从环境变量或本地 `.env` 文件加载配置。
- 在测试期间无需 MCP 身份验证即可运行本地 MCP 服务器。
## 要求
- Python 3.11+
- 访问 SysReptor
- SysReptor API令牌
- Python 依赖项:
```bash
pip install -e .
```
如果您只想要直接的运行时依赖项:
```bash
pip install fastmcp httpx
```
## 配置
在项目根目录或 `sysraptor_mcp/.env` 中创建 `.env` 文件:
```bash
cp .env.example .env
```
编辑文件:
```env
SYSRAPTOR_SERVER=https://sysreptor.example.com
SYSRAPTOR_ALLOW_INSECURE_HTTP=false
SYSRAPTOR_TOKEN=Authorization: Bearer sysreptor_YOUR_TOKEN_HERE
SYSRAPTOR_OUTPUT_DIR=/tmp/sysraptor-mcp
```
您也可以使用原始令牌值:
```env
SYSRAPTOR_TOKEN=sysreptor_YOUR_TOKEN_HERE
```
支持的变量:
| 变量 | 是否必需 | 描述 |
| --- | --- | --- |
| `SYSRAPTOR_SERVER` | 是 | SysReptor 基本 URL。例如:`https://sysreptor.example.com` |
| `SYSRAPTOR_TOKEN` | 通常是 | SysReptor API 令牌。接受原始令牌或 `Authorization: Bearer ...` 头 |
| `SYSRAPTOR_ALLOW_INSECURE_HTTP` | 仅适用于非本地 HTTP | 设置为 `true` 以允许内部 HTTP 端点 |
| `SYSRAPTOR_VERIFY_TLS` | 否 | 仅在实验室中使用无效证书时设置 |
| `SYSRAPTOR_TIMEOUT_SECONDS` | 否 | HTTP 超时。默认:`30` |
| `SYSRAPTOR_OUTPUT_DIR` | 否 | PDF/存档输出目录。默认:`/tmp/sysraptor-mcp` |
永远不要提交实际的 `.env` 文件。`.gitignore` 已经排除 `.env` 和 `.env.*`。
## 创建 SysReptor 令牌
在 SysReptor 中:
1. 打开 Web 界面。
2. 使用应能访问目标项目的用户登录。
3. 打开用户/个人资料菜单。
4. 找到 API 令牌、令牌、个人访问令牌或等效的设置区域。
5. 创建新令牌。
6. 复制生成的数值一次。
7. 将其存储在 `.env` 中作为 `SYSRAPTOR_TOKEN`。
建议:
- 为此 MCP 服务器使用专用令牌。
- 如果您的 SysReptor 部署支持,限制权限。
- 如果令牌粘贴到聊天记录、日志或截图中,请轮换令牌。
- 在测试后删除旧令牌。
## 启动服务器
从项目根目录:
```bash
cd /path/to/SysRaptor-MCP
python3 -m sysraptor_mcp.server
```
快速导入和工具注册检查:
```bash
PYTHONPATH=/path/to/SysRaptor-MCP python3 - <<'PY'
import anyio
from sysraptor_mcp.server import mcp
async def main():
tools = await mcp.list_tools()
print(len(tools))
for tool in tools:
print(tool.name)
anyio.run(main)
PY
```
无需 MCP 的 API 测试:
```bash
python3 - <<'PY'
from sysraptor_mcp.config import load_settings
from sysraptor_mcp.client import SysReptorClient
client = SysReptorClient(load_settings())
try:
projects = client.search_projects("")
for project in projects[:10]:
print(project.get("id"), "-", project.get("name"), "- readonly:", project.get("readonly"))
finally:
client.close()
PY
```
## 可用工具
| 工具 | 描述 |
| --- | --- |
| `sysraptor_health` | 显示加载的设置而不暴露令牌 |
| `search_projects` | 搜索项目 |
| `get_project` | 通过 `project_id` 获取完整项目 |
| `check_report` | 运行 SysReptor 报告检查 |
| `get_sections` | 列出报告章节 |
| `update_section` | 更新一个章节 |
| `update_sections` | 更新多个章节 |
| `get_findings` | 列出发现结果 |
| `get_finding` | 获取一个发现结果 |
| `create_finding` | 创建发现结果 |
| `create_finding_from_template` | 从模板创建发现结果 |
| `update_finding` | 更新现有发现结果 |
| `render_project_pdf` | 在 `SYSRAPTOR_OUTPUT_DIR` 中渲染 PDF |
| `export_project_archive` | 在 `SYSRAPTOR_OUTPUT_DIR` 中导出 `.tar.gz` 存档 |
## 安全模型
- 本地 MCP 服务器在测试期间无需 MCP 身份验证即可运行。
- 不要将此 MCP 服务器暴露在不受信任的网络中。
- 写操作需要 `project_id`。
- 写操作在写入前验证报告。
- 写操作默认为 `dry_run=true`。
- 要实际写入,请设置 `dry_run=false` 并在 `confirm_project_id` 和 `confirm_project_name` 中重复项目 ID 和项目名称。
- 发现更新还需要 `confirm_finding_id` 和 `confirm_finding_title`。
- 发现更新可以验证 `expected_finding_title`。
- 删除操作在此第一个版本中未公开。
- PDF 和存档导出被写入受控目录,而不是作为原始 MCP 二进制输出返回。
安全发现创建示例:
```json
{
"project_id": "11111111-1111-1111-1111-111111111111",
"expected_project_name": "[JOHN DOE] - Pentest Example",
"confirm_project_id": "11111111-1111-1111-1111-111111111111",
"confirm_project_name": "[JOHN DOE] - Pentest Example",
"dry_run": false,
"data": {
"title": "PT09 - Example Finding",
"retest": false,
"corrigido": "Not Compliant",
"cwe": "200",
"cvss": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N",
"summary": "- Executive summary.",
"impact": "Technical and business impact.",
"affected_components": ["https://example.com"],
"recommendation": "- Recommendation.",
"references": ["CWE-200"],
"description": "Technical evidence."
}
}
```
MCP 客户端自动规范化发现结果有效载荷。您可以直接在 `data` 中传递发现结果字段;客户端会将其转换为 SysReptor API 格式:`{"data": {...}}`。
## Codex 集成
编辑:
```text
~/.codex/config.toml
```
添加:
```toml
[mcp_servers.sysraptor]
command = "python3"
args = ["-m", "sysraptor_mcp.server"]
env = { PYTHONPATH = "/path/to/SysRaptor-MCP" }
```
重启 Codex 以使其加载新的 MCP 服务器。
预期命名空间是:
```text
mcp__sysraptor
```
示例提示:
```text
Use the sysraptor MCP and list project 11111111-1111-1111-1111-111111111111.
```
## Claude Desktop 集成
在 macOS 上,编辑:
```text
~/Library/Application Support/Claude/claude_desktop_config.json
```
示例:
```json
{
"mcpServers": {
"sysraptor": {
"command": "python3",
"args": ["-m", "sysraptor_mcp.server"],
"env": {
"PYTHONPATH": "/path/to/SysRaptor-MCP"
}
}
}
}
```
如果您不想依赖 `.env`,请将变量放在 `env` 块中:
```json
{
"mcpServers": {
"sysraptor": {
"command": "python3",
"args": ["-m", "sysraptor_mcp.server"],
"env": {
"PYTHONPATH": "/path/to/SysRaptor-MCP",
"SYSRAPTOR_SERVER": "https://sysreptor.example.com",
"SYSRAPTOR_ALLOW_INSECURE_HTTP": "false",
"SYSRAPTOR_TOKEN": "Authorization: Bearer sysreptor_YOUR_TOKEN_HERE"
}
}
}
}
```
在更改文件后重启 Claude Desktop。
## 开发
运行测试:
```bash
python3 -m unittest discover -s tests
```
验证语法:
```bash
python3 -m compileall sysraptor_mcp tests
```
## 故障排除
### `ModuleNotFoundError: No module named 'sysraptor_mcp'`
从项目根目录运行或配置 `PYTHONPATH`:
```bash
export PYTHONPATH=/path/to/SysRaptor-MCP
```
### `Refusing non-local HTTP`
端点使用 HTTP。请显式启用它:
```bash
export SYSRAPTOR_ALLOW_INSECURE_HTTP=true
```
### `401 Unauthorized`
检查:
- `SYSRAPTOR_TOKEN` 已设置。
- 令牌未被撤销。
- 令牌用户可以访问目标项目。
- 值不包括额外的 shell 引号。
### DNS 在 `curl` 中有效,但在 Python 中失败
在某些沙盒环境中,Python 可能看不到内部 DNS。请在沙盒外运行或在本地配置主机/IP 解析。
## 警告
此 MCP 操作实际报告。在任何写入之前,请确认 `project_id`、项目名称以及更新发现结果时的 `finding_id` 和预期标题。