Skip to content
Merged
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
48 changes: 48 additions & 0 deletions .github/workflows/publish-mcp-registry.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Publish to MCP Registry

on:
release:
types: [published]
workflow_dispatch:

permissions:
contents: read
id-token: write # Required for OIDC authentication with MCP Registry

jobs:
publish:
name: Publish server.json to MCP Registry
runs-on: ubuntu-24.04
steps:
- name: Checkout repo
uses: actions/checkout@v7
Comment on lines +17 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Checkout doesn't set persist-credentials: false or fetch-depth.

Two related gaps in the checkout step:

  1. This workflow never pushes back to the repo (publishing is done via mcp-publisher), so persisting the token via persist-credentials (default true) is unnecessary credential exposure — flagged by zizmor as artipacked.
  2. Default fetch-depth: 1 fetches only the triggering commit with no tags, which breaks the git describe --tags --abbrev=0 fallback used later (see lines 24-26) whenever the workflow runs via workflow_dispatch — the git command will fail on a shallow clone with no tags.
🔧 Proposed fix
       - name: Checkout repo
         uses: actions/checkout@v7
+        with:
+          fetch-depth: 0
+          persist-credentials: false

As per static analysis hints, zizmor flagged "credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false" for these lines.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout repo
uses: actions/checkout@v7
- name: Checkout repo
uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

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

(artipacked)

🤖 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/update-server-json.yml around lines 17 - 18, The checkout
step in the workflow is missing two required options: disable persisted GitHub
credentials and fetch full history/tags. Update the actions/checkout usage in
the Checkout repo step to set persist-credentials to false and fetch-depth to 0
so later git describe fallback logic can find tags during workflow_dispatch runs
and no unnecessary token is left available.

Source: Linters/SAST tools


- name: Extract version from release tag
id: version
run: |
TAG="${{ github.event.release.tag_name }}"
if [ -z "$TAG" ]; then
TAG="$(git describe --tags --abbrev=0)"
fi
VERSION="${TAG#v}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
Comment on lines +20 to +29

Copy link
Copy Markdown

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

Untrusted template expansion into shell (github.event.release.tag_name).

Interpolating ${{ github.event.release.tag_name }} directly into the run: script is a code-injection risk if the tag contains shell metacharacters. Pass it via env: instead.

🛡️ Proposed fix
       - name: Extract version from release tag
         id: version
+        env:
+          RELEASE_TAG: ${{ github.event.release.tag_name }}
         run: |
-          TAG="${{ github.event.release.tag_name }}"
+          TAG="$RELEASE_TAG"
           if [ -z "$TAG" ]; then
             TAG="$(git describe --tags --abbrev=0)"
           fi
           VERSION="${TAG#v}"
           echo "tag=$TAG" >> "$GITHUB_OUTPUT"
           echo "version=$VERSION" >> "$GITHUB_OUTPUT"

As per static analysis hints, zizmor flagged "code injection via template expansion (template-injection): may expand into attacker-controllable code" at line 23.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Extract version from release tag
id: version
run: |
TAG="${{ github.event.release.tag_name }}"
if [ -z "$TAG" ]; then
TAG="$(git describe --tags --abbrev=0)"
fi
VERSION="${TAG#v}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Extract version from release tag
id: version
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
TAG="$RELEASE_TAG"
if [ -z "$TAG" ]; then
TAG="$(git describe --tags --abbrev=0)"
fi
VERSION="${TAG#v}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
🧰 Tools
🪛 zizmor (1.26.1)

[error] 23-23: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 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/update-server-json.yml around lines 20 - 29, The
version-extraction step in the workflow is interpolating
github.event.release.tag_name directly inside the shell script, which is the
template-injection issue. Update the “Extract version from release tag” step to
read the tag from an env variable instead of embedding the GitHub expression in
the run block, and keep the existing TAG/VERSION logic in that step using the
env-provided value. Use the step’s id version and the existing tag/version
output handling to preserve behavior while removing the untrusted direct
template expansion.

Source: Linters/SAST tools


- name: Set version in server.json
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "Setting server.json version to $VERSION"
jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v' server.json > server.json.tmp
mv server.json.tmp server.json
echo "=== Updated server.json ==="
cat server.json
Comment on lines +31 to +38

Copy link
Copy Markdown

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

Same template-injection pattern for steps.version.outputs.version.

Prefer env: over direct interpolation here as well, consistent with the fix above.

🛡️ Proposed fix
       - name: Set version in server.json
+        env:
+          VERSION: ${{ steps.version.outputs.version }}
         run: |
-          VERSION="${{ steps.version.outputs.version }}"
           echo "Setting server.json version to $VERSION"
           jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v' server.json > server.json.tmp
           mv server.json.tmp server.json
           echo "=== Updated server.json ==="
           cat server.json

As per static analysis hints, zizmor flagged "code injection via template expansion (template-injection)" at line 33.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Set version in server.json
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "Setting server.json version to $VERSION"
jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v' server.json > server.json.tmp
mv server.json.tmp server.json
echo "=== Updated server.json ==="
cat server.json
- name: Set version in server.json
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
echo "Setting server.json version to $VERSION"
jq --arg v "$VERSION" '.version = $v | .packages[0].version = $v' server.json > server.json.tmp
mv server.json.tmp server.json
echo "=== Updated server.json ==="
cat server.json
🧰 Tools
🪛 zizmor (1.26.1)

[info] 33-33: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 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/update-server-json.yml around lines 31 - 38, The Set
version in server.json step is using direct template interpolation for
steps.version.outputs.version, which triggers the template-injection warning.
Update the workflow to pass that value through env: instead of embedding it
directly in the run script, then reference the environment variable inside the
jq update in the Set version in server.json step. Keep the change consistent
with the surrounding version-handling logic in this job.

Source: Linters/SAST tools


- name: Install mcp-publisher
run: |
curl -L "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: Authenticate to MCP Registry (OIDC)
run: ./mcp-publisher login github-oidc

- name: Publish server to MCP Registry
run: ./mcp-publisher publish