Purple AI MCP Server
README.md
<picture>
<source media="(prefers-color-scheme: dark)" type="image/svg+xml" srcset="https://www.sentinelone.com/wp-content/themes/sentinelone/assets/svg/header-logo-light.svg">
<source media="(prefers-color-scheme: light)" type="image/svg+xml" srcset="https://www.sentinelone.com/wp-content/themes/sentinelone/assets/svg/header-logo-dark.svg">
<img alt="SentinelOne" src="https://www.sentinelone.com/wp-content/themes/sentinelone/assets/svg/header-logo-light.svg">
</picture>
# Purple AI MCP Server
[](https://opensource.org/licenses/MIT)
Purple AI MCP Server allows you to access SentinelOne Services with any MCP client.
## Features
This server exposes SentinelOne's platform through the Model Context Protocol:
- **Purple AI**: Ask security questions, investigate threats
- **Events**: Run PowerQueries on events in your SentinelOne data lake
- **Alerts**: Query, search, and investigate alerts
- **Vulnerabilities**: Track CVEs and security findings
- **Misconfigurations**: Analyze security posture issues
- **Inventory**: Ask questions about endpoints, cloud resources, identities, and network devices
- **CVE Search**: Query public CVE databases for vulnerability details
- **Threat Intelligence**: Get file, URL, domain, and IP analysis from VirusTotal
Purple AI MCP is a read-only service - you cannot make changes to your account or any objects
within your account from this MCP.
## Quick Start
### Using uv (Recommended for Local Development or Deployment)
```bash
# Install uv if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh
# Set credentials
export PURPLEMCP_CONSOLE_TOKEN="your_token"
export PURPLEMCP_CONSOLE_BASE_URL="https://your-console.sentinelone.net"
# Run
uvx --from git+https://github.com/Sentinel-One/purple-mcp.git purple-mcp --mode=stdio
```
#### ⚠️ Security note ⚠️
For production or security-sensitive environments, pin to a specific commit hash instead of using
the default branch to reduce supply chain risk from the our
[releases](https://github.com/Sentinel-One/purple-mcp/releases) or our verified commits in
[main](https://github.com/Sentinel-One/purple-mcp/commits/main) branch.
```bash
# Run with pinned hash
uvx --from git+https://github.com/Sentinel-One/purple-mcp.git@<commit-hash> purple-mcp --mode=stdio
```
### Using Docker
Follow instructions for Docker Deployment [here](deploy/README.md#using-docker)
### Using Amazon Bedrock AgentCore
Follow instructions for Amazon Bedrock AgentCore Deployment
[here](deploy/README.md#using-amazon-bedrock-agentcore)
### Using Amazon Elastic Container Service (ECS)
Follow instructions for Amazon Elastic Container Service Deployment
[here](deploy/README.md#using-amazon-elastic-container-service-ecs)
### Using a Cloud Provider
For cloud deployments, see [Deployment Guide](deploy/cloud/CLOUD_SETUP.md).
**Note:** Purple AI MCP does not include built-in authentication. For network-exposed deployments,
place it behind a reverse proxy or load balancer. See [cloud Setup](deploy/cloud/CLOUD_SETUP.md)
for cloud load balancer configurations (AWS ALB, GCP Cloud Load Balancing, Azure Application
Gateway) or nginx examples for self-hosted deployments.
---
Your token needs Account or Site level permissions (not Global). Get one from Policy & Settings →
User Management → Service Users in your console. Currently, this server only supports tokens that
have access to a single Account or Site. If you need to access multiple sites, you will need to run
multiple MCP servers with Account-specific or Site-specific tokens.
## Authentication
Purple MCP uses a SentinelOne Console token configured at startup via environment variables. The
server authenticates with your SentinelOne Console using the provided token and base URL.
```bash
# Configure authentication credentials
PURPLEMCP_CONSOLE_TOKEN=YOUR_CONSOLE_TOKEN
PURPLEMCP_CONSOLE_BASE_URL=https://console.sentinelone.net
```
In addition you may define a console scope for Purple AI query operations:
```bash
PURPLEMCP_PURPLE_AI_CONSOLE_ACCOUNT_ID=1234567890123456789
```
This will scope Purple AI queries to account-scope with id `1234567890123456789`.
**Health Check Endpoints:**
The following endpoints bypass authentication to support container orchestration systems
(Kubernetes, Docker, etc.):
- `/health`, `/ready`, `/ping`
These endpoints return only basic status (`{"status": "ok"}`) and do not expose sensitive
information. See [SECURITY.md](SECURITY.md) for details.
## Clients
Purple AI MCP supports `stdio`, `sse`, and `streamable-http` protocols and should work in any
client that supports MCP. Some sample configurations are listed below.
### Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or
`%APPDATA%/Claude/claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"purple-mcp": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/Sentinel-One/purple-mcp.git",
"purple-mcp",
"--mode",
"stdio"
],
"env": {
"PURPLEMCP_CONSOLE_TOKEN": "your_token",
"PURPLEMCP_CONSOLE_BASE_URL": "https://your-console.sentinelone.net"
}
}
}
}
```
### Claude Code
Run this command in a terminal:
`claude mcp add --transport stdio purple-mcp --env PURPLEMCP_CONSOLE_TOKEN=your_token --env PURPLEMCP_CONSOLE_BASE_URL=https://your-console.sentinelone.net -- uvx --from git+https://github.com/Sentinel-One/purple-mcp.git purple-mcp --mode stdio`
### OpenAI Codex
Run this command in a terminal:
`codex mcp add purple-mcp --env PURPLEMCP_CONSOLE_TOKEN=your_token --env PURPLEMCP_CONSOLE_BASE_URL=https://your-console.sentinelone.net -- uvx --from git+https://github.com/Sentinel-One/purple-mcp.git purple-mcp --mode stdio`
### Pydantic AI
Here is some example Python code to use Purple MCP with a Pydantic AI Agent.
```python
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStdio
server = MCPServerStdio(
'uvx', args=["--from", "git+https://github.com/Sentinel-One/purple-mcp.git", "purple-mcp", "--mode", "stdio"], timeout=10
)
agent = Agent('anthropic:claude-haiku-4-5', toolsets=[server])
```
### Zed
Edit `~/.zed/mcp.json`:
```json
{
"mcpServers": {
"purple-mcp": {
"enabled": true,
"source": "custom",
"command": "uvx",
"args": [
"--from",
"git+https://github.com/Sentinel-One/purple-mcp.git",
"purple-mcp",
"--mode",
"stdio"
],
"env": {
"PURPLEMCP_CONSOLE_TOKEN": "your_token",
"PURPLEMCP_CONSOLE_BASE_URL": "https://your-console.sentinelone.net"
}
}
}
}
```
### Other Clients
For debugging or to host server for multiple clients, run in streamable-http mode and connect via
mcp-remote:
```bash
# Terminal 1: Start server
export PURPLEMCP_CONSOLE_TOKEN="your_token"
export PURPLEMCP_CONSOLE_BASE_URL="https://your-console.sentinelone.net"
uvx --from git+https://github.com/Sentinel-One/purple-mcp.git purple-mcp --mode streamable-http --host localhost --port 8000
# Terminal 2: Connect with any client
npx -y mcp-remote http://127.0.0.1:8000/mcp
```
We suggest you **do not** expose Purple AI MCP on a network at this time, as there is no
authentication enforced and anyone could access a configured SentinelOne account.
## Available Tools
### Purple AI
- `purple_ai(query)` - Ask security questions
### Data Lake
- `powerquery(query, start_time, end_time)` - Run PowerQuery analytics
### Alerts
- `get_alert(alert_id)` - Get alert details
- `list_alerts(first, after, view_type)` - List recent alerts
- `search_alerts(filters, first)` - Search with filters
- `get_alert_notes(alert_id)` - Get alert comments
- `get_alert_history(alert_id)` - View alert timeline
### Vulnerabilities
- `get_vulnerability(id)` - Get vulnerability details
- `list_vulnerabilities(first, after)` - List recent vulnerabilities
- `search_vulnerabilities(filters, first)` - Search CVEs and findings
- `get_vulnerability_notes(id)` - Get comments
- `get_vulnerability_history(id)` - View timeline
### Misconfigurations
- `get_misconfiguration(id)` - Get misconfiguration details
- `list_misconfigurations(first, after)` - List recent issues
- `search_misconfigurations(filters, first)` - Search by criteria
- `get_misconfiguration_notes(id)` - Get comments
- `get_misconfiguration_history(id)` - View timeline
### Asset Inventory
- `get_inventory_item(item_id, fetch_fields)` - Get asset details with field filtering
- `list_inventory_items(limit, skip, surface, fetch_fields)` - List assets by surface type
- `search_inventory_items(filters, limit, skip, fetch_fields)` - Search with advanced filters
**Field Filtering:** All inventory tools support `fetch_fields` parameter to control returned data:
- Presets: `MINIMAL` (7 fields), `STANDARD` (13 fields), `ALL` (~200+ fields)
- Custom lists: Specify exact fields in camelCase, e.g., `["id", "name", "resourceType"]`
- Use `get_inventory_item(item_id, fetch_fields="ALL")` on a single item to discover available
field names
### CVE Search (External)
Query public CVE databases (cve-search.org) for vulnerability information:
- `cve_search_by_id(cve_id)` - Get detailed CVE information by ID
- `cve_search_by_vendor(vendor, product)` - Search CVEs by vendor/product
- `cve_database_status()` - Get database update information
**Note:** No API key required. Data sourced from CIRCL.LU's cve-search.org.
### Threat Intelligence (External)
Query VirusTotal/Google Threat Intelligence for file, URL, domain, and IP analysis:
- `threat_intel_by_hash(hash_value)` - Get threat intel for file hash (MD5/SHA1/SHA256)
- `threat_intel_by_url(url)` - Get URL reputation and analysis
- `threat_intel_by_domain(domain)` - Get domain threat intelligence
- `threat_intel_by_ip(ip_address)` - Get IP address threat intelligence
- `threat_intel_get_file_relationships(hash_value, relationship_type)` - Get file relationships
(contacted domains/IPs, similar files)
- `threat_intel_search(query)` - Search VirusTotal Intelligence (Premium API required)
- `threat_intel_get_file_behavior(hash_value, sandbox)` - Get sandbox behavioral analysis
**Note:** Requires `PURPLEMCP_VT_API_KEY` environment variable with a valid VirusTotal API key.
## Environment Variables
### Required
- `PURPLEMCP_CONSOLE_TOKEN` - Authentication token (Service User token or Console API token)
- `PURPLEMCP_CONSOLE_BASE_URL` - Console URL (e.g., https://console.sentinelone.net)
### Optional
- `PURPLEMCP_SDL_BASE_URL` - Dedicated base URL for the SDL API
- When set, this URL is used directly instead of `PURPLEMCP_CONSOLE_BASE_URL` + `/sdl`
- Example: `https://your-dedicated-sdl-endpoint.sentinelone.net`
- When not set, the SDL API is accessed at `{PURPLEMCP_CONSOLE_BASE_URL}/sdl` (default behavior)
- `PURPLEMCP_VT_API_KEY` - VirusTotal API key for threat intelligence tools (get one from
https://www.virustotal.com/gui/my-apikey)
- `PURPLEMCP_SDL_CONSOLE_ACCOUNT_IDS` - Account IDs for SDL query scoping (comma-separated or JSON
array)
- When specified: queries are scoped to the provided account(s)
- When not specified: queries all accounts accessible to the token
- Example: `"426418030212073761"` or `"123,456,789"` or `["123", "456"]`
- `PURPLEMCP_SDL_CONSOLE_SITE_IDS` - Site IDs for SDL query scoping
- When specified: queries are scoped to the provided site
- Requires `PURPLEMCP_SDL_CONSOLE_ACCOUNT_IDS` to also be set with exactly one account ID
- Example: `"1234567890123456789"` or `"123,456,789"` or `"[123, 456]"`
- **Note:** Currently, only the first site ID is used.
- `PURPLEMCP_TRANSPORT_MODE` - MCP transport mode: `stdio`, `http`, `streamable-http`, or `sse`
(default: `stdio`)
- `PURPLEMCP_STATELESS_HTTP` - Enable stateless HTTP mode for serverless deployments (e.g., Amazon
Bedrock AgentCore) - see [deployment guide](deploy/aws_agentcore/BEDROCK_AGENTCORE_DEPLOYMENT.md)
## Development
We welcome your pull requests or issue submissions.
### Setup
```bash
# Install all dependencies
uv sync --all-groups
# Format and lint
uv run ruff format
uv run ruff check .
uv run mypy src tests
```
### Testing
```bash
# Run unit tests
uv run pytest tests/unit/ -v
# Run integration tests (requires .env.test with real credentials)
uv run pytest tests/integration/ -v
# All tests with coverage
uv run pytest --cov=src/purple_mcp --cov-report=html
```
### Env-vars for integration-testing of Account Scopes
There are some integration tests that require additional configuration to run (if left unconfigured
they will be skipped). If you want to run
[test_sdl_scope_integration.py](tests/integration/test_sdl_scope_integration.py) you will need to
define the following env-vars in your `.env.test` file (with the dummy values replaced for your
test scenario):
# An accessible account for your console token:
PURPLEMCP_SDL_CONSOLE_ACCOUNT_IDS=123456789012345678
# Another account from your console
PURPLEMCP_SDL_INT_TEST_SECOND_ACCOUNT_ID=222333444555666
# An Agent UUID accessible in your primary account:
PURPLEMCP_SDL_INT_TEST_AGENT_UUID=aaabbb-1234-5678-ccdd-678e89100bb1
# A timestamp at the middle of a 10-minute window where you expect to see events from the Agent UUID:
PURPLEMCP_SDL_INT_TEST_AGENT_EVENT_TIMESTAMP=2025-11-18T05:25:00+00:00
## Troubleshooting
- **Authentication errors**: Check your token has Account/Site level permissions (not Global), and
your token has not expired
- **PowerQuery does not return expected results**: Check your token has Account/Site level
permissions (not Global)
- **Connection failures**: Verify your console URL and network access; use `--verbose` for debug
logs
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
This project is open source and community-driven. Although it is not an official SentinelOne
product, it is maintained by SentinelOne in partnership with the broader open source developer
community. See our [LICENSE](LICENSE) file for further information.
For SentinelOne platform support, use the appropriate
[support channel](https://www.sentinelone.com/global-services/get-support-now/).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing