v2.3.0
v2.3.0 — Comprehensive tool audit, edition gating, capability cleanup, dependency refresh
This release lands the culmination of the 1:1 API/SDK tool audit, the 3-tier edition gating model, the post-audit hardening pass, and the quarterly dependency refresh.
Highlights
- ~200 net-new tools and fields exposed to the MCP surface, bringing the catalog to ~861 (Free/CE), ~998 (Premium), ~1061 (Ultimate self-managed). The full per-tool coverage is audited mechanically against the upstream
client-goSDK and the GitLab REST/GraphQL API. - 3-tier edition gating replaces the boolean
GITLAB_ENTERPRISE.GITLAB_TIERnow acceptsfree,ce,premium,ultimate; the instance tier is auto-detected from the license when unset (withGITLAB_ENTERPRISEkept as a deprecated back-compat shim). The gate applies at three levels: action-level (per-actionEdition), field-level (tier:"premium"|"ultimate"struct tags prune Premium/Ultimate fields from both input and output schemas on lower tiers), and tool-surface-level (Premium/Ultimate groups registered as additional meta-tools only when the active tier warrants). - DEPRECATED MCP CAPABILITIES REMOVED (SEP-2577 — Roots, Sampling, MCP Logging). The internal
slog/stderr logging used by the server is unaffected; only the MCP Logging capability (logging/setLevel,notifications/message) is gone. Kept capabilities: progress, completions, elicitation.
Features
New tools (16)
- Container registry tag protection (CE; PR #187):
gitlab_registry_tag_protection_{list,create,update,delete}. - Group relations (CE; PR #187):
gitlab_group_shared_with_list,gitlab_group_invited_list,gitlab_group_transfer_locations. - Group LDAP sync (Premium; PR #187):
gitlab_group_ldap_sync. - Group SAML users (Premium; PR #187):
gitlab_group_saml_users_list. - Project-level Jira integration fields (CE; PR #188): 9 new fields on
gitlab_set_jira_integration—vulnerabilities_enabled,vulnerabilities_issuetype,project_key,customize_jira_issue_enabled, plus the Jira issue check toggles (jira_check_enabled,jira_exists_check_enabled,jira_assignee_check_enabled,jira_status_check_enabled,jira_allowed_statuses_as_string).
1:1 SDK/API surface completeness (PR #190)
Closed gaps across many domains — missing actions, full input/output field coverage (correct types, nested objects, keyset pagination), and per-action discovery metadata (aliases, hints, related, next_steps). New mechanical auditors under cmd/audit_* diff the canonical ActionSpec catalog against client-go endpoints, input/output structs, and discovery metadata; make audit-1to1 merges the streams and writes plan/1to1-backlog.json for backlog triage.
Edition gating (PR #190)
GITLAB_TIER(free/ce/premium/ultimate) replaces the booleanGITLAB_ENTERPRISE. Auto-detection reads the GitLab license endpoint when unset;GITLAB_ENTERPRISE=trueis honored as a deprecated back-compat.- Action-level gating via a central catalog filter; field-level gating via
tier:"premium"|"ultimate"struct tags prune Premium/Ultimate fields from input and output schemas on lower tiers. - Empirically verified against live GitLab EE Ultimate vs CE instances; full coverage in
internal/edition/.
Documentation completeness — DOC-002 (PR #192)
- New
cmd/audit_doc_coverage/auditsdocs/tools/*.mdagainst the catalog. Per-docmissing/orphan/tier_mismatchgates; output inplan/docs-tools-backlog.json(gitignored). Makefile targets:audit-doc-coverage(full report),audit-doc-coverage-check(CI gate). - First-claimer-wins mapping drives routing: the first README row that claims a catalog group owns every tool in that group. Docs that share a group (boards, mirrors, access, security, notifications, integrations, identity-security, analytics-compliance, epics, merge-requests, admin, packages) declare their subset via
parsePrefixAllowlists()incmd/audit_doc_coverage/mapping.go. Hardcoded overrides handle routed tools (branch-rules, capabilities, project-discovery, orbit). - Every domain doc covers exactly its catalog-expected tool set; 178 tools added across 17 docs, 156 orphans resolved, tier badges aligned to catalog
Edition.
Breaking changes
- Removed MCP capabilities (PR #189 — SEP-2577 cleanup; see SEP-2577: Deprecate Roots, Sampling, and Logging for the full spec rationale):
- Roots —
internal/roots/, thegitlab://workspace/rootsresource, roots manager + handlers, and roots-based metadata. - Sampling —
internal/sampling/andinternal/tools/samplingtools/(11 tools:analyze,summarize,generate,review,find), thegitlab_analyzemeta-group, thesamplingcapability requirement andSurfaceKindSamplingUtility, plus all dynamic discovery heuristics for them. - MCP Logging capability —
internal/logging/;toolutil.LogToolCallAlldecoupled from MCP logging. The internalslog/stderr logger (the SEP's recommended replacement) is unaffected.
- Roots —
Maintenance
Post-audit cleanup (PR #191, 91 commits, behavior-preserving)
- DEDUP-001/002/003 — lift shared output shapes into
internal/toolutil(MergeRequestOutput,NoteOutput,DiscussionThreadOutput,CommitOutput,DiffRefsOutput, pipeline/release/note shapes) with per-package aliases. - New shared helpers:
toolutil.ActionMetaEntry+ApplyActionMeta(replaces byte-identicaldecorate*Metaoverlay funcs across domains) andSchemaEnumOverride/SchemaFormatOverrideone-liners. - Move
formatTimePtr/formatISOTimePtrtotoolutilwith a guardrail. - Central canonical input-schema injection in
NewActionSpec: enums (sort,visibility,variable_type), date/date-time formats (*_after/*_before,due_date,start_date,expires_at),uriformats (URL inputs), and pagination ranges (per_page1–100,page≥1) — doc-grounded against the GitLab REST pagination docs. - SonarCloud quality gate — CPD remediation to gate-green with zero new exclusions.
go:S1192(duplicated literals) cleared by extractingformatDateTime/formatDateconstants. - Coverage gate raised 80% → 90% (
COVERAGE_MIN); real coverage sits at ~99% across the touched packages.
Dependency refresh (PR #194)
gitlab.com/gitlab-org/api/client-go/v2v2.42.0 → v2.43.0. The only upstream change is a newDiscussionIDfield on theCommitNoteEvent/IssueNoteEventwebhook payload structs. The MCP is an outbound API client (manages hooks viaAddProjectHooketc.) — these webhook payload structs are used by webhook receivers, not by the MCP. No MCP code changes required; the bump is purely additive. Verified: 0 references toCommitNoteEvent/IssueNoteEvent/SnippetNoteEvent/event_webhook_typesin the MCP;project_hooks.go/group_hooks.go/system_hooks.go/integrations.go/group_integrations.godiffs all empty between v2.42 and v2.43;go build ./...andgo vet ./...clean.- Go modules:
golang.org/x/tools0.46.0 → 0.47.0,github.com/lufia/plan9statsto latest, transitivegithub.com/graph-gophers/graphql-gov1.9.0. - pnpm / Astro site:
astro7.0.2 → 7.0.3,astro-mermaid2.0.4 → 2.1.0,eslint10.5.0 → 10.6.0,eslint-plugin-astro2.0.0 → 2.1.1,mermaid11.15.0 → 11.16.0,prettier3.8.4 → 3.9.1,@astrojs/starlight0.41.0 → 0.41.1,starlight-links-validator0.24.1 → 0.25.1. - Dockerfile:
alpine:3.24.0→alpine:3.24.1(Dependabot PR #183). - GitHub Actions:
actions/checkoutv6 → v7 (Dependabot PR #185; 4 workflow files). - CLAUDE.md: GitLab client version (
gitlab.com/gitlab-org/api/client-go/v2) bumped to v2.43.0 to matchgo.mod.
Documentation cleanup (commit 99f09337)
- Dropped the duplicate
Docker CE-on-Enterprise meta 20260527section from bothdocs/testing/model-results.mdandREADME.md— it was already covered by the subsequent## Dynamic Results/## Enterprise Meta-Tools Resultsblocks. Single canonical result per surface/edition per file.
Artifacts and verification
- 9 PRs merged: #187, #188, #189, #190, #191, #192, #194 (release), and the post-#194 follow-ups.
- ~900 files changed across the 8 PRs.
- Local gates:
make test-short,make audit-doc-coverage-check(clean 0/41 docs, 0 missing / 0 orphan / 0 tier_mismatch),go run ./cmd/format_md_tables/ --check,npx markdownlint-cli2 "docs/**/*.md",node scripts/check-doc-links.mjs(193 files),pnpm run build(57 pages),golangci-lint run --build-tags e2e ./cmd/...— all green. - SonarCloud: 0 CRITICAL issues; quality gate
OK(new_duplicated_lines_density: 0.0, all conditions within thresholds). - PGP-signed commits by
José M. Requena Plens <jmrplens@gmail.com>throughout; tags signed viagit tag -s. - Pinned dependencies in
go.sum/site/pnpm-lock.yaml; reproducible binaries viago build -trimpath -buildmode=piewithmod_timestampfrom commit.
Upgrade notes
- MCP clients using
roots,sampling, or the MCP Logging capability (PR #189): the corresponding tools, resources, and capability registrations are removed. The internalslog/stderr logger remains the source of truth for diagnostic output. Plan an upgrade in lockstep with your client if you depend on any of:- The
gitlab://workspace/rootsresource orgitlab_workspace_*tools. - The
gitlab_analyze*tools (sampling) — superseded by direct issue/MR tools in the respective domains. logging/setLevel/notifications/messagecalls — use the server's stderr (or itsMCP_LOG_LEVELenv if you set one) for diagnostics.
- The
- Edition gating (PR #190): clients that previously set
GITLAB_ENTERPRISE=truecontinue to work (deprecated back-compat), but should migrate toGITLAB_TIER=premiumorGITLAB_TIER=ultimateto opt in to the new field-level pruning. Lower tiers see a smaller schema on tools that have Premium/Ultimate fields. - Hooks (client-go v2.43.0): webhook payload structs gained a new
discussion_idfield on commit/snippet note events. Webhook receivers should accept the additional field gracefully (the client-go v2.43.0 JSON decoder does so by default).
Downloads
Binaries for Linux / Darwin / Windows on amd64 and arm64 are attached to this release, signed with cosign sigstore bundles (checksums.txt.sigstore.json). Docker image is published to ghcr.io/jmrplens/gitlab-mcp-server:v2.3.0 and mirrored to docker.io/jmrplens/gitlab-mcp-server:v2.3.0. The MCP server manifest server.json is also updated at https://github.com/jmrplens/gitlab-mcp-server/releases/download/v2.3.0/server.json.
Changelog
✨ Features
- 8b1f506: feat: 1:1 API/SDK tool audit, 3-tier edition gating, and model-eval/discovery hardening (#190) (@jmrplens)
📚 Documentation
- 99f0933: docs(eval): drop duplicate CE-on-Enterprise meta eval section (@jmrplens)
- ce10a5f: docs(tools): complete per-domain tool reference vs catalog (DOC-002) (#192) (@jmrplens)
🚧 Maintenance
- b994c96: chore(deps): client-go v2.42.0 (Jira fields) + dependency refresh; harden HTTP test timeouts (#188) (@jmrplens)
- fcc4c90: chore(deps): update client-go to v2.41.0 — new endpoints, 1:1 fields, metadata, tests & docs (#187) (@jmrplens)
- 8f255da: chore(release): v2.3.0 — version bump + dependency refresh + action updates (#194) (@jmrplens)
- 3d6ce4d: chore: post-PR-190 cleanup — dedup, discovery/input metadata, Sonar gate, docs & E2E fixes (#191) (@jmrplens)
- 4394f0d: chore: update manifests for v2.2.1 (@jmrplens)
- 6218106: refactor: remove deprecated MCP capabilities — Roots, Sampling, Logging (SEP-2577) (#189) (@jmrplens)