Skip to content
This repository was archived by the owner on May 25, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/schema-drift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Schema Drift

# Phase 4 of the response-schemas initiative (DOT-555 / DOT-559).
# Calls real GitLab against every response-schema-bearing endpoint and
# fails the workflow on any Zod schema mismatch — catches GitLab API
# drift the moment it ships, not the moment a user trips over it.
#
# Required repo secrets:
# GITLAB_API_URL — e.g. https://gitlab.com
# GITLAB_PERSONAL_ACCESS_TOKEN — read_api scope only
# GITLAB_PROJECT_ID — fixture project with at least one
# MR, commit, issue, and pipeline.

on:
schedule:
- cron: "0 6 * * 1" # Mondays 06:00 UTC
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: read

jobs:
drift:
runs-on: blacksmith-4vcpu-ubuntu-2404

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Check schema drift
env:
GITLAB_API_URL: ${{ secrets.GITLAB_API_URL }}
GITLAB_PERSONAL_ACCESS_TOKEN: ${{ secrets.GITLAB_PERSONAL_ACCESS_TOKEN }}
GITLAB_PROJECT_ID: ${{ secrets.GITLAB_PROJECT_ID }}
LOG_LEVEL: warn
run: bun run scripts/check-schema-drift.ts
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ It's [redacted by default](#secret-redaction) for safety. To get it back, pass `

For `list_issues`, `list_merge_requests`, etc.: GitLab's global endpoints (when no `project_id` is supplied) historically defaulted to `scope: created_by_me`. To see everything, pass `scope: "all"` explicitly. If you supply `project_id`, the call routes to the project-scoped endpoint and this default doesn't apply.

### `GitLab response failed schema validation` in MCP server logs

GitLab responses on the server's schematized read endpoints (users, projects, merge requests, commits, issues, pipelines, repository tree) run through a Zod schema. On a mismatch the server logs `WARN GitLab response failed schema validation; passing through unchanged` with the field path and Zod error code, then passes the response on to your LLM unchanged — so the call still succeeds, but you've got a signal that GitLab returned a shape we don't know about. Causes are usually GitLab API drift (new field, type change, removal) or a self-hosted EE instance returning EE-only fields. If you see one of these warnings, [open an issue](https://github.com/detailobsessed/efficient-gitlab-mcp/issues) with the `path`, `code`, and which tool triggered it — that's our cue to update the schema.

---

## Development
Expand All @@ -525,6 +529,27 @@ bun run check
bun run build
```

### Schema-drift CI

The runtime path through `parseGitLabResponse` is intentionally lenient (`.safeParse()` + log warning + pass through) so an unexpected GitLab field never blocks an MCP tool call. The drift gate is the strict counterpart: a Bun script that calls every response-schema-bearing GitLab REST endpoint and `.parse()`s each response against its declared Zod schema, failing on any mismatch.

Run it locally:

```bash
export GITLAB_API_URL=https://gitlab.com
export GITLAB_PERSONAL_ACCESS_TOKEN=glpat-... # read_api scope only
export GITLAB_PROJECT_ID=12345 # must have ≥1 MR/commit/issue/pipeline
bun run drift
```

When to run it manually:

- **Before merging a PR that touches `src/schemas/`** — catches schema bugs against a real instance, complementing the fixture-based unit tests.
- **After upgrading a self-hosted GitLab** — quick sanity check that nothing in the response shape moved.
- **Triaging suspicious LLM behavior** — if responses look wrong but the tool returned OK, a schema mismatch silently passed through; drift check confirms or rules that out.

The same script runs in CI via `.github/workflows/schema-drift.yml` — `schedule` Mondays 06:00 UTC and `workflow_dispatch` on demand. The same three env vars are wired as repo secrets.

---

## Upstream Tracking
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"dev": "bun run build && bun start",
"test": "bun test",
"check": "biome check --write",
"clean": "rm -rf dist"
"clean": "rm -rf dist",
"drift": "bun run scripts/check-schema-drift.ts"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.29.0",
Expand Down
Loading