Skip to content

Conversation

Gaurav-Gosain
Copy link

This commit implements support for publishing MCP servers to GitHub Container
Registry (ghcr.io) in addition to the existing Docker Hub support, addressing
Docker Hub rate limiting concerns as requested in #393.

Key changes:

  • Add RegistryURLGHCR constant for https://ghcr.io
  • Refactor OCI validation to support multiple container registries with extensible RegistryConfig system
  • Implement registry-agnostic authentication system that handles:
    • Docker Hub token-based authentication via auth.docker.io
    • GHCR token-based authentication via ghcr.io/token service
  • Update Accept headers to support OCI image indexes for multi-arch images
  • Extract helper functions to reduce cyclomatic complexity and improve code maintainability
  • Add comprehensive test coverage for both Docker Hub and GHCR scenarios
  • Include real image testing with github/github-mcp-server and nkapila6/mcp-local-rag
  • Update publishing documentation with GHCR examples and authentication details

The implementation maintains backward compatibility with existing Docker Hub
usage while providing a future-proof architecture for adding additional
container registries. All authentication is now handled through proper token
services for both registries.

Fixes #393

Motivation and Context

Docker Hub rate limiting has been causing issues for the MCP registry when validating OCI images. Adding GHCR support provides an alternative container registry that many MCP server authors are already using, reducing the load on Docker Hub and providing more options for the community.

How Has This Been Tested?

  • All existing unit tests continue to pass
  • Added comprehensive test coverage for GHCR scenarios including:
    • Non-existent images (proper error handling)
    • Real images without MCP annotations (github/github-mcp-server)
    • Real images with proper MCP annotations (nkapila6/mcp-local-rag)
    • Registry URL validation for both supported registries
  • Tested authentication flow manually using curl commands
  • Verified multi-arch image support with OCI index manifests

Breaking Changes

None. This is a purely additive change that maintains full backward compatibility with existing Docker Hub configurations.

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

The implementation uses a RegistryConfig struct to abstract registry-specific details like API endpoints, authentication URLs, and token services. This design makes it straightforward to add support for additional container registries in the future (such as AWS ECR, Azure Container Registry, etc.) by simply adding new cases to the getRegistryConfig function.

The authentication system properly handles the different token services used by each registry:

  • Docker Hub: auth.docker.io with service=registry.docker.io
  • GHCR: ghcr.io/token with service=ghcr.io

Both registries now support the full OCI specification including multi-arch images via OCI image indexes.

@Gaurav-Gosain Gaurav-Gosain marked this pull request as ready for review September 11, 2025 13:48
Copy link
Collaborator

@rdimitrov rdimitrov left a comment

Choose a reason for hiding this comment

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

@claude - please review this PR

edit: I'm starting to think I hold claude wrong 😄

Copy link
Collaborator

@rdimitrov rdimitrov left a comment

Choose a reason for hiding this comment

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

@Gaurav-Gosain - Thank you very much for addressing this! 💯

I like that it was implemented in a way that makes it easy to extend in the future. I left a small comment, but overall it looks great 👍

This commit implements support for publishing MCP servers to GitHub Container
Registry (ghcr.io) in addition to the existing Docker Hub support, addressing
Docker Hub rate limiting concerns as requested in modelcontextprotocol#393.

Key changes:
- Add RegistryURLGHCR constant for https://ghcr.io
- Refactor OCI validation to support multiple container registries
- Create registry-agnostic authentication system that handles:
  - Docker Hub token-based authentication
  - GHCR anonymous access (no token required)
- Update validation logic to accept both docker.io and ghcr.io URLs
- Add comprehensive tests for both registries
- Update documentation with GHCR examples and usage instructions

The implementation maintains backward compatibility with existing Docker Hub
usage while providing a future-proof architecture for adding additional
container registries.

Fixes modelcontextprotocol#393
- Extract helper functions to reduce ValidateOCI complexity from 21 to under 20
- Remove unused getDockerIoAuthToken function
- Fix rate limiting handling to avoid nilnil linter issue
- Maintain all existing functionality while improving code quality
- Add proper GHCR token authentication with correct service parameter
- Update accept headers to support OCI image indexes for multi-arch images
- Add working test with real GitHub MCP server image from GHCR
- Verify GHCR connectivity and proper error handling for missing annotations
- Update documentation to accurately reflect authentication requirements
- Document the current state of MCP ecosystem regarding container annotations
- Add TODO for future success test case when properly annotated images exist
- Explain that the current test with github-mcp-server proves GHCR integration works
- Provide template for future test cases with expectError: false
…entication

- Update publishing guide to specify both registries use token-based auth
- Remove any implication that GHCR supports anonymous access
- Add details about which token service each registry uses
- Ensure documentation matches the implementation
- Replaced TODO with descriptive note about adding test cases
  when properly annotated MCP images are available in GHCR
- The MCP ecosystem is still new and such test cases will be
  added when the ecosystem matures
- Remove separate TestValidateOCI_GHCR_Integration function
- Add GHCR test cases to main TestValidateOCI_RealPackages table
- Include successful validation test case with nkapila6/mcp-local-rag
- Maintain clean table-driven test pattern from main branch
- Preserve skip logic for rate limiting protection
- Use fmt.Sprintf to construct AuthURL from ghcrAPIBaseURL constant
- Improves consistency with registry configuration pattern
- Addresses PR feedback from @rdimitrov
- Add explicit ErrRateLimited error type for clear rate limiting detection
- Update ValidateOCI to handle rate limiting explicitly via error checking
- Remove empty manifest logic from getConfigDigestFromManifest
- Make genuinely empty manifests fail validation with clear error message
- Ensure rate limiting only skips validation when HTTP 429 is encountered
- Address PR feedback about distinguishing rate limits from broken responses

This change ensures:
- HTTP 429 → ErrRateLimited → skip validation (intended behavior)
- Empty/broken manifest → validation fails with error (correct behavior)
- No false positives where broken responses are treated as rate limiting
@Gaurav-Gosain Gaurav-Gosain force-pushed the feature/add-ghcr-support branch from 721faff to 9a9783f Compare September 12, 2025 16:42
@Gaurav-Gosain
Copy link
Author

@Gaurav-Gosain - Thank you very much for addressing this! 💯

I like that it was implemented in a way that makes it easy to extend in the future. I left a small comment, but overall it looks great 👍

Thank you for the positive feedback 🙏!

The implementation now properly separates concerns and ensures that only explicit rate limiting (HTTP 429) results in skipped validation, while broken or empty responses properly fail validation.

Copy link
Collaborator

@rdimitrov rdimitrov left a comment

Choose a reason for hiding this comment

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

It looks good from my side. I'll wait for the others to have a look at it too before we can merge it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ghrc as a docker registry
2 participants