icinga-mcp
MCP server for analysing an Icinga 2 monitoring setup with an LLM.
Implements the Model Context Protocol revision 2026-07-28
(via the official Python SDK, which also falls back to 2025-11-25 for older clients).
Status: early development. Available on PyPI.
Scope (v1)
- Read active problems, host/service details, comments and downtimes (Icinga 2 REST API)
- Acknowledge problems, add comments, schedule/remove downtimes (opt-in, every change is confirmed by the user)
- Tools are grouped into toolsets that can be enabled/disabled individually; read-only by default
- Alert history via the IcingaDB Web module, optional (legacy
monitoringmodule supported) - Icinga Director configuration (read-only): hosts, templates, apply rules, commands, optional
Runs on Linux, macOS and Windows (Python 3.11+).
Creating, changing or deleting monitoring objects is intentionally out of scope.
Installation
icinga-mcp is started by your MCP client via uv. Install uv once:
# Linux / macOS
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Quick start (VS Code)
Add the server to your MCP configuration. Recommended: the user configuration
(command palette: MCP: Open User Configuration), so the credentials stay outside of any
repository. A workspace file .vscode/mcp.json works too, but must not be committed.
{
"servers": {
"icinga": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "domon-mcp-server", "icinga-mcp"],
"env": {
"ICINGA_URL": "https://icinga-master.example.com:5665",
"ICINGA_USER": "icinga-mcp",
"ICINGA_PASSWORD": "change-me",
"ICINGAWEB_URL": "https://icinga.example.com",
"ICINGAWEB_USER": "jdoe",
"ICINGAWEB_PASSWORD": "change-me",
"ICINGA_MCP_READ_ONLY": "false",
"ICINGA_MCP_AUTHOR": "jdoe"
}
}
}
}
The ICINGAWEB_* lines enable the alert history and the Director tools (optional). Omit the last two lines to keep
icinga-mcp read-only. The password is stored in plain text in this file. Use a dedicated, minimally privileged
ApiUser (see permissions) and protect the file accordingly.
To run from a local checkout instead of PyPI:
"command": "uv",
"args": ["run", "--directory", "/path/to/icinga-mcp", "icinga-mcp"],
On Windows use forward slashes or escaped backslashes in JSON paths, e.g.
"C:/Users/me/icinga-mcp".
Configuration
All settings are read from environment variables (the env block of the MCP configuration).
| Variable | Required | Description |
|---|---|---|
ICINGA_URL |
yes | Icinga 2 API base URL, e.g. https://icinga-master:5665 |
ICINGA_USER |
yes | Icinga 2 ApiUser name |
ICINGA_PASSWORD |
yes | API password |
ICINGA_CA_CERT |
no | Path to the CA that signed the API certificate (e.g. the Icinga CA). Setting it enables TLS certificate verification |
ICINGA_TLS_SERVER_NAME |
no | Expected certificate host name if it differs from the URL host (used for SNI and verification), e.g. when the API sits behind a Kubernetes ingress |
ICINGA_VERIFY_TLS |
no | Force verification on (true, e.g. for publicly trusted certificates without ICINGA_CA_CERT) or off (false). Default: on if ICINGA_CA_CERT is set, otherwise off |
ICINGA_TIMEOUT |
no | Request timeout in seconds (default 30) |
Icinga Web: history and Director (optional)
The Icinga 2 API has no history and does not know the Director data model. get_history
reads alert history from Icinga Web 2's IcingaDB module by default, the
director_* tools read the configuration from the Icinga Director REST API. Both are only
available when these variables are set:
| Variable | Required | Description |
|---|---|---|
ICINGAWEB_URL |
yes | Icinga Web 2 root URL, e.g. https://icinga.example.com (or .../icingaweb2) |
ICINGAWEB_USER |
yes | Icinga Web user (needs IcingaDB module access for history by default; monitoring module for legacy history; Director API access for Director tools) |
ICINGAWEB_PASSWORD |
yes | Password (HTTP basic auth) |
ICINGAWEB_HISTORY_BACKEND |
no | History source: icingadb (default) or monitoring for legacy IDO installations |
ICINGAWEB_CA_CERT |
no | CA bundle if the web server certificate is not publicly trusted |
ICINGAWEB_VERIFY_TLS |
no | Default true; set false only for debugging |
ICINGAWEB_TIMEOUT |
no | Request timeout in seconds (default 60) |
ICINGA_MCP_MAX_HISTORY |
no | Longest time window per query (default 31d) |
TLS certificate verification (optional)
Icinga 2 API certificates are usually signed by the internal Icinga CA, which no operating system trusts. By default icinga-mcp therefore connects without certificate verification and logs a warning. The API password is still sent encrypted, but the server identity is not checked, so a man-in-the-middle could capture the credentials.
To enable verification, store the CA once per instance and add to the env block:
"ICINGA_CA_CERT": "/home/me/.config/icinga-mcp/<instance>-ca.pem",
"ICINGA_TLS_SERVER_NAME": "<CN of the server certificate>"
ICINGA_TLS_SERVER_NAME is only needed if the certificate name differs from the URL host.
The CA is the last certificate printed by the following command (OpenSSL is included in
Linux, macOS and Git for Windows):
openssl s_client -connect <host>:5665 -showcerts </dev/null
Compare the CA fingerprint (openssl x509 -in <file> -noout -fingerprint -sha256) with the
one provided by your Icinga administrators.
Icinga 2 API permissions
Minimal ApiUser permissions:
object ApiUser "icinga-mcp" {
password = "..."
permissions = [
"status/query",
"objects/query/Host", "objects/query/Service",
"objects/query/HostGroup", "objects/query/ServiceGroup",
"objects/query/Comment", "objects/query/Downtime",
// only needed for write tools
"actions/acknowledge-problem", "actions/remove-acknowledgement",
"actions/add-comment", "actions/schedule-downtime", "actions/remove-downtime",
]
}
Tools
| Tool | Toolset | Mode | Description |
|---|---|---|---|
icinga_status |
status |
read | Version, feature flags, host/service counts per state, unhandled problems |
list_problems |
problems |
read | Current alerts (DOWN hosts, WARNING/CRITICAL/UNKNOWN services); filters for host/service patterns, host group, states, handled, hard states |
get_host |
objects |
read | Host details incl. check output, perfdata, custom vars (redacted) and its services |
get_service |
objects |
read | Service details incl. check output, perfdata, command and custom vars (redacted) |
list_hosts |
objects |
read | Search hosts by name/address pattern or host group |
acknowledge_problem |
acknowledgements |
write | Acknowledge problems (sticky, notify, expiry); OK or already acknowledged objects are skipped |
remove_acknowledgement |
acknowledgements |
write | Remove acknowledgements |
list_comments |
comments |
read | Comments and acknowledgement texts, newest first |
add_comment |
comments |
write | Add a comment (note) to hosts/services |
list_downtimes |
downtimes |
read | Scheduled downtimes and whether they are in effect |
director_list |
director |
read | Search the Director configuration: hosts, host/service templates, service apply rules, commands, host groups, notification templates, time periods. Needs Icinga Web |
director_get |
director |
read | One Director object with inherited properties (hosts/templates) and the objects that use a template or command. Needs Icinga Web |
get_history |
history |
read | Alert history in a time window (since = 24h, 7d or ISO 8601): hard/soft state changes, notifications, acknowledgements, comments, downtimes, flapping; summary with the most active objects. Needs Icinga Web |
schedule_downtime |
downtimes |
write | Fixed or flexible downtime (start = now or ISO 8601, end or duration like 2h), optionally for all services of a host |
remove_downtime |
downtimes |
write | Remove downtimes by name (from list_downtimes) |
Values below keys whose names look sensitive (*pass*, *secret*, *token*, *basicauth*,
...) are replaced by ***REDACTED*** in all tool results. Pure macro references such as
$snmp_password$ (e.g. in command arguments) stay visible because they contain no secret.
Enabling and disabling tools
| Variable | Default | Description |
|---|---|---|
ICINGA_MCP_TOOLSETS |
all | Comma-separated toolsets to enable, e.g. status,problems,objects |
ICINGA_MCP_DISABLED_TOOLS |
none | Comma-separated tool names to hide, e.g. remove_downtime |
ICINGA_MCP_READ_ONLY |
true |
Hide all write tools. Set to false to enable them |
Disabled tools are not registered at all, so the model never sees them.
icinga-mcp list-tools shows the effective selection.
Write tools and safety
Write tools are only available with ICINGA_MCP_READ_ONLY=false and need these settings:
| Variable | Default | Description |
|---|---|---|
ICINGA_MCP_AUTHOR |
(required) | Name recorded as author in Icinga, e.g. your user name |
ICINGA_MCP_MAX_TARGETS |
20 |
Maximum number of objects per call |
ICINGA_MCP_MAX_DOWNTIME |
14d |
Maximum length of a downtime |
ICINGA_MCP_REQUIRE_ELICITATION |
false |
Refuse changes from clients that cannot ask the user (see below) |
Safety measures:
- Targets are exact object names (
hostorhost!service), never patterns or free filters. All targets are looked up first; unknown names abort the call before anything is changed. - Every change is confirmed by the user. If the MCP client supports
elicitation
(e.g. VS Code), the user gets a dialog listing the objects and options. Clients without
elicitation get a preview on the first call; only a second call with
confirm=trueapplies the change. In that mode the model is instructed to ask the user first, but technically it could setconfirm=trueon its own; setICINGA_MCP_REQUIRE_ELICITATION=trueto rule that out. - Results report per object whether Icinga applied the change.
Command line
| Command | Description |
|---|---|
icinga-mcp / icinga-mcp serve |
Run the MCP server on stdio (started by the MCP client) |
icinga-mcp check |
Test connection, TLS, credentials, API permissions and (if configured) Icinga Web history access |
icinga-mcp list-tools |
Show all tools and which ones are enabled (no credentials needed) |
check reads the same environment variables as the server:
# Linux / macOS
ICINGA_URL=https://icinga-master:5665 ICINGA_USER=icinga-mcp ICINGA_PASSWORD='...' uvx --from domon-mcp-server icinga-mcp check
# Windows (PowerShell)
$env:ICINGA_URL = "https://icinga-master:5665"; $env:ICINGA_USER = "icinga-mcp"; $env:ICINGA_PASSWORD = "..."
uvx --from domon-mcp-server icinga-mcp check
Development
uv sync
uv run pytest # unit tests
uv run pytest -m integration # read-only tests against a real instance (needs ICINGA_* env)
uv run ruff check .
uv run ruff format --check .
uv run mypy
See AGENTS.md for architecture and conventions.
Metadata
Release files for domon-mcp-server 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| domon_mcp_server-0.1.1.tar.gz | 39.3 kB | With provenance | Details for domon_mcp_server-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| domon_mcp_server-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for domon_mcp_server-0.1.1-py3-none-any.whl |
Total release size: 91.3 kB
Release files / domon_mcp_server-0.1.1.tar.gz
| Download URL | domon_mcp_server-0.1.1.tar.gz |
|---|---|
| Size | 39.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
14d8ad71141dec866f8f278175ce4eebb462ad6bb978075d73dd635af834f285
|
|
BLAKE2b-256 checksum How to use checksums |
062a64cdf1ce3fd2d57c862076d0598970b996398610fd16598f075cf5f1cfcd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.
Transparency logRelease files / domon_mcp_server-0.1.1-py3-none-any.whl
| Download URL | domon_mcp_server-0.1.1-py3-none-any.whl |
|---|---|
| Size | 52.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59621ff36fc4d09f9f70dba9fe07e7fdc5e87bd8ec057682d9808651608ea60f
|
|
BLAKE2b-256 checksum How to use checksums |
7ac7fe40bba6ab14a6cba6519ccc4342a6272c95cd7a7a9902de15bf7090e7fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.
Transparency logSecurity for domon-mcp-server 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for domon_mcp_server-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.