A Model Context Protocol server that lets an AI assistant — Claude Code, OpenCode, Claude Desktop, or any MCP client — drive your UTMStack SIEM/XDR platform: triage alerts, search logs, run SQL, manage incidents, inspect agents, create and delete correlation rules, manage data filters, and run commands on endpoints.
Ships as a single self-contained binary. No Python installation required.
Find your platform below and copy the matching command. Each installer detects your CPU architecture automatically — one command per operating system, not per architecture.
curl -fsSL https://raw.githubusercontent.com/utmstack/MCP/main/install.sh | shcurl -fsSL https://raw.githubusercontent.com/utmstack/MCP/main/install.sh | shirm https://raw.githubusercontent.com/utmstack/MCP/main/install.ps1 | iexRun this in PowerShell, not cmd.exe. Under Git Bash or WSL, use the macOS/Linux
command instead.
| Operating system | Architecture | Asset |
|---|---|---|
| macOS 12+ | Apple Silicon (arm64) |
utmstack-mcp-darwin-arm64.tar.gz |
| macOS 12+ | Intel (x86_64) |
utmstack-mcp-darwin-amd64.tar.gz |
| Linux (glibc 2.35+) | x86_64 |
utmstack-mcp-linux-amd64.tar.gz |
| Linux (glibc 2.39+) | arm64 / aarch64 |
utmstack-mcp-linux-arm64.tar.gz |
| Windows 10/11 | x64 |
utmstack-mcp-windows-amd64.zip |
| Windows 11 | ARM64 |
utmstack-mcp-windows-arm64.zip |
Linux x86_64 targets glibc 2.35 (Ubuntu 22.04+, Debian 12+, RHEL 9+). Linux arm64 is built on a newer runner and targets glibc 2.39 (Ubuntu 24.04+, Debian 13+, Kali rolling). Alpine/musl is not covered — run from source there. 32-bit systems are not supported.
Every installer verifies the download's SHA256 against the checksums.txt published with
the release, and refuses to install if it cannot.
| Location | |
|---|---|
| macOS / Linux | /usr/local/bin/utmstack-mcp, or ~/.local/bin without sudo |
| Windows | %LOCALAPPDATA%\Programs\utmstack-mcp\utmstack-mcp.exe |
Set UTMSTACK_MCP_VERSION=1.2.3 to install a specific version.
These binaries are not code-signed. They run normally — signing is not required to execute anything on macOS or Windows — but it affects two situations:
macOS. Binaries fetched by curl are not quarantined, so the installer path works
as-is. If you download an asset from the Releases page in a browser, Gatekeeper will
block it — use the installer, or clear the flag:
xattr -dr com.apple.quarantine /usr/local/lib/utmstack-mcpWindows. SmartScreen triggers on Mark-of-the-Web, which browsers apply to downloads;
Invoke-WebRequest (what install.ps1 uses) does not, so the installer path is normally
silent. Separately, Microsoft Defender is known to heuristically flag PyInstaller-built
executables. If it quarantines utmstack-mcp.exe, the file is a false positive — verify
its SHA256 against checksums.txt on the release, then add an exclusion for
%LOCALAPPDATA%\Programs\utmstack-mcp.
Every release publishes checksums.txt, and the installers verify against it and refuse to
proceed if they cannot.
utmstack-mcp initThe wizard asks for your UTMStack URL, how to authenticate, and your TLS preference, then
validates the credentials against the live API before saving anything. It writes them
to a 0600 file (~/.config/utmstack-mcp/config.json, or %APPDATA%\utmstack-mcp on
Windows), so no credentials end up in shell history or in an MCP client's config.
Check it any time:
utmstack-mcp check # verify configuration and connectivity
utmstack-mcp config-path # print the config file locationBecause credentials live in the config file, registration carries no secrets and is the same everywhere.
Claude Code
claude mcp add --scope user utmstack -- utmstack-mcpOpenCode — add to ~/.config/opencode/opencode.json:
Claude Desktop — add to claude_desktop_config.json:
{ "mcpServers": { "utmstack": { "command": "utmstack-mcp" } } }The UTMStack CLI bundles this server preconfigured — nothing to register there.
utmstack-mcp init writes this file for you. Configuration is resolved in this order,
first match wins:
UTMSTACK_SERVERS(a JSON array) in the environmentUTMSTACK_SERVERS_FILEpointing at a JSON file~/.config/utmstack-mcp/config.json— whatinitwrites.envin the current directory (development convenience)
[
{
"name": "prod",
"url": "https://utm.example.com",
"user": "admin",
"pass": "...",
"default": true
},
{
"name": "lab",
"url": "https://10.0.0.2",
"apiKey": "...",
"caBundle": "/etc/ssl/certs/lab-ca.pem",
"allowAgentCommands": true
}
]| Key | Meaning |
|---|---|
name |
identifier used by the server= argument and use_server |
url |
base URL of the deployment |
user + pass |
console login — recommended, and required for run_agent_command |
apiKey |
sent as the Utm-Api-Key header |
jwt |
a ready id_token (static; cannot be refreshed) |
verifySSL |
defaults to true; see below |
caBundle |
path to a CA certificate — the right way to trust a self-signed cert |
allowAgentCommands |
defaults to false; see below |
default |
marks the default server |
Auth precedence per server: user+pass > jwt > apiKey.
Multiple deployments are supported: every tool takes an optional server= argument,
use_server switches the default, and list_servers shows what is configured.
TLS verification is on. UTMStack instances often use a self-signed certificate. The
right fix is caBundle, pointing at that certificate. You can set "verifySSL": false
instead, but the server warns on every start — that same connection carries your
administrator password to /api/authenticate, so anyone on the network path can read it.
Remote command execution is off. run_agent_command gives the assistant a root/SYSTEM
shell on an endpoint. SIEM log content is partly written by attackers and reaches the model
through search_logs and search_alerts, which puts a remote shell downstream of data you
do not control. Enable it per server with "allowAgentCommands": true, only where you want
that capability.
Beyond utmstack-mcp init, the assistant can set up or change a connection when you
ask it to in conversation — "connect to my UTMStack at https://utm.example.com with API
key …", or "change the UTMStack URL to …". It uses the configure_server tool, which
validates against the live API, writes the same owner-only config file, and applies the
change immediately. remove_server deletes a connection.
For safety, configure_server cannot enable remote agent command execution — turning on
allowAgentCommands stays a deliberate edit to the config file or a run of
utmstack-mcp init, never something reachable from a conversation that may contain
attacker-influenced log data.
Servers and health — list_servers, use_server, configure_server, remove_server, ping, whoami, get_version
Alerts — count_open_alerts, search_alerts, get_alert, get_alerts_for_response,
change_alert_status, mark_alert_false_positive, add_alert_notes, add_alert_tags
Logs — list_index_patterns, list_indices, get_index_properties, search_logs,
count_events, get_field_values, get_field_values_with_count, run_sql
Incidents — list_incidents, get_incident, create_incident, change_incident_status
Agents and data sources — list_agents, get_agent_by_hostname,
list_data_input_statuses, list_supported_data_types
Correlation rules — list_correlation_rules, get_correlation_rule,
create_correlation_rule, set_correlation_rule_active, delete_correlation_rule
Data filters — list_filters, get_filters_by_pipeline, create_filter, delete_filter
Agent commands — can_run_command, run_agent_command, list_agent_commands,
list_agents_with_commands
Destructive operations are bounded, because an assistant acting on a security product can suppress detections as easily as it can read them:
delete_correlation_ruleanddelete_filterrequireconfirm=True- Bulk alert writes are capped at 100 ids per call
- Page sizes are clamped, and oversized responses return a structured marker rather than truncated JSON
run_agent_commandvalidates the hostname, clamps its timeout, and refuses to run unless the permission check returns an explicit allow
git clone https://github.com/utmstack/MCP.git
cd MCP
python3 -m venv .venv && . .venv/bin/activate
pip install -e .
utmstack-mcp initBuild a binary for your platform:
pip install pyinstaller
pyinstaller --clean --noconfirm utmstack-mcp.spec
# -> dist/utmstack-mcp/Requires Python 3.10+.
Correlation rules take about five minutes to load into the engine before they fire.
The correlation engine matches normalized fields (log.eventCode, target.user,
log.eventDataScriptBlockText, …), not raw log.data.* fields.
User-created filters attach to module/integration pipelines. The built-in Windows and Linux system filters are edited in the web UI; the API returns 500 for those.
UTMStack's /ws console endpoint authenticates with ?access_token=<JWT> in the
query string, and accepts no header alternative we could find — so
run_agent_command has to send it that way. Query strings are commonly recorded
in reverse-proxy and gateway access logs. If your deployment ingests its own web
logs, that token can end up in the log store.
This only affects run_agent_command, which is disabled by default. Every other
tool authenticates with an Authorization header. If you enable agent commands,
consider excluding /ws request URIs from your access-log ingestion.
run_agent_command uses the interactive console, which speaks STOMP over SockJS at
/ws and requires a JWT — the Utm-Api-Key header is rejected there. Configure user and
pass for that tool; every other tool works with an API key.
Some deployments return HTTP 500 on the API-key path for certain endpoints, which is why JWT login is preferred throughout.
{ "mcp": { "utmstack": { "type": "local", "command": ["utmstack-mcp"], "enabled": true } } }