-
-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Claude Desktop extension (.mcpb) build and release pipeline #224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,7 @@ | |
| audit-struct-completeness audit-action-coverage audit-metadata-completeness audit-1to1 audit-1to1-validate-docs audit-edition-tier \ | ||
| audit-discovery audit-discovery-check audit-e2e-gaps \ | ||
| audit-doc-coverage audit-doc-coverage-check \ | ||
| gen-action-catalog-manifest check-action-catalog-manifest gen-llms check-llms check-server-json check-openplugin gen-readme gen-footprint check-footprint gen-stats check-stats gen-site-stats check-site-stats gen-testing-docs update-all \ | ||
| gen-action-catalog-manifest check-action-catalog-manifest gen-llms check-llms check-server-json check-openplugin check-mcpb mcpb gen-readme gen-footprint check-footprint gen-stats check-stats gen-site-stats check-site-stats gen-testing-docs update-all \ | ||
| docs-local-go \ | ||
| docker-build docker-push docker-run \ | ||
| fly-check fly-deploy fly-deploy-release fly-status fly-logs fly-ssh fly-restart \ | ||
|
|
@@ -687,6 +687,28 @@ check-server-json: | |
| check-openplugin: | ||
| scripts/check-openplugin.sh | ||
|
|
||
| # Pin the MCPB packer CLI for supply-chain integrity (also pinned in scripts/build-mcpb.sh). | ||
| MCPB_CLI_VERSION := 2.1.2 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (bug_risk): The MCPB CLI version is now pinned in two places (Makefile and scripts/build-mcpb.sh), which can easily drift out of sync. Because MCPB_CLI_VERSION here and MCPB_VERSION in scripts/build-mcpb.sh are independent, they can diverge, causing local Suggested implementation: To fully implement the centralization and avoid drift, you should also:
|
||
|
|
||
| ## check-mcpb: validate the Claude Desktop extension manifest (mcpb/manifest.json). | ||
| check-mcpb: | ||
| npx --yes @anthropic-ai/mcpb@$(MCPB_CLI_VERSION) validate mcpb/manifest.json | ||
|
|
||
| ## mcpb: build the Claude Desktop extension bundle (dist/gitlab-mcp-server.mcpb). | ||
| ## Cross-compiles the darwin universal binary (lipo) and the windows/amd64 binary, | ||
| ## then assembles and packs the bundle with scripts/build-mcpb.sh. | ||
| mcpb: | ||
| @command -v lipo >/dev/null || { echo "ERROR: lipo is required (macOS Xcode CLT)"; exit 1; } | ||
| @set -e; \ | ||
| VER=$$(tr -d '[:space:]' < VERSION); \ | ||
| rm -rf dist/local_darwin_arm64 dist/local_darwin_amd64 dist/local_darwin_all dist/local_windows_amd64; \ | ||
| mkdir -p dist/local_darwin_arm64 dist/local_darwin_amd64 dist/local_darwin_all dist/local_windows_amd64; \ | ||
| CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -trimpath -ldflags "-s -w -X main.version=$$VER" -o dist/local_darwin_arm64/gitlab-mcp-server ./cmd/server; \ | ||
| CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -trimpath -ldflags "-s -w -X main.version=$$VER" -o dist/local_darwin_amd64/gitlab-mcp-server ./cmd/server; \ | ||
| lipo -create -output dist/local_darwin_all/gitlab-mcp-server dist/local_darwin_arm64/gitlab-mcp-server dist/local_darwin_amd64/gitlab-mcp-server; \ | ||
| CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "-s -w -X main.version=$$VER" -o dist/local_windows_amd64/gitlab-mcp-server.exe ./cmd/server; \ | ||
| bash scripts/build-mcpb.sh "$$VER" | ||
|
|
||
|
Comment on lines
+697
to
+711
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win Extract Static analysis (checkmake) flags this target's body length. Given the project already externalizes MCPB packaging logic into 🧰 Tools🪛 checkmake (0.3.2)[warning] 700-700: Target body for "mcpb" exceeds allowed length of 5 lines (10). (maxbodylength) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| ## gen-readme: regenerate all managed README.md sections (token footprint + stats). | ||
| gen-readme: gen-footprint gen-stats | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Privacy Policy | ||
|
|
||
| Last updated: 2026-07-07 | ||
|
|
||
| **gitlab-mcp-server** is a local Model Context Protocol (MCP) server. It runs | ||
| entirely on your machine and acts as a bridge between your MCP client (Claude | ||
| Desktop, Claude Code, Cursor, VS Code, …) and the GitLab instance you | ||
| configure. This policy describes what data the server handles and where it | ||
| goes. | ||
|
|
||
| ## What we collect | ||
|
|
||
| **Nothing.** The server has no telemetry, no analytics, no crash reporting, | ||
| and no backend of its own. The maintainer never receives, stores, or has | ||
| access to any of your data, credentials, or usage information. | ||
|
|
||
| ## Data flows | ||
|
|
||
| - **Your GitLab instance.** Every tool call results in requests to the GitLab | ||
| URL you configure (`GITLAB_URL`), authenticated with your Personal Access | ||
| Token (`GITLAB_TOKEN`). Data returned by GitLab (projects, issues, merge | ||
| requests, pipeline logs, …) is passed directly to your MCP client and is | ||
| never sent anywhere else. GitLab's handling of that data is governed by the | ||
| [GitLab Privacy Statement](https://about.gitlab.com/privacy/) (for | ||
| GitLab.com) or by your organization's own policies (for self-managed | ||
| instances). | ||
| - **GitHub (auto-update only).** When the auto-update feature is enabled | ||
| (`AUTO_UPDATE=true`, the default for standalone binaries), the server | ||
| periodically checks GitHub Releases on this repository for new versions and | ||
| downloads signed binaries from there. No personal data is sent — it is a | ||
| standard HTTPS request to `api.github.com`, subject to the | ||
| [GitHub Privacy Statement](https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement). | ||
| The Claude Desktop extension (`.mcpb`) ships with auto-update **disabled**; | ||
| updates arrive through new extension versions instead. | ||
|
Comment on lines
+27
to
+34
|
||
|
|
||
| There are no other network destinations. | ||
|
|
||
| ## Credentials | ||
|
|
||
| Your GitLab Personal Access Token is provided by you through environment | ||
| variables or your MCP client's configuration UI. Claude Desktop stores | ||
| extension secrets in the operating system keychain. The server keeps the | ||
| token in process memory only, uses it solely to authenticate requests to your | ||
| configured GitLab instance, and never logs it. | ||
|
|
||
| ## Local storage and logs | ||
|
|
||
| The server writes logs to standard error only (collected, if at all, by your | ||
| MCP client). It does not create databases, caches, or files with your GitLab | ||
| data. In HTTP mode, token identities are cached in memory for the configured | ||
| TTL and are never persisted to disk. | ||
|
|
||
| ## Data retention and sharing | ||
|
|
||
| The server retains nothing after it exits and shares data with no third | ||
| parties beyond the GitLab instance you explicitly configure. | ||
|
|
||
| ## Changes | ||
|
|
||
| Changes to this policy are published in this file and noted in release | ||
| changelogs. | ||
|
|
||
| ## Contact | ||
|
|
||
| Questions or concerns: [open an issue](https://github.com/jmrplens/gitlab-mcp-server/issues) | ||
| or email <jmrplens@gmail.com>. | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -64,9 +64,14 @@ Pick one. Each path ends with you typing a prompt to your assistant. | |||||||||||||||||||||||||||||||||||||||
| <td><a href="https://kiro.dev/launch/mcp/add?name=gitlab&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22-e%22%2C%22GITLAB_TOKEN%22%2C%22ghcr.io%2Fjmrplens%2Fgitlab-mcp-server%3Alatest%22%2C%22--http%3Dfalse%22%5D%2C%22env%22%3A%7B%22GITLAB_TOKEN%22%3A%22YOUR_GITLAB_TOKEN%22%7D%7D"><img alt="Add to Kiro" src="https://kiro.dev/images/add-to-kiro.svg" height="28" /></a></td> | ||||||||||||||||||||||||||||||||||||||||
| <td>edit <code>YOUR_GITLAB_TOKEN</code></td> | ||||||||||||||||||||||||||||||||||||||||
| </tr> | ||||||||||||||||||||||||||||||||||||||||
| <tr> | ||||||||||||||||||||||||||||||||||||||||
| <td><b>Claude Desktop</b></td> | ||||||||||||||||||||||||||||||||||||||||
| <td><a href="https://github.com/jmrplens/gitlab-mcp-server/releases/latest/download/gitlab-mcp-server.mcpb"><img alt="Download .mcpb extension" src="https://img.shields.io/badge/Download-.mcpb_extension-d97757?style=flat-square&logo=claude&logoColor=white" /></a></td> | ||||||||||||||||||||||||||||||||||||||||
| <td>settings UI (keychain)</td> | ||||||||||||||||||||||||||||||||||||||||
| </tr> | ||||||||||||||||||||||||||||||||||||||||
| </table> | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| Each button registers the **Docker**-based server (auto-pulls the image on first run; you need [Docker](https://www.docker.com/) installed). Need a token? [Create a Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with the **`api`** scope. Self-managed GitLab? Add a `GITLAB_URL` env var in your client's MCP config after install. | ||||||||||||||||||||||||||||||||||||||||
| Each button registers the **Docker**-based server (auto-pulls the image on first run; you need [Docker](https://www.docker.com/) installed). The **Claude Desktop** row instead downloads a native [.mcpb desktop extension](docs/guides/claude-desktop-extension.md) (macOS universal + Windows, no Docker) — open it with Claude Desktop and fill in the settings. Need a token? [Create a Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with the **`api`** scope. Self-managed GitLab? Add a `GITLAB_URL` env var in your client's MCP config after install. | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+67
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Clarify the self-managed GitLab instruction for Claude Desktop. The Claude Desktop extension uses the settings UI ( Proposed fix-Each button registers the **Docker**-based server (auto-pulls the image on first run; you need [Docker](https://www.docker.com/) installed). The **Claude Desktop** row instead downloads a native [.mcpb desktop extension](docs/guides/claude-desktop-extension.md) (macOS universal + Windows, no Docker) — open it with Claude Desktop and fill in the settings. Need a token? [Create a Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with the **`api`** scope. Self-managed GitLab? Add a `GITLAB_URL` env var in your client's MCP config after install.
+Each button registers the **Docker**-based server (auto-pulls the image on first run; you need [Docker](https://www.docker.com/) installed). The **Claude Desktop** row instead downloads a native [.mcpb desktop extension](docs/guides/claude-desktop-extension.md) (macOS universal + Windows, no Docker) — open it with Claude Desktop and fill in the settings.
+Need a token? [Create a Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with the **`api`** scope.
+For the Docker-based options, add `GITLAB_URL` in your client's MCP config after install. For Claude Desktop, set the URL in the extension settings UI.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| ### Claude Code (`claude mcp add`) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
@@ -343,6 +348,14 @@ The published container image is `ghcr.io/jmrplens/gitlab-mcp-server:latest`. Se | |||||||||||||||||||||||||||||||||||||||
| | GitLab Client | `gitlab.com/gitlab-org/api/client-go/v2` v2.46.0 | | ||||||||||||||||||||||||||||||||||||||||
| | Transport | stdio (default), HTTP (Streamable HTTP) | | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| ## Privacy Policy | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| The server runs entirely on your machine and has **no telemetry, analytics, or | ||||||||||||||||||||||||||||||||||||||||
| backend of its own** — data flows only between your MCP client and the GitLab | ||||||||||||||||||||||||||||||||||||||||
| instance you configure (plus an optional signed-binary update check against | ||||||||||||||||||||||||||||||||||||||||
| GitHub Releases). Your token is used solely to authenticate GitLab requests | ||||||||||||||||||||||||||||||||||||||||
| and is never logged. Full details: [PRIVACY.md](PRIVACY.md). | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| ## Contributing & Security | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| - **Contributing**: see [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines, branch naming, commit conventions, and the PR process. | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,63 @@ | ||||||
| # Claude Desktop Extension (.mcpb) | ||||||
|
|
||||||
| The server ships as a one-click [Desktop Extension](https://www.anthropic.com/engineering/desktop-extensions) | ||||||
| (MCPB bundle) for Claude Desktop on macOS and Windows. The bundle contains a | ||||||
| macOS universal binary (arm64 + amd64) and a Windows amd64 executable — no | ||||||
| Docker, Node.js, or Python required. | ||||||
|
|
||||||
| ## Install | ||||||
|
|
||||||
| 1. Download `gitlab-mcp-server.mcpb` from the | ||||||
| [latest release](https://github.com/jmrplens/gitlab-mcp-server/releases/latest). | ||||||
| 2. Open the file with Claude Desktop (double-click, or drag it onto the | ||||||
| window). Claude shows an install dialog with the extension details. | ||||||
| 3. Fill in the settings: | ||||||
|
|
||||||
| | Setting | Required | Default | Maps to | | ||||||
| | ---------------------------- | -------- | -------------------- | ------------------------ | | ||||||
| | GitLab URL | Yes | `https://gitlab.com` | `GITLAB_URL` | | ||||||
| | GitLab Personal Access Token | Yes | — | `GITLAB_TOKEN` | | ||||||
| | Tool surface | No | `dynamic` | `TOOL_SURFACE` | | ||||||
| | GitLab tier | No | auto-detect | `GITLAB_TIER` | | ||||||
| | Read-only mode | No | off | `GITLAB_READ_ONLY` | | ||||||
| | Safe mode | No | off | `GITLAB_SAFE_MODE` | | ||||||
| | Skip TLS verification | No | off | `GITLAB_SKIP_TLS_VERIFY` | | ||||||
|
|
||||||
| The token is stored in the operating system keychain by Claude Desktop. | ||||||
|
|
||||||
| Auto-update is disabled inside the extension (`AUTO_UPDATE=false`): updates | ||||||
| arrive as new extension versions rather than in-place binary swaps. | ||||||
|
|
||||||
| ## Build locally | ||||||
|
|
||||||
| ```bash | ||||||
| make mcpb # builds dist/gitlab-mcp-server.mcpb (requires macOS lipo + npx) | ||||||
| make check-mcpb # validates mcpb/manifest.json with the official CLI | ||||||
| ``` | ||||||
|
|
||||||
| `make mcpb` cross-compiles the darwin arm64/amd64 binaries, merges them with | ||||||
| `lipo`, cross-compiles the Windows amd64 binary, and packs everything with the | ||||||
| pinned `@anthropic-ai/mcpb` CLI via `scripts/build-mcpb.sh`. | ||||||
|
|
||||||
| In CI, the release workflow builds the bundle from the GoReleaser artifacts | ||||||
| (including the `universal_binaries` darwin build) and uploads it as a release | ||||||
| asset. The manifest version is stamped from the git tag by | ||||||
| `scripts/update-server-json-sha.sh`, the same flow that versions `server.json`. | ||||||
|
|
||||||
| ## Files | ||||||
|
|
||||||
| | Path | Purpose | | ||||||
| | ----------------------- | ------------------------------------------------------------ | | ||||||
| | `mcpb/manifest.json` | MCPB manifest (source of truth; version stamped per release) | | ||||||
| | `mcpb/icon.png` | 512×512 icon rendered from `site/src/assets/logo-dark.svg` | | ||||||
| | `scripts/build-mcpb.sh` | Bundle assembly + `mcpb pack` | | ||||||
| | `PRIVACY.md` | Privacy policy referenced by the manifest | | ||||||
|
|
||||||
| ## Privacy and directory submission | ||||||
|
|
||||||
| The manifest's `privacy_policies` points to [PRIVACY.md](../../PRIVACY.md) and | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick (typo): Minor subject–verb agreement tweak in the "privacy_policies" sentence. Because the field name is plural, “The manifest’s
Suggested change
|
||||||
| the [GitLab Privacy Statement](https://about.gitlab.com/privacy/). Directory | ||||||
| submissions for desktop extensions go through Anthropic's | ||||||
| [submission form](https://claude.com/docs/connectors/building/submission), | ||||||
| which requires the documentation URL, the privacy policy, the icon, and test | ||||||
| credentials. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Non-essential MCPB step can block the rest of the release job.
This step has no retry and no
continue-on-error, unlike the curl calls elsewhere in this job that use--retry 3 --retry-connrefused(Lines 135-136). A transientnpxfetch failure orgh release uploadhiccup here will abort the job before "Publish to MCP Registry" and the manifest-commit step run, even though the core GoReleaser release already succeeded — turning a packaging nicety into a release blocker.🤖 Prompt for AI Agents