From 4bd005ee575b617df60aac5387ba33c982de3306 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 08:06:09 +0000 Subject: [PATCH] ci: publish server.json to the MCP Registry on release The MCP Registry still lists io.github.neuledge/context at 0.2.3 because server.json was never bumped and nothing published it, so registry clients install a months-old version. Add an `mcp-registry` job after `release`, gated like "Tag releases" (changesets' `published` output never turns true with `pnpm -r publish`). It publishes only when the registry lacks packages/context's version, so no-op pushes skip and a failed publish is retried by the next push. It installs a pinned, checksum-verified mcp-publisher v1.8.1, stamps the version into server.json, waits for npm to serve that version (the registry checks its mcpName), then logs in with github-oidc and publishes. Being its own job, a registry failure stays visible without failing the npm release. Also bump the checked-in server.json to 1.2.9. The $schema URL (2025-12-11) is still the current one in mcp-publisher v1.8.1. Follows https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/github-actions.mdx Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01UX3uvgjRrv9uYuZxKjNF4o --- .github/workflows/release.yml | 77 +++++++++++++++++++++++++++++++++++ server.json | 4 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b62516..f897036 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,6 +13,8 @@ jobs: release: name: Release runs-on: ubuntu-latest + outputs: + hasChangesets: ${{ steps.changesets.outputs.hasChangesets }} permissions: contents: write @@ -73,3 +75,78 @@ jobs: - name: Tag releases if: steps.changesets.outputs.hasChangesets == 'false' run: pnpm tags + + # A separate job so an MCP Registry failure shows on its own without marking + # the npm release as failed. + mcp-registry: + name: Publish to MCP Registry + needs: release + # Same gate as "Tag releases": `published` never turns true here. + if: needs.release.outputs.hasChangesets == 'false' + runs-on: ubuntu-latest + + permissions: + contents: read + # `mcp-publisher login github-oidc` exchanges this job's OIDC token for + # publish rights on io.github.neuledge/*, so no registry secret is stored. + id-token: write + + env: + # Bump when the registry rejects logins with "invalid audience". + MCP_PUBLISHER_VERSION: v1.8.1 + MCP_PUBLISHER_SHA256: a06c9096dcb9727c13555b6be26c7effa707b01f06a4c561ba7a3635443cf2cc + + steps: + - name: Checkout code + uses: actions/checkout@v7 + + # Publish only a version the MCP Registry lacks, so pushes that release + # nothing new are no-ops and a failed publish is retried by the next one. + - name: Check MCP Registry version + id: check + run: | + version=$(jq -r .version packages/context/package.json) + name=$(jq -r .name server.json) + status=$(curl -s -o /dev/null -w '%{http_code}' \ + "https://registry.modelcontextprotocol.io/v0/servers/${name/\//%2F}/versions/$version") + case "$status" in + 200) echo "$name@$version is already in the MCP Registry" ;; + 404) echo "version=$version" >> "$GITHUB_OUTPUT" ;; + *) echo "Unexpected MCP Registry status $status"; exit 1 ;; + esac + + - name: Install mcp-publisher + if: steps.check.outputs.version + run: | + curl -fsSL -o mcp-publisher.tar.gz \ + "https://github.com/modelcontextprotocol/registry/releases/download/$MCP_PUBLISHER_VERSION/mcp-publisher_linux_amd64.tar.gz" + echo "$MCP_PUBLISHER_SHA256 mcp-publisher.tar.gz" | sha256sum -c - + tar xzf mcp-publisher.tar.gz mcp-publisher + + - name: Set version in server.json + if: steps.check.outputs.version + env: + VERSION: ${{ steps.check.outputs.version }} + run: | + jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v' server.json > server.tmp + mv server.tmp server.json + + # The registry checks the npm package's mcpName, so wait until npm serves + # the version that was just published. + - name: Wait for npm + if: steps.check.outputs.version + env: + VERSION: ${{ steps.check.outputs.version }} + run: | + for _ in $(seq 20); do + [ "$(npm view "@neuledge/context@$VERSION" version)" = "$VERSION" ] && exit 0 + sleep 15 + done + echo "@neuledge/context@$VERSION is not on npm" + exit 1 + + - name: Publish server + if: steps.check.outputs.version + run: | + ./mcp-publisher login github-oidc + ./mcp-publisher publish diff --git a/server.json b/server.json index 171a277..7e9bf09 100644 --- a/server.json +++ b/server.json @@ -6,12 +6,12 @@ "url": "https://github.com/neuledge/context", "source": "github" }, - "version": "0.2.3", + "version": "1.2.9", "packages": [ { "registryType": "npm", "identifier": "@neuledge/context", - "version": "0.2.3", + "version": "1.2.9", "transport": { "type": "stdio" }