INFOKOM-KI/blue-team-soc-mcp
GitHub: INFOKOM-KI/blue-team-soc-mcp
面向蓝队 SOC 分析师的防御性安全 MCP 服务器,集成 Wazuh SIEM、主机取证和威胁情报,为 AI 客户端提供 48 个安全调查与监控工具。
Stars: 0 | Forks: 0
# 蓝队 MCP Server (Wazuh SIEM)
一个用于 Claude Desktop 或任何 MCP 客户端的防御性安全 MCP server —— 它是 [mcp-kali-server](https://www.kali.org/blog/kali-llm-claude-desktop/) 的防御者对应版本。
如果说 Kali Linux 为 Claude 提供了攻击工具(nmap、gobuster、sqlmap),那么这个工具则为 Claude 提供了**蓝队 / SOC 分析师工具**,用于调查、监控和加固您的系统。
**程序员** : `NAuliajati` (`csirt[at]tangerangkota[.]go[.]id`)
## **重新编写** : `https://github.com/not2cleverdotme/blue-team-mcp`
## 架构
`blue_team_server.py` 是一个**单一、统一的 MCP server**,包含 48 个工具,涵盖主机取证、Wazuh SIEM、威胁情报和 3-Sum APT 关联引擎。它支持两种传输方式:
| 传输方式 | 用例 | MCP 客户端连接 |
|---|---|---|
| `stdio` | 本地子进程或 SSH 管道 | 直接连接 (Claude Desktop stdio) |
#### | `streamable_http` | 远程 HTTP 服务 | `http://:/mcp` |
```
┌──────────────────────────────────┐
│ blue_team_server.py │
│ 48 tools · 1 file · 2 transports │
│ │
│ ┌────────────────────────────┐ │
│ │ Host Forensics (26 tools) │ │
│ │ • Log analysis │ │
│ │ • Network monitoring │ │
│ │ • Fail2Ban management │ │
│ │ • File integrity │ │
│ │ • System hardening (Lynis) │ │
│ │ • User/session monitoring │ │
│ │ • Process & cron analysis │ │
│ │ • System health │ │
│ └────────────────────────────┘ │
│ ┌────────────────────────────┐ │
│ │ Wazuh SIEM (14 tools) │ │
│ │ • Agent inventory & status │ │
│ │ • Security alerts │ │
│ │ • Manager logs │ │
│ │ • OpenSearch indexer query │ │
│ │ • Email/domain compromise │ │
│ │ • Alert timeline │ │
│ │ • Attack velocity │ │
│ │ • 3-Sum APT correlation │ │
│ └────────────────────────────┘ │
│ ┌────────────────────────────┐ │
│ │ Threat Intel (8 tools) │ │
│ │ • AbuseIPDB IP reputation │ │
│ │ • VirusTotal hash & domain │ │
│ │ • CrowdSec CTI (2 tools) │ │
│ │ • GreyNoise Community │
│ │ • Netra multi-source │ │
│ └────────────────────────────┘ │
└──────────────────────────────────┘
│ │
stdio streamable_http
```
#### (默认) :8000/mcp
### 两种部署模式
#### **模式 1 — 通过 SSH 本地连接 (stdio):** Claude Desktop 通过 SSH 连接;服务器作为子进程在防御者主机上运行。
┌─────────────────────┐ SSH + stdio ┌─────────────────────────┐
│ 你的工作站 │ ────────────────────── │ 防御者主机 │
│ Claude Desktop │ │ Ubuntu/Debian 服务器 │
└─────────────────────┘ │ blue_team_server.py │
#### └─────────────────────────┘
#### **模式 2 — 远程服务 (Streamable HTTP):** 服务器作为持久化 HTTP 服务运行。任何 MCP 客户端都可以通过网络连接 —— 无需 SSH。
┌─────────────────────┐ Streamable HTTP ┌─────────────────────────┐
│ 任何 MCP 客户端 │ ────────────────────── │ 防御者主机 │
│ (Claude Desktop, │ http://:8000 │ systemd 服务: │
│ 自定义客户端) │ │ blue_team_server.py │
└─────────────────────┘ │ --transport http │
#### └─────────────────────────┘
| 文件 | 工具 | 何时使用 |
|---|---|---|
## | `blue_team_server.py` | **全部 48 个工具** | **推荐** —— 完整功能、凭据剥离、PII 脱敏 |
## 性能架构
该套件经过了重构,旨在支持超越单分析师交互式分流的**批量数据处理和并发工作负载**。套件中的每个服务器现在都共享相同的性能模式。
### Wazuh 服务器 (`blue_team_server.py`)
#### 基于游标的分页 (无硬性上限的批量数据)
所有 Wazuh 工具都支持通过 base64 编码的 JSON token 进行迭代游标分页。每一页都会返回一个 `next_cursor`;将其作为 `cursor` 参数传回以获取下一页。当数据集提取完毕时,`next_cursor` 将为 `null`。
| 工具 | 分页机制 | 每页最大数量 | 游标结构 |
|---|---|---|---|
| `wazuh_alert_aggregate_analysis` | OpenSearch `size:0` 聚合(服务器端)—— 涵盖所有匹配的文档,**没有文档数量限制** | ∞ (涵盖所有匹配文档) | n/a — 无需游标 |
| `wazuh_alert_dsl_query` | OpenSearch `size:0` 聚合(用户提供的 DSL)—— 涵盖所有匹配的文档 | ∞ (涵盖所有匹配文档) | n/a — 无需游标 |
| `wazuh_alert_focused_crawl` | OpenSearch `search_after` (排序键遍历) | 200 | `{"search_after": []}` |
| `blueteam_wazuh_indexer_search` | OpenSearch `search_after` (排序键遍历) —— 还支持**自动分页**(通过 `max_scanned` 进行聚合或取证) | 10,000 | `{"search_after": []}` |
| `wazuh_wazuh_indexer_search` | `blueteam_wazuh_indexer_search` 的别名 —— 行为一致 | 10,000 | `{"search_after": []}` |
| `blueteam_wazuh_agents` | Wazuh API `offset`/`limit` | 10,000 | `{"offset": N}` |
| `blueteam_wazuh_manager_logs` | Wazuh API `offset`/`limit` | **500** (自动限制上限) | `{"offset": N}` |
| `blueteam_wazuh_alerts` | 本地 `alerts.json` 中的行偏移量 | 2,000 | `{"scanned": N}` |
| `wazuh_email_lookup` | OpenSearch `search_after` (排序键遍历) | 1,000 | `{"search_after": []}` |
| `wazuh_domain_lookup` | OpenSearch `search_after` (排序键遍历) —— 还支持通过 `max_scanned` **自动分页** | 10,000 | `{"search_after": []}` |
| `wazuh_compromised_emails_analysis` | OpenSearch `search_after` (排序键遍历) —— 每批次内部自动分页 | 1,000 | `{"search_after": []}` |
| `wazuh_alert_timeline` | OpenSearch `date_histogram` (size:0,服务器端) | ∞ (涵盖所有匹配文档) | n/a — 无需游标 |
| `wazuh_attack_velocity` | OpenSearch `date_histogram` (size:0,服务器端) | ∞ (涵盖所有匹配文档) | n/a — 无需游标 |
#### **Agent 工作流:**
1. 调用工具 (不带游标) → 第 1 页 + next_cursor
2. 调用工具(cursor=next_cursor) → 第 2 页 + next_cursor
#### 3. 重复操作直到 next_cursor 为 null —— 获取所有结果
所有输入 schema 都是**向后兼容的** —— `cursor` 是可选的,且默认值保持不变。
#### 相对时间表达式
所有 Wazuh 工具除了支持 ISO 8601 字符串外,还支持在 `since`/`until` 参数中使用**相对时间表达式**:
| 表达式 | 含义 | 示例 |
|---|---|---|
| `Ns` | N 秒前 | `15s` — 过去 15 秒 |
| `Nm` | N 分钟前 | `5m` / `30m` — 过去 5 / 30 分钟 |
| `Nh` | N 小时前 | `1h` / `24h` / `6h` — 过去 N 小时 |
| `Nd` | N 天前 | `1d` / `7d` / `30d` — 过去 N 天 |
| `Nw` | N 周前 | `1w` / `4w` — 过去 N 周 |
| ISO 8601 | 绝对时间戳 (直接透传) | `2026-07-07T17:00:00Z` |
受支持的工具:`blueteam_wazuh_alerts`、`blueteam_wazuh_indexer_search`、`wazuh_email_lookup`、`wazuh_domain_lookup`、`wazuh_compromised_emails_analysis`、`wazuh_alert_timeline`、`wazuh_attack_velocity`。
#### 通过 `search_after` 分页 (`blueteam_wazuh_indexer_search`)
Wazuh Indexer 搜索工具已从基于偏移量的分页(`from`/`size`)迁移至 OpenSearch 的 `search_after` 游标,从而消除了 10,000 个文档的 `max_result_window` 上限:
- **排序锚点**:结果按 `@timestamp`(升序)排序,并以 `_id` 作为确定性的决胜关键。这保证了每个文档都有一个唯一、稳定的排序键。
- **游标遍历**:`next_cursor` 对当前页面中最后一个文档的原始排序值进行了编码。在下一次调用中,这些值将作为 `search_after` 数组发送 —— OpenSearch 将从上一页结束的确切位置继续扫描。
- **截断元数据**:响应将 `total` 暴露为一个对象 `{"value": , "relation": <"eq"|"gte">}`。当 `relation` 为 `"gte"`(大于或等于)时,LLM 客户端便知道实际的文档数量超出了报告的上限,并会继续分页。
- **自然终止**:当返回的文档数量严格小于所请求的 `limit` 时,`next_cursor` 将变为 `null` —— 无需根据受限的 `total.value` 进行计算。
#### 自动上限保护机制 (自愈防御)
Wazuh Manager API (`/manager/logs`) 会以 HTTP 400 拒绝 `limit > 500` 的请求。Pydantic 输入模型允许高达 1,000 的限制,这造成了一个缺口,使得 LLM 客户端可能会无意中构造出会导致失败的请求。`blueteam_wazuh_manager_logs` 工具现在会在 HTTP 调用之前应用内联安全限制:
```
#### wazuh_safe_limit = min(params.limit, 500)
This silently caps the value to 500 at the application layer. The client still receives the full pagination metadata (`next_cursor`, `total`) and can iterate through all results without ever triggering a validation error.
In addition, the global `_handle_api_error` helper returns a specific, actionable message for HTTP 400 (Bad Request) advising the caller to reduce limit size or switch filter parameters. This guard is deployed across all three server files.
#### 远程架构回退 (`blueteam_wazuh_alerts`)
#### 当 Wazuh Manager 在远程主机上运行时,本地 `alerts.json` 文件不存在。工具不会返回通用的 OS 错误,而是返回严格的元数据指令:
[CRITICAL METADATA] This tool is disabled because the Wazuh Manager
is running on a remote host. DO NOT RETRY this local tool. You MUST
immediately switch to 'blueteam_wazuh_indexer_search' or
#### 'blueteam_wazuh_manager_logs' 以查询安全事件。
This prevents the LLM client from wasting context loops retrying a fundamentally unavailable data path and directs it toward the correct remote-capable alternatives.
#### 具有连接池的共享 HTTP 客户端
Four dedicated `httpx.AsyncClient` instances, one per SSL trust domain:
| Client | `verify` | Endpoints |
|---|---|---|
| `_get_http_client()` | `True` (public CA) | AbuseIPDB, VirusTotal, CrowdSec CTI, GreyNoise |
| `_get_netra_http_client()` | `NETRA_VERIFY_SSL` (default `false`) | Netra Threat Intelligence (:8013) |
| `_get_wazuh_client()` | `WAZUH_API_VERIFY_SSL` (default `true`) | Wazuh Manager API (port 55000) |
| `_get_indexer_client()` | `WAZUH_INDEXER_VERIFY_SSL` (default `true`) | OpenSearch (port 9200) |
Each client pools connections independently (20 keepalive / 100 max for public APIs; 5 / 20 for Netra staging; 10 / 50 for Wazuh and Indexer). SSL verification is set at client creation — no per-request `verify=` keyword arguments.
#### Wazuh JWT Token 缓存
Cached for **300 seconds (5 minutes)** with automatic cache clearance on authentication failure.
#### 非阻塞子进程执行
`_run_async()` wraps synchronous subprocess calls in `asyncio.to_thread()`, preventing 30 tools from blocking the event loop under concurrent load.
### CrowdSec CTI — 内存 TTL 缓存 + 批量查找
CrowdSec IP reputation and GreyNoise context lookups are integrated directly into the unified server (`blue_team_server.py`). All functionality is available through the main server — no standalone files needed.
#### 内存缓存(仅限 CrowdSec CTI)
Per `SKILLS.md` §3.1, CrowdSec CTI responses are cached in-process with configurable TTL:
- **Default TTL**: 900 seconds (15 minutes) — configurable via `CROWDSEC_CACHE_TTL`
- **Cache scope**: per-IP, per-path — identical requests hit the cache; different IPs do not
- **Error exclusion**: HTTP 4xx/5xx responses are NEVER cached (structurally excluded — `raise_for_status()` throws before the cache-store point)
- **Cache hit**: returns stored data immediately with no HTTP call
- **Cache expired**: stale entry is deleted, fresh HTTP call is made, result is re-cached
#### 并行批量 IP 查找(仅限 CrowdSec)
`crowdsec_ip_reputation_bulk` executes up to 10 IP lookups concurrently via `asyncio.gather()` bounded by an `asyncio.Semaphore`:
- **Default concurrency**: 5 (configurable via `BLUETEAM_BULK_CONCURRENCY`)
- **Error isolation**: per-IP failure does not affect sibling lookups
- **Latency**: ~5× speedup vs serial iteration
### 外部 API 弹性
All external API calls (CrowdSec CTI, Wazuh Manager, Wazuh Indexer, Argus) use a simple try/except pattern with specific exception handling — no circuit breaker state machine needed for a local MCP server.
```python
try:
data = await _do_request()
except httpx.HTTPStatusError as e:
return {"error": f"API error: {e.response.status_code}"}
except httpx.TimeoutException:
#### return {"error": "Request timed out"}
**Per-service caching** (CrowdSec CTI only): successful responses are cached in-memory with a configurable TTL (`CROWDSEC_CACHE_TTL`, default 900s). Cache hits skip the HTTP call entirely — no exception handling needed. Error responses are never cached.
### 凭据和密钥脱敏(输出清理)
Ported from the Wazuh-MCP-Server output sanitization pattern. Before any Wazuh alert or traffic capture data reaches the LLM context, `_redact_alert_data()` strips credentials, API keys, and secret material from `full_log` and other text fields.
**Applied automatically** to ALL tool outputs that may contain sensitive data — Wazuh alerts, log readers, user lists, SSH keys, cron jobs, process lists, system health, and network captures. Six-layer pipeline with per-layer env var control:
- Layer 1 (MANDATORY): Credential stripping (15 regex patterns, never bypassable)
- Layer 2: Email redaction (`BLUETEAM_REDACT_EMAILS`, default `true`)
- Layer 3: Internal IP masking (`BLUETEAM_REDACT_PII`, default `true`)
- Layer 4: Domain/hostname masking (`BLUETEAM_REDACT_DOMAINS`, default `true`)
- Layer 5: Log location masking (`BLUETEAM_REDACT_LOCATIONS`, default `true`)
- Layer 6: User-agent truncation (`BLUETEAM_REDACT_UAS`, default `true`)
Per-call override: `bypass_redaction=True` skips all optional Layers 2-6.
**Stripping rules (15 credential regex patterns + 4 PII/mask layers, applied in order):**
| Category | Patterns detected | Replacement |
|----------|------------------|-------------|
| Auth headers | `Authorization: Bearer `, `Authorization: Basic ` | ``, `` |
| API keys | `x-api-key: `, `api_key=` | `` |
| JWT tokens | 3-segment base64url tokens starting with `eyJ` | `` |
| Private keys | PEM blocks (`-----BEGIN ... PRIVATE KEY-----`) | `` |
| Cloud keys | AWS (`AKIA...`), Google (`AIza...`) | ``, `` |
| Payment keys | Stripe (`sk_live_...`, `sk_test_...`) | `` |
| VCS tokens | GitHub (`ghp_...`, `gho_...`, etc.), GitLab (`glpat-...`) | ``, `` |
| AI API keys | Anthropic (`sk-ant-...`), OpenAI (`sk-proj-...`) | `` |
| Messaging | Slack (`xoxb-...`, `xoxp-...`, etc.) | `` |
| Passwords | `password=`, `passwd=`, `pwd=`, `secret=` params | `password=` |
| **Layer 4 — Domains** | `data.domain`, standalone hostnames in `full_log` | Subdomain masked (`e-***i.tangerangkota.go.id`), parent+TLD visible |
| **Layer 5 — Locations** | `location` field (file paths) | `.../access_log [h:a3f8c2]` (leaf + forensic hash) |
| **Layer 6 — User agents** | `data.user_agent`, UA strings in `full_log` | Truncated to 80 chars (OS/browser preserved) |
The credential stripping (Layer 1) runs **before** all other masking inside `_redact_alert_data()`. All six layers are independently controlled by their `BLUETEAM_REDACT_*` env var. The original alert data on disk is never modified.
### GreyNoise Community — 免费版,无需 API Key
## GreyNoise 上下文查找 (`greynoise_ip_context`) 已集成到统一服务器中,无需身份验证。Community API 将 IP 分类为互联网扫描器(噪声)、业务服务(RIOT)或两者兼有——并在 Markdown 输出中提供解释指南。
## 配置参考
All environment variables accepted by the suite. Variables marked **[unified]** apply to all three servers; others are server-specific.
### 性能与限制 [unified]
| Variable | Default | Description |
|---|---|---|
| `BLUETEAM_CHARACTER_LIMIT` | `100000` | Maximum characters per tool response before truncation |
| `WAZUH_INDEXER_MAX_SIZE` | `10000` | Max documents per page in Wazuh Indexer search queries |
| `BLUETEAM_ALLOW_UNTRUNCATED` | `false` | ADMIN GATE — enables `bypass_character_limit` and `include_all_docs` for forensic deep-dives |
### CrowdSec CTI 缓存
| Variable | Default | Description |
|---|---|---|
| `CROWDSEC_CACHE_TTL` | `900` | In-memory cache TTL in seconds for CrowdSec CTI responses |
### Wazuh API
| Variable | Default | Description |
|---|---|---|
| `WAZUH_API_URL` | (empty) | Wazuh Manager API base URL (`https://:55000`) |
| `WAZUH_API_USER` | `wazuh-wui` | Wazuh API username |
| `WAZUH_API_PASSWORD` | (empty) | Wazuh API password |
| `WAZUH_API_VERIFY_SSL` | `true` | TLS certificate verification for Wazuh API |
### Wazuh Indexer (OpenSearch)
| Variable | Default | Description |
|---|---|---|
| `WAZUH_INDEXER_URL` | (empty) | OpenSearch base URL (`https://:9200`) |
| `WAZUH_INDEXER_USER` | `admin` | OpenSearch username |
| `WAZUH_INDEXER_PASSWORD` | (empty) | OpenSearch password |
| `WAZUH_INDEXER_VERIFY_SSL` | `true` | TLS certificate verification for indexer |
| `WAZUH_INDEXER_MAX_SIZE` | `10000` | Max documents per page in `_wazuh_indexer_search` |
### 威胁情报 API
| Variable | Default | Description |
|---|---|---|
| `CROWDSEC_API_KEY` | (empty) | CrowdSec CTI API key (required for CrowdSec tools) |
| `ABUSEIPDB_API_KEY` | (empty) | AbuseIPDB API key |
| `VIRUSTOTAL_API_KEY` | (empty) | VirusTotal API key |
| `NETRA_API_KEY` | (empty) | Netra Threat Intelligence API key |
| `ARGUS_API_KEY` | (empty) | Argus Threat Intelligence API key (TangerangKota-CSIRT) |
| `ARGUS_BASE_URL` | (empty) | Argus Threat Intelligence API base URL |
| `NETRA_VERIFY_SSL` | `false` | TLS certificate verification for Netra API (set `true` for production) |
### 传输和部署
| Variable | Default | Description |
|---|---|---|
| `MCP_TRANSPORT` | `stdio` | Transport mode: `stdio` or `streamable_http` |
| `MCP_HOST` | `127.0.0.1` | Bind address for Streamable HTTP transport |
| `MCP_PORT` | `8000` | Bind port for Streamable HTTP transport |
| `BLUE_TEAM_MCP_SERVER_NAME` | `blue_team_mcp` | Server name reported to MCP clients — use lowercase to avoid LLM casing mismatches |
| `LOG_LEVEL` | `INFO` | Python logging level |
### 安全和审计
| Variable | Default | Description |
|---|---|---|
| `BLUETEAM_AUDIT_LOG` | (empty) | Path to audit log file |
| `BLUETEAM_RATE_LIMIT` | `0` (disabled) | Max tool calls per minute |
| `BLUETEAM_ALLOWED_PATHS` | `/var:/etc:/home:/opt:/usr` | Colon-separated path allowlist for file tools |
| `BLUETEAM_CAPTURE_DIR` | `/tmp` | Output directory for `blueteam_capture_traffic` pcap files |
| `BLUETEAM_REDACT_PII` | `true` | Mask internal IPs (RFC1918, loopback, IPv6 ::1) |
| `BLUETEAM_REDACT_EMAILS` | `true` | Hash email local-parts in alert payloads (domain preserved) |
| `BLUETEAM_REDACT_DOMAINS` | `true` | Mask subdomains in `data.domain` and `full_log` |
| `BLUETEAM_REDACT_LOCATIONS` | `true` | Strip directory tree from `location` field |
| `BLUETEAM_REDACT_UAS` | `true` | Truncate `data.user_agent` to 80 chars |
## | `BLUETEAM_REDACT_SALT` | (hostname-derived) | 用于确定性取证电子邮件/路径哈希的 Salt |
## 快速开始
### 1. 在你的 Defender 主机上 (Ubuntu/Debian)
```bash
git clone https://github.com/INFOKOM-KI/blue-team-soc-mcp.git
cd blue-team-mcp
#### sudo bash setup.sh
The setup script will:
- Install system packages (tcpdump, fail2ban, lynis, rkhunter, chkrootkit, and Python 3 toolchain)
- Create a Python virtualenv with MCP dependencies at `/opt/blue-team-mcp/venv`
- Copy all server files, `requirements.txt`, and `README.md` to `/opt/blue-team-mcp/`
- Place the `mcp-server-blueteam` wrapper in `/usr/local/bin`
- Grant tcpdump network capture capabilities
### 2. 设置 API Keys 和 Wazuh(可选但推荐)
Edit the config file created by setup:
```bash
#### sudo nano /opt/blue-team-mcp/config.env
Uncomment and set the variables you need:
- **CROWDSEC_API_KEY** — https://www.crowdsec.net/en/user/profile (free CTI tier; powers the `crowdsec_ip_reputation` tools)
- **ABUSEIPDB_API_KEY** — https://www.abuseipdb.com/account/api
- **VIRUSTOTAL_API_KEY** — https://www.virustotal.com/gui/my-apikey
- **WAZUH_API_URL** — `https://:55000` (if Wazuh is on same host) or `https://:55000`
- **WAZUH_API_USER** — `wazuh-wui` (Wazuh Docker default)
- **WAZUH_API_PASSWORD** — e.g. `MyS3cr37P450r.*-` (Wazuh Docker default)
- **WAZUH_API_VERIFY_SSL** — `false` for self-signed certs
- **WAZUH_INDEXER_URL** — `https://:9200` (if on same host) or `https://:9200`
- **WAZUH_INDEXER_USER** — `admin` (indexer default)
- **WAZUH_INDEXER_PASSWORD** — indexer password (often different from Wazuh API)
- **WAZUH_INDEXER_VERIFY_SSL** — `false` for self-signed certs
**GreyNoise Community requires no API key** — the `greynoise_ip_context` tool works out of the box (rate-limited per GreyNoise's fair-use policy).
**Note:** The indexer (port 9200) stores HYDRA-DC Windows events in OpenSearch. Its password may differ from the Wazuh API. For Wazuh Docker, check your `docker-compose` or `.env` for `OPENSEARCH_INITIAL_ADMIN_PASSWORD`. If adding Indexer support to an existing install, re-run `setup.sh` to update the wrapper with the new exports.
### 3. 配置 Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS).
**Option A — Local deployment (SSH + stdio):**
```json
{
"mcpServers": {
"blue-team-mcp": {
"command": "ssh",
"args": [
"-i", "/Users/defence/.ssh/ubuntu-soc",
"soc-admin@192.168.153.5",
"mcp-server-blueteam"
],
"transport": "stdio"
}
}
#### }
**Option B — Remote service (Streamable HTTP, recommended for shared SOC use):**
First start the server on the defender host:
```bash
#### python3 blue_team_server.py --transport streamable_http --host 0.0.0.0 --port 8000
Then point Claude Desktop at it:
```json
{
"mcpServers": {
"blue-team-mcp": {
"url": "http://192.168.153.5:8000/mcp",
"transport": "streamable-http"
}
}
#### }
Replace `192.168.153.5` with the IP reachable from your workstation (`192.168.153.5` for NAT, `172.16.101.5` for LAB).
Restart Claude Desktop. You should see all 48 blue-team-mcp tools available.
### 4. 远程服务部署 (systemd)
For a persistent remote service accessible to multiple MCP clients, run `blue_team_server.py` as a systemd unit:
```ini
# /etc/systemd/system/blue-team-mcp.service
[Unit]
Description=Blue Team MCP Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/blue-team-mcp
EnvironmentFile=/opt/blue-team-mcp/config.env
Environment="MCP_TRANSPORT=streamable_http"
Environment="MCP_HOST=0.0.0.0"
Environment="MCP_PORT=8000"
ExecStart=/usr/local/bin/mcp-server-blueteam
Restart=on-failure
RestartSec=5
[Install]
#### WantedBy=multi-user.target
```bash
sudo systemctl daemon-reload
sudo systemctl enable blue-team-mcp
sudo systemctl start blue-team-mcp
#### sudo systemctl status blue-team-mcp (确保服务正在运行)
The server is now reachable at `http://:8000/mcp` (Streamable HTTP).
Transport can be controlled via environment variables instead of CLI flags:
- `MCP_TRANSPORT` — `stdio` (default) or `streamable_http`
- `MCP_HOST` — bind address (default `127.0.0.1`; use `0.0.0.0` for remote access)
## - `MCP_PORT` — 绑定端口(默认为 `8000`)
## 可用工具
All tools below are registered on `blue_team_server.py`. Tools not requiring a specific API key work out of the box; optional API keys unlock additional capabilities as noted.
### 日志分析
| Tool | Description |
|------|-------------|
| `blueteam_read_auth_log` | SSH/sudo/PAM events from auth.log |
| `blueteam_read_syslog` | General system events |
| `blueteam_read_web_log` | nginx/Apache access & error logs |
| `blueteam_journalctl` | Query any systemd unit's journal |
### 网络监控
| Tool | Description |
|------|-------------|
| `blueteam_list_listening_ports` | All open/listening ports with process |
| `blueteam_list_connections` | Established TCP connections |
| `blueteam_capture_traffic` | Live packet capture via tcpdump |
### Wazuh SIEM
*All fourteen tools support cursor-based pagination — see [Cursor-Based Pagination](#cursor-based-pagination-bulk-data-without-hard-caps). `blueteam_wazuh_indexer_search`, `wazuh_domain_lookup`, and `wazuh_alert_focused_crawl` also support **auto-pagination** via the `max_scanned` parameter. `blueteam_wazuh_indexer_search` additionally supports **forensic mode** (`include_all_docs=True`) when `BLUETEAM_ALLOW_UNTRUNCATED=true`.*
| Tool | Description |
|------|-------------|
| `blueteam_wazuh_agents` | List all Wazuh agents — paginated via `cursor`/`limit` (up to 10,000/page) |
| `blueteam_wazuh_agents_summary` | Agent count by status (active/disconnected) |
| `blueteam_wazuh_manager_logs` | Manager daemon logs — paginated via `cursor`/`limit` (up to 1,000/page) |
| `blueteam_wazuh_alerts` | Security alerts from alerts.json — paginated via `cursor`/`limit` (up to 2,000/page) |
| `blueteam_wazuh_indexer_search` | Query OpenSearch for agent alerts/events — paginated via `cursor`/`limit` (up to 10,000/page). Set `max_scanned` for auto-pagination. |
| `wazuh_alert_aggregate_analysis` | 🆕 **Tier 1** — Full-period statistical analysis via `size:0` OpenSearch aggregations. Modes: topology, anomaly, correlation, trend, summary. **No document limit** |
| `wazuh_alert_dsl_query` | 🆕 **Tier 2** — Power-user escape hatch: submit raw OpenSearch DSL with `size:0` enforced. For custom aggregations not covered by Tier 1 |
| `wazuh_alert_focused_crawl` | 🆕 **Tier 3** — Surgical drill-down: retrieve representative alert samples for specific hot spots identified by Tiers 1 & 2 |
| `wazuh_email_lookup` | Find top-N compromised email addresses by scanning `full_log` + `data.account` fields (auto-paginates up to `max_scanned`) |
| `wazuh_domain_lookup` | Search alerts by domain name with cursor pagination and source IP aggregation. Set `max_scanned` for auto-pagination. |
| `wazuh_compromised_emails_analysis` | Correlate compromised emails with attacker IPs, optional Netra enrichment (auto-paginates per batch) |
| `wazuh_alert_timeline` | Time-bucketed alert aggregation using OpenSearch `date_histogram` — covers ALL matching alerts |
| `wazuh_attack_velocity` | Compare two time windows to detect attack acceleration/deceleration — covers ALL matching alerts |
| `three_sum_correlation` | **3-Sum APT Detection Engine**: Advanced correlation applying the 3-Sum logical concept to Wazuh telemetry. Engine A (Multi-IoC Risk Thresholding) finds IPs appearing in 3 alert categories, sums risk scores, flags ≥10. Engine B (Volumetric Z-Score) detects simultaneous volumetric anomalies across 3 sources when all Z ≥ 2.5 in the same minute. Opt-in enrichments: `use_geo` (GeoLocation hints), `use_domain` (domain hints), `use_mitre` (MITRE ATT&CK tactic refinement). Category B defaults include `spam`/`postfix` groups. Returns structured JSON with per-engine triggers and summary. |
### 威胁情报
| Tool | Description |
|------|-------------|
| `blueteam_lookup_ip_abuseipdb` | IP reputation via AbuseIPDB |
| `blueteam_lookup_hash_virustotal` | File hash lookup via VirusTotal |
| `blueteam_lookup_domain_virustotal` | Domain reputation via VirusTotal |
### Netra 威胁情报
### Argus 威胁情报
*Requires `ARGUS_API_KEY` and `ARGUS_BASE_URL`*
| Tool | Description |
|------|-------------|
| `argus_ip_lookup` | Multi-source IP lookup via Argus TI — aggregates VirusTotal, AbuseIPDB, CyberProtect, CrowdSec, ThreatBook, IPAPI, and local Argus reports in a single call |
### Netra 威胁情报
*Requires `NETRA_API_KEY`*
| Tool | Description |
|------|-------------|
| `netra_ip_analysis` | Multi-source IP analysis aggregating VirusTotal, AbuseIPDB, CrowdSec, IPAPI, and Argus with composite threat score and AI-generated insight |
### CrowdSec CTI
*Requires `CROWDSEC_API_KEY`*
| Tool | Description |
|------|-------------|
| `crowdsec_ip_reputation` | Single IP reputation via CrowdSec CTI Smoke API (behaviors, MITRE ATT&CK, CVEs) |
| `crowdsec_ip_reputation_bulk` | Batch reputation lookup for up to 10 IPs — **parallel execution** via `asyncio.gather()` + semaphore (configurable concurrency) |
### GreyNoise Community
*Free — no API key required*
| Tool | Description |
|------|-------------|
| `greynoise_ip_context` | Check if an IP is a known internet scanner (noise) or trusted business service (RIOT) |
### Fail2Ban
| Tool | Description |
|------|-------------|
| `blueteam_fail2ban_status` | List all jails and ban counts |
| `blueteam_fail2ban_jail_status` | Detailed status of a specific jail |
| `blueteam_fail2ban_unban` | Unban an IP from a jail |
### 文件完整性
| Tool | Description |
|------|-------------|
| `blueteam_hash_file` | Hash any file (MD5/SHA1/SHA256/SHA512) |
| `blueteam_find_suid_files` | Find unexpected SUID/SGID binaries |
| `blueteam_find_world_writable` | Find world-writable files (persistence indicator) |
| `blueteam_rootkit_scan` | Run rkhunter or chkrootkit |
### 系统加固
| Tool | Description |
|------|-------------|
| `blueteam_lynis_audit` | Full Lynis hardening audit |
| `blueteam_check_updates` | Check for pending security updates |
| `blueteam_check_open_firewall` | View ufw/nftables/iptables rules |
### 用户和会话监控
| Tool | Description |
|------|-------------|
| `blueteam_who_is_logged_in` | Active user sessions with source IPs |
| `blueteam_last_logins` | Login history (last 50) |
| `blueteam_failed_logins` | Failed login attempts |
| `blueteam_sudo_history` | Sudo command usage |
| `blueteam_list_users` | All local accounts with risk flags |
| `blueteam_check_ssh_authorized_keys` | All authorized_keys files |
### 进程和持久化
| Tool | Description |
|------|-------------|
| `blueteam_list_processes` | All running processes |
| `blueteam_list_cron_jobs` | System and user cron jobs |
### 系统健康
| Tool | Description |
|------|-------------|
## | `blueteam_system_health` | 运行时间、磁盘、内存、CPU 负载 |
## 示例提示
#### 通过 Claude Desktop 连接后,你可以询问:
"Check the last 2 hours of auth.log and tell me if there are any brute force
attempts. Group by source IP."
"Show me all listening ports. Are any unexpected services running?"
"Here are 5 IPs from my nginx access log: 1.2.3.4, 5.6.7.8, 9.10.11.12,
13.14.15.16, 200.1.2.3 — look them all up on AbuseIPDB."
"Run a Lynis audit and give me the top 5 highest priority hardening items."
"Check for any SUID binaries that aren't in the standard list of expected ones."
"Who is currently logged into this server, and when did they log in?"
"Scan all user cron jobs and flag anything that looks suspicious."
"Hash /usr/bin/sshd and check it against VirusTotal."
"Check the CrowdSec reputation of 185.220.101.1 — does it have known attack
behaviors or associated CVEs?"
"Is 71.6.135.131 a known internet scanner? Check with GreyNoise and tell me
if it's noise I can ignore or something to investigate."
"Triage these 5 IPs from my firewall logs against both GreyNoise and CrowdSec.
Filter out known scanners and business services, then prioritize the rest
by reputation."
"Search the Wazuh indexer for all alerts from agent HYDRA-DC in the last 24 hours.
Use cursor pagination to iterate through all results — don't stop at the first page."
"List every Wazuh agent across the fleet. We have over 1,500 endpoints, so use
#### cursor 分页以枚举它们——然后按 OS 和状态分组。"
---
## MAESTRO Framework 对齐(目前仅用于开发)
This server aligns with the [CSA MAESTRO](https://cloudsecurityalliance.org/blog/2025/02/06/agentic-ai-threat-modeling-framework-maestro) framework for agentic AI security. See [MAESTRO.md](MAESTRO.md) for the threat model and mitigations.
### 可选:审计日志(防抵赖缓解)
Enable audit logging to record tool invocations:
```bash
#### export BLUETEAM_AUDIT_LOG=/var/log/blue-team-mcp/audit.log
Ensure log rotation (e.g., logrotate) to prevent unbounded growth.
### 可选:速率限制(DoS 缓解)
Limit tool calls per minute:
```bash
#### export BLUETEAM_RATE_LIMIT=60
---
## 安全说明
- The MCP server runs with **whatever privileges the SSH user has**. Running as a dedicated low-privilege user (with sudo for specific tools) is recommended for production.
- Threat intel tools make **outbound API calls** to:
- AbuseIPDB (`api.abuseipdb.com`)
- VirusTotal (`www.virustotal.com`)
- CrowdSec CTI (`cti.api.crowdsec.net`) — requires `CROWDSEC_API_KEY`
- GreyNoise Community (`api.greynoise.io`) — free, no auth required
Ensure outbound HTTPS to these endpoints is acceptable in your environment.
- `blueteam_capture_traffic` requires `CAP_NET_RAW` or root. The setup script attempts to grant this to tcpdump via `setcap`.
- Log files under `/var/log/` often require root or membership in the `adm` group to read. Add your SSH user to the `adm` group: `usermod -aG adm youruser`
## - **路径限制:** `blueteam_hash_file` 允许 `/var`, `/etc`, `/home`, `/opt`, `/usr` 下的路径(可通过 `BLUETEAM_ALLOWED_PATHS` 配置)。`blueteam_capture_traffic` 仅在 `BLUETEAM_CAPTURE_DIR`(默认为 `/tmp`)下写入 pcap 文件。
## 要求
**Defender Host:**
- Ubuntu 20.04+ or Debian 11+ (other distros work with minor adjustments)
- Python 3.11+ (required for modern type hints and Pydantic v2)
- OpenSSH server
**Optional system tools** (setup.sh installs these):
- `tcpdump`, `fail2ban`, `lynis`, `rkhunter`, `chkrootkit`
**Python packages** (auto-installed in venv):
- `mcp>=1.0.0,<2.0.0`
- `httpx>=0.27.0,<0.28.0`
- `pydantic>=2.0.0,<3.0.0`
**Server files:**
| File | Role |
|---|---|
| `blue_team_server.py` | **Primary** — all 48 tools, both transports (stdio / Streamable HTTP) |
### 遗留命名技术债
Five Wazuh tools use the prefix `wazuh_` without the `blueteam_` namespace
qualifier, while the other Wazuh tools use `blueteam_wazuh_`:
| Current Name | Preferred (Future) | Status |
|---|---|---|
| `wazuh_email_lookup` | `blueteam_wazuh_email_lookup` | Active — do not rename (backward compat) |
| `wazuh_domain_lookup` | `blueteam_wazuh_domain_lookup` | Active — do not rename (backward compat) |
| `wazuh_compromised_emails_analysis` | `blueteam_wazuh_compromised_emails_analysis` | Active — do not rename (backward compat) |
| `wazuh_alert_timeline` | `blueteam_wazuh_alert_timeline` | Active — do not rename (backward compat) |
| `wazuh_attack_velocity` | `blueteam_wazuh_attack_velocity` | Active — do not rename (backward compat) |
| `wazuh_wazuh_indexer_search` | `blueteam_wazuh_indexer_search` | **Alias** — delegates to `blueteam_wazuh_indexer_search` (both names valid) |
Per CLAUDE.md Hard Rule 1, these names are frozen to avoid breaking active
client workflows. A future major version may introduce the `blueteam_wazuh_`
aliases alongside a deprecation window for the short names.
```
标签:MCP服务器, SOC自动化, Wazuh, Web报告查看器, 主机取证, 子域名变形, 逆向工具