AI Slop Code Risk Monitor

zereight/gitlab-mcp

SlopCodeMonitor badge for zereight/gitlab-mcp Adjusted legacy signal; badge bands: 25 / 50 / 75 (different from dashboard bands).

MCP server for GitLab: 277 tools for projects, MRs, issues, pipelines, wikis and more via the GitLab REST/GraphQL API

2.0 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for zereight/gitlab-mcp, a TypeScript project with 2,079 GitHub stars. SynthScan examined 141,702 lines of code across 481 source files, recording 256 pattern matches distributed across 10 syntactic categories. The legacy adjusted pattern signal is 2.0 (Low pattern signal); it is not an authorship estimate.

Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.

2.0
Adjusted Signal
2.0
Raw Pattern Score
100%
Time Factor
2026-10-31
Last Push
2.1K
Stars
TypeScript
Language
141.7K
Lines of Code
481
Files
256
Pattern Hits
2026-10-31
Scan Date
0.00
HC Hit Rate

Risk Review · Payload v1

Use each vector to guide manual verification of the underlying findings.

Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.

Cognitive Ownership Risk 8.4/100 · LOW

Can maintainers explain intent, assumptions, and trade-offs? 244 finding(s).

Hallucinated Dependency & Supply Chain Risk 0.1/100 · LOW

Are imports declared and package/API names verified? 2 finding(s).

Agent Over-Engineering Ratio 6.8/100 · LOW

Are wrappers, guards, and repeated structures necessary? 206 finding(s).

PR Review Velocity Impact 9.4/100 · LOW

Which changes need focused human review? 256 finding(s).

What These Metrics Mean

Adjusted Signal
Legacy pattern score normalized per 1,000 scanned lines and multiplied by the repository-level time factor. It is not an estimate of AI authorship.
Raw Pattern Score
Sum of severity- and context-weighted pattern findings before applying the time factor.
Time Factor
A coarse multiplier based on repository last-push metadata. It does not identify when individual code was written.
Pattern Hits
Count of configured pattern findings. Review each location and surrounding code before acting.
HC Hit Rate
High- and critical-severity findings per scanned file. Severity is a configured detector weight, not proof of a vulnerability or authorship.
Lines / Files
Scan coverage denominators used by the legacy normalized score.

Pattern-Signal History

This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.

Severity Breakdown

Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.

CRITICAL 0HIGH 0MEDIUM 12LOW 244

Directory Score Breakdown

This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.

Pattern Findings

The scanner identified 256 distinct pattern matches across 10 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.

Hyper-Verbose Identifiers196 hits · 170 pts
SeverityFileLineSnippetContext
LOWdeprecated-env.ts280export function deprecatedEnvInputFromSources(CODE
LOWoauth.ts56export function isAuthInvalidTokenResponse(status: number, bodyText: string): boolean {CODE
LOWoauth.ts96export async function closeSharedOAuthServersAsync(): Promise<void> {CODE
LOWoauth.ts242async function requestAuthFromExistingServer(port: number, requestId: string): Promise<TokenData> {CODE
LOWschemas.ts5781function hasExactlyOneWebhookScope(data: { project_id?: string; group_id?: string }): boolean {CODE
LOWoauth-proxy.ts1174export function createGitLabOAuthProvider(CODE
LOW⚡index.ts2343function isGitLabUserApiRateLimitBody(errorBody: string): boolean {CODE
LOW⚡index.ts2347function isGitLabInsufficientUserScopeBody(errorBody: string): boolean {CODE
LOW⚡index.ts2354async function isInsufficientUserScopeForbiddenAsync(response: UndiciResponse): Promise<boolean> {CODE
LOW⚡index.ts2362async function throwUserApiScopeErrorUnlessRateLimitedAsync(CODE
LOWindex.ts134function isConstantTimeSecretMatch(CODE
LOWindex.ts849function buildToolUnavailableMessage(toolName: string): string {CODE
LOWindex.ts1401function getMcpDnsRebindingProtection() {CODE
LOWindex.ts1710function configuredGitLabApiUrlErrors(): string[] {CODE
LOWindex.ts1717function emitDeprecatedEnvWarnings(): void {CODE
LOWindex.ts1784function isToolAllowedByPermissionMode(toolName: string): boolean {CODE
LOWindex.ts2024function rejectIfStrictProjectScope(toolName: string): void {CODE
LOWindex.ts2077function isExcludedFromToolsetListing(toolName: string): boolean {CODE
LOWindex.ts2122function parseAllowedGitLabApiUrls(value: string): Array<{ host: string; apiUrl: string }> {CODE
LOWindex.ts2129function resolveTrustedGitLabApiUrl(value: string): string {CODE
LOWindex.ts2373async function authenticateWithJobTokenFallbackAsync(response: UndiciResponse): Promise<boolean> {CODE
LOWindex.ts2426function rejectIfProjectScopedDeployment(toolName: string): void {CODE
LOWindex.ts2711function appendMergeRequestFilters(url: URL, options: Record<string, unknown>): void {CODE
LOWindex.ts3277async function listCustomFieldDefinitions(CODE
LOWindex.ts3795async function updateIncidentEscalationStatus(CODE
LOWindex.ts3841async function resolveProjectOrGroupPath(CODE
LOWindex.ts5055async function listMergeRequestDiscussions(CODE
LOWindex.ts5079async function deleteMergeRequestDiscussionNote(CODE
LOWindex.ts5117async function updateMergeRequestDiscussionNote(CODE
LOWindex.ts5264async function createMergeRequestDiscussionNote(CODE
LOWindex.ts5416async function getMergeRequestDiscussion(CODE
LOWindex.ts5853async function getMergeRequestSourceCommitCount(CODE
LOWindex.ts5895async function listMergeRequestPipelines(CODE
LOWindex.ts5937async function buildMergeRequestCommitAdditionSummary(CODE
LOWindex.ts5971async function buildMergeRequestApprovalSummary(CODE
LOWindex.ts6006async function buildMergeRequestDeploymentSummary(CODE
LOWindex.ts6168async function listMergeRequestChangedFiles(CODE
LOWindex.ts6506async function getMergeRequestRebaseStatus(CODE
LOWindex.ts6537async function getMergeRequestApprovalState(CODE
LOWindex.ts6621async function getMergeRequestApprovalsFallback(CODE
LOWindex.ts6946function healthCheckTransportErrorResult(error: unknown) {CODE
LOWindex.ts6969async function fetchGitLabVersionMetadata(): Promise<GitLabInstanceVersionMetadata | null> {CODE
LOWindex.ts6982async function fetchGitLabInstanceVersion(): Promise<string | null> {CODE
LOWindex.ts7051async function resolveMergeRequestThread(CODE
LOWindex.ts8134function restrictRunnerDetailsToAllowlist(CODE
LOWindex.ts8163async function assertRunnerAvailableToProject(projectId: string, runnerId: string): Promise<void> {CODE
LOWindex.ts8808async function listPipelineSchedulePipelines(CODE
LOWindex.ts8945async function takeOwnershipPipelineSchedule(CODE
LOWindex.ts8972async function getPipelineScheduleVariable(CODE
LOWindex.ts8999async function createPipelineScheduleVariable(CODE
LOWindex.ts9032async function updatePipelineScheduleVariable(CODE
LOWindex.ts9065async function deletePipelineScheduleVariable(CODE
LOWindex.ts9209async function getMergeRequestRebaseStatusBeforeDeadline(CODE
LOWindex.ts9226async function waitForMergeRequestRebase(CODE
LOWindex.ts9552async function getMilestoneMergeRequests(CODE
LOWindex.ts9604async function getMilestoneBurndownEvents(CODE
LOWindex.ts9773async function getGroupMilestoneMergeRequests(CODE
LOWindex.ts9799async function getGroupMilestoneBurndownEvents(CODE
LOWindex.ts10318function normalizeIterationLookupId(iterationId: string): {CODE
LOWindex.ts10330function selectGroupIterationMatch(CODE
136 more matches not shown…
Structural Annotation Overuse27 hits · 46 pts
SeverityFileLineSnippetContext
LOWindex.ts17115 // Step 1: derive the effective auth for this request.COMMENT
LOWindex.ts17275 // Step 3: build the AsyncLocalStorage context so buildAuthHeaders andCOMMENT
LOWindex.ts17287 // Step 4: create a fresh transport per request.COMMENT
LOWtest/remote-auth-simple-test.ts303 // Step 1: Connect WITH auth header to establish sessionCOMMENT
LOW⚡test/remote-auth-simple-test.ts329 // Step 2: Wait for timeout WITHOUT making any requestsCOMMENT
LOW⚡test/remote-auth-simple-test.ts336 // Step 3: A stale stateful session must return the MCP re-initialization signal.COMMENT
LOW⚡test/stateless/callback-proxy.test.ts321 // Step 1: register client on podA (signed client_id → every pod can read it)COMMENT
LOW⚡test/stateless/callback-proxy.test.ts327 // Step 2: authorize on podA — captures the redirect URL to GitLabCOMMENT
LOWtest/stateless/callback-proxy.test.ts353 // Step 3: GitLab redirects to our /callback — on a DIFFERENT pod (B).COMMENT
LOWtest/stateless/callback-proxy.test.ts383 // Step 4: MCP client redeems the proxy code on a THIRD pod (C).COMMENT
LOWdocs/auth/oauth-setup.md33## Step 1: Create a GitLab OAuth ApplicationCOMMENT
LOWdocs/auth/oauth-setup.md69## Step 2: Configure the MCP ServerCOMMENT
LOWdocs/auth/oauth-setup.md123## Step 3: First-Time AuthenticationCOMMENT
LOW.github/skills/security-scan/SKILL.md21### Step 1: Determine ScopeCOMMENT
LOW.github/skills/security-scan/SKILL.md29### Step 2: Secrets ScanCOMMENT
LOW.github/skills/security-scan/SKILL.md47### Step 3: Dependency AuditCOMMENT
LOW.github/skills/security-scan/SKILL.md68### Step 4: Input Validation Spot-CheckCOMMENT
LOW.github/skills/security-scan/SKILL.md75### Step 5: Auth/Authz Quick CheckCOMMENT
LOW.github/skills/skill-stocktake/SKILL.md22### Step 1: InventoryCOMMENT
LOW.github/skills/skill-stocktake/SKILL.md36### Step 2: Frontmatter Validation (v1.0.5+)COMMENT
LOW⚡.github/skills/skill-stocktake/SKILL.md65### Step 3: Template Sync CheckCOMMENT
LOW⚡.github/skills/skill-stocktake/SKILL.md74### Step 4: Quality ChecksCOMMENT
LOW⚡.github/skills/skill-stocktake/SKILL.md84### Step 5: Coverage AnalysisCOMMENT
LOWskills/gitlab-mcp/reference/code-review.md8## Step 1: List Changed FilesCOMMENT
LOWskills/gitlab-mcp/reference/code-review.md27## Step 2: Batch Diff RetrievalCOMMENT
LOWskills/gitlab-mcp/reference/code-review.md43## Step 3: Leave CommentsCOMMENT
LOWskills/gitlab-mcp/reference/code-review.md81## Step 4: Resolve ThreadsCOMMENT
Decorative Section Separators10 hits · 30 pts
SeverityFileLineSnippetContext
MEDIUMstateless/codec.ts42// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts45// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts80// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts82// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts101// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts103// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts171// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts173// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts247// ──────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMstateless/codec.ts249// ──────────────────────────────────────────────────────────────────────────COMMENT
Verbosity Indicators10 hits · 18 pts
SeverityFileLineSnippetContext
LOWindex.ts17115 // Step 1: derive the effective auth for this request.COMMENT
LOWindex.ts17275 // Step 3: build the AsyncLocalStorage context so buildAuthHeaders andCOMMENT
LOWindex.ts17287 // Step 4: create a fresh transport per request.COMMENT
LOWtest/remote-auth-simple-test.ts303 // Step 1: Connect WITH auth header to establish sessionCOMMENT
LOW⚡test/remote-auth-simple-test.ts329 // Step 2: Wait for timeout WITHOUT making any requestsCOMMENT
LOW⚡test/remote-auth-simple-test.ts336 // Step 3: A stale stateful session must return the MCP re-initialization signal.COMMENT
LOW⚡test/stateless/callback-proxy.test.ts321 // Step 1: register client on podA (signed client_id → every pod can read it)COMMENT
LOW⚡test/stateless/callback-proxy.test.ts327 // Step 2: authorize on podA — captures the redirect URL to GitLabCOMMENT
LOWtest/stateless/callback-proxy.test.ts353 // Step 3: GitLab redirects to our /callback — on a DIFFERENT pod (B).COMMENT
LOWtest/stateless/callback-proxy.test.ts383 // Step 4: MCP client redeems the proxy code on a THIRD pod (C).COMMENT
AI Slop Vocabulary2 hits · 6 pts
SeverityFileLineSnippetContext
MEDIUMindex.ts936 // This is a robust workaround for AsyncLocalStorage context loss.COMMENT
MEDIUMindex.ts1915 // Use tough-cookie's parse function for robust parsingCOMMENT
Over-Commented Block6 hits · 6 pts
SeverityFileLineSnippetContext
LOWindex.ts17581COMMENT
LOWtest/stateless/session-id-integration.test.ts581// OAuth + stateless — sid-only follow-up across podsCOMMENT
LOWutils/redact-url.ts801 lastAt,COMMENT
LOW.github/workflows/tool-docs-sync.yml1name: Sync Generated Tool DocsCOMMENT
LOW.github/hooks/pre-tool-use.sh1#!/bin/bashCOMMENT
LOW.github/hooks/post-tool-use.sh1#!/bin/bashCOMMENT
Redundant / Tautological Comments2 hits · 3 pts
SeverityFileLineSnippetContext
LOWscripts/release.sh22# Check if gh CLI is availableCOMMENT
LOWscripts/release.sh546# Check if the current version tag already exists locallyCOMMENT
Fake / Example Data1 hit · 1 pts
SeverityFileLineSnippetContext
LOWtest/schema-tests.ts1577 email: 'admin@example.com',CODE
Unused Imports1 hit · 1 pts
SeverityFileLineSnippetContext
LOWscripts/generate-star-history.py4CODE
Deep Nesting1 hit · 1 pts
SeverityFileLineSnippetContext
LOWscripts/generate-star-history.py51CODE