SentinelOne (Purple)
Multitenant Streamable HTTP wrapper for the SentinelOne purple-mcp server.
Installation
Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).
ghcr.io/wyre-ai/sentinelone-mcp:v1.0.9claude mcp add sentinelone-purple -e 'PORT=8080' -e 'IDLE_EVICT_MS=900000' -e 'SPAWN_READY_TIMEOUT_MS=30000' -e 'LOG_LEVEL=info' -- docker run -i --rm ghcr.io/wyre-ai/sentinelone-mcp:v1.0.9
{
"mcpServers": {
"sentinelone-purple": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/sentinelone-mcp:v1.0.9"
],
"env": {
"PORT": "8080",
"IDLE_EVICT_MS": "900000",
"SPAWN_READY_TIMEOUT_MS": "30000",
"LOG_LEVEL": "info"
}
}
}
}
Variables d'environnement
PORTPublic 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
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
sentinelone-mcp
Multitenant Streamable HTTP wrapper for sentinel-one/purple-mcp, built so the wyre-technology MCP gateway can forward per-tenant SentinelOne credentials as HTTP headers.
Why
purple-mcp is a great first-party MCP server, but it reads its SentinelOne console token + URL from environment variables at process startup, which makes it single-tenant per container. Our gateway is multi-tenant: every request carries the calling org's credentials as HTTP headers, and the vendor container has to translate those headers into something the upstream understands.
This image bundles purple-mcp plus a small Node/Fastify proxy. The proxy:
- Listens on
:8080withPOST /mcpandGET /health. - Requires a valid
X-Gateway-S2Sproof, then readsX-S1-API-TokenandX-S1-Console-URLfrom that request (legacyx-purplemcp-token/x-purplemcp-base-urlstill accepted). A request missing either the token or the console URL, after per-field fallback, gets 401, which Conduit's vendor-monitor treats as reachable but auth-gated. There is no fallback toPURPLEMCP_CONSOLE_*in the environment. - Lazily spawns one
purple-mcp --mode streamable-httpchild per(token, base-url)tenant on a private loopback port, with the right env vars set. - Proxies the request body to that child and streams the response back.
- Evicts idle children after 60 minutes (
IDLE_EVICT_MS).
The result is a single container that the gateway can talk to like any other vendor MCP server.
Configuration
| Env var | Default | Notes |
|---|---|---|
PORT | 8080 | Public listen port. |
MCP_HTTP_HOST | 0.0.0.0 when a real secret is set | Bind address. A configured CONDUIT_S2S_SECRET honors this value, including 0.0.0.0. Unset keeps that historical bind. The image and Compose set 0.0.0.0 inside the container and publish 127.0.0.1:8080:8080 on the host. |
CONDUIT_S2S_SECRET | — | Required. Service-to-service secret. The process logs an error and exits non-zero when this is empty or a known placeholder (changeme, secret, replace-me, replace-with-a-real-secret, and the other example values). Generate one with openssl rand -hex 32. Compose will not start without it. The value is never logged. |
MCP_ALLOW_INSECURE_DEV | unset | Set to exactly 1 only for local development to start without CONDUIT_S2S_SECRET. The process logs a warning, does not enforce X-Gateway-S2S, and binds 127.0.0.1 only. A non-loopback MCP_HTTP_HOST refuses to start. A known placeholder secret still refuses to start. |
PURPLE_MCP_DIR | /opt/purple-mcp | Where purple-mcp source + venv live. |
PURPLE_MCP_PYTHON | /opt/purple-mcp/.venv/bin/python | Python interpreter from the upstream venv. |
IDLE_EVICT_MS | 3600000 | Idle tenant timeout (60 min). Longer keeps children warm and avoids repeated cold starts. |
SPAWN_READY_TIMEOUT_MS | 30000 | How long to wait for a child to start serving HTTP. |
MAX_CHILDREN | 50 | Cap on distinct concurrent tenant children. A new-tenant spawn beyond the cap is rejected (502) rather than evicting an existing child. |
LOG_LEVEL | info | Fastify log level. Startup refusals and the insecure-dev warning go to stderr and are not filtered by this level. |
Copy .env.example. Leave CONDUIT_S2S_SECRET empty in that file; put a real value only in an uncommitted .env or the process environment.
Request headers
This server is gateway mode. It does not read PURPLEMCP_CONSOLE_TOKEN or PURPLEMCP_CONSOLE_BASE_URL from the environment for an incoming request. The gateway must forward these headers on every /mcp request. Names are case-insensitive. When both pairs are present, the X-S1-* value wins per field.
| Header | SentinelOne credential |
|---|---|
X-Gateway-S2S | Service-to-service proof. Required on /mcp when CONDUIT_S2S_SECRET is set. Not a SentinelOne credential. |
X-S1-API-Token | PURPLEMCP_CONSOLE_TOKEN passed to that request's child (Account- or Site-level service user token). Catalog headerMapping name. |
X-S1-Console-URL | PURPLEMCP_CONSOLE_BASE_URL passed to that request's child (e.g. https://yourtenant.sentinelone.net). Catalog headerMapping name. |
x-purplemcp-token | Legacy alias for the API token. |
x-purplemcp-base-url | Legacy alias for the console URL. |
X-Gateway-S2S
With CONDUIT_S2S_SECRET set, every POST /mcp must include X-Gateway-S2S. The check is verifyS2sHeader in src/s2s-verify.ts: the header value is t=<unix seconds>,v1=<hex>, where the hex is HMAC-SHA256 of the literal string t=<unix seconds> keyed with CONDUIT_S2S_SECRET (64 lowercase hex characters). The timestamp must be within 300 seconds of the server clock. A missing or invalid header is HTTP 401, before tenant credentials are read, and the secret is not logged.
X-Gateway-S2S: t=1710000000,v1=<hmac-sha256 hex of "t=1710000000">
In gateway mode, /mcp also requires X-S1-API-Token and X-S1-Console-URL (or the legacy x-purplemcp-* pair, including a mixed pair). A request missing either credential is HTTP 401 (JSON-RPC -32001) and does not fall back to PURPLEMCP_CONSOLE_* in the process environment. Vendor-monitor's credless initialize probe relies on that: 401/403 means the sidecar is up but auth-gated, while 400 marks the slug DOWN.
GET /health stays unauthenticated and does not read credentials.
Build
docker build -t ghcr.io/wyre-ai/sentinelone-mcp:latest .
The image listens on 0.0.0.0 inside the container (MCP_HTTP_HOST) and refuses to start until CONDUIT_S2S_SECRET is set. Publish the port on loopback. SentinelOne credentials arrive on each request as headers; they are not read from the environment.
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
Compose refuses to start when CONDUIT_S2S_SECRET is unset, publishes 127.0.0.1:8080:8080, and does not inject PURPLEMCP_CONSOLE_TOKEN or PURPLEMCP_CONSOLE_BASE_URL:
CONDUIT_S2S_SECRET="$(openssl rand -hex 32)" docker compose up --build
Local HTTP without a secret is development-only. It binds 127.0.0.1 and logs a warning. A non-loopback MCP_HTTP_HOST (including 0.0.0.0) makes startup exit:
npm run build
MCP_ALLOW_INSECURE_DEV=1 npm start
License
Apache-2.0. The bundled purple-mcp is MIT-licensed by SentinelOne.
Questions fréquentes
Qu'est-ce que SentinelOne (Purple) ?
Multitenant Streamable HTTP wrapper for the SentinelOne purple-mcp server.
Comment installer SentinelOne (Purple) ?
Il s'exécute sur votre machine. Dans Claude Code : claude mcp add sentinelone-purple -e 'PORT=8080' -e 'IDLE_EVICT_MS=900000' -e 'SPAWN_READY_TIMEOUT_MS=30000' -e 'LOG_LEVEL=info' -- docker run -i --rm ghcr.io/wyre-ai/sentinelone-mcp:v1.0.9. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.
Faut-il une clé API pour SentinelOne (Purple) ?
Son entrée au registre n'indique aucune clé ni secret obligatoire. Certaines fonctions peuvent tout de même demander un compte auprès du service auquel il se connecte.
SentinelOne (Purple) est-il open source ?
Oui. Son code est sur GitHub sous licence Apache-2.0.
Qui maintient SentinelOne (Purple) ?
Il est publié par WYRE-AI. AI.tn le référence sans le maintenir ni le recommander.
Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.