diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index dfb35bd..ab7d23b 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -31,7 +31,8 @@ jobs:
run: |
mkdir -p _site
cp -r schema _site/schema
- cp server.json _site/server.json
+ # the image tag follows "version", which release-please bumps
+ jq '.packages[0].identifier = "ghcr.io/virtbase/proxbase:" + .version' server.json > _site/server.json
echo proxbase.virtbase.com > _site/CNAME
printf '
Proxbase\n' > _site/index.html
- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f276330..fbe667b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -88,3 +88,47 @@ jobs:
major="${RELEASE_TAG%%.*}"
git tag -f "$major" "$RELEASE_TAG^{commit}"
git push -f origin "refs/tags/$major"
+
+ # Publishes server.json for the released image to the MCP registry
+ # (registry.modelcontextprotocol.io), authenticated by the workflow's OIDC token.
+ mcp-registry:
+ needs: [release-please, goreleaser]
+ if: ${{ !cancelled() && needs.goreleaser.result == 'success' }}
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ id-token: write
+ env:
+ RELEASE_TAG: ${{ inputs.tag || needs.release-please.outputs.tag }}
+ PUBLISHER_VERSION: v1.8.1
+ PUBLISHER_SHA256: a06c9096dcb9727c13555b6be26c7effa707b01f06a4c561ba7a3635443cf2cc # mcp-publisher_linux_amd64.tar.gz
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ ref: ${{ env.RELEASE_TAG }}
+ persist-credentials: false
+ - name: Install mcp-publisher
+ run: |
+ curl -fsSLo mcp-publisher.tar.gz "https://github.com/modelcontextprotocol/registry/releases/download/$PUBLISHER_VERSION/mcp-publisher_linux_amd64.tar.gz"
+ echo "$PUBLISHER_SHA256 mcp-publisher.tar.gz" | sha256sum -c
+ tar -xzf mcp-publisher.tar.gz mcp-publisher
+ - name: Set version and image tag
+ run: |
+ version="${RELEASE_TAG#v}"
+ jq --arg v "$version" '.version = $v | .packages[0].identifier = "ghcr.io/virtbase/proxbase:" + $v' server.json > server.tmp
+ mv server.tmp server.json
+ cat server.json
+ - name: Wait for the image
+ run: |
+ # The registry checks the image's io.modelcontextprotocol.server.name label.
+ image="ghcr.io/virtbase/proxbase:${RELEASE_TAG#v}"
+ for _ in $(seq 30); do
+ docker buildx imagetools inspect "$image" --format '{{json .Image.Config.Labels}}' 2>/dev/null |
+ jq -e '."io.modelcontextprotocol.server.name" == "io.github.virtbase/proxbase"' >/dev/null && exit 0
+ sleep 10
+ done
+ echo "::error::$image is not pullable or lacks the MCP label"
+ exit 1
+ - run: ./mcp-publisher validate
+ - run: ./mcp-publisher login github-oidc
+ - run: ./mcp-publisher publish
diff --git a/docs/mcp.md b/docs/mcp.md
index 6997b5d..9e333ab 100644
--- a/docs/mcp.md
+++ b/docs/mcp.md
@@ -121,10 +121,11 @@ conversation accordingly. Progress and errors are logged to stderr.
[MCP registry](https://registry.modelcontextprotocol.io) as the container image
(`io.github.virtbase/proxbase`); the image carries the matching
`io.modelcontextprotocol.server.name` label and Pages publishes the file at
-`https://proxbase.virtbase.com/server.json`. Publishing is manual after a release:
+`https://proxbase.virtbase.com/server.json`. The `Release` workflow publishes every
+release with `mcp-publisher` and the workflow's OIDC token
+([releasing.md](releasing.md)). By hand, after setting `version` and the image tag in `server.json` to the release:
```bash
-# set "version" and the image tag in server.json to the release, then:
mcp-publisher login github # as a member of the virtbase organization
mcp-publisher publish
```
diff --git a/docs/releasing.md b/docs/releasing.md
index 8de89cb..4143530 100644
--- a/docs/releasing.md
+++ b/docs/releasing.md
@@ -11,10 +11,20 @@ Releases are automatic; nobody tags by hand.
release. The same `Release` workflow then runs GoReleaser, which uploads archives,
deb/rpm/apk packages, SBOMs, `checksums.txt` with its cosign bundle, pushes the
amd64 image to GHCR (signed), updates the Homebrew tap and attests build
- provenance. Afterwards the major tag (`v0`) is moved to the release for
- `uses: virtbase/proxbase@v0`.
-4. Optional, manual: update `version` and the image tag in `server.json` and publish
- it to the MCP registry (see [mcp.md](mcp.md#mcp-registry)).
+ provenance. Afterwards the workflow
+ - moves the major tag (`v0`) to the release for `uses: virtbase/proxbase@v0`, and
+ - publishes `server.json` with the release's version and image tag to the
+ [MCP registry](mcp.md#mcp-registry) (OIDC login, after the labelled image is
+ pullable). release-please keeps `version` in `server.json` current.
+4. Manual, optional: list the release in the GitHub Marketplace. GitHub offers no
+ API for this: open the release, **Edit**, tick *Publish this Action to the GitHub
+ Marketplace*, **Update release** (two-factor authentication required). The first
+ time, an organization owner accepts the Marketplace Developer Agreement there.
+ Users of `@v0` get new releases through the tag either way; the tick only updates
+ the version shown on the Marketplace page.
+
+To re-run the publishing for an existing release, run the `Release` workflow manually
+with its tag.
Local dry run (no signing, no publishing):
diff --git a/release-please-config.json b/release-please-config.json
index fe70e96..6d88182 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -9,6 +9,9 @@
"bump-patch-for-minor-pre-major": false,
"include-component-in-tag": false,
"include-v-in-tag": true,
+ "extra-files": [
+ { "type": "json", "path": "server.json", "jsonpath": "$.version" }
+ ],
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },