monitoring-aiops 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- monitoring_aiops-0.1.0/.github/workflows/publish.yml +26 -0
- monitoring_aiops-0.1.0/.gitignore +7 -0
- monitoring_aiops-0.1.0/CHANGELOG.md +55 -0
- monitoring_aiops-0.1.0/LICENSE +21 -0
- monitoring_aiops-0.1.0/PKG-INFO +114 -0
- monitoring_aiops-0.1.0/README.md +98 -0
- monitoring_aiops-0.1.0/RELEASE_NOTES.md +56 -0
- monitoring_aiops-0.1.0/SECURITY.md +80 -0
- monitoring_aiops-0.1.0/mcp_server/__init__.py +1 -0
- monitoring_aiops-0.1.0/mcp_server/_shared.py +101 -0
- monitoring_aiops-0.1.0/mcp_server/server.py +36 -0
- monitoring_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
- monitoring_aiops-0.1.0/mcp_server/tools/alerts.py +35 -0
- monitoring_aiops-0.1.0/mcp_server/tools/prtg.py +95 -0
- monitoring_aiops-0.1.0/mcp_server/tools/prtg_write.py +67 -0
- monitoring_aiops-0.1.0/mcp_server/tools/sw_health.py +97 -0
- monitoring_aiops-0.1.0/mcp_server/tools/sw_write.py +189 -0
- monitoring_aiops-0.1.0/mcp_server/tools/swql.py +52 -0
- monitoring_aiops-0.1.0/monitoring_aiops/__init__.py +9 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/__init__.py +9 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/_common.py +78 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/_root.py +57 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/alert.py +51 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/doctor.py +21 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/init.py +118 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/overview.py +16 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/secret.py +105 -0
- monitoring_aiops-0.1.0/monitoring_aiops/cli/swql.py +51 -0
- monitoring_aiops-0.1.0/monitoring_aiops/config.py +148 -0
- monitoring_aiops-0.1.0/monitoring_aiops/connection.py +188 -0
- monitoring_aiops-0.1.0/monitoring_aiops/doctor.py +91 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/__init__.py +40 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/audit.py +377 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/budget.py +225 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/decorators.py +474 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/paths.py +23 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/patterns.py +378 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/policy.py +411 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/sanitize.py +39 -0
- monitoring_aiops-0.1.0/monitoring_aiops/governance/undo.py +218 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/__init__.py +1 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/_util.py +32 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/alerts.py +79 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/overview.py +29 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/prtg.py +145 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/prtg_write.py +59 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/sw_health.py +199 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/sw_write.py +179 -0
- monitoring_aiops-0.1.0/monitoring_aiops/ops/swql.py +95 -0
- monitoring_aiops-0.1.0/monitoring_aiops/secretstore.py +302 -0
- monitoring_aiops-0.1.0/pyproject.toml +59 -0
- monitoring_aiops-0.1.0/server.json +21 -0
- monitoring_aiops-0.1.0/skills/monitoring-aiops/SKILL.md +143 -0
- monitoring_aiops-0.1.0/skills/monitoring-aiops/references/capabilities.md +76 -0
- monitoring_aiops-0.1.0/skills/monitoring-aiops/references/cli-reference.md +57 -0
- monitoring_aiops-0.1.0/skills/monitoring-aiops/references/setup-guide.md +105 -0
- monitoring_aiops-0.1.0/smithery.yaml +9 -0
- monitoring_aiops-0.1.0/tests/test_prtg.py +81 -0
- monitoring_aiops-0.1.0/tests/test_prtg_write.py +50 -0
- monitoring_aiops-0.1.0/tests/test_secretstore.py +99 -0
- monitoring_aiops-0.1.0/tests/test_smoke.py +233 -0
- monitoring_aiops-0.1.0/tests/test_sw_health.py +73 -0
- monitoring_aiops-0.1.0/tests/test_sw_write.py +91 -0
- monitoring_aiops-0.1.0/uv.lock +962 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Trusted Publishing (OIDC) — publishes from GitHub's runners with no API token,
|
|
4
|
+
# sidestepping the local-IP / account new-project rate limit. Configure a matching
|
|
5
|
+
# "trusted publisher" for this package on PyPI (see the repo release notes).
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
publish:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
permissions:
|
|
18
|
+
id-token: write # required for PyPI Trusted Publishing (OIDC)
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Set up uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
- name: Build sdist + wheel
|
|
24
|
+
run: uv build
|
|
25
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
26
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to monitoring-aiops are documented here. This project adheres
|
|
4
|
+
to [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## [0.1.0] — preview
|
|
7
|
+
|
|
8
|
+
Initial preview release: governed AI-ops for **network / infrastructure
|
|
9
|
+
monitoring** across **SolarWinds Orion** (SWIS REST + SWQL) and **Paessler PRTG**
|
|
10
|
+
(web API), with a bundled governance harness. One config can span both NOCs.
|
|
11
|
+
**Mock-validated only — not yet verified against a live NOC.**
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **31 MCP tools** (23 read, 8 write), every one wrapped with the bundled
|
|
16
|
+
`@governed_tool` harness (audit, policy, token/runaway budget, undo,
|
|
17
|
+
risk-tiers):
|
|
18
|
+
- **SWQL (SolarWinds, read)** — `swql_library` (list the canned queries),
|
|
19
|
+
`swql_canned` (run a named canned query), `swql_query` (validated read-only
|
|
20
|
+
SELECT passthrough).
|
|
21
|
+
- **Alerts (both platforms)** — `active_alerts` (read; dedup/rollup by
|
|
22
|
+
message, collapsing flap/down storms into counted entries),
|
|
23
|
+
`alert_acknowledge` (write, low).
|
|
24
|
+
- **SolarWinds health (read)** — `node_status`, `nodes_list`,
|
|
25
|
+
`interface_status` (top-N by utilisation), `volume_status` (by % used),
|
|
26
|
+
`application_status` (SAM), `topn` (cpu/memory/latency/packetloss),
|
|
27
|
+
`noc_rollup` (down/warning counts + worst CPU).
|
|
28
|
+
- **SolarWinds writes** — `list_events`, `list_unmanaged`, `list_muted`
|
|
29
|
+
(read); `mute_alerts` (med, time-boxed, undo→unmute), `unmute_alerts` (med),
|
|
30
|
+
`schedule_maintenance` (med, requires end time), `unmanage_node` (**high**,
|
|
31
|
+
dry-run, undo→remanage), `remanage_node` (med), `remove_node` (**high**,
|
|
32
|
+
dry-run).
|
|
33
|
+
- **PRTG (read)** — `prtg_sensors`, `prtg_sensor_details`, `prtg_devices`,
|
|
34
|
+
`prtg_groups`, `prtg_history`, `prtg_system_status`, `prtg_alarms`.
|
|
35
|
+
- **PRTG writes** — `pause_sensor` (med, undo→resume), `resume_sensor` (med),
|
|
36
|
+
`schedule_maintenance_prtg` (med, time-boxed, requires minutes).
|
|
37
|
+
- **Canned-SWQL library** — the most-repeated THWACK questions as named,
|
|
38
|
+
validated queries: `nodes_down`, `flapping_interfaces`, `muted_report`,
|
|
39
|
+
`high_cpu_nodes`, `volumes_full`, `unmanaged_scheduled`.
|
|
40
|
+
- **Encrypted secret store** — the Orion account password or PRTG API token is
|
|
41
|
+
stored encrypted in `~/.monitoring-aiops/secrets.enc` (Fernet + scrypt); never
|
|
42
|
+
plaintext on disk. Legacy `MONITORING_<TARGET>_SECRET` env var honoured as a
|
|
43
|
+
fallback.
|
|
44
|
+
- **CLI** (`monitoring-aiops`) — `init` platform-picking wizard, `overview`,
|
|
45
|
+
`swql library/canned/query`, `alert list/ack`, `secret` management, and a
|
|
46
|
+
platform-aware `doctor` (SWQL query for SolarWinds, `/api/status.json` for
|
|
47
|
+
PRTG).
|
|
48
|
+
|
|
49
|
+
### Known limitations
|
|
50
|
+
|
|
51
|
+
- Preview / mock-only: SWIS REST + SWQL and PRTG web API responses are mocked and
|
|
52
|
+
need live verification against a real NOC. PRTG's free Freeware edition is the
|
|
53
|
+
easiest live check; SolarWinds is a 30-day trial only (largest verification
|
|
54
|
+
debt).
|
|
55
|
+
- Zabbix and other monitoring stacks are out of scope by design.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wei <zhouwei008@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: monitoring-aiops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Governed AI-ops for SolarWinds Orion (SWIS/SWQL) + Paessler PRTG: canned SWQL, alert dedup/rollup, node/interface health, and governed maintenance writes with a built-in governance harness (audit, budget, undo, risk tiers)
|
|
5
|
+
Author-email: wei <zhouwei008@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: cryptography>=42.0
|
|
10
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
11
|
+
Requires-Dist: mcp[cli]<2.0,>=1.10
|
|
12
|
+
Requires-Dist: pyyaml<7.0,>=6.0
|
|
13
|
+
Requires-Dist: rich<16.0,>=13.0
|
|
14
|
+
Requires-Dist: typer<1.0,>=0.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
<!-- mcp-name: io.github.AIops-tools/monitoring-aiops -->
|
|
18
|
+
|
|
19
|
+
# Monitoring AIops (preview)
|
|
20
|
+
|
|
21
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by SolarWinds, Paessler, or any monitoring vendor.** SolarWinds, Orion, SWQL, THWACK, PRTG and Paessler are trademarks of their respective owners. MIT licensed.
|
|
22
|
+
|
|
23
|
+
Governed AI-ops for **network / infrastructure monitoring** across two NOC
|
|
24
|
+
platforms in one server — **SolarWinds Orion** (SWIS REST + SWQL, port 17778,
|
|
25
|
+
HTTP Basic auth) and **Paessler PRTG** (web API, port 443/8080, API token) — with
|
|
26
|
+
a **built-in governance harness**: unified audit log, policy engine,
|
|
27
|
+
token/runaway budget guard, undo-token recording, and graduated-autonomy risk
|
|
28
|
+
tiers. One config can span both NOCs; each target names its own `platform`.
|
|
29
|
+
**Preview — mock-validated only, not yet verified against a live NOC.**
|
|
30
|
+
|
|
31
|
+
## What it does
|
|
32
|
+
|
|
33
|
+
Answers the questions a NOC operator actually repeats, and guards the writes
|
|
34
|
+
that follow:
|
|
35
|
+
|
|
36
|
+
- **Canned-SWQL library** — the most-asked THWACK questions shipped as named,
|
|
37
|
+
validated queries (`nodes_down`, `flapping_interfaces`, `muted_report`,
|
|
38
|
+
`high_cpu_nodes`, `volumes_full`, `unmanaged_scheduled`), plus a **validated
|
|
39
|
+
read-only SWQL passthrough** (SELECT-only) for everything else.
|
|
40
|
+
- **Active-alert dedup / rollup** — collapses an interface-flap or node-down
|
|
41
|
+
storm into a single counted entry instead of a wall of near-identical alerts,
|
|
42
|
+
across both SolarWinds and PRTG.
|
|
43
|
+
- **Dual SolarWinds + PRTG coverage** — one MCP server spans both NOCs; no
|
|
44
|
+
incumbent hobby MCP does.
|
|
45
|
+
- **Governed writes** — mute/unmute, maintenance windows, unmanage/remanage,
|
|
46
|
+
node removal, and PRTG sensor pause/resume — each audited, risk-tiered, and
|
|
47
|
+
the destructive ones gated with **dry-run + double-confirm**. Suppression and
|
|
48
|
+
maintenance writes are **time-boxed** (they require an end time / duration).
|
|
49
|
+
|
|
50
|
+
## Capability matrix (31 MCP tools)
|
|
51
|
+
|
|
52
|
+
| Group | Platform | Tools | Count | R/W |
|
|
53
|
+
|-------|----------|-------|:-----:|:---:|
|
|
54
|
+
| **SWQL** | SolarWinds | `swql_library`, `swql_canned`, `swql_query` | 3 | read |
|
|
55
|
+
| **Alerts** | both | `active_alerts` (dedup/rollup) | 1 | read |
|
|
56
|
+
| | both | `alert_acknowledge` | 1 | write (low) |
|
|
57
|
+
| **SolarWinds health** | SolarWinds | `node_status`, `nodes_list`, `interface_status`, `volume_status`, `application_status`, `topn`, `noc_rollup` | 7 | read |
|
|
58
|
+
| **SolarWinds writes** | SolarWinds | `list_events`, `list_unmanaged`, `list_muted` | 3 | read |
|
|
59
|
+
| | SolarWinds | `mute_alerts`, `unmute_alerts`, `schedule_maintenance`, `remanage_node` | 4 | write (med) |
|
|
60
|
+
| | SolarWinds | `unmanage_node`, `remove_node` | 2 | write (**high**) |
|
|
61
|
+
| **PRTG reads** | PRTG | `prtg_sensors`, `prtg_sensor_details`, `prtg_devices`, `prtg_groups`, `prtg_history`, `prtg_system_status`, `prtg_alarms` | 7 | read |
|
|
62
|
+
| **PRTG writes** | PRTG | `pause_sensor`, `resume_sensor`, `schedule_maintenance_prtg` | 3 | write (med) |
|
|
63
|
+
|
|
64
|
+
The CLI exposes a convenience subset; the full 31-tool surface is via the MCP
|
|
65
|
+
server.
|
|
66
|
+
|
|
67
|
+
## Quick start
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv tool install monitoring-aiops # or: pipx install monitoring-aiops
|
|
71
|
+
monitoring-aiops init # wizard: pick platform (solarwinds/prtg) + store the secret (encrypted)
|
|
72
|
+
monitoring-aiops doctor # verify config, secrets, connectivity
|
|
73
|
+
monitoring-aiops overview # NOC summary: platform + active/unacked alerts + top rollup
|
|
74
|
+
monitoring-aiops swql library # list the canned SWQL queries
|
|
75
|
+
monitoring-aiops swql canned nodes_down # run a named canned query
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Run as an MCP server (stdio):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
export MONITORING_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
|
|
82
|
+
monitoring-aiops mcp
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Governance
|
|
86
|
+
|
|
87
|
+
Every MCP tool passes through the bundled `@governed_tool` harness:
|
|
88
|
+
|
|
89
|
+
- **Audit** — every call (params, result, status, duration, risk tier,
|
|
90
|
+
approver, rationale) is logged to `~/.monitoring-aiops/audit.db` (relocatable
|
|
91
|
+
via `MONITORING_AIOPS_HOME`).
|
|
92
|
+
- **Budget / runaway guard** — token and call budgets trip a circuit breaker on
|
|
93
|
+
tight poll/retry loops.
|
|
94
|
+
- **Risk tiers** — graduated autonomy; high-risk ops (`unmanage_node`,
|
|
95
|
+
`remove_node`) can require a named approver (`MONITORING_AUDIT_APPROVED_BY` /
|
|
96
|
+
`MONITORING_AUDIT_RATIONALE`).
|
|
97
|
+
- **Undo recording** — reversible writes record an inverse descriptor
|
|
98
|
+
(`mute_alerts`→unmute, `unmanage_node`→remanage, `pause_sensor`→resume).
|
|
99
|
+
|
|
100
|
+
## Supported scope & limitations
|
|
101
|
+
|
|
102
|
+
- **Platforms**: SolarWinds Orion (SWIS REST + SWQL) and Paessler PRTG (web API).
|
|
103
|
+
Zabbix is deliberately **out of scope** for this tool.
|
|
104
|
+
- **Preview / mock-only.** All behaviour is validated against mocked SWIS/PRTG
|
|
105
|
+
responses. **PRTG has a free perpetual 100-sensor Freeware edition with the
|
|
106
|
+
API — the easiest live check.** SolarWinds is a 30-day trial only; past the
|
|
107
|
+
trial this tool is **mock-only, which is the largest verification debt.**
|
|
108
|
+
`monitoring-aiops doctor` is the fastest live check (a SWQL query for
|
|
109
|
+
SolarWinds, `/api/status.json` for PRTG).
|
|
110
|
+
|
|
111
|
+
## Missing a capability?
|
|
112
|
+
|
|
113
|
+
Want another canned query, a platform dialect fixed, or a capability that isn't
|
|
114
|
+
here? **Open an issue or a PR — feedback and contributions are welcome.**
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.AIops-tools/monitoring-aiops -->
|
|
2
|
+
|
|
3
|
+
# Monitoring AIops (preview)
|
|
4
|
+
|
|
5
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by SolarWinds, Paessler, or any monitoring vendor.** SolarWinds, Orion, SWQL, THWACK, PRTG and Paessler are trademarks of their respective owners. MIT licensed.
|
|
6
|
+
|
|
7
|
+
Governed AI-ops for **network / infrastructure monitoring** across two NOC
|
|
8
|
+
platforms in one server — **SolarWinds Orion** (SWIS REST + SWQL, port 17778,
|
|
9
|
+
HTTP Basic auth) and **Paessler PRTG** (web API, port 443/8080, API token) — with
|
|
10
|
+
a **built-in governance harness**: unified audit log, policy engine,
|
|
11
|
+
token/runaway budget guard, undo-token recording, and graduated-autonomy risk
|
|
12
|
+
tiers. One config can span both NOCs; each target names its own `platform`.
|
|
13
|
+
**Preview — mock-validated only, not yet verified against a live NOC.**
|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
Answers the questions a NOC operator actually repeats, and guards the writes
|
|
18
|
+
that follow:
|
|
19
|
+
|
|
20
|
+
- **Canned-SWQL library** — the most-asked THWACK questions shipped as named,
|
|
21
|
+
validated queries (`nodes_down`, `flapping_interfaces`, `muted_report`,
|
|
22
|
+
`high_cpu_nodes`, `volumes_full`, `unmanaged_scheduled`), plus a **validated
|
|
23
|
+
read-only SWQL passthrough** (SELECT-only) for everything else.
|
|
24
|
+
- **Active-alert dedup / rollup** — collapses an interface-flap or node-down
|
|
25
|
+
storm into a single counted entry instead of a wall of near-identical alerts,
|
|
26
|
+
across both SolarWinds and PRTG.
|
|
27
|
+
- **Dual SolarWinds + PRTG coverage** — one MCP server spans both NOCs; no
|
|
28
|
+
incumbent hobby MCP does.
|
|
29
|
+
- **Governed writes** — mute/unmute, maintenance windows, unmanage/remanage,
|
|
30
|
+
node removal, and PRTG sensor pause/resume — each audited, risk-tiered, and
|
|
31
|
+
the destructive ones gated with **dry-run + double-confirm**. Suppression and
|
|
32
|
+
maintenance writes are **time-boxed** (they require an end time / duration).
|
|
33
|
+
|
|
34
|
+
## Capability matrix (31 MCP tools)
|
|
35
|
+
|
|
36
|
+
| Group | Platform | Tools | Count | R/W |
|
|
37
|
+
|-------|----------|-------|:-----:|:---:|
|
|
38
|
+
| **SWQL** | SolarWinds | `swql_library`, `swql_canned`, `swql_query` | 3 | read |
|
|
39
|
+
| **Alerts** | both | `active_alerts` (dedup/rollup) | 1 | read |
|
|
40
|
+
| | both | `alert_acknowledge` | 1 | write (low) |
|
|
41
|
+
| **SolarWinds health** | SolarWinds | `node_status`, `nodes_list`, `interface_status`, `volume_status`, `application_status`, `topn`, `noc_rollup` | 7 | read |
|
|
42
|
+
| **SolarWinds writes** | SolarWinds | `list_events`, `list_unmanaged`, `list_muted` | 3 | read |
|
|
43
|
+
| | SolarWinds | `mute_alerts`, `unmute_alerts`, `schedule_maintenance`, `remanage_node` | 4 | write (med) |
|
|
44
|
+
| | SolarWinds | `unmanage_node`, `remove_node` | 2 | write (**high**) |
|
|
45
|
+
| **PRTG reads** | PRTG | `prtg_sensors`, `prtg_sensor_details`, `prtg_devices`, `prtg_groups`, `prtg_history`, `prtg_system_status`, `prtg_alarms` | 7 | read |
|
|
46
|
+
| **PRTG writes** | PRTG | `pause_sensor`, `resume_sensor`, `schedule_maintenance_prtg` | 3 | write (med) |
|
|
47
|
+
|
|
48
|
+
The CLI exposes a convenience subset; the full 31-tool surface is via the MCP
|
|
49
|
+
server.
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
uv tool install monitoring-aiops # or: pipx install monitoring-aiops
|
|
55
|
+
monitoring-aiops init # wizard: pick platform (solarwinds/prtg) + store the secret (encrypted)
|
|
56
|
+
monitoring-aiops doctor # verify config, secrets, connectivity
|
|
57
|
+
monitoring-aiops overview # NOC summary: platform + active/unacked alerts + top rollup
|
|
58
|
+
monitoring-aiops swql library # list the canned SWQL queries
|
|
59
|
+
monitoring-aiops swql canned nodes_down # run a named canned query
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Run as an MCP server (stdio):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export MONITORING_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
|
|
66
|
+
monitoring-aiops mcp
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Governance
|
|
70
|
+
|
|
71
|
+
Every MCP tool passes through the bundled `@governed_tool` harness:
|
|
72
|
+
|
|
73
|
+
- **Audit** — every call (params, result, status, duration, risk tier,
|
|
74
|
+
approver, rationale) is logged to `~/.monitoring-aiops/audit.db` (relocatable
|
|
75
|
+
via `MONITORING_AIOPS_HOME`).
|
|
76
|
+
- **Budget / runaway guard** — token and call budgets trip a circuit breaker on
|
|
77
|
+
tight poll/retry loops.
|
|
78
|
+
- **Risk tiers** — graduated autonomy; high-risk ops (`unmanage_node`,
|
|
79
|
+
`remove_node`) can require a named approver (`MONITORING_AUDIT_APPROVED_BY` /
|
|
80
|
+
`MONITORING_AUDIT_RATIONALE`).
|
|
81
|
+
- **Undo recording** — reversible writes record an inverse descriptor
|
|
82
|
+
(`mute_alerts`→unmute, `unmanage_node`→remanage, `pause_sensor`→resume).
|
|
83
|
+
|
|
84
|
+
## Supported scope & limitations
|
|
85
|
+
|
|
86
|
+
- **Platforms**: SolarWinds Orion (SWIS REST + SWQL) and Paessler PRTG (web API).
|
|
87
|
+
Zabbix is deliberately **out of scope** for this tool.
|
|
88
|
+
- **Preview / mock-only.** All behaviour is validated against mocked SWIS/PRTG
|
|
89
|
+
responses. **PRTG has a free perpetual 100-sensor Freeware edition with the
|
|
90
|
+
API — the easiest live check.** SolarWinds is a 30-day trial only; past the
|
|
91
|
+
trial this tool is **mock-only, which is the largest verification debt.**
|
|
92
|
+
`monitoring-aiops doctor` is the fastest live check (a SWQL query for
|
|
93
|
+
SolarWinds, `/api/status.json` for PRTG).
|
|
94
|
+
|
|
95
|
+
## Missing a capability?
|
|
96
|
+
|
|
97
|
+
Want another canned query, a platform dialect fixed, or a capability that isn't
|
|
98
|
+
here? **Open an issue or a PR — feedback and contributions are welcome.**
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Monitoring AIops v0.1.0 — preview
|
|
2
|
+
|
|
3
|
+
Governed AI-ops for **network / infrastructure monitoring** across **SolarWinds
|
|
4
|
+
Orion** (SWIS REST + SWQL) and **Paessler PRTG** (web API) for AI agents, with a
|
|
5
|
+
built-in governance harness (audit, policy, token/runaway budget, undo-token
|
|
6
|
+
recording, graduated risk tiers) and an encrypted credential store. Standalone —
|
|
7
|
+
no external skill-family dependency. One config can span both NOCs.
|
|
8
|
+
|
|
9
|
+
> **Preview / mock-only.** All behaviour is validated against mocked SWIS/PRTG
|
|
10
|
+
> responses; it has not been run against a live NOC. **PRTG's free perpetual
|
|
11
|
+
> 100-sensor Freeware edition (with the API) is the easiest live check;
|
|
12
|
+
> SolarWinds is a 30-day trial only — mock-only past that, the largest
|
|
13
|
+
> verification debt.** The fastest live check is `monitoring-aiops doctor`.
|
|
14
|
+
|
|
15
|
+
## Highlights
|
|
16
|
+
|
|
17
|
+
- **31 MCP tools** (23 read, 8 write), every one wrapped with `@governed_tool`.
|
|
18
|
+
- **SWQL (SolarWinds)** — `swql_library`, `swql_canned`, `swql_query`
|
|
19
|
+
(validated read-only SELECT passthrough).
|
|
20
|
+
- **Alerts (both platforms)** — `active_alerts` (dedup/rollup by message),
|
|
21
|
+
`alert_acknowledge`.
|
|
22
|
+
- **SolarWinds health** — `node_status`, `nodes_list`, `interface_status`,
|
|
23
|
+
`volume_status`, `application_status`, `topn`, `noc_rollup`.
|
|
24
|
+
- **SolarWinds writes** — `list_events`, `list_unmanaged`, `list_muted`;
|
|
25
|
+
`mute_alerts`/`unmute_alerts`, `schedule_maintenance`,
|
|
26
|
+
`unmanage_node`/`remanage_node`, `remove_node`.
|
|
27
|
+
- **PRTG** — `prtg_sensors`, `prtg_sensor_details`, `prtg_devices`,
|
|
28
|
+
`prtg_groups`, `prtg_history`, `prtg_system_status`, `prtg_alarms`;
|
|
29
|
+
`pause_sensor`/`resume_sensor`, `schedule_maintenance_prtg`.
|
|
30
|
+
- **Canned-SWQL library** — the most-repeated THWACK questions shipped as named,
|
|
31
|
+
validated queries (`nodes_down`, `flapping_interfaces`, `muted_report`,
|
|
32
|
+
`high_cpu_nodes`, `volumes_full`, `unmanaged_scheduled`).
|
|
33
|
+
- **Active-alert rollup** — collapses interface-flap / node-down storms into one
|
|
34
|
+
counted entry, across SolarWinds and PRTG.
|
|
35
|
+
- **Encrypted secret store** (`~/.monitoring-aiops/secrets.enc`, Fernet + scrypt)
|
|
36
|
+
— the Orion account password or PRTG API token, never plaintext on disk;
|
|
37
|
+
legacy `MONITORING_<TARGET>_SECRET` env fallback.
|
|
38
|
+
- **Guarded writes** — destructive ops (`unmanage_node`, `remove_node`) require
|
|
39
|
+
dry-run + double-confirm; suppression/maintenance writes are time-boxed
|
|
40
|
+
(require an end time / duration).
|
|
41
|
+
- **CLI** with an `init` platform-picking wizard, `secret` management, and a
|
|
42
|
+
platform-aware `doctor`.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv tool install monitoring-aiops
|
|
48
|
+
monitoring-aiops init # pick platform (solarwinds/prtg) + store the secret
|
|
49
|
+
monitoring-aiops doctor
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Caveats
|
|
53
|
+
|
|
54
|
+
- Preview / mock-only: SWIS REST + SWQL and the PRTG web API responses are
|
|
55
|
+
mocked and need live verification (SolarWinds especially, past the trial).
|
|
56
|
+
- Zabbix and other monitoring stacks are out of scope by design.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Disclaimer
|
|
4
|
+
|
|
5
|
+
Community-maintained open-source project. **Not affiliated with, endorsed by, or
|
|
6
|
+
sponsored by SolarWinds or Paessler.** Product and trademark names (SolarWinds,
|
|
7
|
+
Orion, PRTG) belong to their owners. Source is auditable under the MIT license.
|
|
8
|
+
|
|
9
|
+
## Reporting Vulnerabilities
|
|
10
|
+
|
|
11
|
+
Report privately via a GitHub Security Advisory on
|
|
12
|
+
[github.com/AIops-tools/Monitoring-AIops](https://github.com/AIops-tools/Monitoring-AIops/security/advisories)
|
|
13
|
+
or email zhouwei008@gmail.com. Please do not open public issues for security
|
|
14
|
+
reports.
|
|
15
|
+
|
|
16
|
+
## Security Design
|
|
17
|
+
|
|
18
|
+
### Credential Management
|
|
19
|
+
- Per-target secrets — the SolarWinds Orion account password (used for SWIS HTTP
|
|
20
|
+
Basic auth) or the PRTG API token — live **encrypted** in
|
|
21
|
+
`~/.monitoring-aiops/secrets.enc` (Fernet/AES-128 + scrypt-derived key; chmod
|
|
22
|
+
600), never in `config.yaml` and never in source. The master password is never
|
|
23
|
+
stored — only a per-store random salt and the ciphertext are on disk.
|
|
24
|
+
- A legacy plaintext env var `MONITORING_<TARGET_NAME_UPPER>_SECRET` is still
|
|
25
|
+
honoured as a fallback with a deprecation warning (migrate with
|
|
26
|
+
`monitoring-aiops secret migrate`).
|
|
27
|
+
- The secret is held only in memory and never logged or echoed. For PRTG the API
|
|
28
|
+
token is passed as the `apitoken` request parameter (not embedded in a stored
|
|
29
|
+
URL); the config file holds only platform, host, port, username, and TLS
|
|
30
|
+
settings. SWQL passthrough is validated read-only (SELECT only) to keep the
|
|
31
|
+
query surface from being used for writes.
|
|
32
|
+
|
|
33
|
+
### Governed Operations
|
|
34
|
+
Every MCP tool runs through the bundled `@governed_tool` harness
|
|
35
|
+
(`monitoring_aiops.governance`):
|
|
36
|
+
- **Audit** — every call logged to a local SQLite DB under `~/.monitoring-aiops/`
|
|
37
|
+
(relocatable via `MONITORING_AIOPS_HOME`), agent-attributed, secret-redacted.
|
|
38
|
+
- **Token/runaway budget** — hard ceilings (`MONITORING_MAX_TOOL_CALLS` /
|
|
39
|
+
`MONITORING_MAX_TOOL_SECONDS`) plus an on-by-default guard that trips a tight
|
|
40
|
+
poll/retry loop, preventing unbounded API consumption (e.g. polling a slow
|
|
41
|
+
session).
|
|
42
|
+
- **Graduated risk tiers** — `~/.monitoring-aiops/rules.yaml` `risk_tiers` gate
|
|
43
|
+
writes by environment/tag; the highest tiers require a recorded approver.
|
|
44
|
+
- **Undo-token recording** — reversible writes capture the BEFORE state and
|
|
45
|
+
record an inverse descriptor (e.g. `mute_alerts`→`unmute_alerts`,
|
|
46
|
+
`unmanage_node`→`remanage_node`, `pause_sensor`→`resume_sensor`) so the change
|
|
47
|
+
can be rolled back.
|
|
48
|
+
|
|
49
|
+
### State-Changing Operations
|
|
50
|
+
Destructive writes — `unmanage_node`, `remove_node` — are `risk_level=high`,
|
|
51
|
+
accept a `dry_run` preview, and (under `risk_tiers`) require a recorded approver
|
|
52
|
+
(`MONITORING_AUDIT_APPROVED_BY` + `MONITORING_AUDIT_RATIONALE`). Suppression and
|
|
53
|
+
maintenance writes (`mute_alerts`, `schedule_maintenance`, `pause_sensor`,
|
|
54
|
+
`schedule_maintenance_prtg`) are `risk_level=medium` and **time-boxed** — they
|
|
55
|
+
require an end time / duration (no open-ended suppression). Acknowledge is
|
|
56
|
+
`risk_level=low`. Reversible writes capture before-state and record an undo token.
|
|
57
|
+
|
|
58
|
+
### SSL/TLS Verification
|
|
59
|
+
`verify_ssl` defaults to true; disable only for self-signed lab certificates.
|
|
60
|
+
|
|
61
|
+
### Prompt-Injection Protection
|
|
62
|
+
All server-returned text (node/interface captions, alert messages, sensor names,
|
|
63
|
+
event text) is passed through a `sanitize()` truncate + control-character strip
|
|
64
|
+
before reaching the agent.
|
|
65
|
+
|
|
66
|
+
### Network Scope
|
|
67
|
+
No webhooks, no telemetry, no outbound calls beyond the configured SolarWinds
|
|
68
|
+
SWIS and PRTG API endpoints. No post-install scripts or background services.
|
|
69
|
+
|
|
70
|
+
## Static Analysis
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uvx bandit -r monitoring_aiops/ mcp_server/
|
|
74
|
+
uv run ruff check .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Supported Versions
|
|
78
|
+
|
|
79
|
+
The latest released version receives security fixes. This is a preview (0.x);
|
|
80
|
+
pin a version in production.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""MCP server package for monitoring-aiops."""
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Shared MCP server primitives: the FastMCP instance, connection helper,
|
|
2
|
+
error sanitisation, and the ``@tool_errors`` decorator.
|
|
3
|
+
|
|
4
|
+
Tool modules under ``mcp_server/tools/`` import ``mcp`` from here and register
|
|
5
|
+
their ``@mcp.tool()`` functions onto it. ``mcp_server/server.py`` then imports
|
|
6
|
+
those modules and runs the server.
|
|
7
|
+
|
|
8
|
+
Keep ``Optional[X]`` (never PEP 604 ``X | None``) in any FastMCP-reflected
|
|
9
|
+
tool signature — on older mcp/pydantic the union eval'd to ``types.UnionType``
|
|
10
|
+
crashes FastMCP's ``issubclass`` check.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import functools
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
from collections.abc import Callable
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any, Optional
|
|
19
|
+
|
|
20
|
+
from mcp.server.fastmcp import FastMCP
|
|
21
|
+
|
|
22
|
+
from monitoring_aiops.config import load_config
|
|
23
|
+
from monitoring_aiops.connection import ConnectionManager, MonitoringApiError
|
|
24
|
+
from monitoring_aiops.governance import sanitize
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
_DOCTOR_HINT = "Run 'monitoring-aiops doctor' to verify connectivity and credentials."
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _safe_error(exc: Exception, tool: str) -> str:
|
|
32
|
+
"""Return an agent-safe error string; log full detail server-side only."""
|
|
33
|
+
logger.error("Tool %s failed", tool, exc_info=True)
|
|
34
|
+
_passthrough = (
|
|
35
|
+
ValueError,
|
|
36
|
+
FileNotFoundError,
|
|
37
|
+
KeyError,
|
|
38
|
+
PermissionError,
|
|
39
|
+
TimeoutError,
|
|
40
|
+
ConnectionError,
|
|
41
|
+
MonitoringApiError,
|
|
42
|
+
)
|
|
43
|
+
if isinstance(exc, _passthrough):
|
|
44
|
+
return sanitize(str(exc), 300)
|
|
45
|
+
return f"{type(exc).__name__}: operation failed."
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def tool_errors(shape: str = "dict") -> Callable:
|
|
49
|
+
"""Wrap a tool body in the canonical try/except → ``_safe_error`` pattern.
|
|
50
|
+
|
|
51
|
+
Place this *between* ``@governed_tool`` and the function so the audit
|
|
52
|
+
decorator and FastMCP still see the original signature.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def decorator(func: Callable) -> Callable:
|
|
56
|
+
name = func.__name__
|
|
57
|
+
|
|
58
|
+
@functools.wraps(func)
|
|
59
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
60
|
+
try:
|
|
61
|
+
return func(*args, **kwargs)
|
|
62
|
+
except Exception as e: # noqa: BLE001 — sanitised below
|
|
63
|
+
msg = _safe_error(e, name)
|
|
64
|
+
if shape == "list":
|
|
65
|
+
return [{"error": msg, "hint": _DOCTOR_HINT}]
|
|
66
|
+
if shape == "str":
|
|
67
|
+
return f"Error: {msg} {_DOCTOR_HINT}"
|
|
68
|
+
return {"error": msg, "hint": _DOCTOR_HINT}
|
|
69
|
+
|
|
70
|
+
return wrapper
|
|
71
|
+
|
|
72
|
+
return decorator
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
mcp = FastMCP(
|
|
76
|
+
"monitoring-aiops",
|
|
77
|
+
instructions=(
|
|
78
|
+
"Network/infra monitoring operations (preview) over SolarWinds Orion "
|
|
79
|
+
"(SWIS/SWQL) and Paessler PRTG: a canned-SWQL library + validated "
|
|
80
|
+
"read-only SWQL passthrough; node/interface/volume/application health and "
|
|
81
|
+
"top-N; active alerts with dedup/rollup; events and historical metrics; "
|
|
82
|
+
"PRTG sensors/alarms/history; and governed light writes — acknowledge "
|
|
83
|
+
"alerts, mute/pause (time-boxed), schedule maintenance, and "
|
|
84
|
+
"unmanage/add/remove a node. Destructive writes (unmanage / remove node) "
|
|
85
|
+
"are risk=high with a dry_run preview and require an approver. Every tool "
|
|
86
|
+
"runs through the monitoring-aiops governance harness (audit / budget / "
|
|
87
|
+
"risk-tier / undo)."
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
_conn_mgr: Optional[ConnectionManager] = None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _get_connection(target: Optional[str] = None) -> Any:
|
|
95
|
+
"""Return a Monitoring connection, lazily initialising the manager."""
|
|
96
|
+
global _conn_mgr # noqa: PLW0603
|
|
97
|
+
if _conn_mgr is None:
|
|
98
|
+
config_path_str = os.environ.get("MONITORING_AIOPS_CONFIG")
|
|
99
|
+
config_path = Path(config_path_str) if config_path_str else None
|
|
100
|
+
_conn_mgr = ConnectionManager(load_config(config_path))
|
|
101
|
+
return _conn_mgr.connect(target)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""MCP server wrapping monitoring-aiops operations (stdio transport).
|
|
2
|
+
|
|
3
|
+
Thin adapter layer: each ``@mcp.tool()`` function (in ``mcp_server/tools/``)
|
|
4
|
+
delegates to the ``monitoring_aiops`` ops package and is wrapped with the
|
|
5
|
+
monitoring-aiops ``@governed_tool`` harness (audit / budget / undo / risk-tier).
|
|
6
|
+
|
|
7
|
+
Standalone, self-governed network/infra monitoring operations (preview) over
|
|
8
|
+
SolarWinds Orion (SWIS/SWQL) and Paessler PRTG: SWQL, alert rollup, health, and
|
|
9
|
+
governed maintenance writes.
|
|
10
|
+
|
|
11
|
+
Source: https://github.com/AIops-tools/Monitoring-AIops
|
|
12
|
+
License: MIT
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
|
|
17
|
+
from mcp_server._shared import _safe_error, mcp, tool_errors
|
|
18
|
+
|
|
19
|
+
# Importing the tool modules registers every @mcp.tool() onto the shared
|
|
20
|
+
# `mcp` instance. Order does not matter; each module is self-contained.
|
|
21
|
+
from mcp_server.tools import ( # noqa: F401 — side effects
|
|
22
|
+
alerts,
|
|
23
|
+
prtg,
|
|
24
|
+
prtg_write,
|
|
25
|
+
sw_health,
|
|
26
|
+
sw_write,
|
|
27
|
+
swql,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
__all__ = ["mcp", "main", "_safe_error", "tool_errors"]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def main() -> None:
|
|
34
|
+
"""Run the MCP server over stdio."""
|
|
35
|
+
logging.basicConfig(level=logging.INFO)
|
|
36
|
+
mcp.run(transport="stdio")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""MCP tool modules. Importing each registers its @mcp.tool() functions."""
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Active-alert MCP tools (SolarWinds + PRTG): rollup read + acknowledge."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from mcp_server._shared import _get_connection, mcp, tool_errors
|
|
6
|
+
from monitoring_aiops.governance import governed_tool
|
|
7
|
+
from monitoring_aiops.ops import alerts as ops
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@mcp.tool()
|
|
11
|
+
@governed_tool(risk_level="low")
|
|
12
|
+
@tool_errors("dict")
|
|
13
|
+
def active_alerts(target: Optional[str] = None) -> dict:
|
|
14
|
+
"""[READ] Active alerts with dedup/rollup by message (SolarWinds or PRTG).
|
|
15
|
+
|
|
16
|
+
Rolls up storms (e.g. interface-flap repeats) into one counted entry so the
|
|
17
|
+
signal isn't buried under duplicates.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
target: Monitoring target name from config; omit for the default.
|
|
21
|
+
"""
|
|
22
|
+
return ops.active_alerts(_get_connection(target))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@mcp.tool()
|
|
26
|
+
@governed_tool(risk_level="low")
|
|
27
|
+
@tool_errors("dict")
|
|
28
|
+
def alert_acknowledge(alert_id: str, target: Optional[str] = None) -> dict:
|
|
29
|
+
"""[WRITE][risk=low] Acknowledge one active alert (reversible triage action).
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
alert_id: Alert id (AlertActiveID on SolarWinds, sensor objid on PRTG).
|
|
33
|
+
target: Monitoring target name from config; omit for the default.
|
|
34
|
+
"""
|
|
35
|
+
return ops.acknowledge_alert(_get_connection(target), alert_id)
|