AgentStack
MCP verified MIT-0 Self-run

Sample Mcp Registry Infrastructure

mcp-aws-samples-sample-mcp-registry-infrastructure · by aws-samples

Sample AWS CloudFormation infrastructure for hosting a private MCP registry with S3, CloudFront, and optional WAF IP filtering or signed URL authentication.

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add mcp-aws-samples-sample-mcp-registry-infrastructure

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Sample Mcp Registry Infrastructure? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

MCP Registry Infrastructure

A sample for a secure, enterprise-grade infrastructure for hosting MCP (Model Context Protocol) registry files using AWS CloudFront, S3, WAF, and CloudFront signed URLs.

Overview

This sample solution provides a complete infrastructure-as-code deployment for hosting an MCP registry JSON file that Kiro and other AI assistant clients can use to discover approved MCP servers. The architecture follows AWS security best practices with three access control modes:

  • Public: CloudFront serves the registry without access restrictions
  • Restricted: WAF filters requests based on source IP addresses
  • Signed: CloudFront signed URLs require a cryptographic token to access the registry (can be combined with IP filtering for defense-in-depth)

Architecture

Features

  • Private S3 Bucket: All public access blocked, server-side encryption with AES-256
  • CloudFront CDN: Global edge caching with HTTPS-only access and TLS 1.2 minimum
  • Origin Access Control (OAC): Secure S3 access using SigV4 signing
  • Optional WAF IP Filtering: Restrict access to specific IP ranges
  • Optional Signed URL Authentication: Token-based access via CloudFront signed URLs with automated key lifecycle management
  • Idempotent Deployment: Safe to run multiple times without errors
  • Cache Invalidation: Automatic CloudFront cache invalidation on updates

Prerequisites

  • AWS CLI configured with appropriate credentials
  • jq installed for JSON parsing
  • Bash shell (macOS, Linux, or WSL on Windows)

Quick Start

1. Deploy in Public Mode

./deploy.sh \
  --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json \
  --mode public

2. Deploy with IP Restrictions

./deploy.sh \
  --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json \
  --mode restricted \
  --allowed-ips "10.0.0.0/8,192.168.1.0/24,203.0.113.50/32"

3. Deploy with Signed URL Authentication

./deploy.sh \
  --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json \
  --mode signed

4. Deploy with Signed URL + IP Filtering (Defense-in-Depth)

./deploy.sh \
  --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json \
  --mode signed \
  --allowed-ips "10.0.0.0/8,192.168.1.0/24"

Files

| File | Description | |------|-------------| | mcp-registry-infrastructure.yaml | CloudFormation template defining all AWS resources | | deploy.sh | Idempotent deployment script | | mcp-registry.json | Sample MCP registry with AWS servers | | lambda_handler/index.py | Lambda custom resource for signed URL key lifecycle | | validate_registry.py | Schema validation script for registry files |

Deploy Script Options

Usage: deploy.sh [OPTIONS]

Required Options:
  --stack-name                 CloudFormation stack name
  --registry-file              Path to mcp-registry.json file
  --mode   Access control mode

Optional Options:
  --allowed-ips       Comma-separated CIDR ranges (for restricted or signed+IP mode)
  --region           AWS region (default: us-east-1)
  --skip-validation          Skip registry file schema validation before upload
  -h, --help                 Display help message

Exit Codes:
  0 - Success
  1 - Invalid arguments
  2 - CloudFormation deployment failed
  3 - S3 upload failed
  4 - CloudFront invalidation failed

MCP Registry Format

The registry file follows the MCP registry JSON schema:

{
  "servers": [
    {
      "server": {
        "name": "server-name",
        "description": "Server description",
        "version": "1.0.0",
        "packages": [
          {
            "registryType": "pypi",
            "identifier": "package-name@version",
            "transport": {
              "type": "stdio"
            }
          }
        ]
      }
    }
  ]
}

Validating Your Registry File

uv run --with jsonschema python validate_registry.py mcp-registry.json

Updating the Registry

To update the registry after initial deployment, run the deploy script again with the updated registry file:

./deploy.sh \
  --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json \
  --mode public

The script will:

  1. Update the CloudFormation stack (if template changed)
  2. Validate the registry file against the MCP schema
  3. Upload the new registry file to S3
  4. Invalidate the CloudFront cache

CloudFormation Outputs

After deployment, the stack provides these outputs:

| Output | Description | |--------|-------------| | BucketName | S3 bucket name for direct uploads | | DistributionId | CloudFront distribution ID | | DistributionDomainName | CloudFront domain (e.g., d1234567890.cloudfront.net) | | MCPRegistryURL | Full URL to the registry file | | WebACLArn | WAF Web ACL ARN (restricted mode only) | | SignedRegistryURL | Secrets Manager ARN containing the signed URL (signed mode only) | | PrivateKeySecretArn | Secrets Manager ARN for the RSA private key (signed mode only) |

Security

S3 Bucket Security

  • All public access blocked (BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, RestrictPublicBuckets)
  • Server-side encryption with AES-256
  • Access logging enabled to a dedicated log bucket (90-day retention)
  • Bucket policy allows only CloudFront OAC access

CloudFront Security

  • HTTPS-only (ViewerProtocolPolicy: https-only)
  • TLS 1.2 minimum protocol version
  • GET and HEAD methods only
  • Origin Access Control with SigV4 signing
  • Standard access logging enabled for request-level visibility

WAF Security (Restricted Mode)

  • IP-based allow list with default-block policy
  • Custom 403 JSON response for blocked requests
  • CloudWatch metrics enabled for monitoring

Signed URL Security (Signed Mode)

  • RSA 2048-bit key pair generated by Lambda custom resource
  • Private key stored in AWS Secrets Manager (never leaves your account)
  • CloudFront validates signature, expiry, and key pair ID on every request
  • Treat the signed URL as a secret credential — do not commit to version control

Signed URL Rotation

When using --mode signed, the signed URL acts as a bearer credential. Rotate it periodically or immediately if you suspect compromise.

Quick Rotation via Redeployment

The simplest approach — redeploy the stack and the Lambda handles the full key lifecycle automatically:

./deploy.sh --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json \
  --mode signed

The stack update replaces the old key group with a new one and outputs a fresh signed URL. Update the URL in your AI assistant's admin console (e.g., Kiro enterprise governance settings). There is a brief moment during the update where the old key group is removed before the new one is active — for a registry JSON file, this is typically acceptable.

Zero-Downtime Rotation (Manual)

For environments where even brief interruptions are unacceptable, you can manually add a second key group alongside the existing one using the AWS CLI. CloudFront supports up to 4 trusted key groups simultaneously.

Step 1: Generate a new key pair and register it with CloudFront Step 2: Add the new key group to the distribution alongside the old one Step 3: Update the admin console with the new signed URL Step 4: Remove the old key group and clean up resources

See the [detailed guide](GUIDE.md) for CLI commands for each step.

Emergency Revocation

# Revoke immediately by switching to public mode
./deploy.sh --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json --mode public

# Then redeploy with a fresh signed URL
./deploy.sh --stack-name my-mcp-registry \
  --registry-file ./mcp-registry.json --mode signed

Recommended Rotation Schedule

| Environment | Expiry | Rotation Frequency | |-------------|--------|--------------------| | Development | 365 days | Every 6 months | | Production | 90 days | Every 60 days | | High security | 30 days | Every 21 days |

Troubleshooting

Deployment Fails

  • Verify AWS credentials are configured: aws sts get-caller-identity
  • Check CloudFormation events in AWS Console for detailed errors
  • Ensure the stack name is unique in your account/region

Registry Not Updating

  • CloudFront cache invalidation takes 1-5 minutes to propagate
  • Check invalidation status: aws cloudfront list-invalidations --distribution-id

Access Denied (403)

  • In restricted mode, verify your IP is in the allowed list
  • In signed mode, verify the signed URL hasn't expired
  • Check WAF logs in CloudWatch for blocked requests

Cleanup

To delete all resources:

# Empty the registry bucket
aws s3 rm s3://$(aws cloudformation describe-stacks \
  --stack-name my-mcp-registry \
  --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' \
  --output text) --recursive

# Empty the access log bucket
aws s3 rm s3://$(aws cloudformation describe-stacks \
  --stack-name my-mcp-registry \
  --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' \
  --output text)-access-logs --recursive

# Delete the stack
aws cloudformation delete-stack --stack-name my-mcp-registry

Cost Warning

This deployment creates AWS resources that will incur costs. The primary cost drivers are:

  • Amazon CloudFront distribution (request pricing + data transfer)
  • Amazon S3 storage and requests
  • AWS WAF (if using restricted or signed+IP mode)
  • AWS Secrets Manager (if using signed mode)
  • AWS Lambda invocations (if using signed mode, only during deployment)

For a single JSON file with moderate traffic, costs are minimal. Use the AWS Pricing Calculator to estimate costs for your specific usage.

License

This project is licensed under the MIT-0 License. See the [LICENSE](LICENSE) file.

Contributing

See [CONTRIBUTING](CONTRIBUTING.md) for guidelines.

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.