Populars: Dades actualitzades el 26 d’octubre del 2026

Categories

Internet1.355
Comunicació321
Àudio i vídeo898
Gràfics i disseny539
Ofimàtica i productivitat1.120
Eines per a desenvolupadors3.132
Eines d’IA527
Seguretat i privadesa385
Eines del sistema3.113
Jocs523
Educació i ciència239
Xarxa i TI284

GitLab MCP Server: baixar versions anteriors

GitLab MCP server exposing the REST v4 and GraphQL APIs as tools for AI assistants.

Aquí hi ha 17 versions de GitLab MCP Server, des de 7 de juliol del 2026 fins a l’actual, 3.3.0. Cadascuna enllaça amb els instal·ladors del mateix desenvolupador.

2026: 17 17 26
VersióDataMidaFitxers
3.3.0Darrera versió 20 d’octubre del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Changelog
### ✨ Features
• 1311b41404283553e0c67b03f1aa45b7be23a6ec:feat(search): pass num_context_lines and regex through code search (#1409) (@jmrplens)
### 🐛 Bug Fixes
• 680ce00faeabbdf58f7057284e00004352c235fe:fix(audit_1to1): hold always-sent findings to the package's methods (#1381) (@jmrplens)
### 📚 Documentation
• b0db60516ae9ec8166cf97dd6ece539cb183fe19:docs(upstream-bugs): record entry 132 as in review upstream (#1412) (@jmrplens)
• b0fb129cae1cf773308044024e3de0ad26d60cb0:docs(upstream-bugs): record rows 16 and 124 as settled upstream (#1449) (@jmrplens)
• 993740e695cc71d44083bd35ac4329a002dcefcd:docs(upstream-bugs): record the state of 2026-10-16 (#1397) (@jmrplens)
• 51c3bb4fd7eef409f901fb29eac5a338d73848c5:docs(upstream-bugs): record the state of 2026-10-19 (#1429) (@jmrplens)
• ef4d83500b66a763906eefbcc5455ab7ee65dd0a:docs: declare docs.jmrp.io/gitlab-mcp-server as the documentation address (#1379) (@jmrplens)
### 🚧 Maintenance
• 1743e18fb66da34e916e58721423f4eedc121ff8:Answer a GraphQL write GitLab ran without its object as probably committed, and leave null list items out (#1277) (@jmrplens)
• e194b79645cfd873fb235aeb4fbc6a8f5d9a449e:Answer each retry-later refusal with the code of what it says, and a tier-removed action with the tier it needs (#1346) (@jmrplens)
• 69e9e349743d37f3414bf2a1d5853f0db304b198:Answer the stdio frames the SDK rejects, send each session a copy of a resource update, and bring the register to 2026-10-13 (#1373) (@jmrplens)
• 28615b66a9140357da7c64ed2c2c218ab48e84db:Bring the upstream register to its state on 2026-10-10 (#1281) (@jmrplens)
• 63b21108c8829a0469c8b35e66e8152bc9df3b83:Bring the upstream register to its state on 2026-10-12 (#1345) (@jmrplens)
• 1895639ab56a33a26086d6dd5a3e36c402617404:Bring the upstream register to its state on 2026-10-12, evening (#1357) (@jmrplens)
• b25caca4665499ccc3fbb06df4bf5ca04d5b5cfd:Bump client-go from v3.15.0 to v3.29.0 (#1435) (@jmrplens)
• b970327459b056bd82f5f68deb9325e061c36ca0:Cancel an auto-merge through cancel_auto_merge on GitLab 19.5 or later (#1422) (@jmrplens)
• f17c87c047174f99e11532f410f3dc55ab017eae:Compare hosts by ASCII case alone, so a lookalike of the instance is another host (#1268) (@jmrplens)
• e5bdf76b6251c4b86b2eec3fad325be7fc42b35f:Count prompt reports the way GitLab counts, and complete what a caller types (#1366) (@jmrplens)
• 30a94fd6d30d1960dbfe79ba62a59fd993efd485:Detect the GitLab.com tier from the top-level groups a token is a member of (#1273) (@jmrplens)
• 9cf6aaadc49889d70e79479003df30dd79ac5dd7:Filter group packages by version, list topics without projects, and edit an award's message (#1439) (@jmrplens)
• d95b1a5339d7ff0820b959271466147d6e6bcf02:Give the wait poll tests a deadline no first poll can miss (#1450) (@jmrplens)
• be51b4cb9caba9654cb64cfb2074875e86d0701c:Hold client-go's GraphQL decoders to their documents, and record what they leave out (#1348) (@jmrplens)
• 8f741a9dd3fe003b0f5c8154cdb2c4248a225914:Hold each driven request to the instant it was due (#1378) (@jmrplens)
• 6d381855b527f64e9d74bfb8725c94b4171a3b2e:Hold epic note writes and child moves to the epic named, report the GraphQL nulls GitLab explains, and render each note, discussion and schema as its own (#1371) (@jmrplens)
• 6fa76d96ba9b3af83fef37ddf42e1cd9a12f3424:Hold every uses: to a pin, find a mutation wherever it starts, and move latest only for the newest release (#1364) (@jmrplens)
• 382f9e9a489acb78866a1b441ba026c4fc5a31a5:Hold the Spanish code blocks to the English ones outside comments and prose, and fail the lint when they drift (#1386) (@jmrplens)
• 491fbd5f7b7972baef2240b2d28388b854765fcd:Judge outbound hops by the address they spell, keep token verification on the instance, and fix the client address, probe, listing and CLI edges (#1365) (@jmrplens)
• 996d829f01ea99e9891dfb5f382831e567cd9b59:Keep a retried request's failed body out of the mirror's answers (#1361) (@jmrplens)
• 3cf8bc8071f1bc98edde1eaf6b282d4b3c22f13a:Kee
3.2.0 9 d’octubre del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Changelog
### 🚧 Maintenance
• 4656ffb1cf9b7c75a5b3683823967fbde2f0f6ad:Admit legacy HTTP tokens at the read_api minimum, uncharged and remembered (#1159) (@jmrplens)
• 4ef4e1d205f5597434c08e9ed53ebfc4637adcde:Answer a missing door permission uncharged (#1139) (@jmrplens)
• 219e7e08c5ffea6c87f7b2d4715b1ce66aba7ec8:Answer pipeline.latest from the ref GitLab was asked about when its head commit has no pipeline (#1252) (@jmrplens)
• 1dfe5367e227f71acf3f314797c9ead2e06a7a18:Answer the review of the documentation stack (#1196) (@jmrplens)
• ab63183edc9082de3470301a6ffc5591bc710b58:Ask GitLab for label counts where they are read, and publish only the counts it sent (#1217) (@jmrplens)
• 04630a41fe819e7c52daff1b262f5fd1835482c7:Attest the NuGet packages, hold nuget.org to them, and say how to verify what each package runs (#1123) (@jmrplens)
• d274a25d49efb5b732c07ea0910b161b29323b15:Bring the site level with the HTTP, OAuth, token and security guides (#1186) (@jmrplens)
• d8b46ffa4dd01b90886fefe6643f7a64bf529142:Bring the site level with the deployment, telemetry and sizing guides (#1187) (@jmrplens)
• 1696f0deec70780c80a1795ba57ebc22afc19986:Bring the site level with the install, client and CI/CD guides (#1188) (@jmrplens)
• 7939917b8ecc9e8a9616f3872589610b4d989d6a:Bring the site level with the reference and concept pages (#1189) (@jmrplens)
• 8fa69e1b1f227378eb56ccb9c412193e6b064147:Bring the upstream register to its state of 2026-10-06 (#1223) (@jmrplens)
• 6bc2c071d8eb24e544a01fb0236d69db370d8c06:Bring the upstream register to its state on 2026-10-08 (#1259) (@jmrplens)
• 96db3f73f62c1c6cc01bb9bb4f1ec1d68bf8d142:Bring the upstream register to its state on 2026-10-09 (#1264) (@jmrplens)
• e19b57926784dcdf40e53d9e5174146d020810c9:Bring the upstream register to the state of 2026-10-05 (#1178) (@jmrplens)
• ce4c7f39e56fd8bd26af8ad574f72e9647cc4276:Build the site on every change and hold its links and tables in CI (#1183) (@jmrplens)
• 39fcdb2626922eb93c88833b8fbaeb69f605b31d:Bump client-go to v3.15.0 and retire the system hook capture (#1177) (@jmrplens)
• 97e22dd2c1a37d2208bb37c7fa1a8ffc36f93888:Call the binary self-contained rather than static, and correct stale statements in llms-install.md and the Docker Hub page (#1263) (@jmrplens)
• d29641d5b1f7bf5fc84b553be170aae21ae730a6:Check the release binaries again when releasing, hold the image, bundles and notices to the release, and correct the stack's documentation (#1127) (@jmrplens)
• dec3a0936c497e210e2eab438e86c1b47da18f75:Clear the 56 open SonarCloud findings on main (#1118) (@jmrplens)
• f4c169d41a412e8d3a6238630016d76216751554:Close the condition and mutation gate of cmd/server, and gate the files only Windows and macOS build (#1206) (@jmrplens)
• c12f7bf4c97da0db3c2888245a4932ae56881c1a:Cover gitlab-org/gitlab and the Hackathon in the upstream contribution skill (#1261) (@jmrplens)
• 7efa36fb4c0b98af7c258d7358c82af2a816d538:Derive every action's requests and join them to the fine-grained permissions GitLab declares (#1143) (@jmrplens)
• aee74b3f603eafc09acfdcbcd767ef310b6bc540:Derive the classic scope each action needs and write it into the action grants table (#1244) (@jmrplens)
• 8153f1e4d0d0f435ce0cb6df76e09fc7ebad74de:Describe the widened supply-chain rule 2 in the command reference (#1249) (@jmrplens)
• 0f36d8982cab57ba8f5a69d1974d53bf2e137af0:Document fine-grained tokens (#1148) (@jmrplens)
• ae0d8c8c6bc9112e344de14e4c6d17481d65aecf:Document per-action token scopes and the read_api narrowing (#1248) (@jmrplens)
• bfee94634b07da48513510d2dbe7161b9013e02e:Fix what review found on the fine-grained stack: the collection flag, the spelling bound, an empty batch and SonarCloud's findings (#1152) (@jmrplens)
• a1a8fd3cee7e218b5c9e6d1ffea8aeb3aed73ee9:Generate the per-domain tool reference from the action catalog (#1191) (@jmrplens)
• 2d0bcea6e67c2491b8365360cb22c96808a53c86:Give gitlab_achievement an icon of its own, and hold the icon map to every group the catalog builds 
3.1.0 30 de setembre del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Changelog
### ✨ Features
• b744f34409a6db43f238eeecd527f3fc039aad3b:feat!: read every setting under its prefixed name and no other (#807) (@jmrplens)
• 6bac5426ae7eb97609876edaace5b3e03bc6ac6d:feat(1:1): publish the three clean sent-field blocks, and give memberroles a context (#685) (@jmrplens)
• 9798d14a76f1c7c9dcdcdca316f4229b33f11a36:feat(1to1): R-PAGE, the dimension that asks whether a list says where it ends (#719) (@jmrplens)
• eb67d88e17d6df54499c383ed6855eecee09c5c8:feat(audit): the e2e coverage command, credited from what the server dispatched (#728) (@jmrplens)
• 3d777c978ef754685ad14bac989ceb03b3efa144:feat(audit): two gates for the card shape, reporting what the migration owes (#712) (@jmrplens)
• 6379aba532a6ba5327b51aba196c2f0a5f33e0d9:feat(e2e): call the real server by canonical action ID on every surface (#724) (@jmrplens)
• 71d781288dd803c73ceedba127d60ce856e6b9c2:feat(e2e): declare the call record the rebuilt suite writes and the audit reads (#722) (@jmrplens)
• 6bbaaabcbbe0e75e1e80c2c8f7193a6fe16b7eb9:feat(e2e): measure the server binary in the transport modules (#771) (@jmrplens)
• 64343caef5c7b56f212a01dbc865fe762810aab6:feat(e2e): record what the old suite drives, and the two baselines it produces (#732) (@jmrplens)
• 76c611d4a3aad4a70a7be98391309d50358514bb:feat(e2e): record what the server dispatched, not what the test asked for (#725) (@jmrplens)
• 9c8d44da6c13e68ff18d26740e74505c260b4e42:feat(e2e): start the real server from a harness that probes before it writes (#723) (@jmrplens)
• 35e00d25523f5885c246468da826e81b4da295e9:feat(e2e): the fixture library, with the shared World and the run-scoped sweep (#729) (@jmrplens)
• 015a351e9dee5b71bda02f6b4701c00f4eb03bcb:feat(e2e): the runtime packages, their first tests on the real binary, and a non-blocking CI job (#733) (@jmrplens)
• fbe86dcb4ad25d52681b0d8e0ca1a311b4ae31c3:feat(eval): stop publishing, tell the truth about the numbers, and measure the prompt leak (#772) (@jmrplens)
• f3bad2fc2b48627c3f4677627e5e502abef41f19:feat(http): publish an ETag on the three unauthenticated documents (#694) (@jmrplens)
• 41b95a8b83cbfc4beb8f3f8b21bbf426228e4e5e:feat(http): serve the SEP-2127 card at /server-card, the catalog at the legacy path (#692) (@jmrplens)
• 0a488d504b83c9017eef6c79613e1f91bcc32e40:feat(modeleval): build the Free worlds a case runs in, one recipe at a time (#800) (@jmrplens)
• 9290d77b99d111ccc0b6384d33647f2506c7c8f3:feat(modeleval): call a model, and hash exactly what was sent (#799) (@jmrplens)
• 55fe5c9ea4b6aaf3698ca65b79e623adf1e4f738:feat(modeleval): decide what an attempt was worth, from the record alone (#798) (@jmrplens)
• f484278b99e7951aa7b8cb3406faed3b0a8f63a8:feat(modeleval): declare what one run writes down, before anything writes it (#785) (@jmrplens)
• f55be1233b6ebd44b2287d357abc21c560b613fc:feat(modeleval): finish the corpus, and write down what the move left behind (#794) (@jmrplens)
• c892584c95407df7acbab5178e2a883e7fc05f63:feat(modeleval): hold a case's answer where nothing that asks it can read (#792) (@jmrplens)
• 6d01453b0552342ce2a7b2d6e079916e2f6adf38:feat(modeleval): publish a measurement only when it can say what it measured (#804) (@jmrplens)
• 737e701cae7cf24b82e96b1300b06ea52b315c63:feat(modeleval): put the corpus to a model and write down what happened (#803) (@jmrplens)
• aba93c30d49e6c9a5c73cda202a93bc81deef818:feat(modeleval): raise the world every case runs in, licensed half included (#801) (@jmrplens)
• 34893e181bc6e8e0bd8e62ab942fbed0ed33d360:feat(modeleval): send a model's own call and say what the server ran (#797) (@jmrplens)
• 7ce34e7be86e20a234b6c0edaeae9c2e464578e2:feat(modeleval): show a model the slice of the catalog it can be given (#806) (@jmrplens)
• 874fd3f15d7caad7c2da5d112a703cd071f01c98:feat(release): attest the container image on both registries, and declare Docker Hub (#684) (@jmrplens)
• a036dcdc24ac88f7d4648b071d08756f8d96e336:feat(tenancy): bound tools/list across the process (RTC-007
3.0.0 10 de setembre del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Changelog
### ✨ Features
• b771c0541b03d42adaa09dc83ff3c350a8bf9631:feat!: remove what v2 deprecated, minus the one window that never opened (#641) (@jmrplens)
• e9626dfda03695a6e367a8450f94eab3c9f7a858:feat(achievements): take the avatar upload, and judge the GraphQL documents that carry a file (#592) (@jmrplens)
• 0664a2861ec3beff7f07f369735f43c6debbb86d:feat(apiexposes): pin the condition GitLab sends each REST entity field under (#622) (@jmrplens)
• 73b04d36a9d15593c403764d14c742420708f3de:feat(audit): add R-PATH, the dimension that reads the request rather than the surface (#598) (@jmrplens)
• bf04b7714cf6cf2f2830133e02ccd480c77f964f:feat(audit): ask a booted GitLab what its own REST API is (#650) (@jmrplens)
• d6993c06e5ec0fe37ad6a03dcee76846fc734cb8:feat(audit): ask the sent question of GraphQL, where nothing asked it (#648) (@jmrplens)
• 0b23a9e474b0e7dc2f3921c0247b75213a0aad94:feat(audit): check the prose a meta-tool serves against the parameters it takes (#590) (@jmrplens)
• f8f8f9c51504d49abff33a2b0c3df8276031ecbf:feat(audit): judge every GraphQL decoder against the document it decodes (#621) (@jmrplens)
• ca4d86a2755d01a2d62ace3c825961e9a7c444e6:feat(audit): pin what GitLab says its own API returns, from the document GitLab generates (#599) (@jmrplens)
• de07060d299752e5cf3e3bc4642699f5252e3ffa:feat(audit): read the SDK's enum values instead of trusting the field (#527) (@jmrplens)
• be21f5e7098ca6a23305036f37dbf81e6e1fe4d6:feat(audit): report the output fields GitLab's own document says it does not send (#585) (@jmrplens)
• b62edb0e066e8dda9f81fb9eddab800f2669d589:feat(audit): say which sent findings belong upstream in client-go (#654) (@jmrplens)
• b244e4149b961f84203beb2271b335caad4088b0:feat(audit_1to1): ask the shape check at type grain, and adjudicate what it found (#589) (@jmrplens)
• cb452bd5b31f367425a161a795c1ad60f059ec83:feat(bench): measure and publish what the server costs to run (#463) (@jmrplens)
• 80245f6d4b89d86249165c16ebd6a8d574b3b961:feat(bench): measure whether a bound leaves the quiet tenant better off (#597) (@jmrplens)
• 5492f2b51f6434e5a388d580f7b831cdb2672661:feat(bench): step one process up to a thousand credentials, with a profile at every step (#534) (@jmrplens)
• b2c4bdd523f8288e55fe98f47a7905aba23509d3:feat(catalog): declare the documented value sets as schema enums (#494) (@jmrplens)
• 13371b538326547143fe0387a18f5198d274fd8b:feat(catalog): embed the canonical resource of every get action again (#503) (@jmrplens)
• 735329de6c55074ec76cb7778168d74ff283b6ac:feat(config): prefix every server variable with GITLAB_MCP_, the GITLAB_ switches included (#523) (@jmrplens)
• 124f103b09e83cc9286947b2cb330233697ef03c:feat(dependencyfirewall): expose the Dependency Firewall evaluate endpoint (#451) (@jmrplens)
• 36089b8d750f2898bec3894bdd802eae2ff32b84:feat(epics): expose what the Work Items API offers an epic, and publish only what GitLab sends (#593) (@jmrplens)
• 764a12fd016410772465a6e45b35d8d89df0fbe5:feat(gen_testing_docs): pass -timeout through, refresh testing.md, gate it in CI (#441) (@jmrplens)
• 1c5edb74470a17a98af4776c056b478521625859:feat(geo): publish what a Geo site and its status send, declare the matrix (#665) (@jmrplens)
• 6befc450256254b2d1b10727d4762b68bc6c905b:feat(gitlab): read a field client-go does not model from the captured response (#625) (@jmrplens)
• 677e1dbf53eaa0e1638da772690d534857e56b5f:feat(graphql): judge every document against the schema an instance serves today (#579) (@jmrplens)
• 476f7ad74a057e6c78062c91492a5a89c5456d24:feat(graphql): make the mocks refuse what GitLab refuses, and fix the nine tools that proved (#575) (@jmrplens)
• 04e528414424db9835931491f40047fcfc2fc90b:feat(http): believe the client-address header only from listed proxies (#480) (@jmrplens)
• 97132dc33328e162b0fb7a6d75e7c07bf389bfd1:feat(http): meter tools/list on a bucket of its own (#566) (@jmrplens)
• e5402d301beda45e8150d7ccdc2b866350d773f6:feat(http): report draining on /health an
2.7.5 27 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Yes, another one. In my defence, 2.7.4 shipped a flag whose entire purpose was to let browsers talk to this server, and it did not let browsers talk to this server. The flag was fine. The preflight it depended on was refused, so the browser never got as far as sending the request the flag would have allowed. `curl` said `200` throughout, which is how it shipped.

So:2.7.5 is the one where the browser path is actually exercised by something other than optimism.

---

## The browser path

**`--trusted-origins` now works from a browser.** A preflight `OPTIONS` from a trusted origin is answered `204` with the CORS headers, and `Mcp-Session-Id` / `Mcp-Protocol-Version` are exposed so a client can read them back.

**⚠️ If you run behind a reverse proxy that adds its own CORS headers, remove that block in the same deploy as this upgrade.** This is not tidiness — upgrading without it makes your deployment *worse than it was*:

> Access to fetch at `.../gitlab` has been blocked by CORS policy:The `'Access-Control-Allow-Origin'` header contains multiple values `'http://127.0.0.1:18090, *'`, but only one is allowed.

Fetch treats two `Access-Control-Allow-Origin` headers as a failure rather than merging them. Before the upgrade your proxy's lone `*` at least worked for uncredentialed requests; after it, the server sends its own and the pair cancel out. `curl` reports `200` either way, so nothing but a real browser will tell you. See [Security — The browser preflight](https://jmrp.io/docs/gitlab-mcp-server/concepts/security).

## What happens to a request that does not get through

**A public deployment was an amplifier.** Unauthenticated traffic — which anyone can generate — was relayed to GitLab one request for one, and on gitlab.com that became rate-limit pressure charged to *this server's* address, landing on the legitimate users who share it. Three layers now sit in front:a per-address failure budget checked before anything else, a five-minute rejected-token cache keyed by SHA-256 digest (never the raw credential, bounded to 4096 entries because callers choose the keys), and the existing verified-identity cache. Six retries with the same bad token now reach GitLab once.

**A throttled GitLab was reported as an invalid token.** A `429` was wrapped in `ErrInvalidToken`, so a well-behaved MCP client did the worst possible thing:discarded a perfectly good credential and started a fresh authorization flow — more upstream traffic at the exact moment the instance asked for less, and a user asked to re-approve an application that was never at fault. Upstream conditions now answer `503`, carry GitLab's own `Retry-After`, and are never cached as a rejection.

**Rejections say what they are.** RFC 6750 `error` codes distinguish *reauthorize* from *ask for more scope* from *just retry*, in the JSON-RPC shape the rest of the endpoint uses rather than plain text — which a client is told by the specification to read as an initialization-era server, turning a missing header into a false protocol diagnosis.

**Least-privilege scope.** A read-only deployment asks for `read_api` instead of `api`, and `api` is accepted where `read_api` is required, since it is a strict superset. Real introspection had turned the old hardcoded `api` into a lockout for `read_api` tokens.

## Fixes you would only notice in the logs

**Every HTTP legacy request logged no user at all.** Identity was read from a field only the SDK's bearer middleware can populate, and legacy mode does not mount it, so the zero identity resolved every time. The pool now resolves the user once when it builds an entry — one call per entry, not per request.

**`Bearer` is matched case-insensitively**, per RFC 9110. The SDK verified the token, spending an API call, and the gate then refused it.

**The SEP-2243 header annotation was doubled.** The SDK prepends `Mcp-Param-` on both the sending and validating side, so declaring the full name put `Mcp-Param-Mcp-Param-Action` on the wire and made the d
2.7.4 27 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Yes, another release. Sorry. That is four in two days, and I promise there is no grand strategy behind the cadence — just someone finally trying the OAuth mode in anger and discovering it had never authenticated a single human being in its entire life.
In my defence: it looked fine. It had a verifier, a metadata endpoint, a token cache, tests, and documentation. What it did not have was a working request.
OAuth mode never worked. At all. (#309)
--auth-mode=oauth verified your Bearer token correctly, extracted your identity correctly, cached it correctly — and then built the GitLab client that does the actual work with the token in a PRIVATE-TOKEN header. GitLab accepts glpat- there. It does not accept gloas- OAuth access tokens there, in any header but Authorization: Bearer. So every single call after a perfectly successful login came back 401.
Fixed by giving the pool an OAuth-aware constructor (NewAuthSourceClient + a static token source) that it selects when --auth-mode=oauth, and by making the two raw HTTP probes — the version check and the credential-rejection check — pick their scheme from the same decision instead of hardcoding PRIVATE-TOKEN. Verified end-to-end against gitlab.com with a real authorization-code + PKCE flow, which is how it should have been verified the first time.
The same PR stopped assuming scopes. The verifier used to stamp every identity as api-scoped; it now introspects the token's real scopes (/personal_access_tokens/self for PATs, /oauth/token/info for OAuth tokens) and falls back to the old assumption only where introspection is unavailable.
Browser clients were being refused before anyone looked at them (#312)
The cross-origin protection wrapped the handler with no way to configure it, so every cross-origin POST got a 403 from Go's stdlib before MCP dispatched anything. That is correct default behaviour and it stays the default — but "validate the Origin header" is not the same instruction as "reject every origin", and there was no allowlist.
- --trusted-origins — comma-separated absolute origins (scheme://host[:port], an IP is fine for local deployments) allowed to make cross-origin browser requests. Empty by default, so nothing changes for anyone who does not set it. * accepts any origin and logs a warning that the protection is off. A malformed entry fails startup rather than being quietly dropped.
- --public-url's origin is trusted automatically. The flag already declared "the externally reachable origin of this deployment"; now it also behaves like one. It is validated in legacy mode too, since it finally has an effect there.
- A dual-header hole is closed. In OAuth mode the SDK verified the Bearer token, but credential extraction still preferred PRIVATE-TOKEN when both headers were present — so a request could be authorized as one identity and executed as another. OAuth mode is now Bearer-only.
- The RFC 9728 metadata endpoint answers its own CORS preflight. It was mounted GET-only, which sent OPTIONS to the catch-all gate and 401-ed it, locking out exactly the browser-based clients that discover the server that way. It also gained the two RECOMMENDED fields it was missing, resource_name and resource_documentation.
- Two flags that -h had never listed, -public-url and -trusted-origins, are in the full help output. The first is required for OAuth mode, so following the help text could not get you a running server.
Documentation that matches the software (#311)
Twenty-one files, including the bilingual site. The parts worth calling out are the ones that were actively false: the site claimed PRIVATE-TOKEN still works in OAuth mode through header normalization (it does not — that is a 401), and every OAuth startup example omitted the --public-url flag without which the server refuses to start.
Beyond the corrections: which MCP clients can actually complete an OAuth flow against gitlab.com and which cannot (and why mcp is the one scope you must never grant a Dynamic Client Registration client)
2.7.3 26 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Follow-through release on the mcp.jmrp.io directory audit: every cross-reference the surface emits now resolves, in every text layer — not only the See-also clauses v2.7.2 fixed.
The 13 invisible clauses (#307)
The follow-up audit found 32 unprojected See-also references across 13 entries on the deployed 2.7.2. Root cause was format, not names: the integrations family's clauses ended without a trailing period and discovery's clause carried parenthetical annotations, so the canonical clause pattern never matched — no per-surface rewrite, no tier-aware drop, and no guard extraction. All 13 canonicalized, and the guard gained a format-lint leg (with its rules pinned by a table-driven test): any See also: occurrence outside the canonical shape now fails CI naming the entry. Live after the fix: 2,052 references, 0 orphans.
The whole text surface, swept
Tool-name references live in more places than See-also clauses. A full sweep of runtime error hints, markdown next-step hints, workflow guides, schema descriptions, and aliases corrected ~40 stale references across 27 files — pre-rename names (gitlab_user_gpg_keys_list → gitlab_list_gpg_keys), wrong dispatchers (gitlab_commit → gitlab_repository), the pipeline guide's gitlab_job_log → gitlab_job_trace, a ghost alias, and two hints that named actions that do not exist (a db-migrations list, a topic merge), both reworded honestly. Polymorphic resource-event hints now name both their issue and MR variants. A permanent guard validates every gitlab_* token in the catalog's text fields against the catalog itself.
Honest wording
- project.archive and group.archive said "(read-only)" — describing the archived object, but reading as a safety claim on a mutating action. Now: "making it read-only in GitLab". (Neither action's actual read-only classification was ever wrong.)
- The typed required_params omission semantics are documented: an entry without type means the schema states no single plain type (admin.feature_set's value, the only case in 851 entries) — read it as "any" and consult gitlab://tools/{id}.
Full detail in #307.
2.7.1 26 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Conformance and discoverability release:everything the server answers, advertises, and refuses is now aligned with the ratified MCP **2026-07-28** specification — cross-reviewed both ways with the sibling [libgen-mcp](https://github.com/jmrplens/libgen-mcp) server.

## Server Card discoverability (#303)

• The card at `/.well-known/mcp/server-card.json` now carries the **negotiated `capabilities`** (live from the same handshake `serverInfo` comes from) and a machine-readable **`subscriptions` block**:per-method availability (`subscriptions/listen`, and `resources/subscribe` with `available: false` plus a `requires` note on stateless HTTP) and the full `subscribable_uri_templates` list — a directory can learn all of it without connecting.
• Every subscribable resource template also declares itself in-band:a marker sentence in its description and the vendor-namespaced `_meta` key `io.github.jmrplens/subscribable: true` (the spec's sanctioned per-object extension point).
• Cross-origin reads work end to end:`Access-Control-Allow-Origin` on GET, an OPTIONS preflight that echoes `Access-Control-Request-Headers`, and `Access-Control-Max-Age` so scanners preflight once an hour, not once a fetch.

## Full-surface conformance round (#303)

• **No deprecated capability advertised**:every server this repository constructs pins `capabilities` explicitly, so the SEP-2577-deprecated `logging` capability never appears in a handshake, the card, or generated manifests.
• **Capability/method consistency** (`internal/capguard`):`logging/setLevel` answers `-32601` on every surface, and on `CAPABILITY_SURFACE=minimal` so do `prompts/list`/`prompts/get` — no more successful empty answers for features the handshake never declared.
• **OAuth HTTP mode hardened**:`--public-url` is now required and validated (RFC 9728 resource identifier, metadata served at the path-inserted well-known location), only `Authorization: Bearer` is accepted (`PRIVATE-TOKEN` is rejected with 401 in this mode), and token **scopes are introspected** (`/personal_access_tokens/self`, `/oauth/token/info`) instead of assumed.
• **Stateless HTTP fixed for long streams**:the server-initiated keepalive ping is off on stateless transport (the spec forbids it there, and the SDK kills the stream on the first failed ping), and SSE responses carry `X-Accel-Buffering: no` so proxies deliver progress as it happens.
• **Strict elicitation schemas**:integer selections are offered as string enums (the elicitation subset defines enums for strings only) with lenient parsing kept for numeric answers, and the legacy `elicitationId` is only sent to pre-2026-07-28 clients.

## Deliberate error codes (#304)

Every refused stateful `resources/subscribe` now reaches the wire as a proper JSON-RPC error instead of the accidental `code:0`: `-32602` for a non-subscribable URI or an unreadable resource, `-32000` (transient, retry) for rate limiting, a full watcher cap, or shutdown, `-32603` for a transient GitLab failure, and `-32600` for the legacy method on stateless HTTP. Messages keep the upstream detail verbatim; the code table lives in the [subscriptions reference](https://jmrp.io/docs/gitlab-mcp-server/reference/capabilities/subscriptions/).

## Fixes

• `gitlab_instance_variable_*` descriptions no longer claim the value is "redacted when masked":GitLab's API returns raw values to admins (masking redacts CI job logs), and the payload mirrors the API — the markdown view is what masks.
• `mcpb/manifest.json` moved to manifest format **0.4** and its `$schema` points at a URL that exists again (the upstream schemas moved out of `dist/`).
• `make publish-lobehub` uses the LobeHub CLI's `update` verb for the existing listing (#302).

Full spec receipts, the vendor-surface inventory, and the cross-review record are in [#303](https://github.com/jmrplens/gitlab-mcp-server/pull/303) and [#304](https://github.com/jmrplens/gitlab-mcp-server/pull/304).
2.7.0 25 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Changelog
### ✨ Features
• 0ab74c13b1bf36d979cf2b179242264e0bd7d177:feat(icons): ship WebP light/dark fallbacks for clients that reject SVG (#295) (@jmrplens)
• 84b7897f601a2dd1eb659d8a612c52532fbb7bd8:feat(mcp): honor resources/subscribe by polling GitLab (ADR-0015) (#296) (@jmrplens)
• e2a5d3623798a8050c2fb60f72d558d5d5ea84b7:feat(site): responsive polish — compact header controls, stacking record tables, and the facts vocabulary (#300) (@jmrplens)
• b0133ae0f793c2e9c97b0588f8311e79d6279040:feat: brand redesign — the fan-out mark, circuit-violet theme, data-driven landing, generated cards (#299) (@jmrplens)
### 🐛 Bug Fixes
• 2d3ca56df66099a55cb7abe8736b71924123b8a1:fix(config): layer environment under HTTP flags, add a brand mark, and stop counting icons as model context (#294) (@jmrplens)
• cc0edd38eaacc67f2d0a31de2200bfd184449172:fix(mcp): complete the display metadata every surface advertises (#293) (@jmrplens)
• f7da136cf92cbe0cdcd6e10ecd9079fe788a4d0c:fix: make HTTP serving independent of machine luck, in tests and in production (#297) (@jmrplens)
### 📚 Documentation
• a6ddbe6a602afa69fd9a7229ea3b8c207825786a:docs: swap Smithery badge for MCP Toplist, drop stale mentions (#292) (@jmrplens)
### 🚧 Maintenance
• 21ae656912c38c8c89d5a90420b9a8b53a02028c:chore(deps): client-go v2.59.0 + site refresh, with job_inputs parity on gitlab_job_play (#298) (@jmrplens)
• 77827a7f62271308eb132e42414bc208983a9178:chore: bump version to 2.7.0 (#301) (@jmrplens)
• 98a213bd5cb9eeffa76d47c5835075c8e94846ae:chore: update manifests for v2.6.6 (@jmrplens)

## ⚠️ New server icon in MCP clients

This release replaces the server's MCP brand mark:clients that render server icons (VS Code, Claude Desktop, Cursor, …) will now show **the fan-out** — GitLab MCP Server's own mark (a source node branching into three arcs, the action catalog reaching its three tool surfaces) — where previous versions showed the GitLab tanuki. Same server, new face; the tanuki is GitLab's trademark and has been retired from all of this project's assets.
2.6.6 22 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Highlights

### 🚦 Every rejected request now says why — and `initialize` no longer looks like an outage

HTTP mode answered **every** unroutable request with `400 Bad Request` and the plain-text body `no server available`. That string is not ours:the MCP SDK emits it whenever the server-selection callback returns nil, which this server did for four unrelated reasons — a missing credential, an unparseable `GITLAB-URL` header, an exhausted authentication rate limiter, and an unreachable backend.

Two things were wrong with that beyond the lost detail.

**A missing credential is `401`.** The MCP authorization specification's own error table says `401 — Authorization required or token invalid` and reserves `400` for a *malformed authorization request*. Nothing in the specification exempts `initialize` from authentication — the transport says servers **SHOULD** implement authentication for all connections — and protocol `2026-07-28` removed the initialize handshake entirely, so there is no handshake to open up.

**And `400` now carries protocol meaning.** Revision `2026-07-28` tells a client that receives `400` with a body that is *not* a recognised JSON-RPC error to conclude the server is initialization-era and downgrade. A plain-text rejection therefore turned a missing header into a false protocol diagnosis — and the downgraded `initialize` answered `400` as well.

Each cause now carries its own status, headers, and machine-readable reason:

| Condition | Status | JSON-RPC code | Notable headers |
| --- | --- | --- | --- |
| No `PRIVATE-TOKEN` and no `Authorization:Bearer` | `401` | `-40100` | `WWW-Authenticate` |
| GitLab answered `401`/`403` to the credential | `401` | `-40100` | `WWW-Authenticate` |
| `GITLAB-URL` header is not a parseable URL | `400` | `-32600` | — |
| More than 10 auth failures from one IP in a minute | `429` | `-42900` | `Retry-After` |
| GitLab session could not be built for the token | `503` | `-50300` | — |

The legacy challenge is `Bearer realm="gitlab-mcp-server"` and deliberately omits `resource_metadata`:clients discover an OAuth authorization server through that parameter, and legacy mode has none, so advertising it would start a discovery flow that cannot complete. `Bearer` is still honest — the server accepts `Authorization: Bearer <pat>` alongside `PRIVATE-TOKEN` — and per RFC 6750 §3.1 a challenge for a request carrying no credential omits the error code, so the accepted headers are named in the JSON body instead. `GET` and `DELETE` keep their `405`, which is what `2026-07-28` prescribes.

Error codes are allocated **outside** the JSON-RPC reserved range, as the specification requires:`-32000`–`-32019` is legacy and `-32020`–`-32099` belongs to MCP. A test enforces the rule so a future code cannot squat there.

The cost of the old behaviour was measurable:the [does-it-install](https://github.com/chryaner/does-it-install) tracker recorded the hosted endpoint as `connect_failed` — *"endpoint unreachable"* — because its classifier maps `401`/`403` to *needs credentials* and every other status to *unreachable*. "No server available" reads as a dead service, not an absent header.

### 🔐 A token GitLab refuses no longer gets a session

The server pool admitted an entry for any non-empty string, so `PRIVATE-TOKEN:x` completed a full MCP handshake — and a stream of distinct invented tokens churned the bounded LRU that real sessions live in.

Checking the token *format* would not fix it:GitLab lets self-managed administrators change the `glpat-` prefix, so a prefix rule would reject legitimate self-hosted tokens while still admitting any well-shaped fake. GitLab itself is the only deterministic, format-agnostic judge, so it is now asked — `GET /api/v4/user`, once per new pooled session and never per request.

Only an explicit `401`/`403` rejects. Every other outcome admits the session:failing closed whenever GitLab is unreachable would turn an instance outage into a total denial of service, which i
2.6.5 21 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
## Highlights

### 🧪 A fully skip-free test suite — and the two product bugs it caught

The end-to-end suite now provisions everything it needs and runs **1,453 tests with zero skips**:an ephemeral Bitbucket Data Center container backs the `import_bitbucket_server` coverage (unattended setup with Atlassian's public timebomb test license), the db-migration bookkeeping path seeds itself through the Rails console, CI catalog versions are published through a real runner pipeline, and pending-approval users are provisioned for the approve/reject flows.

Exercising every path for real immediately exposed — and fixed — two bugs mocks had been hiding:

• **`gitlab_get_catalog_resource` / `gitlab_list_catalog_resources` never worked against current GitLab**:their GraphQL queries used fields GitLab has removed (`webUrl`, `forksCount`, `readmeHtml`, `latestVersion`, …), and the validation error was misreported as *not found*. The queries and output shapes now mirror the live schema 1:1 (`web_path`, `last_30_day_usage_count`, `archived`, `topics`, `verification_level`, `visibility_level`; README and components sourced from the newest version; `semver` flattened from its object form).
• **`gitlab_group_board_list_update` could never decode a successful response**:client-go's group-level wrapper declares `[]*BoardList` while GitLab returns the single updated object. The handler issues the request directly until the upstream fix lands — contributed by this project as [client-go!2996](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2996), accepted for the v3.0 release branch.

### 🎯 1:1 parity audit:zero findings

The group Datadog integration output now mirrors client-go's own dual shape:the canonical configuration lives in the nested `properties` object, while the flat top-level copies remain as **deprecated** conveniences (prefer `properties.*`). The change is purely additive — no consumer loses a field on any surface. With it, `make audit-1to1` reports **zero findings across every dimension** (struct input/output, action coverage, discovery metadata) for the first time in the project's history.

### ⚙️ Go 1.27 toolchain

Built with **Go 1.27.0** end to end:`go.mod`, CI, and the Docker image (`golang:1.27.0-alpine3.24`). The codebase adopts Go 1.27's promoted-fields-in-composite-literals style (enforced by the golangci-lint 2.13 baseline), and CodeQL moved from GitHub's default setup to a repository-owned workflow so security scanning keeps working the day a new Go version ships.

### 📦 GitLab client v2.58.2 — directory-structured package file names

Generic Package Registry file names may now describe a directory structure:`/` is kept as a real path separator, and empty, `.`, or `..` segments are rejected client-side before any request. `gitlab_package_publish` / `gitlab_package_download` document the contract in their schemas and return a specific, actionable hint when a name is invalid.

### 📌 Versioning policy, now written down

The server's **major version tracks client-go's major**:when client-go releases v3, this project moves to v3 in that same dependency bump — and that release removes the deprecated compatibility fields kept during the v2 cycle (the flat Datadog copies above, among others). Every other dependency update ships as a minor or patch release. Documented on the [about page](https://jmrplens.github.io/gitlab-mcp-server/about/) and in the contributor docs.

## Also in this release

• The release gate itself hardened by this release's own dry runs:the e2e db-migration seeding now picks a version the GitLab **web process** can resolve (Omnibus ships a relative `db/migrate` path that Puma, running with `cwd=/`, cannot — only the absolutely-pathed `post_migrate` directory is visible to the API), and the CI gates' test timeout was sized to the suite's real duration.
• Off-goroutine `testing.T` abort sweep completed (541 → 0 sites) with a CI gate (`cmd/audit_test_goroutines`) so they cannot return; two latent 
2.6.4 17 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Changelog
✨ Features
• a13a226:feat(deps): client-go v2.55.1 with new API surface, dependency updates, and 2.6.1 (#264) (@jmrplens)
🐛 Bug Fixes
• 11cbeed:fix(modes)!: apply read-only and safe mode per action so dispatcher surfaces keep serving reads (#263) (@jmrplens)
🚧 Maintenance
• 14c021d:chore: update manifests for v2.6.0 (@jmrplens)
2.6.1 2 d’agost del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Changelog
✨ Features
- a13a226: feat(deps): client-go v2.55.1 with new API surface, dependency updates, and 2.6.1 (#264) (@jmrplens)
🐛 Bug Fixes
- 11cbeed: fix(modes)!: apply read-only and safe mode per action so dispatcher surfaces keep serving reads (#263) (@jmrplens)
🚧 Maintenance
- 14c021d: chore: update manifests for v2.6.0 (@jmrplens)
2.6.0 31 de juliol del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Changelog
✨ Features
- 05ff168: feat(http)!: stateless by default plus SDK v1.7.0 follow-ups (cache hints, cancellation, body limit, x-mcp-header) (#261) (@jmrplens)
- 517fe69: feat(http): stateless streamable HTTP mode (SEP-2567, protocol 2026-07-28) (#260) (@jmrplens)
🚧 Maintenance
- 3e36df9: chore: bump version to 2.6.0 (#262) (@jmrplens)
- 4486f0c: chore: update manifests for v2.5.3 (@jmrplens)
- 69f135c: ci(release): retry cosign signing on transient OIDC failures (#258) (@jmrplens)
2.5.3 29 de juliol del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Changelog
✨ Features
- 5292429: feat(deps): update client-go to v2.53.0 and close the 1:1 input gaps (#256) (@jmrplens)
- c7d2700: feat(deps): update go-sdk to v1.7.0 and adopt multi round-trip elicitation (#255) (@jmrplens)
- 91cdaef: feat(release): track lhm.plugin.json and auto-stamp it on releases (#244) (@jmrplens)
- 4eb4310: feat(site): optimise documentation for AI discovery and citation (#249) (@jmrplens)
- 36f4ce5: feat(site): read the Person entity from its canonical source (#251) (@jmrplens)
- 3a79ebf: feat(tooling): generate the LobeHub manifest capability arrays (#253) (@jmrplens)
🐛 Bug Fixes
- dd5a90e: fix(lint): cap golangci-lint concurrency to keep cold runs finishing (#248) (@jmrplens)
- bace8af: fix(site): correct false publication dates and align the Person entity (#246) (@jmrplens)
📚 Documentation
- 9a3cd59: docs(readme): add the Cline settings paths to the manual JSON section (#250) (@jmrplens)
- d29ffdb: docs(readme): refresh badges — drop Go Report Card, add Smithery + Cursor (#243) (@jmrplens)
- 8736222: docs: add winget install option (#242) (@jmrplens)
🚧 Maintenance
- eac6a5e: chore(deps): refresh Go, pnpm and Actions, fix the e2e notification race, bump to 2.5.3 (#257) (@jmrplens)
- f1000dd: chore(deps): update Go modules, pnpm packages, and Node/pnpm toolchain (#245) (@jmrplens)
- f887a12: chore(docs): refresh the generated README and testing statistics (#254) (@jmrplens)
- 3379e90: chore: update manifests for v2.5.2 (@jmrplens)
2.5.2 22 de juliol del 2026 — 64 bits PortableARM64 Portable
Notes de la versió
Changelog
🐛 Bug Fixes
- 077a557: fix(http): default to gitlab.com when no instance URL is provided (#241) (@jmrplens)
🚧 Maintenance
- 90f2ed5: chore: update manifests for v2.5.1 (@jmrplens)
2.5.0 7 de juliol del 2026 — 64 bits PortableARM64 Portable

El més popular a Assistents d’IA i LLM

Mostra-ho tot
  1. Claude CodeAssistents d’IA i LLM · Anthropic PBC
  2. Codex CLIAssistents d’IA i LLM · OpenAI, Inc.
  3. ChatGPTAssistents d’IA i LLM · lencx
  4. GPT4AllAssistents d’IA i LLM · Nomic
  5. JanAssistents d’IA i LLM · Jan
  6. WSL ManagerAssistents d’IA i LLM · Bostrot
  7. oh-my-piAssistents d’IA i LLM · Can Bölük
  8. T3 CodeAssistents d’IA i LLM · T3 Tools
  9. CC SwitchAssistents d’IA i LLM · farion1231
  10. LobeHubAssistents d’IA i LLM · LobeHub

Etiquetes

Comparteix