内容
# PyRIT MCP 服务器
一个模块化的 [MCP(模型上下文协议)](https://modelcontextprotocol.io) 服务器,封装了
[微软 PyRIT](https://github.com/Azure/PyRIT) `0.14.0` 并暴露了 **31 个可组合工具**,用于**授权**的 AI 红队演练 —— 攻击执行、评分、提示转换和结果检查。
它旨在成为一个更大的自主红队平台的“武器库 + 评分实验室”组件。因为它使用标准的 MCP,因此任何代理或支持 MCP 的主机都可以驱动它 —— 例如,一个
[LangGraph](https://langchain-ai.github.io/langgraph/) 代理,它运行攻击循环并存储
发现结果。 与其使用单一的整体端点,它提供了小型、独立的工具,代理可以在 ReAct 循环中自由组合。
> ⚠️ **仅限授权使用。** 本项目用于安全研究、CTF 和您拥有或明确允许测试的系统的红队演练。未经书面授权,不得将其用于第三方系统。
---
## 架构
```
任意 MCP 代理/主机 ──► PyRIT MCP 服务器(本项目) ──► 目标 LLM(s)
(大脑 — 例如 (攻击 + 评分,31 个工具) (受害者/对抗)
LangGraph、Claude
桌面、自定义循环)
```
```
pyrit_mcp_server/
├── main.py # FastMCP 实例 + 注册所有工具模块
├── __main__.py # python -m pyrit_mcp_server
├── core/
│ ├── memory.py # CentralMemory 单例(幂等,内存 SQLite)
│ ├── targets.py # TargetRegistry — 创建/获取/删除 OpenAI 兼容目标
│ └── jobs.py # JobManager — 通过 asyncio.Task 进行后台执行
└── tools/
├── targets.py # 3 个工具
├── attacks.py # 11 个工具(4 个单回合 + 4 个多回合 + 3 个作业管理)
├── scoring.py # 7 个工具
├── converters.py # 3 个工具
├── scenarios.py # 2 个工具
├── datasets.py # 2 个工具
└── memory_tools.py# 3 个工具
```
### 关键设计决策
- **多回合攻击在后台运行。** 否则,MCP 工具调用将超时,因此
`red_team`、`crescendo`、`pair` 和 `tap` 立即返回一个 `job_id` 并作为
`asyncio.Task` 运行。 使用 `get_job_status` / `list_jobs` 进行轮询。
- **代币成本防护。** 在每次攻击时,都会对 (`MAX_TURNS=30`、`MAX_TREE_WIDTH=10`、
`MAX_TREE_DEPTH=15`、`MAX_BRANCHING=5`) 进行硬限制,以防止失控。
`tap` 还返回估计的 LLM 调用次数。
- **两阶段混合评分。** `score_hybrid` 首先运行快速静态检查,然后仅在触发时使用
LLM 进行验证 —— 减少假阳性。
- **设计上使用短暂内存。** PyRIT 自己的存储是内存 SQLite(`:memory:`);持久性
预期在主机平台中,而不是在这里。
---
## 31 个工具
### 目标(3)
| 工具 | 描述 |
|------|-------------|
| `create_target` | 创建一个 OpenAI 兼容的聊天目标(端点、模型、api_key) |
| `list_targets` | 列出所有已注册的目标 |
| `remove_target` | 删除目标 |
### 攻击 — 单回合、同步(4)
| 工具 | 描述 |
|------|-------------|
| `send_prompt` | 直接发送提示(PromptSendingAttack) |
| `run_skeleton_key_attack` | Skeleton Key 越狱 |
| `run_flip_attack` | 基于 Flip 的越狱 |
| `run_role_play_attack` | 角色扮演越狱(需要对抗性 LLM + 场景) |
### 攻击 — 多回合、后台作业(4)
| 工具 | 描述 |
|------|-------------|
| `run_red_team_attack` | 对抗性 LLM 迭代生成提示 |
| `run_crescendo_attack` | 逐渐升级攻击 |
| `run_pair_attack` | PAIR — Prompt Automatic Iterative Refinement |
| `run_tap_attack` | TAP — Tree of Attacks with Pruning(最昂贵) |
### 攻击 — 作业管理(3)
| 工具 | 描述 |
|------|-------------|
| `get_job_status` | 查询后台作业的状态/结果 |
| `list_jobs` | 列出所有作业 |
| `wait_for_job` | 阻塞直到作业完成(或 `timeout_seconds`),每 `poll_interval_seconds` 秒轮询一次 |
### 评分(7)
| 工具 | 类型 | 描述 |
|------|------|-------------|
| `score_likert` | LLM | 13 个类别,浮点数 0–1(伤害、暴力、网络、…) |
| `score_true_false` | LLM | 5 个问题类型(task_achieved、prompt_injection、…) |
| `score_refusal` | LLM | 检测 AI 是否拒绝 |
| `score_substring` | 非 LLM | 子字符串匹配 |
| `score_regex` | 非 LLM | 正则表达式模式匹配 |
| `score_security` | 非 LLM | 6 个检查:xss、sql_injection、shell_command、path_traversal、credential_leak、markdown_injection |
| `score_hybrid` | 混合 | 静态检查 + LLM 验证(减少假阳性) |
### 转换器(3)
| 工具 | 描述 |
|------|-------------|
| `convert_prompt` | 使用一个转换器(base64、rot13、leetspeak、…)转换文本 |
| `chain_convert` | 顺序应用多个转换器 |
| `list_converters` | 列出可用的转换器 |
### 场景(2)
| 工具 | 描述 |
|------|-------------|
| `list_scenarios` | 列出 PyRIT 内置场景(AIRT、Garak、Foundry) |
| `run_scenario` | 运行内置场景(支持 `max_objectives`) |
### 数据集(2)
| 工具 | 描述 |
|------|-------------|
| `list_seed_datasets` | 列出 PyRIT YAML 种子数据集 |
| `load_objectives` | 加载种子目标(带有过滤) |
### 内存(3)
| 工具 | 描述 |
|------|-------------|
| `get_attack_history` | 查询攻击历史 |
| `get_conversation` | 通过 ID 获取对话 |
| `export_results` | 将结果导出为 JSON |
---
## 要求
- Python **3.11+**
- `pyrit==0.14.0`、`mcp>=1.27`(自动安装)
- 一个 OpenAI 兼容的端点用于 LLM 目标 —— 例如 OpenAI API 或本地
[Ollama](https://ollama.com) 服务器(`http://127.0.0.1:11434/v1`)。
## 安装
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
# 配置密钥
cp .env.example .env # 然后编辑 .env 并添加您的 API 密钥(s)
```
## 运行
```bash
# 作为已安装的入口点
pyrit-mcp-server
# 或作为模块
python -m pyrit_mcp_server
```
服务器通过 stdio 使用 MCP。 示例客户端(例如 Claude Desktop)配置:
```json
{
"mcpServers": {
"pyrit": {
"command": "/path/to/.venv/bin/python",
"args": ["-m", "pyrit_mcp_server"]
}
}
}
```
### 典型流程
1. 为受害者创建目标(和一个用于对抗性/评分 LLM 的目标)。
2. 运行攻击 — `send_prompt`(同步)或 `run_crescendo_attack`(返回 `job_id`)。
3. 对于多回合作业,轮询 `get_job_status` 直到 `completed` / `failed`。
4. 使用 `score_likert`、`score_refusal`、`score_security` 等对响应进行评分。
5. 使用 `get_attack_history` / `export_results` 进行检查。
---
## 示例
[`examples/crescendo_attack.py`](examples/crescendo_attack.py) 是一个完整的、可运行的 MCP 客户端,
它驱动服务器端到端地针对本地 [Ollama](https://ollama.com) 模型
(`llama3.2:1b`):它启动两个目标(受害者 + 对抗性),启动 `run_crescendo_attack`,
轮询 `get_job_status` 直到作业完成,然后通过 `get_attack_history` 拉取结果并
使用 `score_security` 对最后一个响应进行评分。
```bash
# 需要在 http://127.0.0.1:11434 上运行本地 Ollama 服务器
.venv/bin/python examples/crescendo_attack.py
```
它兼作烟雾测试:如果它运行完成并打印结果,则核心
目标 → 攻击 → 作业 → 历史 → 评分路径正在工作。 真实 OpenAI 目标的 API 密钥从环境中读取
(`OPENAI_API_KEY`)—— 永远不要硬编码它们。
---
## 已知限制
- **并发多回合争用** — 同时启动所有四个多回合攻击可能会使作业卡在 `running` 状态。
依次运行它们。
- **私有属性耦合** — 一些代码路径深入 PyRIT 内部
(`OpenAIChatTarget._endpoint/_api_key`,场景的 `_default_dataset_config`)。 这些可能会在未来的 PyRIT 升级中中断。
- **无作业清理** — 已完成的作业/任务在进程生命周期内保留(仅内存)。
- **`run_scenario` `max_objectives`** 得到遵守,通过限制场景的默认数据集大小;
不公开此配置的场景会静默忽略限制。
---
## 许可证
在 [MIT License](LICENSE) 下发布。 在微软的 [MIT] 许可下构建(MIT)