registry/docs/guides/publishing/github-actions.md
adam jones 7ff61e2d6e
Use 'latest' tag for mcp-publisher downloads (#610)
## Summary

This PR removes version numbers from release asset names and updates
documentation to use GitHub's `latest` tag for mcp-publisher downloads.

## Changes

1. **Updated `.goreleaser.yaml`**: Removed `{{ .Version }}` from asset
name templates
   - Changed from: `mcp-publisher_{{ .Version }}_{{ .Os }}_{{ .Arch }}`
   - Changed to: `mcp-publisher_{{ .Os }}_{{ .Arch }}`

2. **Updated documentation**: Changed all download URLs to use `latest`
tag instead of version-pinned URLs
   - `docs/guides/publishing/publish-server.md`
   - `docs/guides/publishing/github-actions.md`

## Benefits

- Documentation stays automatically up-to-date without manual changes or
workflows
- Users always get the latest version by default
- Version pinning still possible using specific tags (e.g.,
`https://github.com/modelcontextprotocol/registry/releases/download/v1.2.3/mcp-publisher_darwin_amd64.tar.gz`)
- Simpler maintenance and better user experience

## Notes

The new asset naming will take effect with the next release. After that,
users can immediately start using the `latest` tag.

Fixes #607
2025-10-04 00:00:27 +03:00

4.1 KiB

Automate Publishing with GitHub Actions

Set up automated MCP server publishing using GitHub Actions.

What You'll Learn

By the end of this tutorial, you'll have:

  • A GitHub Actions workflow that automatically publishes your server
  • Understanding of GitHub OIDC authentication
  • Knowledge of best practices for automated publishing
  • Working examples for Node.js, Python, and Docker projects

Prerequisites

  • Understand general publishing requirements like package verification (see the publishing guide)
  • GitHub repository with your MCP server code

GitHub Actions Setup

Step 1: Create Workflow File

Create .github/workflows/publish-mcp.yml. Here's an example for NPM-based packages, but the MCP registry publishing steps are the same for all package types:

name: Publish to MCP Registry

on:
  push:
    tags: ["v*"]  # Triggers on version tags like v1.0.0

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # Required for OIDC authentication
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Setup Node.js  # Adjust for your language
        uses: actions/setup-node@v5
        with:
          node-version: "lts/*"

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm run test --if-present

      - name: Build package
        run: npm run build --if-present

      - name: Publish to npm
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/latest/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher

      - name: Login to MCP Registry
        run: ./mcp-publisher login github-oidc

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

Step 2: Configure Secrets

You don't need any secrets for publishing to the MCP Registry using GitHub OIDC.

However you might need to add secrets for your package registry. For example the workflow above needs a NPM_TOKEN (which you can add in Settings → Secrets and variables → Actions).

Step 3: Tag and Release

Create a version tag to trigger the workflow:

git tag v1.0.0
git push origin v1.0.0

The workflow runs tests, builds your package, publishes to npm, and publishes to the MCP Registry.

Authentication Methods

- name: Login to MCP Registry
  run: mcp-publisher login github-oidc

GitHub Personal Access Token

- name: Login to MCP Registry
  run: mcp-publisher login github --token ${{ secrets.GITHUB_TOKEN }}
  env:
    GITHUB_TOKEN: ${{ secrets.MCP_GITHUB_TOKEN }}

Add MCP_GITHUB_TOKEN secret with a GitHub PAT that has repo access.

DNS Authentication

For custom domain namespaces (com.yourcompany/*):

- name: Login to MCP Registry
  run: |
    echo "${{ secrets.MCP_PRIVATE_KEY }}" > key.pem
    mcp-publisher login dns --domain yourcompany.com --private-key-file key.pem

Add your Ed25519 private key as MCP_PRIVATE_KEY secret.

Examples

See these real-world examples of automated publishing workflows:

Tips

You can keep your package version and server.json version in sync automatically with something like:

- run: |
    VERSION=${GITHUB_REF#refs/tags/v}
    jq --arg v "$VERSION" '.version = $v' server.json > tmp && mv tmp server.json

Troubleshooting

  • "Authentication failed": Ensure id-token: write permission is set for OIDC, or check secrets
  • "Package validation failed": Verify your package published to your registry (NPM, PyPi etc.) successfully first, and that you have done the necessary validation steps in the Publishing Tutorial