This document explains how to publish ggmcp to PyPI and the MCP Registry using GitHub Actions.
Publishing is automated via GitHub Actions and triggered by creating a version tag. The workflow:
- Builds the Python package
- Publishes to PyPI using trusted publishing (no tokens needed!)
- Registers with MCP Registry so users can discover the server
- Creates a GitHub Release with release notes
PyPI trusted publishing allows GitHub Actions to publish without API tokens.
-
Go to PyPI:
- Visit https://pypi.org/manage/account/publishing/
- Or create the project first at https://pypi.org/manage/projects/
-
Add Publisher:
- Project name:
ggmcp - Owner:
GitGuardian - Repository:
ggmcp - Workflow name:
publish.yml - Environment name:
pypi
- Project name:
-
Click "Add"
That's it! No tokens to manage.
For extra protection, create a deployment environment:
- Go to: https://github.com/GitGuardian/ggmcp/settings/environments
- Click "New environment"
- Name it:
pypi - Add protection rules:
- ✅ Required reviewers (optional)
- ✅ Wait timer (optional)
- Save
The workflow needs these permissions (already configured in the workflow):
id-token: write- For PyPI trusted publishingcontents: write- For creating GitHub releases
# Bump version and create tag
cz bump
# Push with tags
git push --follow-tagsThis will:
- Update version in
pyproject.toml - Update
CHANGELOG.md - Create a git tag (
v0.5.1, etc.) - Trigger the publish workflow
# Update version in pyproject.toml manually
# Then create and push tag
git tag v0.5.1
git push origin v0.5.1For testing or special cases:
- Go to: https://github.com/GitGuardian/ggmcp/actions/workflows/publish.yml
- Click "Run workflow"
- Choose options:
- ✅ Publish to PyPI
- ✅ Publish to MCP Registry
- Click "Run workflow"
✓ Checkout code
✓ Set up Python 3.13
✓ Install uv
✓ Build package with uv build
→ Creates dist/gg_mcp-0.5.0.tar.gz
→ Creates dist/gg_mcp-0.5.0-py3-none-any.whl
✓ Authenticate via OIDC (no token needed!)
✓ Upload package to PyPI
→ Available at https://pypi.org/project/ggmcp/
✓ Users can install: uvx ggmcp
✓ Validate server.json
✓ Install mcp-publisher CLI
✓ Authenticate with GitHub
✓ Publish to registry
→ Registered in modelcontextprotocol/registry
✓ Discoverable in MCP clients
✓ Create release with tag
✓ Generate release notes from commits
✓ Mark as latest release
→ Visible at https://github.com/GitGuardian/ggmcp/releases
https://github.com/GitGuardian/ggmcp/actions/workflows/publish.yml
https://pypi.org/project/ggmcp/
https://github.com/modelcontextprotocol/registry
https://github.com/GitGuardian/ggmcp/releases
Error: "Invalid or non-existent authentication information"
- Check PyPI trusted publishing configuration
- Verify owner is
GitGuardian, repository isggmcp - Ensure workflow name is
publish.yml - Ensure environment name is
pypi
Error: "File already exists"
- Version already published to PyPI
- Bump version in
pyproject.toml - Create new tag
Error: "Unauthorized"
- Check GitHub token permissions
- Verify repository has access to modelcontextprotocol org
- Try manual authentication first
Error: "Package not found on PyPI"
- Ensure PyPI publication succeeded first
- Wait a few minutes for PyPI to propagate
- Verify package name matches in
server.json
Tag pushed but workflow not running
- Ensure tag matches pattern
v*(e.g.,v0.5.0) - Check
.github/workflows/publish.ymlexists in main branch - Verify GitHub Actions are enabled for the repository
We follow Semantic Versioning:
- MAJOR (v1.0.0): Breaking changes
- MINOR (v0.5.0): New features, backward compatible
- PATCH (v0.5.1): Bug fixes, backward compatible
Tags must start with v: v0.5.0, v1.0.0, etc.
If you need to publish manually (e.g., for testing):
# Install dependencies
uv add --dev twine
# Build and publish
uv build
uv run twine upload dist/*# Authenticate
mcp-publisher login github
# Publish
mcp-publisher publish- No API tokens in repository: We use OIDC trusted publishing
- Environment protection: Add reviewers in GitHub settings for extra safety
- Read-only by default: Workflow has minimal permissions, escalates only when needed
- Audit trail: All publications visible in GitHub Actions logs
Issues with publishing? Open an issue: https://github.com/GitGuardian/ggmcp/issues