From 859833de089f9b434262ad67f93b3eb06776b59d Mon Sep 17 00:00:00 2001 From: "Jakub A. W" Date: Fri, 17 Jul 2026 16:53:30 +0200 Subject: [PATCH 1/2] feat(mcp): publish server.json to the official MCP registry on release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lists GoModel in registry.modelcontextprotocol.io as io.github.enterpilot/gomodel — an OCI package (docker.io/enterpilot/gomodel) with streamable HTTP transport at /mcp. The Dockerfile LABEL is the registry ownership proof and must match the server.json name. A new release job authenticates via GitHub OIDC (no secrets) after docker-promote, stamps the tag version into server.json, and publishes. Co-Authored-By: Claude Fable 5 --- .github/workflows/release.yml | 30 ++++++++++++++++++++++++++++++ Dockerfile | 3 +++ server.json | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 server.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b04cc59d..f142b700 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -181,3 +181,33 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release edit "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --draft=false --verify-tag + + publish-mcp: + name: Publish to MCP Registry + runs-on: ubuntu-latest + # Registry verification pulls the versioned Docker Hub image, so the tag must exist first + needs: docker-promote + permissions: + id-token: write # GitHub OIDC grants the io.github.enterpilot/* namespace + contents: read + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Install mcp-publisher + run: | + curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher + + - name: Set release version in server.json + shell: bash + run: | + version="${GITHUB_REF_NAME#v}" + jq --arg v "$version" \ + '.version = $v | .packages[0].identifier = "docker.io/enterpilot/gomodel:" + $v' \ + server.json > server.json.tmp && mv server.json.tmp server.json + + - name: Authenticate to MCP Registry + run: ./mcp-publisher login github-oidc + + - name: Publish server to MCP Registry + run: ./mcp-publisher publish diff --git a/Dockerfile b/Dockerfile index b621ae10..c0d6a3a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,6 +31,9 @@ RUN mkdir -p /app/.cache /app/data && touch /app/.cache/.keep /app/data/.keep # Runtime stage FROM gcr.io/distroless/static-debian12:nonroot +# Ownership proof for the MCP Registry; must match the name in server.json +LABEL io.modelcontextprotocol.server.name="io.github.enterpilot/gomodel" + # Copy binary and runtime config COPY --from=builder /gomodel /gomodel COPY --from=builder /app/config/*.yaml /app/config/ diff --git a/server.json b/server.json new file mode 100644 index 00000000..6e27532c --- /dev/null +++ b/server.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.enterpilot/gomodel", + "title": "GoModel", + "description": "Self-hosted gateway aggregating upstream MCP servers behind one authenticated HTTP endpoint.", + "repository": { + "url": "https://github.com/ENTERPILOT/GoModel", + "source": "github" + }, + "version": "0.1.52", + "packages": [ + { + "registryType": "oci", + "identifier": "docker.io/enterpilot/gomodel:0.1.52", + "runtimeHint": "docker", + "transport": { + "type": "streamable-http", + "url": "http://localhost:8080/mcp" + }, + "environmentVariables": [ + { + "name": "GOMODEL_MASTER_KEY", + "description": "Gateway API key clients authenticate with; unset runs the gateway in unsafe (no-auth) mode.", + "isRequired": false, + "isSecret": true + }, + { + "name": "MCP_SERVERS", + "description": "JSON object of upstream MCP servers to aggregate, e.g. {\"github\":{\"url\":\"https://api.githubcopilot.com/mcp/\",\"headers\":{\"Authorization\":\"Bearer ${GITHUB_PAT}\"}}}. Servers can also be declared in config.yaml or the admin dashboard.", + "isRequired": false + } + ] + } + ] +} From eff246dca8f39464d7f1e0ab0a64519dc54c7fbf Mon Sep 17 00:00:00 2001 From: "Jakub A. W" Date: Fri, 17 Jul 2026 18:51:34 +0200 Subject: [PATCH 2/2] fix(ci): harden the MCP registry publish job continue-on-error so a registry outage cannot fail the release, persist-credentials off (the job runs a third-party binary), and mcp-publisher pinned to v1.8.0 with checksum verification. Co-Authored-By: Claude Fable 5 --- .github/workflows/release.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f142b700..01232476 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -187,16 +187,25 @@ jobs: runs-on: ubuntu-latest # Registry verification pulls the versioned Docker Hub image, so the tag must exist first needs: docker-promote + # Best-effort: a registry outage must not fail the release + continue-on-error: true permissions: id-token: write # GitHub OIDC grants the io.github.enterpilot/* namespace contents: read steps: - name: Checkout uses: actions/checkout@v7 + with: + persist-credentials: false - name: Install mcp-publisher + env: + PUBLISHER_VERSION: v1.8.0 + PUBLISHER_SHA256: 1370446bbe74d562608e8005a6ccce02d146a661fbd78674e11cc70b9618d6cf run: | - curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher + curl -fsSL -o 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 release version in server.json shell: bash