proxy-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.
- proxy_aiops-0.1.0/.github/workflows/mcp-publish.yml +55 -0
- proxy_aiops-0.1.0/.github/workflows/publish.yml +26 -0
- proxy_aiops-0.1.0/.gitignore +8 -0
- proxy_aiops-0.1.0/CHANGELOG.md +68 -0
- proxy_aiops-0.1.0/LICENSE +21 -0
- proxy_aiops-0.1.0/PKG-INFO +213 -0
- proxy_aiops-0.1.0/README.md +197 -0
- proxy_aiops-0.1.0/RELEASE_NOTES.md +61 -0
- proxy_aiops-0.1.0/SECURITY.md +96 -0
- proxy_aiops-0.1.0/mcp_server/__init__.py +1 -0
- proxy_aiops-0.1.0/mcp_server/_shared.py +108 -0
- proxy_aiops-0.1.0/mcp_server/server.py +40 -0
- proxy_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
- proxy_aiops-0.1.0/mcp_server/tools/analysis.py +170 -0
- proxy_aiops-0.1.0/mcp_server/tools/certs.py +29 -0
- proxy_aiops-0.1.0/mcp_server/tools/configread.py +50 -0
- proxy_aiops-0.1.0/mcp_server/tools/routes.py +52 -0
- proxy_aiops-0.1.0/mcp_server/tools/services.py +74 -0
- proxy_aiops-0.1.0/mcp_server/tools/status.py +47 -0
- proxy_aiops-0.1.0/mcp_server/tools/traffic.py +36 -0
- proxy_aiops-0.1.0/mcp_server/tools/undo.py +121 -0
- proxy_aiops-0.1.0/mcp_server/tools/writes.py +265 -0
- proxy_aiops-0.1.0/proxy_aiops/__init__.py +14 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/__init__.py +5 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/_common.py +78 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/_root.py +68 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/analyze.py +81 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/certs.py +43 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/configcmd.py +107 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/doctor.py +21 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/init.py +166 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/overview.py +16 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/routes.py +59 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/secret.py +105 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/server.py +74 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/services.py +54 -0
- proxy_aiops-0.1.0/proxy_aiops/cli/undo.py +62 -0
- proxy_aiops-0.1.0/proxy_aiops/config.py +174 -0
- proxy_aiops-0.1.0/proxy_aiops/connection.py +189 -0
- proxy_aiops-0.1.0/proxy_aiops/doctor.py +97 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/__init__.py +40 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/audit.py +377 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/budget.py +225 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/decorators.py +482 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/paths.py +23 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/patterns.py +378 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/policy.py +430 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/sanitize.py +45 -0
- proxy_aiops-0.1.0/proxy_aiops/governance/undo.py +218 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/__init__.py +2 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/_util.py +86 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/analysis.py +469 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/certs.py +146 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/configread.py +94 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/overview.py +55 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/routes.py +209 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/services.py +304 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/status.py +73 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/traffic.py +178 -0
- proxy_aiops-0.1.0/proxy_aiops/ops/writes.py +174 -0
- proxy_aiops-0.1.0/proxy_aiops/platform.py +371 -0
- proxy_aiops-0.1.0/proxy_aiops/secretstore.py +304 -0
- proxy_aiops-0.1.0/pyproject.toml +60 -0
- proxy_aiops-0.1.0/server.json +21 -0
- proxy_aiops-0.1.0/skills/proxy-aiops/SKILL.md +159 -0
- proxy_aiops-0.1.0/skills/proxy-aiops/references/capabilities.md +86 -0
- proxy_aiops-0.1.0/skills/proxy-aiops/references/cli-reference.md +79 -0
- proxy_aiops-0.1.0/skills/proxy-aiops/references/setup-guide.md +99 -0
- proxy_aiops-0.1.0/smithery.yaml +9 -0
- proxy_aiops-0.1.0/tests/conftest.py +34 -0
- proxy_aiops-0.1.0/tests/test_analysis.py +224 -0
- proxy_aiops-0.1.0/tests/test_cli_writes.py +143 -0
- proxy_aiops-0.1.0/tests/test_doctor.py +215 -0
- proxy_aiops-0.1.0/tests/test_governance_persistence.py +187 -0
- proxy_aiops-0.1.0/tests/test_init.py +171 -0
- proxy_aiops-0.1.0/tests/test_platform.py +220 -0
- proxy_aiops-0.1.0/tests/test_reads.py +408 -0
- proxy_aiops-0.1.0/tests/test_secretstore.py +99 -0
- proxy_aiops-0.1.0/tests/test_smoke.py +137 -0
- proxy_aiops-0.1.0/tests/test_undo_executor.py +138 -0
- proxy_aiops-0.1.0/tests/test_writes.py +340 -0
- proxy_aiops-0.1.0/uv.lock +1121 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: mcp-publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
release:
|
|
6
|
+
types: [published]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish-mcp:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Wait for PyPI
|
|
18
|
+
# The release event also triggers the PyPI publish workflow; the MCP
|
|
19
|
+
# registry validates that the package version exists on PyPI, so poll
|
|
20
|
+
# until it has propagated (every 15s, up to 10 minutes).
|
|
21
|
+
run: |
|
|
22
|
+
python3 - <<'EOF'
|
|
23
|
+
import json
|
|
24
|
+
import sys
|
|
25
|
+
import time
|
|
26
|
+
import urllib.error
|
|
27
|
+
import urllib.request
|
|
28
|
+
|
|
29
|
+
with open("server.json", encoding="utf-8") as f:
|
|
30
|
+
package = json.load(f)["packages"][0]
|
|
31
|
+
name, version = package["identifier"], package["version"]
|
|
32
|
+
url = f"https://pypi.org/pypi/{name}/{version}/json"
|
|
33
|
+
deadline = time.monotonic() + 600
|
|
34
|
+
while True:
|
|
35
|
+
try:
|
|
36
|
+
with urllib.request.urlopen(url, timeout=10):
|
|
37
|
+
print(f"{name}=={version} is available on PyPI.")
|
|
38
|
+
sys.exit(0)
|
|
39
|
+
except (urllib.error.URLError, OSError) as exc:
|
|
40
|
+
print(f"{name}=={version} not on PyPI yet ({exc}); "
|
|
41
|
+
"retrying in 15s...")
|
|
42
|
+
if time.monotonic() >= deadline:
|
|
43
|
+
sys.exit(f"Timed out after 10 minutes waiting for "
|
|
44
|
+
f"{name}=={version} to appear on PyPI. "
|
|
45
|
+
"Check the PyPI publish workflow, then re-run "
|
|
46
|
+
"this workflow via workflow_dispatch.")
|
|
47
|
+
time.sleep(15)
|
|
48
|
+
EOF
|
|
49
|
+
- name: Install mcp-publisher
|
|
50
|
+
run: |
|
|
51
|
+
curl -sL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
|
|
52
|
+
- name: Login to MCP Registry (GitHub OIDC)
|
|
53
|
+
run: ./mcp-publisher login github-oidc
|
|
54
|
+
- name: Publish server.json
|
|
55
|
+
run: ./mcp-publisher publish
|
|
@@ -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,68 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to proxy-aiops are documented here. This project adheres
|
|
4
|
+
to [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## v0.1.0 — 2026-07-17
|
|
7
|
+
|
|
8
|
+
Initial preview release: governed AI-ops for **Traefik**, **Caddy** and
|
|
9
|
+
**HAProxy** reverse proxies / load balancers, with a bundled governance
|
|
10
|
+
harness. One MCP server spans all three platforms via a per-target `platform`
|
|
11
|
+
field; an explicit support matrix raises teaching errors for ops a platform
|
|
12
|
+
cannot do (never a silent no-op).
|
|
13
|
+
**Mock-validated only — not yet verified against a live proxy.**
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **26 MCP tools** (21 read, 5 write), every one wrapped with the bundled
|
|
18
|
+
`@governed_tool` harness (audit, policy, token/runaway budget, undo,
|
|
19
|
+
risk-tiers):
|
|
20
|
+
- **Status (read)** — `proxy_overview`, `version_info`, `list_entrypoints`.
|
|
21
|
+
- **Routes (read)** — `list_routes` (normalised hosts/paths across
|
|
22
|
+
platforms), `route_detail`, `find_route` (static host/path match).
|
|
23
|
+
- **Services (read)** — `list_services`, `service_detail`, `list_upstreams`
|
|
24
|
+
(server-level up/down/maint/drain + check info), `upstream_detail`,
|
|
25
|
+
`list_middlewares`.
|
|
26
|
+
- **Certificates (read)** — `list_certificates` (TLS domain inventory +
|
|
27
|
+
optional bounded live handshake probe).
|
|
28
|
+
- **Traffic (read)** — `traffic_stats`, `error_counters` (traefik /metrics
|
|
29
|
+
text parsed per status code; haproxy Data Plane stats per class).
|
|
30
|
+
- **Config (read)** — `config_snapshot`, `search_config`, `get_config_value`.
|
|
31
|
+
- **Flagship analyses (read)** — `backend_health_rca`, `cert_expiry_sweep`,
|
|
32
|
+
`error_rate_rca`, `route_conflict_analysis` — transparent heuristics that
|
|
33
|
+
report their numbers, not a black-box verdict.
|
|
34
|
+
- **Writes** — caddy `set_config_value` (med, prior subtree captured →
|
|
35
|
+
undo restores it), `delete_config_path` (**high**, subtree captured → undo
|
|
36
|
+
re-creates it), `load_config` (**high**, full prior config snapshotted →
|
|
37
|
+
undo re-loads it); haproxy `set_server_state` (med, ready/drain/maint,
|
|
38
|
+
undo restores prior admin state), `set_server_weight` (med, undo restores
|
|
39
|
+
prior weight). Every write takes a `dry_run` preview; high-risk writes
|
|
40
|
+
require an approver.
|
|
41
|
+
- **Platform abstraction with a support matrix** — a name-keyed registry maps
|
|
42
|
+
each target's `platform` (`traefik` / `caddy` / `haproxy`) to its auth style
|
|
43
|
+
+ REST resource paths, and unsupported ops raise **teaching errors**:
|
|
44
|
+
traefik writes point at its providers, haproxy config edits point at the
|
|
45
|
+
runtime writes, caddy error counters point at access logs.
|
|
46
|
+
- **Encrypted secret store** — the haproxy Data Plane API password (required)
|
|
47
|
+
or an optional Basic-auth credential for traefik/caddy is stored encrypted
|
|
48
|
+
in `~/.proxy-aiops/secrets.enc` (Fernet + scrypt); never plaintext on disk.
|
|
49
|
+
Traefik/caddy targets without a secret are treated as unauthenticated
|
|
50
|
+
localhost endpoints. Legacy `PROXY_<TARGET>_SECRET` env var honoured as a
|
|
51
|
+
fallback.
|
|
52
|
+
- **CLI** (`proxy-aiops`) — `init` platform-picking wizard (TLS-verify default
|
|
53
|
+
ON, seeds a starter rules.yaml with the dual-control high-risk tier),
|
|
54
|
+
`overview`, `routes list/show/find`, `services list/show/upstreams`,
|
|
55
|
+
`analyze health/errors/conflicts`, `certs --sweep`,
|
|
56
|
+
`config snapshot/search/get/set/delete` and `server state/weight`
|
|
57
|
+
(dry-run + double-confirm, executed through the governed twins so CLI writes
|
|
58
|
+
are audited + undo-recorded), `secret` management, and a `doctor`
|
|
59
|
+
connectivity check (health/info probe per platform).
|
|
60
|
+
|
|
61
|
+
### Known limitations
|
|
62
|
+
|
|
63
|
+
- Preview / mock-only: Traefik, Caddy and HAProxy responses are mocked and
|
|
64
|
+
need live verification; the modelled REST paths especially (the haproxy
|
|
65
|
+
runtime-server weight write in particular).
|
|
66
|
+
- haproxy host/path routing lives in haproxy.cfg ACLs and is not statically
|
|
67
|
+
analysed; `route_conflict_analysis` covers dead-backend detection there.
|
|
68
|
+
- **Missing a capability? Open an issue or PR** — contributions welcome.
|
|
@@ -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,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proxy-aiops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Governed AI-ops for Traefik + Caddy + HAProxy reverse proxies / load balancers: routes, services, upstream health, TLS cert expiry sweep, 5xx error-rate RCA, route conflict analysis, and governed writes (caddy config, haproxy server state/weight) 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/proxy-aiops -->
|
|
18
|
+
|
|
19
|
+
# Proxy AIops (preview)
|
|
20
|
+
|
|
21
|
+
Governed, audited AI-ops for **Traefik**, **Caddy** and **HAProxy** reverse proxies / load balancers — for AI agents (via MCP) and humans (via CLI).
|
|
22
|
+
|
|
23
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by Traefik Labs, the Caddy project, HAProxy Technologies, or the HAProxy project.** Traefik, Caddy and HAProxy are trademarks of their respective owners. MIT licensed.
|
|
24
|
+
|
|
25
|
+
proxy-aiops speaks to three proxy platforms behind one MCP server — **Traefik**
|
|
26
|
+
(its API under `/api/...`, metrics-text counters via `/metrics`), **Caddy** (the
|
|
27
|
+
admin API, default `localhost:2019`) and **HAProxy** (the Data Plane API v2 under
|
|
28
|
+
`/v2/...`, HTTP Basic auth) — with the **same tools working on all three**. Each
|
|
29
|
+
target in the config names its own `platform`; a name-keyed platform registry
|
|
30
|
+
selects the API shape (auth + resource paths), and an explicit **support matrix**
|
|
31
|
+
raises teaching errors for ops a platform genuinely cannot do — e.g. Traefik
|
|
32
|
+
writes point you at its providers (file, container labels, orchestrator CRDs), never
|
|
33
|
+
a silent no-op.
|
|
34
|
+
|
|
35
|
+
Every tool runs through a **built-in governance harness** (vendored, zero external
|
|
36
|
+
dependency): audit log, token/call budget with runaway circuit-breaker, graduated
|
|
37
|
+
risk-tier approval, undo-token recording, and output sanitisation.
|
|
38
|
+
|
|
39
|
+
## Why this exists
|
|
40
|
+
|
|
41
|
+
- **One server, three proxies** — Traefik, Caddy and HAProxy in a mixed edge,
|
|
42
|
+
spoken to through identical tool names. Adding another proxy later is a new
|
|
43
|
+
platform descriptor, not a rewrite.
|
|
44
|
+
- **Read the whole edge** — version, entrypoints/listeners, routes (routers /
|
|
45
|
+
caddy routes / frontends) with parsed hosts+paths, services and server-level
|
|
46
|
+
upstream health, middlewares, TLS domain inventory, traffic/error counters,
|
|
47
|
+
and the live config tree (snapshot + search).
|
|
48
|
+
- **Flagship RCA analyses** — transparent heuristics that show their numbers,
|
|
49
|
+
never a black-box verdict: `backend_health_rca` (down upstreams → cause class
|
|
50
|
+
L4/L6/L7/DNS/maint + action), `cert_expiry_sweep` (days-to-expiry buckets +
|
|
51
|
+
per-platform renewal hints), `error_rate_rca` (5xx share vs the fleet
|
|
52
|
+
baseline, dominant code → 502/503/504/500 cause), and
|
|
53
|
+
`route_conflict_analysis` (shadowed routes, dead routes, redirect loops).
|
|
54
|
+
- **Governed writes** — caddy config `set` / `delete` / full `load` (the prior
|
|
55
|
+
subtree/config is fetched first, so the recorded undo replays a real restore)
|
|
56
|
+
and haproxy runtime server `state` (ready/drain/maint) and `weight` (undo
|
|
57
|
+
restores the prior value) — all with `dry_run` previews; delete/load are
|
|
58
|
+
**risk=high** behind an approver gate.
|
|
59
|
+
|
|
60
|
+
## Tool inventory (26 tools)
|
|
61
|
+
|
|
62
|
+
| Domain | Tools | # | Kind |
|
|
63
|
+
|--------|-------|:-:|------|
|
|
64
|
+
| **Status** | `proxy_overview`, `version_info`, `list_entrypoints` | 3 | read |
|
|
65
|
+
| **Routes** | `list_routes`, `route_detail`, `find_route` | 3 | read |
|
|
66
|
+
| **Services** | `list_services`, `service_detail`, `list_upstreams`, `upstream_detail`, `list_middlewares` | 5 | read |
|
|
67
|
+
| **Certificates** | `list_certificates` | 1 | read |
|
|
68
|
+
| **Traffic** | `traffic_stats`, `error_counters` | 2 | read |
|
|
69
|
+
| **Config** | `config_snapshot`, `search_config`, `get_config_value` | 3 | read |
|
|
70
|
+
| **Flagship analyses** | `backend_health_rca`, `cert_expiry_sweep`, `error_rate_rca`, `route_conflict_analysis` | 4 | read |
|
|
71
|
+
| **Writes (caddy)** | `set_config_value` | 1 | write (**med**) |
|
|
72
|
+
| **Writes (caddy)** | `delete_config_path`, `load_config` | 2 | write (**high**) |
|
|
73
|
+
| **Writes (haproxy)** | `set_server_state`, `set_server_weight` | 2 | write (**med**) |
|
|
74
|
+
|
|
75
|
+
Reversible writes record an inverse **undo descriptor** built from the real fetched
|
|
76
|
+
before-state (`set_config_value` restores the prior subtree; `delete_config_path`
|
|
77
|
+
re-creates it; `load_config` re-loads the snapshotted config; server state/weight
|
|
78
|
+
restore the prior value). The undo params match each tool's own signature, so the
|
|
79
|
+
descriptor replays as-is.
|
|
80
|
+
|
|
81
|
+
### Per-platform support matrix
|
|
82
|
+
|
|
83
|
+
| Capability | traefik | caddy | haproxy |
|
|
84
|
+
|------------|:-------:|:-----:|:-------:|
|
|
85
|
+
| Routes / services / upstream health | ✅ | ✅ | ✅ |
|
|
86
|
+
| Middlewares list | ✅ | teaching note (inline handlers) | teaching note (haproxy.cfg) |
|
|
87
|
+
| TLS cert inventory + expiry sweep | ✅ | ✅ | teaching note (.pem files) |
|
|
88
|
+
| Error counters / error-rate RCA | ✅ (/metrics) | teaching note (no per-route counters) | ✅ (stats) |
|
|
89
|
+
| Config snapshot / search | ✅ (rawdata, read-only) | ✅ | teaching note |
|
|
90
|
+
| Config writes | teaching error → edit the **provider** | ✅ (the write surface) | teaching error → runtime writes |
|
|
91
|
+
| Runtime server state / weight | teaching error → provider | teaching error → config tree | ✅ |
|
|
92
|
+
|
|
93
|
+
Unsupported combinations **raise a teaching error that says what to use instead**
|
|
94
|
+
— never a silent empty result.
|
|
95
|
+
|
|
96
|
+
## Install
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv tool install proxy-aiops # or: pipx install proxy-aiops
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Quick start
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
proxy-aiops init # wizard: pick platform (traefik/caddy/haproxy) + optional encrypted secret
|
|
106
|
+
proxy-aiops doctor # verify config, secrets, and connectivity
|
|
107
|
+
proxy-aiops overview # one-shot: version + route/service counts + upstream health
|
|
108
|
+
proxy-aiops routes list # normalised route table
|
|
109
|
+
proxy-aiops services upstreams # server-level upstream health
|
|
110
|
+
proxy-aiops analyze health # backend/upstream health RCA
|
|
111
|
+
proxy-aiops analyze errors # 5xx error-rate RCA
|
|
112
|
+
proxy-aiops analyze conflicts # shadowed/dead routes, redirect loops
|
|
113
|
+
proxy-aiops certs --sweep # TLS cert expiry sweep (traefik/caddy)
|
|
114
|
+
proxy-aiops server state app web1 drain --dry-run # governed haproxy write preview
|
|
115
|
+
proxy-aiops config set apps/http/servers/srv0 '{"listen":[":8080"]}' --dry-run
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Run the MCP server (stdio) for an agent:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
proxy-aiops mcp # or: proxy-aiops-mcp
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### MCP client config
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"mcpServers": {
|
|
129
|
+
"proxy-aiops": {
|
|
130
|
+
"command": "uvx",
|
|
131
|
+
"args": ["--from", "proxy-aiops", "proxy-aiops-mcp"],
|
|
132
|
+
"env": { "PROXY_AIOPS_MASTER_PASSWORD": "your-master-password" }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> **Env-block caveat**: the `env` block is only needed when a credential is
|
|
139
|
+
> stored (haproxy always; traefik/caddy only behind Basic auth). MCP clients do
|
|
140
|
+
> **not** inherit your shell profile — set `PROXY_AIOPS_MASTER_PASSWORD` (and
|
|
141
|
+
> `PROXY_AIOPS_CONFIG` / `PROXY_AIOPS_HOME` if you relocated them) explicitly in
|
|
142
|
+
> the client config, or the server cannot unlock `secrets.enc`.
|
|
143
|
+
|
|
144
|
+
## Configuration
|
|
145
|
+
|
|
146
|
+
`~/.proxy-aiops/config.yaml` (non-secret connection details only):
|
|
147
|
+
|
|
148
|
+
```yaml
|
|
149
|
+
targets:
|
|
150
|
+
- name: edge1
|
|
151
|
+
platform: traefik # traefik | caddy | haproxy
|
|
152
|
+
base_url: http://192.0.2.10:8080
|
|
153
|
+
verify_ssl: true
|
|
154
|
+
- name: caddy1
|
|
155
|
+
platform: caddy
|
|
156
|
+
base_url: http://127.0.0.1:2019
|
|
157
|
+
- name: lb1
|
|
158
|
+
platform: haproxy
|
|
159
|
+
base_url: http://192.0.2.20:5555
|
|
160
|
+
username: dpapi # Data Plane API user
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The **secret** — the HAProxy Data Plane API password, or an optional Basic-auth
|
|
164
|
+
password in front of Traefik/Caddy — is stored **encrypted** in
|
|
165
|
+
`~/.proxy-aiops/secrets.enc` (Fernet + scrypt-derived key), never plaintext on
|
|
166
|
+
disk. Traefik and Caddy commonly run unauthenticated on localhost, so their
|
|
167
|
+
secret is **optional** (like a local socket); HAProxy's is required. Set it with
|
|
168
|
+
`proxy-aiops secret set <target>` or the `init` wizard. The store is unlocked by
|
|
169
|
+
a master password from `PROXY_AIOPS_MASTER_PASSWORD` (non-interactive/MCP/CI) or
|
|
170
|
+
an interactive prompt (CLI on a TTY). A legacy plaintext env var
|
|
171
|
+
`PROXY_<TARGET>_SECRET` is honoured as a fallback (migrate with
|
|
172
|
+
`proxy-aiops secret migrate`).
|
|
173
|
+
|
|
174
|
+
## Governance
|
|
175
|
+
|
|
176
|
+
Every MCP tool is wrapped by `@governed_tool`:
|
|
177
|
+
|
|
178
|
+
- **Audit** — every call is logged to `~/.proxy-aiops/audit.db` (tool, params with
|
|
179
|
+
secrets redacted, status, duration, risk tier, approver, rationale).
|
|
180
|
+
- **Budget / runaway guard** — per-process token/call caps and a repeat-call circuit
|
|
181
|
+
breaker (`PROXY_MAX_TOOL_CALLS`, `PROXY_RUNAWAY_MAX`, …).
|
|
182
|
+
- **Graduated risk tiers — secure by default** — with no
|
|
183
|
+
`~/.proxy-aiops/rules.yaml`, high-risk writes (`delete_config_path`,
|
|
184
|
+
`load_config`) require an approver: set `PROXY_AUDIT_APPROVED_BY` (and
|
|
185
|
+
`PROXY_AUDIT_RATIONALE`) before they will run. `init` seeds a starter
|
|
186
|
+
rules.yaml; an operator-authored rules file is honoured as-is.
|
|
187
|
+
- **Undo recording** — reversible writes record an inverse descriptor to
|
|
188
|
+
`~/.proxy-aiops/undo.db` from the fetched before-state (recording only; an
|
|
189
|
+
external orchestrator executes it). Undo params match the target tool's own
|
|
190
|
+
signature, so the descriptor replays as-is.
|
|
191
|
+
- **Sanitisation** — all proxy-returned text is bounded + control-character
|
|
192
|
+
sanitised before it reaches the agent.
|
|
193
|
+
|
|
194
|
+
## Preview status
|
|
195
|
+
|
|
196
|
+
- **Platforms**: Traefik (API + /metrics), Caddy (admin API), HAProxy (Data Plane
|
|
197
|
+
API v2).
|
|
198
|
+
- **Preview — mock-validated only. Not run against a live proxy.** All behaviour is
|
|
199
|
+
validated against mocked JSON/metrics responses; the concrete REST paths are
|
|
200
|
+
modelled from each project's public API and need live verification. All three
|
|
201
|
+
platforms are free and self-hostable (a small container-compose lab with
|
|
202
|
+
traefik + caddy + haproxy/dataplaneapi is a one-evening setup), so
|
|
203
|
+
`proxy-aiops doctor` — a health/info probe per platform — is the fastest
|
|
204
|
+
live check.
|
|
205
|
+
- **Routing note**: this tool operates reverse proxies / load balancers. Do NOT
|
|
206
|
+
use it for firewall rules — use firewall-aiops.
|
|
207
|
+
- **Missing a capability?** Open an issue or PR at
|
|
208
|
+
[github.com/AIops-tools/Proxy-AIops](https://github.com/AIops-tools/Proxy-AIops)
|
|
209
|
+
— contributions and feedback welcome.
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.AIops-tools/proxy-aiops -->
|
|
2
|
+
|
|
3
|
+
# Proxy AIops (preview)
|
|
4
|
+
|
|
5
|
+
Governed, audited AI-ops for **Traefik**, **Caddy** and **HAProxy** reverse proxies / load balancers — for AI agents (via MCP) and humans (via CLI).
|
|
6
|
+
|
|
7
|
+
> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by Traefik Labs, the Caddy project, HAProxy Technologies, or the HAProxy project.** Traefik, Caddy and HAProxy are trademarks of their respective owners. MIT licensed.
|
|
8
|
+
|
|
9
|
+
proxy-aiops speaks to three proxy platforms behind one MCP server — **Traefik**
|
|
10
|
+
(its API under `/api/...`, metrics-text counters via `/metrics`), **Caddy** (the
|
|
11
|
+
admin API, default `localhost:2019`) and **HAProxy** (the Data Plane API v2 under
|
|
12
|
+
`/v2/...`, HTTP Basic auth) — with the **same tools working on all three**. Each
|
|
13
|
+
target in the config names its own `platform`; a name-keyed platform registry
|
|
14
|
+
selects the API shape (auth + resource paths), and an explicit **support matrix**
|
|
15
|
+
raises teaching errors for ops a platform genuinely cannot do — e.g. Traefik
|
|
16
|
+
writes point you at its providers (file, container labels, orchestrator CRDs), never
|
|
17
|
+
a silent no-op.
|
|
18
|
+
|
|
19
|
+
Every tool runs through a **built-in governance harness** (vendored, zero external
|
|
20
|
+
dependency): audit log, token/call budget with runaway circuit-breaker, graduated
|
|
21
|
+
risk-tier approval, undo-token recording, and output sanitisation.
|
|
22
|
+
|
|
23
|
+
## Why this exists
|
|
24
|
+
|
|
25
|
+
- **One server, three proxies** — Traefik, Caddy and HAProxy in a mixed edge,
|
|
26
|
+
spoken to through identical tool names. Adding another proxy later is a new
|
|
27
|
+
platform descriptor, not a rewrite.
|
|
28
|
+
- **Read the whole edge** — version, entrypoints/listeners, routes (routers /
|
|
29
|
+
caddy routes / frontends) with parsed hosts+paths, services and server-level
|
|
30
|
+
upstream health, middlewares, TLS domain inventory, traffic/error counters,
|
|
31
|
+
and the live config tree (snapshot + search).
|
|
32
|
+
- **Flagship RCA analyses** — transparent heuristics that show their numbers,
|
|
33
|
+
never a black-box verdict: `backend_health_rca` (down upstreams → cause class
|
|
34
|
+
L4/L6/L7/DNS/maint + action), `cert_expiry_sweep` (days-to-expiry buckets +
|
|
35
|
+
per-platform renewal hints), `error_rate_rca` (5xx share vs the fleet
|
|
36
|
+
baseline, dominant code → 502/503/504/500 cause), and
|
|
37
|
+
`route_conflict_analysis` (shadowed routes, dead routes, redirect loops).
|
|
38
|
+
- **Governed writes** — caddy config `set` / `delete` / full `load` (the prior
|
|
39
|
+
subtree/config is fetched first, so the recorded undo replays a real restore)
|
|
40
|
+
and haproxy runtime server `state` (ready/drain/maint) and `weight` (undo
|
|
41
|
+
restores the prior value) — all with `dry_run` previews; delete/load are
|
|
42
|
+
**risk=high** behind an approver gate.
|
|
43
|
+
|
|
44
|
+
## Tool inventory (26 tools)
|
|
45
|
+
|
|
46
|
+
| Domain | Tools | # | Kind |
|
|
47
|
+
|--------|-------|:-:|------|
|
|
48
|
+
| **Status** | `proxy_overview`, `version_info`, `list_entrypoints` | 3 | read |
|
|
49
|
+
| **Routes** | `list_routes`, `route_detail`, `find_route` | 3 | read |
|
|
50
|
+
| **Services** | `list_services`, `service_detail`, `list_upstreams`, `upstream_detail`, `list_middlewares` | 5 | read |
|
|
51
|
+
| **Certificates** | `list_certificates` | 1 | read |
|
|
52
|
+
| **Traffic** | `traffic_stats`, `error_counters` | 2 | read |
|
|
53
|
+
| **Config** | `config_snapshot`, `search_config`, `get_config_value` | 3 | read |
|
|
54
|
+
| **Flagship analyses** | `backend_health_rca`, `cert_expiry_sweep`, `error_rate_rca`, `route_conflict_analysis` | 4 | read |
|
|
55
|
+
| **Writes (caddy)** | `set_config_value` | 1 | write (**med**) |
|
|
56
|
+
| **Writes (caddy)** | `delete_config_path`, `load_config` | 2 | write (**high**) |
|
|
57
|
+
| **Writes (haproxy)** | `set_server_state`, `set_server_weight` | 2 | write (**med**) |
|
|
58
|
+
|
|
59
|
+
Reversible writes record an inverse **undo descriptor** built from the real fetched
|
|
60
|
+
before-state (`set_config_value` restores the prior subtree; `delete_config_path`
|
|
61
|
+
re-creates it; `load_config` re-loads the snapshotted config; server state/weight
|
|
62
|
+
restore the prior value). The undo params match each tool's own signature, so the
|
|
63
|
+
descriptor replays as-is.
|
|
64
|
+
|
|
65
|
+
### Per-platform support matrix
|
|
66
|
+
|
|
67
|
+
| Capability | traefik | caddy | haproxy |
|
|
68
|
+
|------------|:-------:|:-----:|:-------:|
|
|
69
|
+
| Routes / services / upstream health | ✅ | ✅ | ✅ |
|
|
70
|
+
| Middlewares list | ✅ | teaching note (inline handlers) | teaching note (haproxy.cfg) |
|
|
71
|
+
| TLS cert inventory + expiry sweep | ✅ | ✅ | teaching note (.pem files) |
|
|
72
|
+
| Error counters / error-rate RCA | ✅ (/metrics) | teaching note (no per-route counters) | ✅ (stats) |
|
|
73
|
+
| Config snapshot / search | ✅ (rawdata, read-only) | ✅ | teaching note |
|
|
74
|
+
| Config writes | teaching error → edit the **provider** | ✅ (the write surface) | teaching error → runtime writes |
|
|
75
|
+
| Runtime server state / weight | teaching error → provider | teaching error → config tree | ✅ |
|
|
76
|
+
|
|
77
|
+
Unsupported combinations **raise a teaching error that says what to use instead**
|
|
78
|
+
— never a silent empty result.
|
|
79
|
+
|
|
80
|
+
## Install
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uv tool install proxy-aiops # or: pipx install proxy-aiops
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quick start
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
proxy-aiops init # wizard: pick platform (traefik/caddy/haproxy) + optional encrypted secret
|
|
90
|
+
proxy-aiops doctor # verify config, secrets, and connectivity
|
|
91
|
+
proxy-aiops overview # one-shot: version + route/service counts + upstream health
|
|
92
|
+
proxy-aiops routes list # normalised route table
|
|
93
|
+
proxy-aiops services upstreams # server-level upstream health
|
|
94
|
+
proxy-aiops analyze health # backend/upstream health RCA
|
|
95
|
+
proxy-aiops analyze errors # 5xx error-rate RCA
|
|
96
|
+
proxy-aiops analyze conflicts # shadowed/dead routes, redirect loops
|
|
97
|
+
proxy-aiops certs --sweep # TLS cert expiry sweep (traefik/caddy)
|
|
98
|
+
proxy-aiops server state app web1 drain --dry-run # governed haproxy write preview
|
|
99
|
+
proxy-aiops config set apps/http/servers/srv0 '{"listen":[":8080"]}' --dry-run
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Run the MCP server (stdio) for an agent:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
proxy-aiops mcp # or: proxy-aiops-mcp
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### MCP client config
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"mcpServers": {
|
|
113
|
+
"proxy-aiops": {
|
|
114
|
+
"command": "uvx",
|
|
115
|
+
"args": ["--from", "proxy-aiops", "proxy-aiops-mcp"],
|
|
116
|
+
"env": { "PROXY_AIOPS_MASTER_PASSWORD": "your-master-password" }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
> **Env-block caveat**: the `env` block is only needed when a credential is
|
|
123
|
+
> stored (haproxy always; traefik/caddy only behind Basic auth). MCP clients do
|
|
124
|
+
> **not** inherit your shell profile — set `PROXY_AIOPS_MASTER_PASSWORD` (and
|
|
125
|
+
> `PROXY_AIOPS_CONFIG` / `PROXY_AIOPS_HOME` if you relocated them) explicitly in
|
|
126
|
+
> the client config, or the server cannot unlock `secrets.enc`.
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
`~/.proxy-aiops/config.yaml` (non-secret connection details only):
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
targets:
|
|
134
|
+
- name: edge1
|
|
135
|
+
platform: traefik # traefik | caddy | haproxy
|
|
136
|
+
base_url: http://192.0.2.10:8080
|
|
137
|
+
verify_ssl: true
|
|
138
|
+
- name: caddy1
|
|
139
|
+
platform: caddy
|
|
140
|
+
base_url: http://127.0.0.1:2019
|
|
141
|
+
- name: lb1
|
|
142
|
+
platform: haproxy
|
|
143
|
+
base_url: http://192.0.2.20:5555
|
|
144
|
+
username: dpapi # Data Plane API user
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The **secret** — the HAProxy Data Plane API password, or an optional Basic-auth
|
|
148
|
+
password in front of Traefik/Caddy — is stored **encrypted** in
|
|
149
|
+
`~/.proxy-aiops/secrets.enc` (Fernet + scrypt-derived key), never plaintext on
|
|
150
|
+
disk. Traefik and Caddy commonly run unauthenticated on localhost, so their
|
|
151
|
+
secret is **optional** (like a local socket); HAProxy's is required. Set it with
|
|
152
|
+
`proxy-aiops secret set <target>` or the `init` wizard. The store is unlocked by
|
|
153
|
+
a master password from `PROXY_AIOPS_MASTER_PASSWORD` (non-interactive/MCP/CI) or
|
|
154
|
+
an interactive prompt (CLI on a TTY). A legacy plaintext env var
|
|
155
|
+
`PROXY_<TARGET>_SECRET` is honoured as a fallback (migrate with
|
|
156
|
+
`proxy-aiops secret migrate`).
|
|
157
|
+
|
|
158
|
+
## Governance
|
|
159
|
+
|
|
160
|
+
Every MCP tool is wrapped by `@governed_tool`:
|
|
161
|
+
|
|
162
|
+
- **Audit** — every call is logged to `~/.proxy-aiops/audit.db` (tool, params with
|
|
163
|
+
secrets redacted, status, duration, risk tier, approver, rationale).
|
|
164
|
+
- **Budget / runaway guard** — per-process token/call caps and a repeat-call circuit
|
|
165
|
+
breaker (`PROXY_MAX_TOOL_CALLS`, `PROXY_RUNAWAY_MAX`, …).
|
|
166
|
+
- **Graduated risk tiers — secure by default** — with no
|
|
167
|
+
`~/.proxy-aiops/rules.yaml`, high-risk writes (`delete_config_path`,
|
|
168
|
+
`load_config`) require an approver: set `PROXY_AUDIT_APPROVED_BY` (and
|
|
169
|
+
`PROXY_AUDIT_RATIONALE`) before they will run. `init` seeds a starter
|
|
170
|
+
rules.yaml; an operator-authored rules file is honoured as-is.
|
|
171
|
+
- **Undo recording** — reversible writes record an inverse descriptor to
|
|
172
|
+
`~/.proxy-aiops/undo.db` from the fetched before-state (recording only; an
|
|
173
|
+
external orchestrator executes it). Undo params match the target tool's own
|
|
174
|
+
signature, so the descriptor replays as-is.
|
|
175
|
+
- **Sanitisation** — all proxy-returned text is bounded + control-character
|
|
176
|
+
sanitised before it reaches the agent.
|
|
177
|
+
|
|
178
|
+
## Preview status
|
|
179
|
+
|
|
180
|
+
- **Platforms**: Traefik (API + /metrics), Caddy (admin API), HAProxy (Data Plane
|
|
181
|
+
API v2).
|
|
182
|
+
- **Preview — mock-validated only. Not run against a live proxy.** All behaviour is
|
|
183
|
+
validated against mocked JSON/metrics responses; the concrete REST paths are
|
|
184
|
+
modelled from each project's public API and need live verification. All three
|
|
185
|
+
platforms are free and self-hostable (a small container-compose lab with
|
|
186
|
+
traefik + caddy + haproxy/dataplaneapi is a one-evening setup), so
|
|
187
|
+
`proxy-aiops doctor` — a health/info probe per platform — is the fastest
|
|
188
|
+
live check.
|
|
189
|
+
- **Routing note**: this tool operates reverse proxies / load balancers. Do NOT
|
|
190
|
+
use it for firewall rules — use firewall-aiops.
|
|
191
|
+
- **Missing a capability?** Open an issue or PR at
|
|
192
|
+
[github.com/AIops-tools/Proxy-AIops](https://github.com/AIops-tools/Proxy-AIops)
|
|
193
|
+
— contributions and feedback welcome.
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Proxy AIops v0.1.0 — preview
|
|
2
|
+
|
|
3
|
+
Governed AI-ops for **Traefik**, **Caddy** and **HAProxy** reverse proxies /
|
|
4
|
+
load balancers for AI agents, with a built-in governance harness (audit,
|
|
5
|
+
policy, token/runaway budget, undo-token recording, graduated risk tiers) and
|
|
6
|
+
an encrypted credential store. Standalone — no external skill-family
|
|
7
|
+
dependency. One MCP server spans all three platforms: a per-target `platform`
|
|
8
|
+
field selects the API shape, and the same 26 tools work on Traefik (API +
|
|
9
|
+
`/metrics`), Caddy (admin API) and HAProxy (Data Plane API v2, HTTP Basic).
|
|
10
|
+
|
|
11
|
+
> **Not affiliated with, endorsed by, or sponsored by Traefik Labs, the Caddy
|
|
12
|
+
> project, HAProxy Technologies, or the HAProxy project.** Traefik, Caddy and
|
|
13
|
+
> HAProxy are trademarks of their respective owners.
|
|
14
|
+
|
|
15
|
+
> **Preview / mock-only.** All behaviour is validated against mocked JSON /
|
|
16
|
+
> metrics-text responses; it has **not** been run against a live proxy. The
|
|
17
|
+
> concrete REST paths are modelled from each project's public API and need
|
|
18
|
+
> live verification. All three platforms are free/self-hostable, so a small
|
|
19
|
+
> lab is the easiest live check — `proxy-aiops doctor` is the fastest.
|
|
20
|
+
|
|
21
|
+
## Highlights
|
|
22
|
+
|
|
23
|
+
- **26 MCP tools** (21 read, 5 write), every one wrapped with `@governed_tool`:
|
|
24
|
+
- **Status** — `proxy_overview`, `version_info`, `list_entrypoints`.
|
|
25
|
+
- **Routes** — `list_routes` (hosts/paths normalised across platforms),
|
|
26
|
+
`route_detail`, `find_route`.
|
|
27
|
+
- **Services** — `list_services`, `service_detail`, `list_upstreams`,
|
|
28
|
+
`upstream_detail`, `list_middlewares`.
|
|
29
|
+
- **Certificates** — `list_certificates` (+ bounded live expiry probe).
|
|
30
|
+
- **Traffic** — `traffic_stats`, `error_counters`.
|
|
31
|
+
- **Config** — `config_snapshot`, `search_config`, `get_config_value`.
|
|
32
|
+
- **Writes** — caddy `set_config_value` / `delete_config_path` /
|
|
33
|
+
`load_config` (prior config captured → replayable undo), haproxy
|
|
34
|
+
`set_server_state` (ready/drain/maint) / `set_server_weight` (undo
|
|
35
|
+
restores the prior value). High-risk writes gate on an approver.
|
|
36
|
+
- **Flagship analyses** (transparent heuristics that show their numbers):
|
|
37
|
+
- `backend_health_rca` — down upstreams per service with the failure class
|
|
38
|
+
(connection refused / L4 timeout / TLS / L7 check / DNS / maint) + action.
|
|
39
|
+
- `cert_expiry_sweep` — days-to-expiry buckets (expired / critical /
|
|
40
|
+
warning / ok) + per-platform renewal hints.
|
|
41
|
+
- `error_rate_rca` — per-service 5xx share vs the fleet baseline; the
|
|
42
|
+
dominant code maps to a cause (503 no-upstream / 502 conn-fail /
|
|
43
|
+
504 timeout / 500 app error).
|
|
44
|
+
- `route_conflict_analysis` — shadowed routes, dead routes (service missing
|
|
45
|
+
or zero servers up), redirect loops.
|
|
46
|
+
- **Support matrix with teaching errors** — ops a platform cannot do fail fast
|
|
47
|
+
with what to use instead (traefik writes → its providers; caddy counters →
|
|
48
|
+
access logs; haproxy certs → the .pem pipeline). Never a silent no-op.
|
|
49
|
+
- **Governance** — audit to `~/.proxy-aiops/audit.db`, budget/runaway guard,
|
|
50
|
+
secure-by-default approver gate for high-risk writes, undo descriptors built
|
|
51
|
+
from the real fetched before-state (replayable as-is), output sanitisation.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv tool install proxy-aiops
|
|
57
|
+
proxy-aiops init && proxy-aiops doctor
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Routing note: this tool operates reverse proxies / load balancers. Do NOT use
|
|
61
|
+
it for firewall rules — use firewall-aiops.
|