| Filename | Latest commit message | Latest commit date |
|---|---|---|
## Motivation and Context - Adds credentials for the new MCP Registry Login GitHub Apps (local, staging, prod) - Adds support for "none" auth to publisher ## How Has This Been Tested? - Tested publisher workflows locally - Unit and integration tests passing ## Breaking Changes None ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [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 --- Merging based on Tadas's approval review, and only making minor docs changes on top of that. |
||
| .. | ||
| pkg | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| Makefile | ||
| Pulumi.aksProd.yaml | ||
| Pulumi.gcpProd.yaml | ||
| Pulumi.gcpStaging.yaml | ||
| Pulumi.local.yaml | ||
| Pulumi.yaml | ||
| README.md | ||
MCP Registry Kubernetes Deployment
This directory contains Pulumi infrastructure code to deploy the MCP Registry service to a Kubernetes cluster. It supports deploying the infrastructure locally (using an existing kubeconfig, e.g. with minikube) or to Google Cloud Platform (GCP).
Quick Start
Local Development
Pre-requisites:
- Pulumi CLI installed
- Access to a Kubernetes cluster via kubeconfig. You can run a cluster locally with minikube.
- Ensure your kubeconfig is configured at the cluster you want to use. For minikube, run
minikube start && minikube tunnel. - Run
make local-upto deploy the stack. Run this again if the first attempt fails. - Access the repository via the ingress load balancer. You can find its external IP with
kubectl get svc ingress-nginx-controller -n ingress-nginx. Then runcurl -H "Host: local.registry.modelcontextprotocol.io" -k https://<EXTERNAL-IP>/v0/pingto check that the service is up.
To change config
The stack is configured out of the box for local development. But if you want to make changes, run commands like:
PULUMI_CONFIG_PASSPHRASE="" pulumi config set mcp-registry:environment local
PULUMI_CONFIG_PASSPHRASE="" pulumi config set mcp-registry:githubClientSecret --secret <some-secret-value>
To delete the stack
make local-destroy and deleting the cluster (with minikube: minikube delete) will reset you back to a clean state.
Production Deployment (GCP)
Note: The production deployment is automatically handled by GitHub Actions. All merges to the main branch trigger an automatic deployment to GCP via the configured GitHub Actions workflow. The steps below are preserved as a log of what we did, or if a manual override is needed.
Pre-requisites:
- Pulumi CLI installed
- A Google Cloud Platform (GCP) account
- A GCP Service Account with appropriate permissions
- Create a project:
gcloud projects create mcp-registry-prod - Set the project:
gcloud config set project mcp-registry-prod - Enable required APIs:
gcloud services enable storage.googleapis.com && gcloud services enable container.googleapis.com - Create a service account with necessary permissions, and get the key:
gcloud iam service-accounts create pulumi-svc sleep 10 gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/container.admin" gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/compute.admin" gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/storage.admin" gcloud iam service-accounts add-iam-policy-binding $(gcloud projects describe mcp-registry-prod --format="value(projectNumber)")-compute@developer.gserviceaccount.com --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/iam.serviceAccountUser" gcloud iam service-accounts keys create sa-key.json --iam-account=pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com - Create a GCS bucket for Pulumi state:
gsutil mb gs://mcp-registry-prod-pulumi-state - Set Pulumi's backend to GCS:
pulumi login gs://mcp-registry-prod-pulumi-state - Get the passphrase file
passphrase.prod.txtfrom the registry maintainers - Init the GCP stack:
PULUMI_CONFIG_PASSPHRASE_FILE=passphrase.prod.txt pulumi stack init gcpProd - Set the GCP credentials in Pulumi config:
# Base64 encode the service account key and set it pulumi config set --secret gcp:credentials "$(base64 < sa-key.json)" - Deploy:
make prod-up - Access the repository via the ingress load balancer. You can find its external IP with:
kubectl get svc ingress-nginx-controller -n ingress-nginx. Then runcurl -H "Host: prod.registry.modelcontextprotocol.io" -k https://<EXTERNAL-IP>/v0/pingto check that the service is up.
Structure
├── main.go # Pulumi program entry point
├── Pulumi.yaml # Project configuration
├── Pulumi.local.yaml # Local stack configuration
├── Pulumi.prod.yaml # Production stack configuration (Azure)
├── Pulumi.gcp.yaml # Production stack configuration (GCP)
├── Makefile # Build and deployment targets
├── go.mod # Go module dependencies
├── go.sum # Go module checksums
└── pkg/ # Infrastructure packages
├── k8s/ # Kubernetes deployment components
│ ├── cert_manager.go # SSL certificate management
│ ├── deploy.go # Deployment orchestration
│ ├── ingress.go # Ingress controller setup
│ ├── mongodb.go # MongoDB deployment
│ └── registry.go # MCP Registry deployment
└── providers/ # Kubernetes cluster providers
├── types.go # Provider interface definitions
├── aks/ # Azure Kubernetes Service provider
├── gcp/ # Google Kubernetes Engine provider
└── local/ # Local kubeconfig provider
Architecture Overview
Deployment Flow
- Pulumi program starts in
main.go - Configuration is loaded from Pulumi config files
- Provider factory creates appropriate cluster provider (AKS or local)
- Cluster provider sets up Kubernetes access
k8s.DeployAll()orchestrates complete deployment:- Certificate manager for SSL/TLS
- Ingress controller for external access
- MongoDB for data persistence
- MCP Registry application
Configuration
| Parameter | Description | Required |
|---|---|---|
environment |
Deployment environment (dev/prod) | Yes |
provider |
Kubernetes provider (local/aks/gcp) | No (default: local) |
githubClientId |
GitHub OAuth Client ID | Yes |
githubClientSecret |
GitHub OAuth Client Secret | Yes |
gcpProjectId |
GCP Project ID (required when provider=gcp) | No |
gcpRegion |
GCP Region (default: us-central1) | No |
Troubleshooting
Check Status
kubectl get pods
kubectl get deployment
kubectl get svc
kubectl get ingress
kubectl get svc -n ingress-nginx
View Logs
kubectl logs -l app=mcp-registry
kubectl logs -l app=mongodb