Skip to content

feat(mcp): publish server.json to the official MCP registry on release#545

Merged
SantiagoDePolonia merged 2 commits into
mainfrom
feat/mcp-registry-publish
Jul 17, 2026
Merged

feat(mcp): publish server.json to the official MCP registry on release#545
SantiagoDePolonia merged 2 commits into
mainfrom
feat/mcp-registry-publish

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Registers GoModel's MCP gateway in the official MCP Registry (the app-store feed consumed by MCP clients) as io.github.enterpilot/gomodel.

The registry is not PR-based — listing happens by publishing a server.json with the mcp-publisher CLI. This PR wires that up so every release publishes automatically:

  • server.json — registry metadata: OCI package docker.io/enterpilot/gomodel:<version>, streamable HTTP transport at http://localhost:8080/mcp, and the GOMODEL_MASTER_KEY / MCP_SERVERS env vars surfaced for configuration. Validated against the official 2025-12-11 schema.
  • Dockerfile — adds the io.modelcontextprotocol.server.name LABEL, which is how the registry verifies we own the Docker Hub image (it must match the server.json name).
  • release.yml — new publish-mcp job, needs: docker-promote (verification pulls the versioned image from Docker Hub, so the tag must exist first). Auth is GitHub OIDC — publishing from this repo's CI grants the io.github.enterpilot/* namespace, no secrets to manage. The job stamps the tag version into server.json before publishing.

User-visible impact

None at runtime. From the next release (v0.1.53+), GoModel appears in the MCP registry and downstream aggregators (client pickers, mcp.so, etc. consume the registry feed).

Notes

  • The registry is in preview; failures in publish-mcp don't block the rest of the release (parallel to goreleaser/github-release).
  • First publish must come from CI on a tag — OIDC namespace ownership is tied to this repository.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added automatic publishing of the release server artifact to the Model Context Protocol (MCP) registry.
    • Introduced server.json with MCP server metadata, transport settings, and runtime configuration for the GoModel gateway.
    • Added configurable support for a gateway master key and aggregation of upstream MCP servers.
  • Documentation
    • Documented the required match between the container image label and MCP server naming.
  • Chores
    • MCP registry publishing is non-blocking if the registry is temporarily unavailable.

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 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2fb9a8ee-5215-4f37-bcc2-3358c9914ac8

📥 Commits

Reviewing files that changed from the base of the PR and between 859833d and eff246d.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

📝 Walkthrough

Walkthrough

Adds MCP server metadata for GoModel and integrates release-time publication of its versioned Docker image to the MCP registry using OIDC authentication.

Changes

MCP registry release

Layer / File(s) Summary
MCP artifact contract
server.json, Dockerfile
Defines the GoModel MCP server identity, Docker package, transport, environment variables, and matching Docker label documentation.
Release workflow publishing
.github/workflows/release.yml
Adds a publish-mcp job that waits for Docker promotion, updates the release image version, authenticates with OIDC, and publishes the server artifact with tolerated failures.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant ServerJson
  participant MCPRegistry
  GitHubActions->>ServerJson: Update release version and Docker image
  GitHubActions->>MCPRegistry: Authenticate using GitHub OIDC
  GitHubActions->>MCPRegistry: Publish MCP server artifact
Loading

Possibly related PRs

Poem

A rabbit hops where release tags gleam,
Bundling GoModel in an MCP dream.
OIDC sings as Docker takes wing,
The registry welcomes the artifact string.
“Publish!” cheers the bunny with a spring.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: publishing server.json to the official MCP registry during release.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/mcp-registry-publish

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 194-196: Update the Checkout step in the release workflow to use a
full commit SHA corresponding to a stable actions/checkout release instead of
the v7 tag, and add persist-credentials: false to disable credential
persistence.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c1c4f00e-3610-4cb6-99b9-50f228c4b9df

📥 Commits

Reviewing files that changed from the base of the PR and between 3bed776 and 859833d.

📒 Files selected for processing (3)
  • .github/workflows/release.yml
  • Dockerfile
  • server.json

Comment on lines +194 to +196
- name: Checkout
uses: actions/checkout@v7

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Pin GitHub Actions to a commit hash and disable credential persistence.

As per static analysis hints (zizmor), the checkout action is not pinned to a hash (violating blanket policy). Additionally, credential persistence should be disabled when not needed (persist-credentials: false) to prevent GitHub token leakage through artifacts.

Note: v7 is likely an invalid version for actions/checkout. Please replace <commit-hash> in the snippet below with the actual SHA of a stable release (e.g., v4).

🔒 Proposed fix
       - name: Checkout
-        uses: actions/checkout@v7
+        uses: actions/checkout@<commit-hash>
+        with:
+          persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 194-195: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 195-195: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 194 - 196, Update the Checkout
step in the release workflow to use a full commit SHA corresponding to a stable
actions/checkout release instead of the v7 tag, and add persist-credentials:
false to disable credential persistence.

Source: Linters/SAST tools

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

Mostly safe to merge after the release workflow behavior is aligned with the intended best-effort publish.

The metadata and Docker label are consistent. The new release job has one contained workflow bug that can make MCP registry failures fail the release workflow.

.github/workflows/release.yml

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex ran a Python verifier against the release workflow to inspect the publish-mcp job and confirmed its needs, permissions, and lack of job-level continue-on-error.
  • T-Rex simulated the mcp-publisher publish step exiting with code 1, showing that the step, job, and overall workflow conclude as failures.
  • T-Rex generated and captured artifacts for review, including the verifier script and the verifier output log.
  • T-Rex noted that the requested verification completed but local artifact references were not uploaded.

View all artifacts

T-Rex Ran code and verified through T-Rex

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Tag as Git tag push
participant Docker as docker job
participant Promote as docker-promote job
participant MCP as publish-mcp job
participant Registry as MCP Registry

Tag->>Docker: Build and push image by digest
Docker->>Promote: Provide image digest
Promote->>Promote: Create versioned Docker Hub tags
Promote->>MCP: needs: docker-promote
MCP->>MCP: Checkout and install mcp-publisher
MCP->>MCP: Stamp server.json version and OCI identifier
MCP->>Registry: Login with GitHub OIDC
MCP->>Registry: Publish server.json
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Tag as Git tag push
participant Docker as docker job
participant Promote as docker-promote job
participant MCP as publish-mcp job
participant Registry as MCP Registry

Tag->>Docker: Build and push image by digest
Docker->>Promote: Provide image digest
Promote->>Promote: Create versioned Docker Hub tags
Promote->>MCP: needs: docker-promote
MCP->>MCP: Checkout and install mcp-publisher
MCP->>MCP: Stamp server.json version and OCI identifier
MCP->>Registry: Login with GitHub OIDC
MCP->>Registry: Publish server.json
Loading

Reviews (1): Last reviewed commit: "feat(mcp): publish server.json to the of..." | Re-trigger Greptile

Comment on lines +185 to +189
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-blocking publish still blocks
The release notes say MCP registry failures should not block the release, but this job has needs: docker-promote and no continue-on-error, so any registry outage, OIDC failure, schema validation error, or mcp-publisher failure marks the whole release workflow failed after Docker promotion. Add job-level continue-on-error: true if this publish step is intended to be best-effort.

Context Used: AGENTS.md (source)

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 <noreply@anthropic.com>
@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Addressed the review findings:

  • greptile P1 (non-blocking publish still blocks): valid — added job-level continue-on-error: true so a registry outage, OIDC hiccup, or publisher failure can't fail the release. The PR description's claim and the workflow now match.
  • coderabbit (checkout hardening): added persist-credentials: false — this job runs a third-party binary, so not persisting the token is a real win. Skipped SHA-pinning the action: actions/checkout@v7 is the tag convention used by every other job in this repo's workflows (and v7 is valid — it's what the existing jobs run); switching one job to SHA style belongs in a repo-wide zizmor pass, not this PR.
  • Bonus: mcp-publisher was fetched from releases/latest — now pinned to v1.8.0 with sha256 verification, removing the unpinned-binary-with-OIDC-token concern.

@SantiagoDePolonia
SantiagoDePolonia merged commit a698eab into main Jul 17, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants