内容
# mcp-server-malcolm
** | [繁體中文](README.zh-TW.md)
一个适用于 [Malcolm](https://malcolm.fyi) 的 MCP 服务器,Malcolm 是一个开源的网络流量分析平台(Zeek + Suricata + Arkime + OpenSearch,可选 NetBox)。
它为任何与 MCP 兼容的 AI 代理提供对 Malcolm 的结构化访问:搜索和聚合网络流量,发现字段名称,查询 Suricata 警报,浏览 Arkime 会话,解析 NetBox 资产,并检查系统健康状况。启用写入类后,它还可以创建警报,标记会话,启动搜索任务和上传 PCAP。
## 默认只读访问
无需配置,该服务器仅暴露只读工具。它表现得像一个只读客户端,它所做的任何操作都不会更改 Malcolm 中的数据。
服务器将写入访问权限分为四个类别,每个类别都有自己的环境标志,默认情况下所有类别都处于关闭状态。它不会注册禁用的类别,因此该类别的工具永远不会出现在 `list_tools()` 中,也无法调用。启动时,它会打印哪些类别处于开启状态:
```
[mcp-server-malcolm] write classes: alerting=off arkime-tag=off hunt-job=off pcap-upload=off
```
每次写入都是累加的。版本 1 没有删除数据、删除标签或触及用户帐户的工具。它故意省略了这些(参见 [非目标](#非目标))。
## 为什么需要 MCP 层
Malcolm 将所有网络元数据存储在一个 OpenSearch 索引(`arkime_sessions3-*`)中,具有非标准字段名称和自己的过滤器语法。大型语言模型(LLM)被要求编写针对该索引的原始 OpenSearch DSL 查询时,经常会出错。该服务器将这项工作从模型中剥离:
- 它公开 Malcolm 的过滤器语法,而不是原始 DSL。
- 它提供字段发现功能,以便模型在查询前检查字段名称。
- 它提供值枚举功能,以便模型查看字段实际包含的值。
- 它封装 Suricata 警报查询并处理字段映射(`suricata.alert.*` 与 `rule.*`)。
- 它添加 NetBox 资产上下文(IP 到设备,网络分段)。
写入端遵循相同的想法。与其向代理提供原始 OpenSearch 和 NetBox 直通访问权限,Malcolm 已经向任何经过身份验证的用户开放了这些权限,该服务器公开了一组小型、命名、审计的写入操作。更多信息请参见[安全模型](#安全模型)。
## 只读工具
这些工具始终注册。
### DSL 核心(与后端无关)
针对已配置端点的纯 OpenSearch DSL。没有 Malcolm 特有的查询形状:将基本 URL 指向任何兼容 OpenSearch 的后端,它们仍然有效。
| 工具 | 描述 |
|------|-------------|
| `search_dsl` | 运行原始 OpenSearch DSL 查询(命中 + 聚合,无隐藏时间窗口) |
| `count` | 统计匹配 DSL 查询子句的文档数量 |
| `list_indices` | 列出索引(名称/健康状态/状态/文档数量) |
| `index_mapping` | 索引的字段映射/模式 |
| `cluster_health` | OpenSearch 集群健康状态 |
### 核心查询
| 工具 | 描述 |
|------|-------------|
| `malcolm_search` | 使用 Malcolm 过滤器语法搜索网络流量 |
| `malcolm_aggregate` | 按一个或多个字段聚合流量(前 N 名,带计数) |
| `malcolm_alerts` | 按签名、严重性、IP 搜索 Suricata 警报 |
### 字段发现(反幻觉)
| 工具 | 描述 |
|------|-------------|
| `malcolm_field_search` | 按关键词、前缀或类型搜索可用字段名称 |
| `malcolm_field_values` | 列出字段的 distinct 值 |
| `malcolm_field_profile` | 显示哪些 `event.dataset` 类型包含字段 |
### 系统健康状态
| 工具 | 描述 |
|------|-------------|
| `malcolm_service_status` | 所有 Malcolm 服务的就绪状态 + 版本信息 |
| `malcolm_data_coverage` | 每个传感器的數據新鮮度,每个数据集的文档数量,索引信息 |
| `malcolm_ping` | Malcolm API 的快速活跃度检查 |
### 资产上下文(NetBox)
| 工具 | 描述 |
|------|-------------|
| `malcolm_netbox_lookup` | 在 NetBox 中查找 IP、设备或网络前缀 |
### Arkime
| 工具 | 描述 |
|------|-------------|
| `arkime_sessions` | 使用 Arkime 表达式语法搜索 Arkime 会话 |
| `arkime_session_pcap` | 获取会话的 PCAP 并报告其大小和文件神奇有效性(仅元数据,不写入磁盘) |
### 相关性和导出
| 工具 | 描述 |
|------|-------------|
| `malcolm_related_sessions` | 查找与 Zeek UID 相关的所有会话 |
| `malcolm_dashboard_export` | 将 OpenSearch Dashboards 保存的对象导出为 JSON |
## 写入工具(需选择开启)
每个类别都通过将其标志设置为 `true` 来启用。未请求时此处无操作。
| 类别 | 标志 | 工具 | 端点 |
|-------|------|-------|----------|
| alerting | `MALCOLM_MCP_ENABLE_ALERTING` | `malcolm_create_alert` | `POST /mapi/event` |
| arkime-tag | `MALCOLM_MCP_ENABLE_ARKIME_TAGS` | `arkime_add_tags` | `POST /arkime/api/sessions/addtags` |
| hunt-job | `MALCOLM_MCP_ENABLE_HUNT_JOBS` | `arkime_create_hunt`, `arkime_hunt_status` | `POST /arkime/api/hunt` |
| pcap-upload | `MALCOLM_MCP_ENABLE_PCAP_UPLOAD` | `malcolm_upload_pcap` | `POST /server/php/submit.php` |
- **alerting**:`malcolm_create_alert` 将分析师或代理生成的发现结果索引为警报文档,您可以在 Malcolm 的仪表板中看到它。它使用 `/mapi/event`,Malcolm 自己的专用写入端点,是其他类别遵循的模板。
- **arkime-tag**:`arkime_add_tags` 为会话添加标签。它仅添加;删除标签需要更高的 Arkime 角色和自己的安全设计,因此推迟。
- **hunt-job**:`arkime_create_hunt` 启动跨 PCAP 的分组搜索(昂贵,因此先限定查询范围)。`arkime_hunt_status` 读取作业进度并随类别一起提供。
- **pcap-upload**:`malcolm_upload_pcap` 将本地捕获文件发送到 Malcolm 进行摄入,带有客户端大小限制。
每个写入工具都带有 MCP 注释 `readOnlyHint: false` 和 `destructiveHint: false`,以便 MCP 客户端可以在调用运行前应用自己的确认步骤。
## 安全模型
Malcolm 的默认部署已经为任何经过身份验证的用户提供对原始 OpenSearch(`/mapi/opensearch/*`)和完整的 NetBox CRUD(`/mapi/netbox/*`)的无限制写入访问权限。两者都是裸露的反向代理,没有 HTTP 动词过滤;Malcolm 的只读模式删除了它们,而不是尝试过滤它们。在常见的身份验证模式中,“已登录”意味着等效于管理员。
在此打开写入类别并不开启一个原本关闭的门。该门在平台级别已经打开。该服务器添加了一种精选的通过方式:
- 一组小型、命名的写入操作,而不是原始直通。
- 默认关闭,按类别逐一启用。
- 每次写入尝试都有审计线。
- MCP 注释允许客户端要求确认。
该服务器 **不** 暴露原始 OpenSearch 和 NetBox 写入直通,无论是否使用标志。策划该界面正是它的用途。
## 审计
每次写入尝试都会发出一行 JSON,成功和失败时都会发出:
```json
{"ts": "2026-07-06T09:12:44Z", "tool": "arkime_add_tags", "class": "arkime-tag", "target": "ids=240601-abc", "params": {"tags": "suspicious"}, "outcome": "ok"}
```
`outcome` 是 `ok`、`http_4xx`、`http_5xx` 或 `error:<type>` 之一。长参数值会被截断,PCAP 字节永远不会被记录。默认情况下,接收器是 stderr;设置 `MALCOLM_MCP_AUDIT_FILE` 以追加到文件中。只读工具不会被审计。
## 快速入门
### 安装
```bash
pip install mcp-server-malcolm
```
或从源代码:
```bash
git clone https://github.com/nagameTW/mcp-server-malcolm.git
cd mcp-server-malcolm
pip install -e .
```
### 配置
为您的 Malcolm 实例设置连接变量:
```bash
export MALCOLM_URL="https://malcolm.example"
export MALCOLM_USERNAME="admin"
export MALCOLM_PASSWORD="admin"
export MALCOLM_SSL_VERIFY="false" # Malcolm 默认情况下会附带自签名证书
export MALCOLM_TIMEOUT="30"
```
保持写入标志未设置以只读运行。要启用类别,请设置其标志:
```bash
export MALCOLM_MCP_ENABLE_ALERTING="true"
export MALCOLM_MCP_AUDIT_FILE="/var/log/malcolm-mcp-audit.jsonl"
```
### 运行
```bash
# 作为 MCP 服务器(stdio 传输)
mcp-server-malcolm
# 或通过 Python 模块
python -m mcp_server_malcolm
```
## 用法
### MCP 客户端(配置文件)
将服务器添加到您的 MCP 客户端配置中:
```json
{
"mcpServers": {
"malcolm": {
"command": "mcp-server-malcolm",
"env": {
"MALCOLM_URL": "https://malcolm.example",
"MALCOLM_USERNAME": "admin",
"MALCOLM_PASSWORD": "admin",
"MALCOLM_SSL_VERIFY": "false"
}
}
}
}
```
有关确切的配置文件位置,请参阅您的 MCP 客户端文档。许多客户端使用项目级 `.mcp.json` 或全局配置文件。
### Python(直接导入)
在不使用 MCP 层的情况下使用 `MalcolmClient`:
```python
import asyncio
from mcp_server_malcolm import MalcolmClient
async def main():
client = MalcolmClient(
base_url="https://malcolm.example",
username="admin",
password="admin",
)
# 搜索网络流量
results = await client.search(
filters={"event.dataset": "conn", "source.ip": "192.0.2.77"},
limit=10,
)
# 按协议聚合
agg = await client.aggregate(
fields="network.protocol",
filters={"network.direction": ["inbound", "outbound"]},
)
# 发现字段名称
fields = await client.search_fields(keyword="useragent")
# 获取不同值
datasets = await client.field_values(field="event.dataset")
# 查找 NetBox 资产
asset = await client.netbox_get(
"api/ipam/ip-addresses/",
params={"address": "192.0.2.77"},
)
await client.close()
asyncio.run(main())
```
写入基元位于 `_write_*` 方法后。仅限已启用的写入工具可达,不可直接导入。
## Malcolm 过滤器语法
Malcolm 使用简单的 JSON 过滤器语法,而不是 OpenSearch DSL:
```python
# 精确匹配
{"event.dataset": "conn"}
# 多个值(OR)
{"network.direction": ["inbound", "outbound"]}
# 取反
{"!network.transport": "icmp"}
# 字段必须存在(非空)
{"!related.password": null}
# 通配符
{"suricata.alert.signature": "*MALWARE*"}
# 组合(AND)
{"event.dataset": "dns", "source.ip": "192.0.2.77"}
```
## 示例
### 搜索对可疑域名的 DNS 查询
```
malcolm_search(
filters='{"event.dataset": "dns", "zeek.dns.query": "*example.com*"}',
limit=20,
time_from="7 days ago"
)
```
### 按协议聚合顶级谈话者
```
malcolm_aggregate(
fields="source.ip,destination.ip,network.protocol",
filters='{"network.direction": ["inbound", "outbound"]}',
limit=20
)
```
### 查询前验证字段名称
```
malcolm_field_search(prefix="zeek.dns")
malcolm_field_values(field="event.dataset")
malcolm_field_profile(field="zeek.ssl.server_name")
```
### 创建警报(启用警报类别)
```
malcolm_create_alert(
title="Periodic beacon to 192.0.2.77",
severity=2,
description="60s-interval C2 candidate",
source_ip="192.0.2.10",
dest_ip="192.0.2.77"
)
```
### 标记会话以供审查(启用 arkime-tag 类别)
```
arkime_add_tags(session_ids="240601-abc,240601-def", tags="review,beacon")
```
### 启动搜索任务(启用 hunt-job 类别)
```
arkime_create_hunt(
name="beacon-bytes",
search="deadbeef",
search_type="hex",
total_sessions=42,
start_time=1717200000,
stop_time=1717203600,
expression="ip==192.0.2.77"
)
```
## 配置参考
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `MALCOLM_URL` | `https://localhost` | Malcolm 基本 URL |
| `MALCOLM_USERNAME` | `admin` | 基本身份验证用户名 |
| `MALCOLM_PASSWORD` | `admin` | 基本身份验证密码 |
| `MALCOLM_SSL_VERIFY` | `false` | 验证 TLS 证书(接受 CA 路径) |
| `MALCOLM_TIMEOUT` | `30` | HTTP 请求超时(秒) |
| `MALCOLM_MCP_ENABLE_ALERTING` | `false` | 启用警报写入类别 |
| `MALCOLM_MCP_ENABLE_ARKIME_TAGS` | `false` | 启用附加会话标记 |
| `MALCOLM_MCP_ENABLE_HUNT_JOBS` | `false` | 启用 Arkime 搜索任务创建 + 状态 |
| `MALCOLM_MCP_ENABLE_PCAP_UPLOAD` | `false` | 启用 PCAP 上传 |
| `MALCOLM_MCP_AUDIT_FILE` | 未设置 | 写入审计文件(未设置时为 stderr) |
## 使用的 Malcolm API 端点
| 端点 | 方法 | 使用者 |
|----------|--------|---------|
| `/mapi/document` | POST | `malcolm_search`, `malcolm_alerts`, `malcolm_related_sessions` |
| `/mapi/agg/<fields>` | POST | `malcolm_aggregate`, `malcolm_field_values`, `malcolm_field_profile`, `malcolm_data_coverage` |
| `/mapi/fields` | GET | `malcolm_field_search`, `malcolm_field_profile` |
| `/mapi/ready`, `/mapi/version` | GET | `malcolm_service_status` |
| `/mapi/ping` | GET | `malcolm_ping` |
| `/mapi/ingest-stats`, `/mapi/indices` | GET | `malcolm_data_coverage` |
| `/mapi/dashboard-export/<id>` | GET | `malcolm_dashboard_export` |
| `/mapi/opensearch/<index>/_search` | POST | `search_dsl` |
| `/mapi/opensearch/<index>/_count` | POST | `count` |
| `/mapi/opensearch/_cat/indices` | GET | `list_indices` |
| `/mapi/opensearch/<index>/_mapping` | GET | `index_mapping` |
| `/mapi/opensearch/_cluster/health` | GET | `cluster_health` |
| `/mapi/netbox/*` | GET | `malcolm_netbox_lookup` |
| `/mapi/event` | POST | `malcolm_create_alert`(写入)|
| `/arkime/api/sessions` | GET | `arkime_sessions` |
| `/arkime/api/sessions.pcap` | GET | `arkime_session_pcap` |
| `/arkime/api/sessions/addtags` | POST | `arkime_add_tags`(写入)|
| `/arkime/api/hunt`, `/arkime/api/hunts` | POST, GET | `arkime_create_hunt`, `arkime_hunt_status`(写入 + 读取)|
| `/server/php/submit.php` | POST | `malcolm_upload_pcap`(写入)|
这些端点路径和正文形状与 Malcolm `26.06.1` 和 Arkime `v6.5.0` 匹配。两者在发布之间会有所不同,因此如果写入工具返回意外错误,请与您自己的版本进行复核。
## 非目标
版本 1 故意省略以下内容:
- 破坏性写入(Arkime 会话删除,标签删除,用户管理)。
- 原始 OpenSearch 写入或原始 NetBox CRUD 直通,带有标志或不带标志。
- `streamable-http` 传输(仅限 stdio)。
## 要求
- Python 3.11+
- 具有 API 访问权限的 Malcolm 实例
- 与 Malcolm 的网络连接(HTTPS)
## 许可证
MIT © nagameTW
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器