Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,42 @@ 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
Comment on lines +185 to +189

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)

# 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

Comment on lines +196 to +200

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

- name: Install mcp-publisher
env:
PUBLISHER_VERSION: v1.8.0
PUBLISHER_SHA256: 1370446bbe74d562608e8005a6ccce02d146a661fbd78674e11cc70b9618d6cf
run: |
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
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
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
35 changes: 35 additions & 0 deletions server.json
Original file line number Diff line number Diff line change
@@ -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
}
]
}
]
}