Skip to main content
Glama

CICD AIops

Audit availability: Real writes require a committed pending audit row and stop before contacting the platform if storage is unavailable. Reads and previews may continue with a warning; new audit rows store outcome summaries rather than full responses.

Governed AI-ops for self-managed GitLab and self-hosted Gitea.

cicd-aiops is for the team running its own CI/CD forge — a GitLab instance or a Gitea server on your hardware, in your lab, behind your VPN — who want an AI agent that can answer "why did the pipeline fail?", "which runner is wedged?", "where did 40 GB of artifact storage go?" and "what work went stale?" and then act (retry, cancel, pause, delete, protect) only through an audited, budgeted, risk-tiered, undo-recorded governance harness. It is not a SaaS integration: it speaks the GitLab REST API v4 and the Gitea API v1 directly against your server, with credentials encrypted at rest.

Verification status: modelled from each project's public API docs and exercised against mocked HTTP responses; there is no recorded end-to-end run against a live server yet. cicd-aiops doctor is the fastest live check — see docs/VERIFICATION.md.

Routing: Do NOT use this for Kubernetes deploy state — use k8s-aiops. This tool ends at the CI/CD server's API (pipelines, runners, artifacts, repo hygiene).

What this tool does, and does not, decide

It delivers CI/CD operations — reads and writes — accurately and efficiently, and records every one of them. It does not decide whether a write is allowed to happen. That is the agent's judgement, or the permission of the token you connect it with: give it a GitLab/Gitea access token without write scope and the writes fail at the server — the place that actually owns the permission.

So there is no read-only switch, no policy file, no approval gate to configure. The one thing the tool guarantees is that nothing is silent: every call, over MCP and over the CLI alike, lands an audit row in ~/.cicd-aiops/audit.db, and destructive writes still capture their before-state and record an inverse where one exists.

Each tool declares a risk_level, kept in agreement with its [READ]/[WRITE] documentation tag by a test, and carried into the audit row as a descriptive tier — so a reviewer can see at a glance that a row was a high-risk delete. It is a label, not a gate.

Running a smaller / local model? See agent-guardrails.md — it lists the guardrails this tool enforces for you (so you don't spend prompt budget restating them) and gives a ready-made system prompt for what's left.

Related MCP server: observability-aiops

Quick start

As a Claude Code plugin

One install gives an agent both the skill and the MCP server:

/plugin marketplace add AIops-tools/marketplace
/plugin install cicd-aiops@aiops-tools

The MCP server is fetched with uv and pinned to the package version this plugin declares, so an audit row can be traced back to the code that wrote it. Credentials are still configured with cicd-aiops init — see below.

As an OpenClaw plugin

The same bundle is published on ClawHub, where one install delivers the skill and its MCP server together:

openclaw plugins install clawhub:@zw008/cicd-aiops
openclaw skills info cicd-aiops          # expect: Visible to model: yes

Restart the OpenClaw gateway afterwards so it loads the plugin. The MCP server is fetched with uv, pinned to this exact release, so uvx has to be on PATH — without it the skill still installs but reports Visible to model: no. Credentials are configured exactly as below.

As a CLI or standalone MCP server

uv tool install cicd-aiops        # or: pip install cicd-aiops

cicd-aiops init        # wizard: base URL + token (encrypted) + TLS verify
cicd-aiops doctor      # connectivity + token-scope probe per target
cicd-aiops overview    # version, identity, projects, runners at a glance

Then the interesting parts:

cicd-aiops rca pipelines dev/api        # classify recent failed pipelines
cicd-aiops rca runners                  # offline/stale runners, tag saturation
cicd-aiops rca storage                  # artifact/repo bloat, reclaimable bytes
cicd-aiops rca stale dev/api            # stale MRs/branches, protection gaps

cicd-aiops pipelines retry dev/api 42 --dry-run
cicd-aiops artifacts delete dev/api --older-than-days 30 --dry-run

Every write has --dry-run and a double confirmation, and executes through the same governed path the MCP tools use — so CLI writes are audited too.

Support scope

Surface

GitLab (REST v4, self-managed)

Gitea (API v1, self-hosted)

Server version + token identity

✅

✅

Projects + storage statistics

✅ (statistics=true)

✅ (repo size)

Pipelines / runs, jobs, trace tails

✅

✅ (Actions runs/jobs/logs)

Runner fleet (list/detail)

✅

❌ teaching error (no API v1 equivalent)

Merge/pull requests, branches, protection, releases

✅

✅

Artifact inventory

✅ (via jobs)

✅ (Actions artifacts)

retry_pipeline / cancel_pipeline

✅

❌ teaching error

pause_runner / resume_runner

✅

❌ teaching error

delete_artifacts

✅

❌ teaching error

update_branch_protection

✅

✅

Where a platform lacks a surface, the platform registry raises a teaching error naming the resources that are available — the agent learns instead of hitting a mystery 404. GitLab.com / Gitea Cloud SaaS accounts are out of scope by design: this tool targets self-managed instances.

Flagship analyses (the reason this tool exists)

  1. pipeline_failure_rca — pulls recent failed pipelines with failed-job trace tails and classifies each failure: test-failure / dependency-network / runner-timeout / oom / script-error, with the matched evidence, a cause, and an action per pipeline.

  2. runner_health_rca — offline/stale/paused runners (contact-age threshold), jobs queued past a threshold, and per-tag saturation (queued jobs vs online runners).

  3. artifact_storage_bloat_analysis — projects ranked by repo + artifact bytes, expired-but-kept artifacts, and a reclaimable-bytes estimate that feeds straight into delete_artifacts --dry-run.

  4. stale_work_audit — merge/pull requests idle past N days, branches with no commits for N days, and protection gaps (unprotected default branch, force-push allowed).

All four are transparent heuristics: thresholds are named parameters and every flag carries its numbers.

Governance (built in, always on)

Every MCP tool and every CLI write runs through the vendored harness in cicd_aiops/governance/. It records; it does not authorize (see above).

  • Audit — every call (params, outcome summary, status, duration, risk tier, and any operator-supplied approver/rationale) is logged to ~/.cicd-aiops/audit.db (relocatable via CICD_AIOPS_HOME). The CLI writes the same row the MCP path does — there is no unaudited entry point.

  • Runaway guard — a safety backstop, not an authorization gate: the same call hammered in a tight loop trips a circuit breaker so a stuck agent can't burn unbounded calls/time. Disable with CICD_RUNAWAY_MAX=0; optional hard ceilings via CICD_MAX_TOOL_CALLS / CICD_MAX_TOOL_SECONDS.

  • Undo — reversible writes record a replayable inverse in ~/.cicd-aiops/undo.db, built from the fetched before-state: pause_runner ⇄ resume_runner, and update_branch_protection replays the prior settings. Irreversible writes (retry_pipeline, cancel_pipeline, delete_artifacts) record priorState (status / bytes+count) instead.

  • Risk tier — a descriptive label on the audit row derived from risk_level (reads low; mutating writes medium; delete_artifacts high); it gates nothing.

  • Dry-run everywhere — every write takes dry_run=True (MCP) / --dry-run (CLI) and previews without calling the server.

  • Sanitize — all server-returned text is folded through an injection-safe normaliser (bounded strings, capped depth) before an agent sees it; all path parameters are percent-encoded so an identifier can never rewrite a URL.

Secrets

Tokens live in ~/.cicd-aiops/secrets.enc — Fernet-encrypted, key derived from a master password via scrypt. Never plaintext on disk. Set CICD_AIOPS_MASTER_PASSWORD for non-interactive/MCP use, and manage with cicd-aiops secret set|list|remove|migrate. TLS verification defaults ON (the init wizard asks before turning it off for lab certs).

MCP server

26 governed tools (20 reads incl. the four flagship analyses, 6 writes).

{
  "mcpServers": {
    "cicd-aiops": {
      "command": "uvx",
      "args": ["--from", "cicd-aiops", "cicd-aiops-mcp"],
      "env": {
        "CICD_AIOPS_MASTER_PASSWORD": "your-master-password"
      }
    }
  }
}

Env-block caveat: MCP clients launch the server with a minimal environment — your shell profile is not sourced. Anything the server needs (CICD_AIOPS_MASTER_PASSWORD, CICD_AIOPS_HOME, and any optional CICD_AUDIT_APPROVED_BY audit annotation) must be set in the env block above, not in ~/.zshrc.

Alternatively: cicd-aiops mcp (same server, CLI entry point).

Configuration

~/.cicd-aiops/config.yaml (the wizard writes this):

targets:
  - name: gl1
    platform: gitlab            # or: gitea
    base_url: https://git.example.com
    verify_ssl: true            # default ON; set false only for lab certs

The token for each target is stored encrypted under the target's name. Relocate all state (config, audit, undo, secrets) with CICD_AIOPS_HOME.

Development

uv sync
uv run pytest -q
uv run ruff check .

缺功能?

缺功能提 issue/PR 欢迎留言 — if a GitLab/Gitea surface you need is missing (runner administration on newer Gitea, per-job retry, scheduled pipelines, group-level rollups…), open an issue or PR at https://github.com/AIops-tools/CICD-AIops. The platform registry is designed so a new resource is one path-map entry, not a refactor.

License

MIT. GitLab is a trademark of GitLab Inc.; Gitea is a trademark of its project owners. This project is independent and not affiliated with either.

Available Tools

28 tools
artifact_storage_bloat_analysisA
Read-only

[READ] Rank projects by storage; estimate reclaimable artifact bytes.

The flagship storage RCA: pulls project storage statistics, ranks projects by repo + artifact bytes, counts expired-but-kept artifacts and artifacts older than old_artifact_days, and estimates the reclaimable bytes per project. Every ranking carries its byte numbers. Pass 'projects' (and optionally 'artifacts_by_project') for pure analysis, or a target to pull live.

Args: old_artifact_days: Age in days past which a kept artifact counts as reclaimable (default 30). limit: How many projects to pull when live (default 100). projects: Injected rows {path, repoBytes, artifactsBytes}; skips the live pull. artifacts_by_project: Injected map {project: [{file, sizeBytes, createdAt, expireAt}]}. target: Server target name from config; omit for the default.

Returns dict: {projectsEvaluated, totalReclaimableBytes, thresholds, projects:[{project, repoBytes, artifactsBytes, totalBytes, expiredButKept, reclaimableBytes, action}], note}.

Inputs: limit, target, projects, old_artifact_days, +1 more.

cancel_pipelineA
Destructive

[WRITE][risk=medium] Cancel a running pipeline.

Reads the pipeline first so priorState records the status it had before the cancel. Irreversible (the stopped run cannot be resumed) — no undo. Pass dry_run=True to preview.

Args: project: Project id or full path. pipeline: Pipeline id (from list_pipelines). dry_run: If True, preview without canceling. target: Server target name from config; omit for the default.

Inputs: project (required), pipeline (required), target, dry_run.

cicd_overviewA
Read-only

[READ] One-shot summary: version, token identity, projects, runners.

Resilient — a failing sub-call degrades to a partial summary with an 'errors' list instead of crashing.

Args: target: Server target name from config; omit for the default.

Inputs: target.

current_userA
Read-only

[READ] The token's identity — who the API sees you as (scope probe).

Args: target: Server target name from config; omit for the default.

Inputs: target.

delete_artifactsA
Destructive

[WRITE][risk=high] Delete a project's artifacts (all, or older than N days).

IRREVERSIBLE — reads the artifact inventory first so priorState records the file count and bytes being destroyed; no undo. Pass dry_run=True to preview (reports what would be reclaimed without deleting).

Args: project: Project id or full path. older_than_days: Only delete artifacts created before this many days ago; 0 = the server's bulk delete of all eligible artifacts. dry_run: If True, preview without deleting. acknowledge_unknown_inventory: Allow the bulk delete when the artifact inventory cannot be read (it is refused otherwise, because nothing would record what was destroyed). Never applies to older_than_days. target: Server target name from config; omit for the default.

Inputs: project (required), target, dry_run, older_than_days, +1 more.

job_trace_tailA
Read-only

[READ] The tail of one job's log/trace — where the failure explains itself.

Returns {project, job, trace, totalLines, tailLines, returned, limit, truncated, charsTruncated}. 'truncated' true means earlier lines were dropped (the trace is only the tail — the FIRST error may be above the window, so raise tail_lines before concluding a root cause); 'charsTruncated' true means the tail itself hit the byte ceiling.

Args: project: Project id or full path. job: Job id (from pipeline_jobs). tail_lines: How many trailing lines to return (default 60). target: Server target name from config; omit for the default.

Inputs: job (required), project (required), target, tail_lines.

list_artifactsA
Read-only

[READ] A project's artifact inventory: files, sizes, expiry.

Also reports how many artifacts are past their expiry date but still kept (the delete_artifacts candidates). 'totalBytes' / 'expiredButKept' / 'artifactsFound' count EVERY artifact found, so they stay correct when the row list is cut; 'truncated' then says the rows are a subset. On GitLab the inventory is assembled from a bounded scan of recent jobs — when 'jobScanTruncated' is true, older jobs' artifacts are NOT in this result, so treat the totals as a lower bound.

Args: project: Project id or full path ('group/project' / 'owner/repo'). limit: Max artifact rows to return (default 500). target: Server target name from config; omit for the default.

Inputs: project (required), limit, target.

list_branchesA
Read-only

[READ] Branches with last-commit date and protected flag.

Args: project: Project id or full path. limit: Max rows to return (default 100, capped at 99); the result carries 'truncated' when the server had more. target: Server target name from config; omit for the default.

Inputs: project (required), limit, target.

list_merge_requestsA
Read-only

[READ] Merge/pull requests for a project (default: open ones).

Args: project: Project id or full path ('group/project' / 'owner/repo'). state: opened/open, merged, closed, all (platform word is translated). limit: Max rows to return (default 50, max 99); the result carries 'truncated' when the server had more. target: Server target name from config; omit for the default.

Inputs: project (required), limit, state, target.

list_pipelinesA
Read-only

[READ] Recent pipelines/runs for a project, newest first.

Returns {project, pipelines:[...], returned, limit, truncated}. When 'truncated' is true the server had MORE pipelines than were returned — re-run with a higher limit rather than treating the list as complete. Truncation is measured (one extra row is fetched), never guessed.

Args: project: Project id or full path ('group/project' / 'owner/repo'). status: Optional status filter (e.g. failed, success, running, pending). limit: Max rows to return (default 20, max 99). target: Server target name from config; omit for the default.

Inputs: project (required), limit, status, target.

list_projectsA
Read-only

[READ] Projects/repositories the token can see, with storage numbers.

Returns {projects:[...], returned, limit, truncated}; 'truncated' true means the server had more projects than were returned (measured, not guessed).

Args: search: Optional name filter. limit: Max rows to return (default 50, max 99). target: Server target name from config; omit for the default.

Inputs: limit, search, target.

list_protected_branchesA
Read-only

[READ] Branch-protection rules for a project (incl. force-push flags).

Returns {project, protections:[...], returned, limit, truncated}.

Args: project: Project id or full path. limit: Max rows to return (default 100). target: Server target name from config; omit for the default.

Inputs: project (required), limit, target.

list_releasesA
Read-only

[READ] Releases for a project, newest first.

Args: project: Project id or full path. limit: Max rows to return (default 20, max 99); the result carries 'truncated' when the server had more. target: Server target name from config; omit for the default.

Inputs: project (required), limit, target.

list_runnersA
Read-only

[READ] All runners visible to the token, offline/paused first.

GITLAB ONLY. Gitea has no runner-administration API, so a Gitea target raises a teaching error naming the resources that DO exist there. That is a platform-capability answer, not a broken tool: do not retry it, and do not report the server as unreachable — answer from the pipeline/job surface instead.

Returns {runners:[...], returned, limit, truncated}; rows are sorted offline/paused first BEFORE the cut, so the most urgent runners survive.

Args: status: Optional status filter (online, offline, paused, stale). limit: Max rows to return (default 100, capped at 99). target: Server target name from config; omit for the default.

Inputs: limit, status, target.

pause_runnerA
Destructive

[WRITE][risk=medium] Pause a runner; reversible (undo resumes it).

Reads the runner first so the harness records its prior paused state. A paused runner stops picking up new jobs; running jobs finish. Pass dry_run=True to preview.

Args: runner: Runner id (from list_runners). dry_run: If True, preview without pausing. target: Server target name from config; omit for the default.

Inputs: runner (required), target, dry_run.

pipeline_detailA
Read-only

[READ] One pipeline/run's full detail.

Args: project: Project id or full path. pipeline: Pipeline/run id (from list_pipelines). target: Server target name from config; omit for the default.

Inputs: project (required), pipeline (required), target.

pipeline_failure_rcaA
Read-only

[READ] Classify recent failed pipelines: cause + action per pipeline.

The flagship pipeline RCA: pulls the project's recent failed pipelines with their failed jobs and trace tails, classifies each failed job (test-failure / dependency-network / runner-timeout / oom / script-error) from its failure_reason and trace markers, and attaches a cause and a recommended action. Every classification names its matched evidence, not a black-box verdict. Pass 'failed_pipelines' for pure analysis, or a project to pull live.

Args: project: Project id or full path (required unless failed_pipelines given). limit: How many recent failed pipelines to pull (default 10). tail_lines: Trace-tail lines pulled per failed job (default 60). failed_pipelines: Injected rows {id, ref, jobs:[{name, stage, status, failureReason, traceTail}]}; skips the live pull. target: Server target name from config; omit for the default.

Returns dict: {pipelinesEvaluated, classCounts, pipelines:[{pipeline, ref, headlineClass, cause, action, failedJobs:[{job, stage, class, cause, action, evidence}]}], note}.

Inputs: limit, target, project, tail_lines, +1 more.

pipeline_jobsA
Read-only

[READ] Jobs of one pipeline/run with status + failure reason.

Returns {project, pipeline, jobs:[...], returned, limit, truncated}. When 'truncated' is true this pipeline had more jobs than were returned.

Args: project: Project id or full path. pipeline: Pipeline/run id (from list_pipelines). limit: Max job rows to return (default 100). target: Server target name from config; omit for the default.

Inputs: project (required), pipeline (required), limit, target.

project_detailB
Read-only

[READ] One project's detail incl. repo/artifact byte counts.

Args: project: Project id or full path ('group/project' / 'owner/repo'). target: Server target name from config; omit for the default.

Inputs: project (required), target.

resume_runnerA
Destructive

[WRITE][risk=medium] Resume a paused runner; reversible (undo pauses it).

Reads the runner first so the harness records its prior paused state. Pass dry_run=True to preview.

Args: runner: Runner id (from list_runners). dry_run: If True, preview without resuming. target: Server target name from config; omit for the default.

Inputs: runner (required), target, dry_run.

retry_pipelineA
Destructive

[WRITE][risk=medium] Retry a failed/canceled pipeline.

Reads the pipeline first so priorState records the status it had before the retry. Irreversible (a retry is a new run) — no undo. Pass dry_run=True to preview.

Args: project: Project id or full path ('group/project' / 'owner/repo'). pipeline: Pipeline id (from list_pipelines). dry_run: If True, preview without retrying. target: Server target name from config; omit for the default.

Inputs: project (required), pipeline (required), target, dry_run.

runner_detailA
Read-only

[READ] One runner's full detail (contacted_at, tags, paused, version).

GITLAB ONLY — a Gitea target raises the same teaching error as list_runners.

Args: runner: Runner id (from list_runners). target: Server target name from config; omit for the default.

Inputs: runner (required), target.

runner_health_rcaA
Read-only

[READ] Flag offline/stale/paused runners, long-queued jobs, tag saturation.

The flagship capacity RCA: pulls the runner fleet, flags each runner that is offline, stale (no contact for stale_contact_min minutes) or paused, lists jobs queued past queue_sec, and computes per-tag saturation (queued jobs vs online unpaused runners). Every flag carries its numbers. Pass 'runners' / 'queued_jobs' for pure analysis, or a target to pull the fleet live.

Args: stale_contact_min: Minutes since last contact at which a runner is stale. queue_sec: Seconds a job may wait before being flagged (default 300). saturation_ratio: Flagged queued jobs per online runner at which a tag is saturated (default 2.0). runners: Injected rows {id, description, status, paused, online, tags, contactedAt}; skips the live pull. queued_jobs: Injected rows {id, name, queuedDurationSec, createdAt, tags}. target: Server target name from config; omit for the default.

Returns dict: {runnersEvaluated, flaggedRunners, longQueuedJobs, saturatedTags, thresholds, note}.

Inputs: target, runners, queue_sec, queued_jobs, +2 more.

server_versionB
Read-only

[READ] CI/CD server version and revision.

Args: target: Server target name from config; omit for the default.

Inputs: target.

stale_work_auditA
Read-only

[READ] Long-open MRs/PRs, inactive branches, protection config gaps.

The flagship hygiene audit: flags open merge/pull requests idle past stale_mr_days, non-default branches with no commit for stale_branch_days, a default branch without protection, and protection rules that allow force-push. Every flag carries its numbers. Pass injected rows for pure analysis, or a project to pull live.

Args: project: Project id or full path (required unless rows are injected). stale_mr_days: Days an open MR may idle before flagging (default 14). stale_branch_days: Days a branch may idle before flagging (default 90). merge_requests: Injected rows {id, title, state, updatedAt, draft}. branches: Injected rows {name, default, protected, lastCommitAt}. protections: Injected rows {branch, allowForcePush}. default_branch: Default-branch name (pulled live when omitted). target: Server target name from config; omit for the default.

Returns dict: {staleMergeRequests, staleBranches, protectionGaps, counts, thresholds, note}.

Inputs: target, project, branches, protections, +4 more.

undo_applyA
Destructive

[WRITE][risk=medium] Apply a recorded undo by dispatching its inverse tool.

The inverse runs through its own governed tool, so its real risk tier is recorded there. Pass dry_run=True to preview the inverse call without executing it. A token can only be applied once.

Args: undo_id: The undoId from undo_list (or an _undo_id in a write result). dry_run: If True, preview the inverse tool + params without running it. target: Passed through to the inverse tool when it accepts a target.

Inputs: undo_id (required), target, dry_run.

undo_listA
Read-only

[READ] List recorded, not-yet-applied undo tokens (most recent first).

Each entry names the original tool, the inverse tool that undo_apply would run, and a human note. Use the undoId with undo_apply.

Returns {undos:[...], returned, limit, truncated}. One extra row is asked for, so 'truncated' is measured — a full page is not assumed to be the end.

Each entry carries effectVerified. False means the original write lost its response, so the change it reverses is PROBABLE, not confirmed — check the live state before applying, and do not report the result as a restore of a state that may never have been reached.

Args: limit: Max rows to return (default 50, max 500). target: Unused (undo state is host-local); accepted for CLI uniformity.

Inputs: limit, target.

update_branch_protectionA
Destructive

[WRITE][risk=medium] Protect/unprotect a branch; reversible.

Reads the branch's current protection first so the harness records an undo that replays this same tool with the prior settings. Pass dry_run=True to preview.

Args: project: Project id or full path. branch: Branch name (from list_branches). protect: True to protect the branch, False to remove protection. allow_force_push: Whether the protection permits force-push (default False — the safe setting). dry_run: If True, preview without changing. target: Server target name from config; omit for the default.

Inputs: branch (required), project (required), target, dry_run, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 28 tools

    Disambiguation5/5

    Each tool targets a distinct resource, action, or analysis purpose: raw list/detail tools are separated from RCA/audit tools, and write tools have explicit risk/dry-run semantics. Minor overlaps like cicd_overview versus component summaries are clearly framed as composite shortcuts rather than alternatives that cause misselection.

    Naming Consistency4/5

    All names use snake_case, and action tools largely follow verb_noun (list_pipelines, retry_pipeline, pause_runner). Detail/RCA/audit tools use noun-based patterns (pipeline_detail, pipeline_failure_rca, stale_work_audit), and undo_list/undo_apply reverse the usual order, which are minor but real deviations.

    Tool Count3/5

    28 tools is heavy for most MCP servers, even though the broad CI/CD AIOps domain—projects, pipelines, jobs, runners, artifacts, branches, merge requests, undo, and remediation—explains much of the surface. The set is mostly purposeful, but several list/detail/introspection tools push it into borderline-heavy territory.

    Completeness3/5

    Read/diagnostic coverage is strong, and core remediation exists for pipelines, runners, artifacts, and branch protection. However, notable lifecycle operations are missing, including pipeline triggering, job-level retry/cancel, merge-request actions, release management, and runner registration/deletion, leaving some dead ends for full CI/CD workflows.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Governed MySQL + MariaDB DBA operations — slow-query, lock-wait/deadlock, replication, and fragmentation RCA, with unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.
      35
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Governed Prometheus + Grafana operations — firing-alert and scrape-target RCA, alert noise/flapping analysis, silences, and dashboards, with unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.
      39
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Governed SSO/IAM operations for Keycloak and Authentik — login-failure, stale-permission, client-config, and MFA RCA, with unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.
      29
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Governed MinIO object-storage operations — capacity, exposure-surface audit, lifecycle, and healing RCA, with guarded bucket writes, unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.
      48
      MIT