cicd-aiops
This server provides governed, audited CI/CD AI-ops for self-managed GitLab and self-hosted Gitea: it reads/analyzes CI/CD state and performs controlled write actions with dry-run, audit, and undo support.
Run flagship RCAs: pipeline failure classification, runner health/capacity, artifact storage bloat, and stale-work/protection audits.
Inspect projects, storage stats, pipelines/runs, jobs, trace tails, merge/pull requests, branches, protected branches, releases, runners, server version, and token identity.
List artifact inventory with sizes, expiry, expired-but-kept counts, and reclaimable-byte estimates.
Retry or cancel pipelines, pause or resume runners, delete artifacts (high risk), and protect/unprotect branches.
Preview writes with
dry_run/--dry-run, record audit rows for every call, and apply recorded undo tokens for reversible writes.Use GitLab for the full surface; Gitea supports core repo/pipeline/PR/branch/protection surfaces but returns teaching errors for unsupported runner/artifact/pipeline write operations.
Target self-managed/self-hosted instances only; SaaS accounts are out of scope by design.
Integrates with self-hosted Gitea servers via the API v1, providing tools for analyzing pipeline/run failures, repository storage, and stale work, plus managing merge/pull requests, branches, branch protection, releases, and Actions artifacts. Runner administration is not available on Gitea and raises a teaching error.
Integrates with self-managed GitLab instances via the REST API v4, providing tools for pipeline failure root-cause analysis, runner health monitoring, artifact storage bloat analysis, stale work audits, and governed write actions such as retrying/canceling pipelines, pausing/resuming runners, deleting artifacts, and updating branch protection.
CICD AIops
Audit availability: Real writes require a committed
pendingaudit 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 doctoris the fastest live check — seedocs/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-toolsThe 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: yesRestart 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 glanceThen 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-runEvery 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 | ✅ ( | ✅ (repo |
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) |
| ✅ | ❌ teaching error |
| ✅ | ❌ teaching error |
| ✅ | ❌ teaching error |
| ✅ | ✅ |
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)
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.runner_health_rca— offline/stale/paused runners (contact-age threshold), jobs queued past a threshold, and per-tag saturation (queued jobs vs online runners).artifact_storage_bloat_analysis— projects ranked by repo + artifact bytes, expired-but-kept artifacts, and a reclaimable-bytes estimate that feeds straight intodelete_artifacts --dry-run.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 viaCICD_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 viaCICD_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, andupdate_branch_protectionreplays the prior settings. Irreversible writes (retry_pipeline,cancel_pipeline,delete_artifacts) recordpriorState(status / bytes+count) instead.Risk tier — a descriptive label on the audit row derived from
risk_level(readslow; mutating writesmedium;delete_artifactshigh); 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 optionalCICD_AUDIT_APPROVED_BYaudit annotation) must be set in theenvblock 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 certsThe 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 toolsartifact_storage_bloat_analysisARead-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_pipelineADestructive
[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_overviewARead-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_userARead-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_artifactsADestructive
[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_tailARead-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_artifactsARead-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_branchesARead-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_requestsARead-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_pipelinesARead-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_projectsARead-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_branchesARead-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_releasesARead-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_runnersARead-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_runnerADestructive
[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_detailARead-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_rcaARead-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_jobsARead-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_detailBRead-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_runnerADestructive
[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_pipelineADestructive
[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_detailARead-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_rcaARead-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_versionBRead-only
[READ] CI/CD server version and revision.
Args: target: Server target name from config; omit for the default.
Inputs: target.
stale_work_auditARead-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_applyADestructive
[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_listARead-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_protectionADestructive
[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
Scored across 28 tools
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.
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.
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.
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
Related MCP Connectors
AI-native git hosting — repos, PRs, issues, CI gates, and AI code review over MCP (60 tools).
LLM cost optimization gateway, repo token-waste auditor & model arbitrage MCP server.
Go MCP server for GitLab: 2 dynamic tools reach 1000+ REST/GraphQL actions. Free/CE, no paid tier.
Autonomous and governed SRE & MLOps control plane for AI agent platforms.
Related MCP Servers
- AlicenseAqualityBmaintenanceGoverned 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.35MIT
- AlicenseAqualityBmaintenanceGoverned 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.39MIT
- AlicenseAqualityBmaintenanceGoverned 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.29MIT
- AlicenseAqualityBmaintenanceGoverned 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.48MIT