Skip to main content

Model Context Protocol (MCP) server exposing the Thruk monitoring REST API (Naemon / Nagios / Icinga / Shinken).

Project description

thruk-mcp

CI codecov PyPI PyPI downloads License: MIT Python ghcr.io GitHub release

Model Context Protocol (MCP) server for Thruk — the unified web frontend for Naemon, Nagios, Icinga and Shinken.

Expose Thruk's REST API to MCP-compatible clients (Claude Desktop, Dust, LibreChat, OpenWebUI...) so that an LLM can query hosts/services, schedule downtimes, acknowledge problems, force rechecks and more in natural language.

Features

  • Read: hosts, services, hostgroups, servicegroups, downtimes, comments, sites, aggregated stats, current problems
  • Write: schedule/delete downtimes, acknowledge & remove acks, force rechecks
  • Escape hatch: thruk_query tool to call any Thruk REST endpoint
  • Multi-backend support (Thruk federated sites): pass backends="prod,dr" to any tool
  • Two transports: stdio (default) or Streamable-HTTP (--listen <port>)
  • Async httpx client with proper error handling and TLS verification
  • Tested with pytest + respx, linted with ruff, packaged with hatchling

Quick start

1. Configure

cp .env.example .env
$EDITOR .env   # set THRUK_BASE_URL and THRUK_API_KEY

An API key can be created from the Thruk user profile page (requires api_keys_enabled in thruk_local.conf) or via the REST API itself.

2a. Run with Docker

docker compose up -d
# MCP Streamable-HTTP endpoint: http://localhost:8001/mcp

2b. Run locally

pip install thruk-mcp        # or: pipx install thruk-mcp

# stdio mode (for Claude Desktop, LibreChat, etc.)
thruk-mcp

# HTTP mode
thruk-mcp --listen 8001

For local development of the project itself, see CONTRIBUTING.md.

3. Wire it to an MCP client

Claude Desktop (~/.config/Claude/claude_desktop_config.json or macOS equivalent):

{
  "mcpServers": {
    "thruk": {
      "command": "thruk-mcp",
      "env": {
        "THRUK_BASE_URL": "https://monitor.example.com/thruk",
        "THRUK_API_KEY": "xxxxxxxx"
      }
    }
  }
}

4. Use with the Docker MCP Gateway

The image at ghcr.io/k9fr4n/thruk-mcp:latest defaults to stdio transport, so it can be spawned natively by the gateway.

Option A — Private local catalog

# 1. Create your private catalog
docker mcp catalog create thruk-private

# 2. Register this server (catalog/server.yaml ships with the repo)
docker mcp catalog add thruk-private thruk-mcp ./catalog/server.yaml

# 3. Configure credentials & enable
docker mcp secret set thruk-mcp.api_key=YOUR_KEY
docker mcp config write thruk-mcp.base_url=https://monitor.example.com/thruk
docker mcp server enable thruk-mcp

# 4. Run the gateway with your catalog
docker mcp gateway run --catalog thruk-private

Then point any MCP client (Claude Desktop, VS Code, Cursor, ...) at the gateway as documented here.

Option B — Submit upstream

catalog/server.yaml, catalog/tools.json and catalog/readme.md follow the docker/mcp-registry schema and can be submitted to the official Docker MCP Catalog via PR.

What's exposed

29 MCP Tools

Read — state thruk_list_hosts, thruk_get_host, thruk_list_services, thruk_get_service, thruk_list_hostgroups, thruk_list_servicegroups, thruk_problems, thruk_stats, thruk_sites.

Read — history & comments thruk_list_logs, thruk_list_alerts, thruk_list_notifications, thruk_recent_events, thruk_list_comments, thruk_list_downtimes, thruk_get_downtime.

Write — downtime management thruk_schedule_downtime (host/service), thruk_schedule_host_services_downtime (all services of a host), thruk_schedule_propagated_host_downtime (parent+children), thruk_schedule_hostgroup_downtime, thruk_schedule_servicegroup_downtime, thruk_delete_downtime, thruk_delete_active_downtimes, thruk_delete_downtimes_by_filter.

Write — problem handling thruk_acknowledge, thruk_remove_acknowledgement, thruk_recheck.

Escape hatches thruk_query (raw call to any REST endpoint), thruk_run_background_query (long-running endpoint via Thruk's ?background=1 mechanism with automatic job polling).

All list-style tools share a consistent limit / offset / sort / columns contract. By default they return a tight subset of columns (~10 fields per row) to keep LLM token consumption low. Pass columns="" to opt out and receive every column the Thruk row contains.

5 MCP Resources

URI templates that MCP clients with a resource browser (Claude Desktop, VS Code, ...) can "open" like files:

URI Content
thruk://hosts/{name} Full host JSON
thruk://services/{host}/{service} Full service JSON
thruk://hostgroups/{name} Host group config + members
thruk://problems Current unhandled problems (hosts + services)
thruk://stats Aggregated host/service stats (cached)

3 MCP Prompts

Pre-canned workflows the user can invoke as a slash-command in the MCP client UI:

Prompt Arguments Purpose
investigate_alert host, optional service 7-step incident triage
schedule_maintenance target, duration_minutes, kind Safe downtime workflow with confirmation
diagnose_flapping host, service Root-cause a flapping service

Robustness

  • Connection retrieshttpx.AsyncHTTPTransport(retries=3) handles DNS failures, connection refusals, TLS handshakes.
  • HTTP retries with backoff — 5xx and 429 responses are retried up to 3 times with exponential backoff + jitter (cap 5 s).
  • Opt-in TTL cache — slow-moving endpoints (/sites, /processinfo, /hosts/stats, /services/stats, /contacts, /timeperiods, ...) are cached in-process for 15 s. Any tool can request caching via cache_ttl= on the underlying client. This absorbs the burst of identical calls an LLM agent typically issues across a multi-tool turn.
  • Pagination helperThrukClient.get_all() is an async generator that iterates pages of 500 rows up to a configurable hard limit (default 50 000), so internal callers can scan entire backends without manual offset math.
  • Long-running queries — the thruk_run_background_query tool wraps Thruk's ?background=1 flow and polls /thruk/jobs/<id>/output until the job completes (5 min default timeout).

Environment variables

Connection

Variable Default Description
THRUK_BASE_URL http://localhost/thruk Thruk URL (no trailing slash)
THRUK_API_KEY (required) X-Thruk-Auth-Key header
THRUK_AUTH_USER Impersonation user (superuser key only)
THRUK_VERIFY_SSL true Set false for self-signed certs
THRUK_TIMEOUT 30 HTTP timeout in seconds
THRUK_DEFAULT_BACKENDS CSV of default backend names (federated Thruk)

Security / multi-tenant (v0.6)

Variable Default Description
THRUK_READ_ONLY false Strip every write tool (ack, downtime, recheck, ...)
THRUK_ENABLED_TOOLS Allowlist of tool names. CSV with fnmatch wildcards. Empty = all
THRUK_AUDIT_LOG true Emit one JSON audit line on stderr per write tool invocation
THRUK_MAX_CONCURRENT 0 Cap of concurrent in-flight HTTP requests. 0 = unlimited

Security

  • Read-only mode — set THRUK_READ_ONLY=true to remove every write tool (thruk_acknowledge, thruk_schedule_*_downtime, thruk_recheck, thruk_delete_*, thruk_run_background_query) from the MCP server. The LLM literally cannot mutate monitoring state. Use this for general-purpose agents that should only observe.

  • Tool allowlistTHRUK_ENABLED_TOOLS=thruk_list_*,thruk_problems,thruk_stats restricts the exposed surface to the listed tools (fnmatch wildcards supported). Useful when fronting multiple LLM clients with the same gateway but different scopes.

  • Audit log — every write tool invocation emits one JSON line on thruk_mcp.audit (stderr by default):

    {"ts":"2026-05-17T22:00:00+00:00","tool":"thruk_acknowledge","user":"alice",
     "args":{"host":"srv01","comment":"investigating"},"target":"srv01","status":"ok"}
    

    Disable with THRUK_AUDIT_LOG=false. Sensitive keys (api_key, password, token) are redacted as *** before logging.

  • Rate limitTHRUK_MAX_CONCURRENT=8 caps in-flight HTTP requests with an asyncio.Semaphore. Combined with the v0.3 TTL cache, this protects the Thruk core from an LLM that loops on tools or chains them aggressively.

Development

pip install -e ".[dev]"
pre-commit install                              # one-time setup of git hooks

ruff check src tests && ruff format src tests   # lint + format
mypy src                                        # type-check
pytest -v --cov=thruk_mcp --cov-fail-under=80   # tests with coverage gate

Conventions:

  • Conventional Commits (feat:, fix:, chore:, docs:, refactor:, test:).
  • No direct push to main: branch → PR → squash merge.
  • Any new tool must come with a respx-mocked unit test in tests/test_tools.py and an entry in catalog/tools.json (Docker MCP Registry contract).
  • CI gate: ruff, ruff format --check, mypy, pytest with 80 % coverage minimum.

References

Project docs

  • CHANGELOG.md — what changed in each release.
  • UPGRADING.md — per-version migration notes.
  • SUPPORT.md — supported Python / Thruk / MCP-client versions, security policy, release cadence.
  • CONTRIBUTING.md — dev setup, PR conventions, tool / env-var contribution checklists.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thruk_mcp-1.0.2.tar.gz (41.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

thruk_mcp-1.0.2-py3-none-any.whl (23.7 kB view details)

Uploaded Python 3

File details

Details for the file thruk_mcp-1.0.2.tar.gz.

File metadata

  • Download URL: thruk_mcp-1.0.2.tar.gz
  • Upload date:
  • Size: 41.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for thruk_mcp-1.0.2.tar.gz
Algorithm Hash digest
SHA256 c1bda69e38d1de19aebf9ce25bdb6c1e53c8c371f22a909397cf09008328d4d9
MD5 46554f99a45d8517e67ded0ea3d299f2
BLAKE2b-256 aca6da1e882d61d032a338b78e808814479873fe4c61e3d3534a7d5c685b00f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for thruk_mcp-1.0.2.tar.gz:

Publisher: pypi.yml on k9fr4n/thruk-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file thruk_mcp-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: thruk_mcp-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 23.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for thruk_mcp-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c302e1cc3e080fa35563e27d223cabb8e864c100b025ba48b316bca993558cb5
MD5 18197a40afd9004ac72e0af82056c402
BLAKE2b-256 ef19431ac1594de89874bc01b8bd7ed930f1e0eb876f1d8b0e74381071db65a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for thruk_mcp-1.0.2-py3-none-any.whl:

Publisher: pypi.yml on k9fr4n/thruk-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page