adityamparikh opened a new issue, #261:
URL: https://github.com/apache/solr-mcp/issues/261

   ## Summary
   
   `release-publish.yml` has a `publish-mcp-registry` job, but on `main` it 
cannot publish 1.0.0 to the [official MCP 
Registry](https://modelcontextprotocol.io/registry/about). This issue is the 
contributor-side spec: what `server.json` and the workflow must look like, and 
where the step sits in the [ATR](https://releases.apache.org/) release in 
[`dev-docs/release-process.md`](https://github.com/apache/solr-mcp/blob/main/dev-docs/release-process.md).
 The PMC and Infra prerequisites (Docker Hub repo, secrets, GHCR visibility) 
are tracked in #251 and are not repeated here.
   
   ## How the official registry works
   
   - **It stores metadata, not artifacts.** A `server.json` lists `packages[]` 
that point at artifacts hosted elsewhere. The accepted package types are `npm`, 
`pypi`, `nuget`, `cargo`, `oci` and `mcpb` 
([`pkg/model/constants.go`](https://github.com/modelcontextprotocol/registry/blob/main/pkg/model/constants.go)).
 There is no Maven type, so the JAR cannot be listed; the JVM container images 
are what get listed.
   - **OCI images must be on an allowed host and carry an ownership label.** 
Allowed hosts are `docker.io`, `ghcr.io`, `quay.io`, `*.pkg.dev` and 
`*.azurecr.io` ([package 
types](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/package-types.mdx)).
 At publish time the registry pulls each image's manifest anonymously and 
requires the label `io.modelcontextprotocol.server.name` to equal the server 
`name`. The Jib JVM image already sets this label (`build.gradle.kts`). The 
native images do not, so they stay out of `server.json`.
   - **OCI packages take the tag in `identifier`, not in `version`.** The 
registry rejects a package `version` with *"OCI packages must not have 
'version' field - include version in 'identifier' instead"* 
([`internal/validators/registries/oci.go`](https://github.com/modelcontextprotocol/registry/blob/main/internal/validators/registries/oci.go)).
   - **The namespace comes from GitHub OIDC.** `mcp-publisher login 
github-oidc` in a workflow grants `io.github.<repository_owner>/*`, so a run in 
`apache/solr-mcp` can publish `io.github.apache/solr-mcp` with no stored 
secret. An interactive `mcp-publisher login github` would need an Owner of the 
`apache` GitHub org, so publishing is CI-only in practice.
   - **A published version can't be edited.** Only its `status` can change 
afterwards (`mcp-publisher status`). A wrong 1.0.0 entry can be deprecated, not 
fixed.
   - **`mcp-publisher validate` does not check what `publish` checks.** 
`validate` checks the schema only. The package checks (allowed host, ownership 
label, the OCI `version` rule) run only in the publish path 
(`validateRegistryOwnership`). The current `server.json` on `main` reports *"✅ 
server.json is valid"* under `validate` while carrying three defects that 
`publish` rejects.
   - **Downstream catalogs read from it.** JFrog AI Catalog's public listings, 
the GitHub MCP Registry (planned) and aggregators such as PulseMCP read from 
the official registry. The Docker MCP Catalog does not; it needs its own PR to 
`docker/mcp-registry` (#251).
   
   ## What is wrong on `main`
   
   `server.json`:
   
   1. `registryType: "docker"`: the type is `oci`.
   2. Each package has a `version`, which is not allowed for OCI.
   3. `identifier` is `ghcr.io/apache/solr-mcp-server`, an image the workflow 
never pushes. It pushes `apache/solr-mcp` (Docker Hub) and 
`ghcr.io/apache/solr-mcp`.
   4. `$schema` is `2025-10-17`; the current schema is `2025-12-11`.
   5. The `streamable-http` package lists only `PROFILES`. HTTP mode is secured 
by default and also needs `OAUTH2_ISSUER_URI`, and a client launching the 
container would have to publish a port. HTTP is for a remote deployment, not 
for a client-launched package.
   
   `release-publish.yml`:
   
   6. Every job checks out `v<version>-<rc>` (e.g. `v1.0.0-rc1`). The release 
process creates `releases/solr-mcp/1.0.0-rc1`, so `validate-release` fails and 
nothing publishes.
   7. The `jq` step adds `.packages[].version`, which reintroduces defect 2 on 
every release.
   8. Docker Hub credentials are read from `DOCKERHUB_APACHE_USERNAME` / 
`DOCKERHUB_APACHE_TOKEN`. Infra provisions `DOCKERHUB_USER` / `DOCKERHUB_TOKEN` 
(#251).
   9. Nothing checks that the images are anonymously pullable before 
publishing. On the first release the new GHCR package is private, and the 
failure surfaces as a registry error instead of a clear message.
   10. The verification step queries `/v0/servers?search=` and never fails, so 
a missing entry still reports success.
   
   ## Design
   
   ### `server.json`
   
   Two stdio packages, one per JVM image host. The workflow writes the release 
tag into each `identifier`:
   
   ```json
   {
     "$schema": 
"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json";,
     "name": "io.github.apache/solr-mcp",
     "title": "Apache Solr",
     "description": "MCP server for Apache Solr providing search, indexing, 
schema and collection management",
     "repository": { "url": "https://github.com/apache/solr-mcp";, "source": 
"github" },
     "version": "1.0.0-SNAPSHOT",
     "packages": [
       { "registryType": "oci", "identifier": 
"docker.io/apache/solr-mcp:1.0.0-SNAPSHOT", "transport": { "type": "stdio" }, 
"environmentVariables": [ "SOLR_URL" ] },
       { "registryType": "oci", "identifier": 
"ghcr.io/apache/solr-mcp:1.0.0-SNAPSHOT",   "transport": { "type": "stdio" }, 
"environmentVariables": [ "SOLR_URL" ] }
     ]
   }
   ```
   
   (`environmentVariables` abbreviated; each is the existing `SOLR_URL` entry.)
   
   ### `publish-mcp-registry` job
   
   1. Check out the voted candidate tag `releases/solr-mcp/<version>-<rc>`.
   2. Rewrite `.version` and the tag in every `packages[].identifier` to 
`<version>`; fail if any package has a `version` field or `SNAPSHOT` survives.
   3. Check that every `identifier` resolves anonymously (`docker manifest 
inspect`, no login), with an error that names the GHCR visibility step from 
#251.
   4. Install `mcp-publisher` at a pinned version, verified against the 
release's checksum file (v1.8.1).
   5. `mcp-publisher validate`, then `login github-oidc`, then `publish`.
   6. Verify with `GET 
/v0.1/servers/io.github.apache%2Fsolr-mcp/versions/<version>`, retrying, and 
fail if it never appears.
   
   The other jobs check out the same `releases/solr-mcp/<version>-<rc>` tag, 
and Docker Hub uses `DOCKERHUB_USER` / `DOCKERHUB_TOKEN`.
   
   ## Where this sits in the ATR release
   
   ATR stages, votes on and publishes the source archive and JARs. It does not 
push container images or registry entries: its finish phase leaves third-party 
distribution to the release manager and only records it ([finish 
phase](https://releases.apache.org/docs/finish-phase)). So the order is:
   
   ```
   ATR vote passes ──► release is in ATR's finish phase
         │
         ├─► ATR Publish: artifacts to downloads.apache.org/solr/mcp/<v>/
         │
         ├─► RM runs release-publish.yml on releases/solr-mcp/<v>-<rc>
         │       images → Docker Hub + GHCR → MCP Registry entry
         │
         ├─► RM records the Docker Hub distribution on ATR's finish page
         │
         └─► ATR Announce (gated on recorded distributions, if a tagging spec 
is set)
   ```
   
   What the ATR process needs for this to work:
   
   - **Run `release-publish.yml` after the vote passes and before announcing.** 
Announcing is ATR's last step, and the optional ATR gate below needs the Docker 
Hub distribution recorded before it.
   - **Record the Docker Hub distribution on ATR by hand.** Use the finish page 
→ *Verify a third-party distribution*, platform Docker Hub, namespace `apache`, 
package `solr-mcp`, version `<v>`, or `POST /api/distribution/record` with a 
PAT-exchanged JWT. Recording from the workflow with 
`apache/tooling-actions/record-atr-distribution` is **not** available to Solr 
today: ATR accepts that OIDC call only from a committee with an Automated 
Release Signing key ("CI builds: Enabled"), which requires Security-team 
approval of reproducible builds (`_trusted_project` in ATR's 
`db/interaction.py`; [Trusted 
Publishing](https://releases.apache.org/docs/trusted-publishing)).
   - **Optionally gate the announcement.** Setting a `dockerhub` tag in the 
project's tagging spec makes ATR refuse to announce until a Docker Hub 
distribution is recorded. ATR is redesigning tags 
([tooling-trusted-releases#1702](https://github.com/apache/tooling-trusted-releases/issues/1702)),
 so this is optional for 1.0.0.
   - **Limits in ATR itself today.** ATR can record `MAVEN`, `PYPI`, `NPM`, 
`NPM_SCOPED`, `DOCKER_HUB` and `ARTIFACT_HUB` only. It has no GHCR/OCI and no 
MCP Registry platform, and its Docker Hub check confirms the tag exists without 
comparing digests. The GHCR image and the registry entry therefore can't be 
recorded on ATR yet; that is an upstream ATR change, under its third-party 
distribution track 
([tooling-trusted-releases#1336](https://github.com/apache/tooling-trusted-releases/issues/1336)).
   
   ## Acceptance criteria
   
   - [ ] `server.json` publishes cleanly with `mcp-publisher` v1.8.1 once the 
images exist (the publish-time checks above all pass).
   - [ ] `release-publish.yml` checks out `releases/solr-mcp/<version>-<rc>` in 
every job.
   - [ ] The registry job rewrites identifier tags, fails on a non-public image 
with a clear message, and fails if the published version can't be read back.
   - [ ] Docker Hub credentials use `DOCKERHUB_USER` / `DOCKERHUB_TOKEN`.
   - [ ] `dev-docs` describes the registry publish and its place in the ATR 
release, and the stale `server.json` examples in `DEPLOYMENT.md` / 
`DOCKER_PUBLISHING.md` point to it.
   
   Related: #251 (PMC/Infra prerequisites), 
[`dev-docs/release-process.md`](https://github.com/apache/solr-mcp/blob/main/dev-docs/release-process.md).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to