{
  "$schema": "https://readbeforerun.ai/schema/entry.schema.json",
  "entry": {
    "id": "sentinelone-purple-mcp",
    "name": "Purple AI MCP Server",
    "summary": "Read-only MCP server for the SentinelOne Singularity platform: Purple AI, data-lake PowerQuery, alerts, vulnerabilities, misconfigurations and inventory.",
    "draft": "review",
    "type": "mcp-server",
    "mission": [
      "defensive"
    ],
    "task": [
      "alert-triage",
      "threat-intel-enrichment"
    ],
    "domain": [
      "security-operations"
    ],
    "runtime": [
      "mcp-generic",
      "claude-code",
      "codex"
    ],
    "tier": "listed",
    "last_checked": "2026-10-21",
    "next_check": "2027-01-19",
    "freshness": "fresh",
    "superseded": false,
    "in_my_kit": null,
    "advice": null,
    "code_shows": "can tunnel or exfiltrate · adds autostart, users or keys · reads broad tokens or the environment · Approval: unknown",
    "source": {
      "repo": "https://github.com/Sentinel-One/purple-mcp",
      "subpath": null,
      "commit": "07d4992089b10affff6163f296b1f6cb5734539f",
      "version": "v0.7.0",
      "license": "MIT"
    },
    "install": {
      "skills_cli": null,
      "claude_code": null,
      "upstream": "uvx --from git+https://github.com/Sentinel-One/purple-mcp.git purple-mcp --mode=stdio",
      "bundled": false
    },
    "scan": {
      "status": "static scan pending (not run)"
    },
    "reach": {
      "method": "reach-v0.1",
      "level": 3,
      "level_source": "static",
      "level_label": "privileged",
      "unknown_axes": 1,
      "verdict": "not-run",
      "badge": "reach 3 · not run yet",
      "long": "reach 3 from code (privileged); lab: not run yet",
      "declared": {
        "fs": 0,
        "net": 3,
        "cred": 2
      },
      "static": {
        "level": 3,
        "fs": 1,
        "net": 3,
        "exec": 0,
        "cred": 2,
        "persist": 3,
        "hitl": null,
        "unknown": [
          "hitl"
        ]
      },
      "observed": null,
      "surplus": null,
      "fit": null,
      "exports": {
        "aivss": {
          "fs": 0.5,
          "net": 1,
          "exec": 0,
          "cred": 0.5,
          "persist": 1,
          "hitl": null
        },
        "usf_risk_tier": "L3"
      }
    },
    "profile": {
      "read_at": "07d4992089b10affff6163f296b1f6cb5734539f",
      "read_on": "2026-10-25",
      "overview": "Purple AI MCP Server is an MCP server that lets any MCP client access SentinelOne services.",
      "purpose": [
        "Exposes the SentinelOne platform to AI clients through the Model Context Protocol.",
        "Lets an analyst ask security questions and investigate threats through SentinelOne Purple AI.",
        "Answers questions about endpoints, cloud resources, identities and network devices in the SentinelOne asset inventory."
      ],
      "use_cases": [
        {
          "text": "Investigate and triage SentinelOne alerts, including their notes, history and auto-investigation reports",
          "task": "alert-triage"
        },
        {
          "text": "Enrich indicators of compromise with VirusTotal data for hashes, URLs, domains and IPs",
          "task": "threat-intel-enrichment"
        },
        {
          "text": "Generate PowerQueries with Purple AI for threat hunting and run them against the data lake",
          "task": "detection-engineering"
        },
        {
          "text": "Track CVEs and vulnerability findings recorded in the SentinelOne console",
          "task": "vuln-prioritization"
        }
      ],
      "maturity": "beta",
      "capabilities": [
        {
          "name": "Purple AI",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "Data Lake",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "Alerts",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "Vulnerabilities",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "Misconfigurations",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "Asset Inventory",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "CVE Search (External)",
          "effects": [
            "reads"
          ],
          "enabled": "default"
        },
        {
          "name": "Threat Intelligence (External)",
          "effects": [
            "reads"
          ],
          "enabled": "optional"
        },
        {
          "name": "purple_utils",
          "effects": [],
          "enabled": "default"
        }
      ],
      "effects": [
        "reads"
      ],
      "runs": "local-process",
      "listens": [
        {
          "mode": "optional",
          "bind": "loopback",
          "sign_in": "none"
        },
        {
          "mode": "optional",
          "bind": "all-interfaces",
          "sign_in": "none"
        },
        {
          "mode": "optional",
          "bind": "all-interfaces",
          "sign_in": "required"
        }
      ],
      "sends_to": [
        {
          "to": "SentinelOne console",
          "kind": "vendor-api",
          "when": "always"
        },
        {
          "to": "SentinelOne Purple AI",
          "kind": "vendor-api",
          "when": "default"
        },
        {
          "to": "Singularity Data Lake API",
          "kind": "vendor-api",
          "when": "default"
        },
        {
          "to": "cve.circl.lu",
          "kind": "other",
          "when": "default"
        },
        {
          "to": "VirusTotal",
          "kind": "other",
          "when": "optional"
        },
        {
          "to": "Pydantic Logfire",
          "kind": "telemetry",
          "when": "optional"
        },
        {
          "to": "GitHub Sentinel-One/purple-mcp",
          "kind": "download",
          "when": "default"
        }
      ],
      "model": "client",
      "needs": [
        {
          "kind": "account",
          "text": "Needs a SentinelOne account to obtain the console token."
        },
        {
          "kind": "credentials",
          "text": "Needs a console or Service User token with Account or Site scope, not Global, set as PURPLEMCP_CONSOLE_TOKEN."
        },
        {
          "kind": "setting",
          "text": "Needs PURPLEMCP_CONSOLE_BASE_URL set to the HTTPS console URL."
        },
        {
          "kind": "runtime",
          "text": "Needs Python 3.11 or later."
        },
        {
          "kind": "tools",
          "text": "Needs uv, whose uvx command fetches and runs the server."
        },
        {
          "kind": "credentials",
          "text": "The threat-intel tools need a VirusTotal API key in PURPLEMCP_VT_API_KEY; threat_intel_search needs a Premium API key."
        }
      ]
    },
    "urls": {
      "page": "/catalog/sentinelone-purple-mcp/",
      "json": "/entries/sentinelone-purple-mcp.json",
      "md": "/catalog/sentinelone-purple-mcp.md",
      "badge": "/badge/sentinelone-purple-mcp.svg"
    }
  },
  "data": {
    "schema_version": "0.5",
    "slug": "sentinelone-purple-mcp",
    "name": "Purple AI MCP Server",
    "summary": "Read-only MCP server for the SentinelOne Singularity platform: Purple AI, data-lake PowerQuery, alerts, vulnerabilities, misconfigurations and inventory.",
    "draft": "review",
    "in_my_kit": null,
    "type": "mcp-server",
    "mission": [
      "defensive"
    ],
    "task": [
      "alert-triage",
      "threat-intel-enrichment"
    ],
    "domain": [
      "security-operations"
    ],
    "phase": [
      "def:detect",
      "def:respond"
    ],
    "role": [
      "soc"
    ],
    "runtime": [
      "mcp-generic",
      "claude-code",
      "codex"
    ],
    "auth": "token",
    "autonomy": null,
    "addresses": [],
    "frameworks": {
      "owasp_ast": [],
      "owasp_asi": [],
      "attack_tactic": [],
      "atlas": []
    },
    "source": {
      "repo": "https://github.com/Sentinel-One/purple-mcp",
      "commit": "07d4992089b10affff6163f296b1f6cb5734539f",
      "version": "v0.7.0",
      "license": "MIT",
      "manifest": "pyproject.toml",
      "also_listed": {
        "tenable-cyberagents-exchange": "https://github.com/tenable/cyberagents-exchange/blob/9d0ddf1fe8dc9651a0c461a2a27d33cb8a160a2c/mcp-servers/sentinelone-purple-ai-mcp-server.md"
      }
    },
    "upstream": {
      "checked_at": "2026-10-21",
      "updated_at": "2026-09-22",
      "current_release": "v0.7.0",
      "archived": false,
      "stars": 101,
      "commit_history": {},
      "releases_since_pin": 0
    },
    "install": {
      "upstream": "uvx --from git+https://github.com/Sentinel-One/purple-mcp.git purple-mcp --mode=stdio",
      "upstream_evidence": "README.md#L42",
      "bundled": false
    },
    "scan": [
      {
        "tool": "cisco-skill-scanner",
        "version": "not-run",
        "llm_judge": false,
        "date": "2026-10-21",
        "result": "pending"
      }
    ],
    "privileges": {
      "method": "reach-v0.1",
      "declared": {
        "axes": {
          "fs": 0,
          "net": 3,
          "cred": 2
        },
        "evidence": {
          "fs": "README.md#L26 the author declares a read-only service that cannot change the account or any of its objects",
          "net": "deploy/docker/DOCKER.md#L72 the documented Docker default binds the SSE and HTTP modes to all interfaces, which declares a network listener",
          "cred": "README.md#L288 the author declares a VirusTotal API key in addition to the required console token, so several tokens"
        }
      },
      "static": {
        "level": 3,
        "axes": {
          "fs": 1,
          "net": 3,
          "exec": 0,
          "cred": 2,
          "persist": 3,
          "hitl": null
        },
        "evidence": {
          "fs": "docker-compose.yml#L111 the optional proxy service mounts the project's ssl directory with certificate and key into the nginx container, read-only",
          "net": "docker-entrypoint.sh#L35 the image entrypoint adds --allow-remote-access by itself while MCP_HOST defaults to 0.0.0.0, so the SSE and HTTP modes listen on all interfaces without authentication of their own; src/purple_mcp/cli.py#L325-331 outside Docker stdio is the default mode, and the HTTP modes refuse non-loopback hosts unless --allow-remote-access is given",
          "exec": "none found: patterns exec-v0.1 in 76 files at 07d4992",
          "cred": "src/purple_mcp/config.py#L56-58 several named tokens are read from environment variables: the console token, an optional VirusTotal key and an optional Logfire token",
          "persist": "docker-compose.yml#L25 the optional compose deployment runs the server and its proxy as services that restart automatically with the Docker daemon",
          "hitl": "no evidence: no approval settings were found, and the two lines the search patterns match are error messages about token permissions"
        },
        "unknown": [
          "hitl"
        ]
      },
      "min_config": {
        "status": "derived",
        "note": "derived from the code, not tested in the lab; run over stdio, or bind the HTTP modes to localhost behind an authenticating proxy, use an Account- or Site-scoped token, and leave the VirusTotal and Logfire keys unset unless needed"
      },
      "override": null,
      "reviews": []
    },
    "status": {
      "tier": "listed",
      "last_checked": "2026-10-21",
      "next_check": "2027-01-19",
      "freshness": "fresh",
      "superseded": false,
      "superseded_by": null,
      "added": "2026-10-21",
      "added_by": "scout"
    },
    "evidence": {
      "runs": [],
      "badge": "/badge/sentinelone-purple-mcp.svg"
    },
    "changes": []
  },
  "profile": {
    "schema_version": "0.1",
    "entry": "sentinelone-purple-mcp",
    "draft": "review",
    "commit": "07d4992089b10affff6163f296b1f6cb5734539f",
    "read_on": "2026-10-25",
    "check": {
      "date": "2026-10-25",
      "facts": 64,
      "confirmed": 64,
      "verified": 58
    },
    "overview": {
      "text": "Purple AI MCP Server is an MCP server that lets any MCP client access SentinelOne services.",
      "ev": "README.md#L11 author's one-line description"
    },
    "maturity": {
      "word": "beta",
      "text": "The package classifier declares Development Status 4 - Beta.",
      "ev": "pyproject.toml#L19 trove classifier"
    },
    "purpose": [
      {
        "text": "Exposes the SentinelOne platform to AI clients through the Model Context Protocol.",
        "ev": "README.md#L15 feature introduction"
      },
      {
        "text": "Lets an analyst ask security questions and investigate threats through SentinelOne Purple AI.",
        "ev": "README.md#L17 Purple AI feature"
      },
      {
        "text": "Answers questions about endpoints, cloud resources, identities and network devices in the SentinelOne asset inventory.",
        "ev": "README.md#L22 Inventory feature"
      }
    ],
    "use_cases": [
      {
        "text": "Investigate and triage SentinelOne alerts, including their notes, history and auto-investigation reports",
        "task": "alert-triage",
        "ev": "src/purple_mcp/tools/alerts.py#L72 common use case in get_alert description"
      },
      {
        "text": "Enrich indicators of compromise with VirusTotal data for hashes, URLs, domains and IPs",
        "task": "threat-intel-enrichment",
        "ev": "src/purple_mcp/tools/threat_intelligence.py#L75 common use case in threat_intel_by_hash description"
      },
      {
        "text": "Generate PowerQueries with Purple AI for threat hunting and run them against the data lake",
        "task": "detection-engineering",
        "ev": "src/purple_mcp/tools/purple_ai.py#L65 what Purple AI can do"
      },
      {
        "text": "Track CVEs and vulnerability findings recorded in the SentinelOne console",
        "task": "vuln-prioritization",
        "ev": "README.md#L20 Vulnerabilities feature"
      }
    ],
    "not_for": [
      {
        "text": "The author describes the server as read-only: it is not meant to change the account or any objects in it.",
        "ev": "README.md#L26 read-only statement"
      },
      {
        "text": "The purple_ai tool description states that Purple AI cannot modify configurations or interact with endpoints directly.",
        "ev": "src/purple_mcp/tools/purple_ai.py#L73 what Purple AI can't do"
      }
    ],
    "capabilities": {
      "coverage": "complete",
      "groups": [
        {
          "name": "Purple AI",
          "does": "purple_ai sends a natural-language security question to SentinelOne Purple AI and returns its answer, which can include a generated PowerQuery.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "src/purple_mcp/server.py#L142 purple_ai tool registration"
        },
        {
          "name": "Data Lake",
          "does": "powerquery runs a PowerQuery over Singularity Data Lake events for a start and end time; get_timestamp_range builds the time range.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "README.md#L226 Data Lake tool list"
        },
        {
          "name": "Alerts",
          "does": "get_alert, list_alerts, search_alerts, get_alert_notes, get_alert_history and get_alert_investigation_report read alerts, notes, timelines and auto-investigation reports.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "src/purple_mcp/server.py#L146-151 alert tool registrations"
        },
        {
          "name": "Vulnerabilities",
          "does": "get, list and search vulnerabilities and read their notes and history from the console's XSPM vulnerability findings.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "README.md#L238-242 Vulnerabilities tool list"
        },
        {
          "name": "Misconfigurations",
          "does": "get, list and search misconfigurations and read their notes and history from the console's XSPM misconfiguration findings.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "README.md#L246-250 Misconfigurations tool list"
        },
        {
          "name": "Asset Inventory",
          "does": "get_inventory_item, list_inventory_items and search_inventory_items read assets by surface type, with fetch_fields presets MINIMAL, STANDARD or ALL.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "README.md#L254-256 Asset Inventory tool list"
        },
        {
          "name": "CVE Search (External)",
          "does": "cve_search_by_id, cve_search_by_vendor and cve_database_status query the public CIRCL cve-search service without an API key.",
          "effects": [
            "reads"
          ],
          "enabled": "default",
          "ev": "README.md#L267-271 CVE Search tool list"
        },
        {
          "name": "Threat Intelligence (External)",
          "does": "Seven threat_intel_* tools look up file hashes, URLs, domains and IPs, file relationships, sandbox behaviour and Intelligence search on VirusTotal.",
          "effects": [
            "reads"
          ],
          "enabled": "optional",
          "ev": "README.md#L277-286 Threat Intelligence tool list"
        },
        {
          "name": "purple_utils",
          "does": "iso_to_unix_timestamp converts ISO 8601 datetimes to UNIX milliseconds for the date filters of the search tools.",
          "effects": [],
          "enabled": "default",
          "ev": "src/purple_mcp/server.py#L144-145 utility tool registration"
        }
      ]
    },
    "architecture": {
      "summary": {
        "text": "A Python FastMCP server (purple-mcp) runs on the user's machine over stdio, or over SSE or streamable HTTP via uvicorn; its tools call SentinelOne console GraphQL/REST and SDL APIs over HTTPS, plus cve.circl.lu and VirusTotal.",
        "ev": "src/purple_mcp/server.py#L139 FastMCP server instance"
      },
      "runs": {
        "where": "local-process",
        "text": "The MCP client starts purple-mcp through uvx and talks to it over stdio, the default mode.",
        "ev": "README.md#L42 quick-start run command"
      },
      "modes": [
        {
          "where": "local-service",
          "mode": "streamable-http or sse",
          "switch": "--mode streamable-http",
          "text": "Runs as an HTTP service in streamable-http or sse mode on port 8000 to serve several clients.",
          "ev": "README.md#L202 streamable-http mode for multiple clients"
        },
        {
          "where": "container",
          "mode": "Docker image",
          "switch": "MCP_MODE",
          "text": "A Dockerfile and docker-compose.yml run the server in a container; MCP_MODE selects stdio, sse or streamable-http.",
          "ev": "Dockerfile#L55 container entrypoint"
        }
      ],
      "parts": [
        {
          "name": "MCP client configuration",
          "zone": "client",
          "does": "The client's mcpServers entry launches purple-mcp via uvx and passes the console token and console URL as env values.",
          "ev": "README.md#L131-140 Claude Desktop configuration"
        },
        {
          "name": "purple-mcp server",
          "zone": "machine",
          "does": "FastMCP server process that registers the tools and runs over stdio, or via uvicorn for SSE and HTTP.",
          "ev": "src/purple_mcp/server.py#L139 server instance"
        },
        {
          "name": "SentinelOne console API",
          "zone": "outside",
          "does": "Console GraphQL endpoints for Purple AI, alerts, misconfigurations and vulnerabilities, and the REST asset inventory API.",
          "ev": "src/purple_mcp/config.py#L481 console GraphQL URL"
        },
        {
          "name": "Singularity Data Lake API",
          "zone": "outside",
          "does": "SDL API at the console URL plus /sdl, or at a dedicated PURPLEMCP_SDL_BASE_URL, that runs PowerQuery jobs.",
          "ev": "src/purple_mcp/config.py#L541 SDL URL derived from console URL"
        },
        {
          "name": "cve.circl.lu",
          "zone": "outside",
          "does": "Public CVE API that answers the three CVE tools.",
          "ev": "src/purple_mcp/libs/cve/config.py#L30 fixed CVE API base URL"
        },
        {
          "name": "VirusTotal API",
          "zone": "outside",
          "does": "VirusTotal API v3, reached through the vt-py client with the user's API key, for the threat-intel tools.",
          "ev": "src/purple_mcp/libs/threat_intelligence/client.py#L156 vt-py client"
        }
      ],
      "listens": [
        {
          "what": "In sse or streamable-http mode uvicorn listens on localhost:8000; other hosts are refused unless --allow-remote-access is given.",
          "mode": "optional",
          "bind": "loopback",
          "sign_in": "none",
          "ev": "src/purple_mcp/cli.py#L333-337 --host option default"
        },
        {
          "what": "In the container, sse and streamable-http modes bind 0.0.0.0 on port 8000 by default, with no sign-in.",
          "mode": "optional",
          "bind": "all-interfaces",
          "sign_in": "none",
          "ev": "docker-entrypoint.sh#L18 default host"
        },
        {
          "what": "The purple-mcp-proxy nginx service publishes ports 80 and 443; its PURPLEMCP_AUTH_TOKEN falls back to the placeholder your-secure-token-here.",
          "mode": "optional",
          "bind": "all-interfaces",
          "sign_in": "required",
          "ev": "docker-compose.yml#L104-113 nginx proxy service with PURPLEMCP_AUTH_TOKEN and ports"
        }
      ],
      "connections": [
        {
          "to": "SentinelOne console",
          "kind": "vendor-api",
          "when": "always",
          "what": "Sends GraphQL and REST requests with the console token to read alerts, vulnerabilities, misconfigurations and inventory.",
          "ev": "README.md#L89 console token authentication"
        },
        {
          "to": "SentinelOne Purple AI",
          "kind": "vendor-api",
          "when": "default",
          "what": "purple_ai posts the question, a session ID and optional console scope IDs to the Purple AI GraphQL endpoint of the console.",
          "ev": "src/purple_mcp/libs/purple_ai/client.py#L281-286 GraphQL POST"
        },
        {
          "to": "Singularity Data Lake API",
          "kind": "vendor-api",
          "when": "default",
          "what": "powerquery submits a PowerQuery job with POST /v2/api/queries using the console token and polls it for results.",
          "ev": "src/purple_mcp/libs/sdl/sdl_query_client.py#L250-254 query job submission"
        },
        {
          "to": "cve.circl.lu",
          "kind": "other",
          "when": "default",
          "what": "The CVE tools send the CVE ID, vendor or product to cve.circl.lu without an API key.",
          "ev": "src/purple_mcp/libs/cve/config.py#L30 fixed CVE API host"
        },
        {
          "to": "VirusTotal",
          "kind": "other",
          "when": "optional",
          "what": "With PURPLEMCP_VT_API_KEY set, the threat-intel tools send hashes, URLs, domains, IPs and search queries to VirusTotal.",
          "ev": "src/purple_mcp/libs/threat_intelligence/client.py#L225 URL lookup request"
        },
        {
          "to": "Pydantic Logfire",
          "kind": "telemetry",
          "when": "optional",
          "what": "With PURPLEMCP_LOGFIRE_TOKEN set, traces of outgoing HTTP calls, server requests and log records go to Pydantic Logfire.",
          "ev": "src/purple_mcp/observability.py#L58 HTTPX instrumentation"
        },
        {
          "to": "GitHub Sentinel-One/purple-mcp",
          "kind": "download",
          "when": "default",
          "what": "The documented uvx command fetches purple-mcp from the GitHub repository Sentinel-One/purple-mcp to run it.",
          "ev": "README.md#L42 run from GitHub"
        }
      ],
      "model": {
        "who": "client",
        "text": "The MCP client's model chooses and calls the tools; the purple_ai tool passes questions to SentinelOne's Purple AI assistant at the vendor.",
        "ev": "src/purple_mcp/tools/purple_ai.py#L62 Purple AI tool description"
      }
    },
    "needs": [
      {
        "kind": "account",
        "text": "Needs a SentinelOne account to obtain the console token.",
        "ev": "deploy/aws_agentcore/BEDROCK_AGENTCORE_DEPLOYMENT.md#L5 account requirement"
      },
      {
        "kind": "credentials",
        "text": "Needs a console or Service User token with Account or Site scope, not Global, set as PURPLEMCP_CONSOLE_TOKEN.",
        "ev": "README.md#L82-83 token scope"
      },
      {
        "kind": "setting",
        "text": "Needs PURPLEMCP_CONSOLE_BASE_URL set to the HTTPS console URL.",
        "ev": "README.md#L295 required environment variable"
      },
      {
        "kind": "runtime",
        "text": "Needs Python 3.11 or later.",
        "ev": "pyproject.toml#L6 Python requirement"
      },
      {
        "kind": "tools",
        "text": "Needs uv, whose uvx command fetches and runs the server.",
        "ev": "README.md#L34-35 install uv step"
      },
      {
        "kind": "credentials",
        "text": "The threat-intel tools need a VirusTotal API key in PURPLEMCP_VT_API_KEY; threat_intel_search needs a Premium API key.",
        "ev": "README.md#L285-288 VirusTotal key requirement"
      }
    ],
    "installer": [
      {
        "text": "The quick start installs uv by piping the astral.sh install script into sh.",
        "ev": "README.md#L34-35 curl piped into sh"
      },
      {
        "text": "The documented uvx commands and client configurations run the server from the repository's default branch without a pinned version.",
        "ev": "README.md#L42 unpinned git source"
      },
      {
        "text": "The README recommends pinning a commit hash (git+...@<commit-hash>) for production or security-sensitive environments.",
        "ev": "README.md#L47 pinning advice"
      }
    ],
    "limits": [
      {
        "text": "Has no built-in authentication; network-exposed deployments rely on a reverse proxy or load balancer placed in front of it.",
        "ev": "README.md#L75 authentication note"
      },
      {
        "text": "The author advises against exposing the server on a network, because anyone who reaches it could use the configured SentinelOne account.",
        "ev": "README.md#L215-216 exposure warning"
      },
      {
        "text": "The container entrypoint adds --allow-remote-access itself for any non-loopback MCP_HOST, so the CLI's loopback refusal does not take effect in Docker.",
        "ev": "docker-entrypoint.sh#L33-36 automatic override flag"
      },
      {
        "text": "Without PURPLEMCP_SDL_CONSOLE_ACCOUNT_IDS, PowerQueries run across all accounts the token can reach.",
        "ev": "README.md#L305-308 SDL scoping"
      },
      {
        "text": "The server supports tokens with access to a single Account or Site; several sites need separate server instances with their own tokens.",
        "ev": "README.md#L83-85 single-scope token support"
      },
      {
        "text": "HTTP modes serve an unauthenticated /health route that returns {\"status\": \"ok\"}.",
        "ev": "src/purple_mcp/server.py#L179-182 health route"
      },
      {
        "text": "PURPLEMCP_DEBUG_UNSAFE_LOGGING=1 writes queries and payloads to the logs; the author limits it to secured, time-boxed debugging.",
        "ev": "SECURITY.md#L163-164 unsafe logging flag"
      },
      {
        "text": "The project is maintained by SentinelOne with the community but is stated not to be an official SentinelOne product.",
        "ev": "README.md#L381-382 support statement"
      },
      {
        "text": "SECURITY.md states that the MCP tools can execute privileged actions through upstream APIs, and that exposing tool endpoints without authentication or rate limiting invites abuse.",
        "ev": "SECURITY.md#L27-28 author threat-model statement on user access"
      },
      {
        "text": "One console token is loaded at startup and used for every request, so all clients of a shared HTTP instance act with the same tenant credentials.",
        "ev": "SECURITY.md#L96-99 security characteristics of the single startup token"
      },
      {
        "text": "TLS verification is on by default. The skip_tls_verify flag is refused when PURPLEMCP_ENV is unset or release, and allowed with warnings for testing, staging and development.",
        "ev": "SECURITY.md#L70-76 TLS bypass rules tied to PURPLEMCP_ENV"
      },
      {
        "text": "In docker-compose.yml the SSE service publishes port 8000 on the host and is set to restart: unless-stopped.",
        "ev": "docker-compose.yml#L23-25 published port and restart policy of the SSE service"
      },
      {
        "text": "The powerquery tool description tells the client's model to use purple_ai to write PowerQueries and to run a user-supplied PowerQuery exactly as sent.",
        "ev": "src/purple_mcp/tools/sdl.py#L42-44 instructions to the model inside the tool description"
      },
      {
        "text": "In the data lake the server submits its own PowerQuery job, polls it for results and deletes the job when done; these are the data-lake client's only POST and DELETE requests.",
        "ev": "src/purple_mcp/libs/sdl/sdl_query_client.py#L49-52 documented workflow: submit query job, ping for results, delete query job (POST at L250-252, DELETE at L351-353, methods limited at L115)"
      }
    ],
    "not_found": [
      {
        "field": "capability_count",
        "searched": "README.md, CHANGELOG.md, AGENTS.md, pyproject.toml for an author-stated number of tools"
      },
      {
        "field": "autonomy",
        "searched": "entry type is mcp-server, not an agent; README.md and src/purple_mcp/server.py show no agent loop"
      }
    ]
  },
  "verdict": null,
  "runs": []
}
