关于 SentinelOne (Purple)
为 SentinelOne 的 purple-mcp 提供多租户 HTTP 封装,适用于按请求转发租户凭据的网关。它为每组租户凭据启动上游子进程,并将 MCP 流量代理至对应进程。
主要功能
- 01按请求接收租户凭据
- 02为各租户启动独立 purple-mcp 子进程
- 03代理 Streamable HTTP 请求与响应
- 04清理空闲租户进程
- 05验证服务间请求
适用场景
- 01在单个容器中服务多个 SentinelOne 租户
- 02将网关凭据转发给 purple-mcp
- 03在请求间复用已启动的租户进程
- 04向网关提供受认证保护的端点
MCP 相关
封装 purple-mcp,并通过 `/mcp` 的 Streamable HTTP 端点代理 MCP 请求。封装层从请求头读取 SentinelOne 凭据,并将流量转发到对应租户的子进程。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e PORT -e IDLE_EVICT_MS -e SPAWN_READY_TIMEOUT_MS -e LOG_LEVEL ghcr.io/wyre-technology/sentinelone-mcp:v1.0.6PORTPublic listen port for the proxy (POST /mcp, GET /health)IDLE_EVICT_MSIdle tenant timeout before a purple-mcp child is evicted (ms)SPAWN_READY_TIMEOUT_MSHow long to wait for a spawned child to start serving HTTP (ms)LOG_LEVELFastify log level: debug, info, warn, error本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/wyre-technology/sentinelone-mcp:v1.0.6stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
sentinelone-mcp
sentinel-one/purple-mcp 的多租户 Streamable HTTP 封装,旨在让 wyre-technology MCP gateway 能通过 HTTP 标头转发各租户的 SentinelOne 凭据。
原因
purple-mcp 是一个出色的官方 MCP 服务,但它会在进程启动时从环境变量读取 SentinelOne 控制台令牌和 URL,因此每个容器只能服务一个租户。我们的网关支持多租户:每个请求都会通过 HTTP 标头携带调用方组织的凭据,供应商容器必须将这些标头转换成上游能理解的形式。
此镜像将 purple-mcp 与一个小型 Node/Fastify 代理打包在一起。代理会:
- 在
:8080上监听POST /mcp和GET /health。 - 要求提供有效的
X-Gateway-S2S验证信息,然后从请求中读取X-S1-API-Token和X-S1-Console-URL(仍接受旧版x-purplemcp-token/x-purplemcp-base-url)。如果在逐字段回退后,请求缺少令牌或控制台 URL,则返回 401;Conduit 的供应商监控会将其视为服务可访问但受身份验证限制。不会回退到环境变量中的PURPLEMCP_CONSOLE_*。 - 按照每个
(token, base-url)租户,在专用的环回端口上按需启动一个purple-mcp --mode streamable-http子进程,并设置相应的环境变量。 - 将请求正文代理给该子进程,并将响应流式传回。
- 60 分钟后清除空闲子进程(
IDLE_EVICT_MS)。
最终只需一个容器,网关即可像与其他供应商 MCP 服务通信一样与其通信。
配置
| 环境变量 | 默认值 | 说明 |
|---|---|---|
PORT | 8080 | 公共监听端口。 |
MCP_HTTP_HOST | 设置了真实密钥时为 0.0.0.0 | 绑定地址。配置了 CONDUIT_S2S_SECRET 时会采用此值,包括 0.0.0.0。未设置时保留原有的绑定行为。镜像和 Compose 会在容器内设置 0.0.0.0,并在主机上发布 127.0.0.1:8080:8080。 |
CONDUIT_S2S_SECRET | — | 必填。服务间密钥。如果此值为空或是已知占位值(changeme、secret、replace-me、replace-with-a-real-secret 以及其他示例值),进程会记录错误并以非零状态退出。使用 openssl rand -hex 32 生成密钥。未设置此值时,Compose 不会启动。此值绝不会被记录到日志中。 |
MCP_ALLOW_INSECURE_DEV | 未设置 | 仅在本地开发时准确设置为 1,即可在未设置 CONDUIT_S2S_SECRET 的情况下启动。进程会记录警告,不会验证 X-Gateway-S2S,并且仅绑定到 127.0.0.1。非环回地址的 MCP_HTTP_HOST 会导致启动被拒绝。已知占位密钥仍会导致启动被拒绝。 |
PURPLE_MCP_DIR | /opt/purple-mcp | purple-mcp 源代码和虚拟环境所在目录。 |
PURPLE_MCP_PYTHON | /opt/purple-mcp/.venv/bin/python | 上游虚拟环境中的 Python 解释器。 |
IDLE_EVICT_MS | 3600000 | 租户空闲超时时间(60 分钟)。设置更长时间可让子进程保持就绪,避免反复冷启动。 |
SPAWN_READY_TIMEOUT_MS | 30000 | 等待子进程开始提供 HTTP 服务的最长时间。 |
MAX_CHILDREN | 50 | 不同租户子进程的并发数量上限。超过上限时,新租户的子进程启动会被拒绝(502),而不会清除现有子进程。 |
LOG_LEVEL | info | Fastify 日志级别。启动拒绝信息和不安全开发模式警告会输出到 stderr,不受此级别过滤。 |
复制 .env.example。将该文件中的 CONDUIT_S2S_SECRET 留空;真实值只能放在未提交的 .env 文件或进程环境中。
请求标头
此服务器处于网关模式。对于传入请求,它不会从环境变量中读取 PURPLEMCP_CONSOLE_TOKEN 或 PURPLEMCP_CONSOLE_BASE_URL。网关必须在每个 /mcp 请求中转发这些标头。名称不区分大小写。两组标头都存在时,各字段以 X-S1-* 的值为准。
| 标头 | SentinelOne 凭据 |
|---|---|
X-Gateway-S2S | 服务间身份验证凭据。设置了 CONDUIT_S2S_SECRET 时,/mcp 请求必须携带此标头。它不是 SentinelOne 凭据。 |
X-S1-API-Token | 传递给该请求子进程的 PURPLEMCP_CONSOLE_TOKEN(账户级或站点级服务用户令牌)。目录中的 headerMapping 名称。 |
X-S1-Console-URL | 传递给该请求子进程的 PURPLEMCP_CONSOLE_BASE_URL(例如 https://yourtenant.sentinelone.net)。目录中的 headerMapping 名称。 |
x-purplemcp-token | API 令牌的旧别名。 |
x-purplemcp-base-url | 控制台 URL 的旧别名。 |
X-Gateway-S2S
设置了 CONDUIT_S2S_SECRET 时,每个 POST /mcp 请求都必须包含 X-Gateway-S2S。检查逻辑位于 src/s2s-verify.ts 的 verifyS2sHeader 中:标头值格式为 t=<unix seconds>,v1=<hex>,其中十六进制字符串是以 CONDUIT_S2S_SECRET 为密钥、对字面字符串 t=<unix seconds> 计算得到的 HMAC-SHA256(64 位小写十六进制字符)。时间戳必须在服务器时钟前后 300 秒以内。缺少标头或标头无效时,会在读取租户凭据之前返回 HTTP 401,且不会记录密钥。
X-Gateway-S2S: t=1710000000,v1=<hmac-sha256 hex of "t=1710000000">
在网关模式下,/mcp 还要求提供 X-S1-API-Token 和 X-S1-Console-URL(或旧版 x-purplemcp-* 标头组合,包括混合组合)。请求缺少任一凭据时,会返回 HTTP 401(JSON-RPC -32001),且不会回退到进程环境中的 PURPLEMCP_CONSOLE_*。Vendor-monitor 的无凭据 initialize 探测依赖此行为:401/403 表示 sidecar 已启动但要求身份验证,而 400 表示 slug 状态为 DOWN。
GET /health 仍无需身份验证,且不会读取凭据。
构建
docker build -t ghcr.io/wyre-ai/sentinelone-mcp:latest .
镜像会在容器内监听 0.0.0.0(MCP_HTTP_HOST),并且在设置 CONDUIT_S2S_SECRET 之前拒绝启动。请将端口发布到回环地址。SentinelOne 凭据会随每个请求通过标头传入;不会从环境变量中读取。
docker run --rm \
-e CONDUIT_S2S_SECRET="$(openssl rand -hex 32)" \
-p 127.0.0.1:8080:8080 \
ghcr.io/wyre-ai/sentinelone-mcp:latest
未设置 CONDUIT_S2S_SECRET 时,Compose 会拒绝启动;它会发布 127.0.0.1:8080:8080,且不会注入 PURPLEMCP_CONSOLE_TOKEN 或 PURPLEMCP_CONSOLE_BASE_URL:
CONDUIT_S2S_SECRET="$(openssl rand -hex 32)" docker compose up --build
不设密钥的本地 HTTP 仅用于开发。它会绑定到 127.0.0.1 并记录警告。若 MCP_HTTP_HOST 设置为非回环地址(包括 0.0.0.0),启动会退出:
npm run build
MCP_ALLOW_INSECURE_DEV=1 npm start
许可证
Apache-2.0。随附的 purple-mcp 由 SentinelOne 以 MIT 许可证授权。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。