- Go 92.9%
- PLpgSQL 3.1%
- HTML 1.9%
- Shell 1.6%
- Makefile 0.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
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 - [x] New feature (non-breaking change which adds functionality) - [x] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] 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. |
||
| .githooks | ||
| .github | ||
| .vscode | ||
| cmd | ||
| data | ||
| deploy | ||
| docs | ||
| internal | ||
| pkg | ||
| scripts | ||
| tests/integration | ||
| tools | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .golangci.yml | ||
| .goreleaser.yaml | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
MCP Registry
The MCP registry provides MCP clients with a list of MCP servers, like an app store for MCP servers.
📤 Publish my MCP server | ⚡️ Live API docs | 👀 Ecosystem vision | 📖 Full documentation
Development Status
2025-09-08 update: The registry has launched in preview 🎉 (announcement blog post). While the system is now more stable, this is still a preview release and breaking changes or data resets may occur. A general availability (GA) release will follow later. We'd love your feedback in GitHub discussions or in the #registry-dev Discord (joining details here).
Current key maintainers:
- Adam Jones (Anthropic) @domdomegg
- Tadas Antanavicius (PulseMCP) @tadasant
- Toby Padilla (GitHub) @toby
Contributing
We use multiple channels for collaboration - see modelcontextprotocol.io/community/communication.
Often (but not always) ideas flow through this pipeline:
- Discord - Real-time community discussions
- Discussions - Propose and discuss product/technical requirements
- Issues - Track well-scoped technical work
- Pull Requests - Contribute work towards issues
Quick start:
Pre-requisites
- Docker
- Go 1.24.x
- golangci-lint v2.4.0
Running the server
# Start full development environment
make dev-compose
This starts the registry at localhost:8080 with PostgreSQL and seed data. It can be configured with environment variables in docker-compose.yml - see .env.example for a reference.
Alternative: Local setup without Docker
Prerequisites:
- PostgreSQL running locally
- Go 1.24.x installed
# Build and run locally
make build
make dev-local
The service runs on localhost:8080 by default. This can be configured with environment variables in .env - see .env.example for a reference.
Alternative: Running a pre-built Docker image
Pre-built Docker images are automatically published to GitHub Container Registry:
# Run latest stable release
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:latest
# Run latest from main branch (continuous deployment)
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main
# Run specific release version
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:v1.0.0
# Run development build from main branch
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250906-abc123d
Available tags:
- Releases:
latest,v1.0.0,v1.1.0, etc. - Continuous:
main(latest main branch build) - Development:
main-<date>-<sha>(specific commit builds)
Publishing a server
To publish a server, we've built a simple CLI. You can use it with:
# Build the latest CLI
make publisher
# Use it!
./bin/mcp-publisher --help
See the publisher guide for more details.
Other commands
# Run lint, unit tests and integration tests
make check
There are also a few more helpful commands for development. Run make help to learn more, or look in Makefile.
Architecture
Project Structure
├── cmd/ # Application entry points
│ └── publisher/ # Server publishing tool
├── data/ # Seed data
├── deploy/ # Deployment configuration (Pulumi)
├── docs/ # Documentation
├── internal/ # Private application code
│ ├── api/ # HTTP handlers and routing
│ ├── auth/ # Authentication (GitHub OAuth, JWT, namespace blocking)
│ ├── config/ # Configuration management
│ ├── database/ # Data persistence (PostgreSQL, in-memory)
│ ├── service/ # Business logic
│ ├── telemetry/ # Metrics and monitoring
│ └── validators/ # Input validation
├── pkg/ # Public packages
│ ├── api/ # API types and structures
│ │ └── v0/ # Version 0 API types
│ └── model/ # Data models for server.json
├── scripts/ # Development and testing scripts
├── tests/ # Integration tests
└── tools/ # CLI tools and utilities
└── validate-*.sh # Schema validation tools
Authentication
Publishing supports multiple authentication methods:
- GitHub OAuth - For publishing by logging into GitHub
- GitHub OIDC - For publishing from GitHub Actions
- DNS verification - For proving ownership of a domain and its subdomains
- HTTP verification - For proving ownership of a domain
The registry validates namespace ownership when publishing. E.g. to publish...:
io.github.domdomegg/my-cool-mcpyou must login to GitHub asdomdomegg, or be in a GitHub Action on domdomegg's reposme.adamjones/my-cool-mcpyou must prove ownership ofadamjones.mevia DNS or HTTP challenge
More documentation
See the documentation for more details if your question has not been answered here!