docs: simplify GitHub Actions publishing guide (#446)
Simplifies the GitHub Actions publishing guide to be more concise and easier to follow: ## Changes - Streamlined MCP publisher installation with single-line curl command (no more chmod/directory operations) - Condensed authentication methods into compact sections - Reduced language-specific examples to essential steps only - Updated GitHub Actions to use latest versions (v5) - Made test/build steps optional with `--if-present` flag - Added helpful AI assistant prompt tip to publish-server.md ## Result The guide is now much more succinct while maintaining all essential information, following the same simplified approach as the main publishing guide.
This commit is contained in:
parent
9322e7855c
commit
ba86c6beb5
2 changed files with 42 additions and 186 deletions
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue