diff --git a/docs/guides/publishing/github-actions.md b/docs/guides/publishing/github-actions.md index a2e7c09..b49b445 100644 --- a/docs/guides/publishing/github-actions.md +++ b/docs/guides/publishing/github-actions.md @@ -13,49 +13,46 @@ By the end of this tutorial, you'll have: ## Prerequisites -- Already published your server manually (complete [Publishing Tutorial](publish-server.md) first) +- Understand general publishing requirements like package verification (see the [publishing guide](publish-server.md)) - GitHub repository with your MCP server code -- Basic understanding of CI/CD concepts -- 20-30 minutes ## GitHub Actions Setup ### Step 1: Create Workflow File -Create `.github/workflows/publish-mcp.yml` in your repository: +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: ```yaml name: Publish to MCP Registry on: push: - tags: ["v*"] # Triggers on version tags like v1.0.0 + tags: ["v*"] # Triggers on version tags like v1.0.0 jobs: publish: runs-on: ubuntu-latest permissions: - id-token: write # Required for OIDC authentication + id-token: write # Required for OIDC authentication contents: read steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - name: Setup Node.js # Adjust for your language - uses: actions/setup-node@v4 + - name: Setup Node.js # Adjust for your language + uses: actions/setup-node@v5 with: - node-version: "20" - registry-url: "https://registry.npmjs.org" + node-version: "lts/*" - name: Install dependencies run: npm ci - name: Run tests - run: npm test + run: npm run test --if-present - name: Build package - run: npm run build + run: npm run build --if-present - name: Publish to npm run: npm publish @@ -64,13 +61,7 @@ jobs: - name: Install MCP Publisher run: | - # Build publisher from source (requires Go) - git clone https://github.com/modelcontextprotocol/registry publisher-repo - cd publisher-repo - make publisher - cp bin/mcp-publisher ../mcp-publisher - cd .. - chmod +x mcp-publisher + curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_$(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 @@ -81,12 +72,9 @@ jobs: ### Step 2: Configure Secrets -For npm publishing, add your NPM token to repository secrets: +You don't need any secrets for publishing to the MCP Registry using GitHub OIDC. -1. Go to repository Settings → Secrets and variables → Actions -2. Add `NPM_TOKEN` with your npm access token - -**Note:** GitHub OIDC authentication requires no additional secrets for MCP Registry publishing. +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 @@ -97,30 +85,18 @@ git tag v1.0.0 git push origin v1.0.0 ``` -The workflow will: +The workflow runs tests, builds your package, publishes to npm, and publishes to the MCP Registry. -1. Run tests -2. Build your package -3. Publish to npm -4. Automatically authenticate with the MCP Registry -5. Publish updated server.json +## Authentication Methods -## Authentication Methods by CI Platform - -### GitHub Actions - OIDC (Recommended) +### GitHub Actions OIDC (Recommended) ```yaml - name: Login to MCP Registry run: mcp-publisher login github-oidc ``` -**Advantages:** - -- No secrets to manage -- Automatically scoped to your repository -- Most secure option - -### GitHub Actions - Personal Access Token +### GitHub Personal Access Token ```yaml - name: Login to MCP Registry @@ -131,7 +107,7 @@ The workflow will: Add `MCP_GITHUB_TOKEN` secret with a GitHub PAT that has repo access. -### DNS Authentication (Any CI) +### DNS Authentication For custom domain namespaces (`com.yourcompany/*`): @@ -144,155 +120,22 @@ For custom domain namespaces (`com.yourcompany/*`): Add your Ed25519 private key as `MCP_PRIVATE_KEY` secret. -## Language-Specific Examples +## Examples -### Python Project +See these real-world examples of automated publishing workflows: +- [NPM, Docker and MCPB](https://github.com/domdomegg/airtable-mcp-server) +- [NuGet](https://github.com/domdomegg/time-mcp-nuget) +- [PyPI](https://github.com/domdomegg/time-mcp-pypi) +## Tips + +You can keep your package version and server.json version in sync automatically with something like: ```yaml -name: Publish Python MCP Server - -on: - push: - tags: ["v*"] - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - contents: read - - steps: - - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: "3.11" - - - name: Install Poetry - run: pipx install poetry - - - name: Build package - run: poetry build - - - name: Publish to PyPI - run: poetry publish - env: - POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} - - - name: Install MCP Publisher - run: | - git clone https://github.com/modelcontextprotocol/registry publisher-repo - cd publisher-repo && make publisher && cd .. - cp publisher-repo/bin/mcp-publisher mcp-publisher - - - name: Publish to MCP Registry - run: | - ./mcp-publisher login github-oidc - ./mcp-publisher publish -``` - -### Docker Project - -```yaml -name: Publish Docker MCP Server - -on: - push: - tags: ["v*"] - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write - contents: read - - steps: - - uses: actions/checkout@v4 - - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Extract version - id: version - run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - push: true - tags: yourname/your-server:${{ steps.version.outputs.version }} - labels: | - io.modelcontextprotocol.server.name=io.github.yourname/your-server - - - name: Install MCP Publisher - run: | - git clone https://github.com/modelcontextprotocol/registry publisher-repo - cd publisher-repo && make publisher && cd .. - cp publisher-repo/bin/mcp-publisher mcp-publisher - - - name: Publish to MCP Registry - run: | - ./mcp-publisher login github-oidc - ./mcp-publisher publish -``` - -## Best Practices - -### 1. Version Alignment - -Keep your package version and server.json version in sync: - -```yaml -- name: Update server.json version - run: | +- run: | VERSION=${GITHUB_REF#refs/tags/v} - jq --arg version "$VERSION" '.version = $version' server.json > tmp.json - mv tmp.json server.json -``` - -### 2. Conditional Publishing - -Only publish to registry after package publishing succeeds: - -```yaml -- name: Publish to npm - run: npm publish - id: npm-publish - -- name: Publish to MCP Registry - if: steps.npm-publish.outcome == 'success' - run: ./mcp-publisher publish + jq --arg v "$VERSION" '.version = $v' server.json > tmp && mv tmp server.json ``` ## Troubleshooting - -**"Publisher binary not found"** - Ensure you download the correct binary for your CI platform (linux/mac/windows). - -**"Authentication failed"** - For GitHub OIDC, verify `id-token: write` permission is set. For other methods, check secret configuration. - -**"Package validation failed"** - Ensure your package was published successfully before MCP Registry publishing runs. - -**"Version already exists"** - Each server.json version must be unique. Consider using build numbers: `1.0.0-build.123`. - -## What You've Accomplished - -You now have automated MCP server publishing that: - -- Triggers on version tags -- Runs tests before publishing -- Publishes to package registry first -- Automatically publishes to MCP Registry -- Handles authentication securely -- Provides failure notifications - -Your MCP server publishing is now fully automated - just tag a release and everything happens automatically! +- **"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](publish-server.md) \ No newline at end of file diff --git a/docs/guides/publishing/publish-server.md b/docs/guides/publishing/publish-server.md index 2ad0b8f..615863a 100644 --- a/docs/guides/publishing/publish-server.md +++ b/docs/guides/publishing/publish-server.md @@ -2,6 +2,12 @@ Complete guide to publishing an MCP server to the registry. +> [!TIP] +> Using an agentic AI coding assistant? Just use this prompt: +> ``` +> Read https://raw.githubusercontent.com/modelcontextprotocol/registry/refs/heads/main/docs/guides/publishing/publish-server.md and https://raw.githubusercontent.com/modelcontextprotocol/registry/refs/heads/main/docs/guides/publishing/github-actions.md. Evaluate the best way to publish this server to the registry (prefer automated CI flows over manual flows where possible), and implement that. If possible, validate the server.json against the $schema before telling the user you are done, using a proper json schema library or tool available on the user's machine. If you get stuck, guide the user through the parts of the publishing process they need to do (e.g. logging into the publisher CLI if doing manual pubishing). +> ``` + ## What You'll Learn By the end of this tutorial, you'll have: @@ -339,6 +345,13 @@ You should see your server metadata returned in the JSON response. **"Namespace not authorized"** - Your authentication method doesn't match your chosen namespace format. +## Examples + +See these real-world examples of published servers: +- [NPM, Docker and MCPB example](https://github.com/domdomegg/airtable-mcp-server) +- [NuGet example](https://github.com/domdomegg/time-mcp-nuget) +- [PyPI example](https://github.com/domdomegg/time-mcp-pypi) + ## Next Steps - **Update your server**: Publish new versions with updated server.json files