Storage Backends
5 min read
MCP Registry supports two storage backends for artifact persistence: S3-compatible object storage and the local filesystem. Both backends implement the same interface, so the registry behaves identically regardless of which backend is in use – the difference is in performance characteristics, scalability, and operational requirements.
Storage Interface
Internally, the registry interacts with storage through a common interface:
| Operation | Description |
|---|---|
| Put | Store an artifact by key |
| Get | Retrieve artifact bytes by key |
| PresignGet | Generate a time-limited download URL (S3 only) |
| PresignPut | Generate a time-limited upload URL (S3 only) |
Artifacts are stored at the path: org/{org}/artifacts/{digest}/{kind}
S3 Storage
S3-compatible storage is the recommended backend for production deployments. It supports presigned URLs for direct client uploads and downloads, horizontal scaling across multiple registry instances, and managed durability and availability.
Configuration
storage:
type: "s3"
s3:
bucket: "mcp-artifacts"
region: "us-east-1"
endpoint: ""
| Key | Required | Description |
|---|---|---|
bucket | Yes | S3 bucket name (must already exist) |
region | Yes | AWS region for the bucket |
endpoint | No | Custom endpoint for S3-compatible services (empty string uses AWS default) |
AWS S3
For production on AWS, configure the bucket and region. Authentication uses the standard AWS SDK credential chain:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - Shared credentials file (
~/.aws/credentials) - IAM instance role (when running on EC2, ECS, or EKS)
storage:
type: "s3"
s3:
bucket: "company-mcp-artifacts"
region: "us-west-2"
endpoint: ""
MinIO (Development)
MinIO is an S3-compatible object storage server that runs locally. The MCP Hub Platform docker-compose includes MinIO for development.
storage:
type: "s3"
s3:
bucket: "mcp"
region: "us-east-1"
endpoint: "http://minio.local:9000"
Set credentials via environment variables:
export AWS_ACCESS_KEY_ID="minioadmin"
export AWS_SECRET_ACCESS_KEY="minioadmin"
When using the docker-compose stack, the minio-init container creates the required buckets and policies. Confirm it has exited with code 0 before starting the registry: docker compose ps minio-init.
Other S3-Compatible Services
Any S3-compatible storage service works with the endpoint override:
DigitalOcean Spaces:
storage:
type: "s3"
s3:
bucket: "mcp-artifacts"
region: "nyc3"
endpoint: "https://nyc3.digitaloceanspaces.com"
Google Cloud Storage (S3 interop):
storage:
type: "s3"
s3:
bucket: "mcp-artifacts"
region: "auto"
endpoint: "https://storage.googleapis.com"
Backblaze B2:
storage:
type: "s3"
s3:
bucket: "mcp-artifacts"
region: "us-west-002"
endpoint: "https://s3.us-west-002.backblazeb2.com"
Filesystem Storage
Filesystem storage stores artifacts as files on the local disk. It is designed for development, testing, and single-instance deployments where simplicity is more important than scalability.
Configuration
storage:
type: "fs"
fs:
root: "/data/mcp-registry/artifacts"
| Key | Required | Description |
|---|---|---|
root | Yes | Root directory for artifact storage (created if it does not exist) |
Artifacts are stored at: {root}/org/{org}/artifacts/{digest}/{kind}
Limitations
- No presigned URL support – All uploads and downloads are proxied through the registry server
- Single-server only – Cannot share storage across multiple registry instances without a shared filesystem (NFS, etc.)
- No managed durability – Data durability depends on the underlying disk; you must handle backups
- File permissions – The registry process must have read/write access to the root directory
Presigned URLs
Presigned URLs allow clients to upload and download artifacts directly from the storage backend, bypassing the registry server. This reduces load on the registry and improves transfer performance for large artifacts.
Configuration
presign:
enabled: true
ttl_seconds: 300
| Key | Default | Description |
|---|---|---|
enabled | true | Enable presigned URL generation |
ttl_seconds | 300 | Presigned URL lifetime in seconds (5 minutes) |
How Presigned URLs Work
Upload (publish flow):
- Publisher calls
POST /publish - Registry creates version record and returns a presigned PUT URL
- Publisher uploads the bundle directly to S3 using the presigned URL
- No artifact bytes pass through the registry
Download (download flow):
- Client calls
GET /artifacts/{digest}/{kind} - Registry validates authentication and authorization
- Registry returns a
302 Redirectto a presigned GET URL - Client downloads directly from S3
When Presigned URLs Are Not Available
Presigned URLs require S3 storage. They are not available when:
storage.typeisfs(filesystem backend)presign.enabledisfalse
In these cases, the registry proxies all artifact bytes through the HTTP server.
TTL Considerations
| TTL | Trade-off |
|---|---|
| Too short (< 60s) | Uploads of large bundles may fail on slow connections |
| Recommended (300s) | Good balance between security and usability |
| Too long (> 3600s) | Risk if URLs are leaked; they remain valid for extended periods |
Choosing the Right Backend
| Criteria | S3 | Filesystem |
|---|---|---|
| Production readiness | Yes | Limited |
| Horizontal scaling | Yes (stateless registry) | No (single instance) |
| Presigned URLs | Yes | No |
| Managed durability | Yes (11 nines on AWS) | No (depends on disk) |
| Operational complexity | Moderate (S3 setup, IAM) | Low (just a directory) |
| Cost | Per-request and per-GB pricing | No additional cost |
| Development setup | MinIO via docker-compose | Zero dependencies |
| Large artifacts | Direct upload/download via presign | Proxied through registry (memory/bandwidth bound) |
Recommendations
Use S3 for:
- Production deployments
- Multi-instance registry setups (behind a load balancer)
- Large artifacts where direct upload/download improves performance
- Environments requiring managed durability and availability
Use filesystem for:
- Local development and testing
- Single-instance deployments with small artifact volumes
- Air-gapped environments without S3-compatible storage
- Quick prototyping (zero external dependencies)
Storage Security
S3 Bucket Policy
Configure your S3 bucket to restrict access:
- The bucket should not be publicly accessible
- Grant access only to the registry’s IAM role or credentials
- Enable server-side encryption (SSE-S3 or SSE-KMS)
- Enable access logging for audit
Filesystem Permissions
When using filesystem storage:
- Set the root directory permissions to
0750(owner read/write/execute, group read/execute) - Run the registry process as a dedicated user
- Ensure the storage directory is not accessible via other web servers or services
- Include the storage directory in your backup strategy