使用说明
Amplify MCP Servers - Deployment Examples
This repository contains example Model Context Protocol (MCP) servers designed to be deployed as AWS Lambda functions and integrated with Amplify applications. These servers provide LLMs with powerful capabilities like data transformation, image processing, code execution, and Jupyter notebook interaction.
⚠️ IMPORTANT: Example Templates
These are demonstration examples and starting templates only. They provide a foundation for building MCP servers but are intentionally kept simple for educational purposes.
🚀 Extend and Customize
You can (and should!) enhance these examples based on your requirements:
-
🔐 Security Enhancements:
- Add user authentication and authorization
- Implement API key validation
- Add rate limiting and throttling
- Enable VPC isolation for sensitive data
- Implement request signing and verification
- Add WAF rules for additional protection
-
💾 User-Specific Storage:
- Implement per-user S3 prefixes/buckets
- Add user session management
- Store user preferences and settings
- Implement workspace isolation
- Add multi-tenancy support
- Enable user data encryption at rest
-
🎨 Custom Features:
- Add your own domain-specific tools
- Integrate with your existing APIs
- Connect to your databases (RDS, DynamoDB, etc.)
- Add caching layers (ElastiCache, CloudFront)
- Implement custom logging and metrics
- Add business logic specific to your use case
- Integrate with third-party services (Stripe, Twilio, etc.)
-
📊 Advanced Capabilities:
- Add queue-based processing (SQS)
- Implement async workflows (Step Functions)
- Add streaming responses
- Enable WebSocket support
- Implement batch processing
- Add data validation and transformation pipelines
Go crazy! These examples are fully extensible. Use them as blueprints to build production-grade MCP servers tailored to your specific needs. The architecture supports any enhancement you can imagine.
📦 Available MCP Servers
| Server | Description | Tools Provided | Status |
|---|---|---|---|
| Data Transformation | Convert between data formats (CSV, JSON, XML, YAML) | csv_to_json, json_to_csv, xml_to_json, json_to_xml, yaml_to_json, json_to_yaml |
✅ Production Ready |
| Image Processing | Comprehensive image manipulation | resize_image, crop_image, rotate_image, apply_filter, convert_format, create_thumbnail |
✅ Production Ready |
| Node.js Execution | Safe sandboxed JavaScript execution | execute_javascript |
✅ Production Ready |
| Jupyter Notebooks | Interactive Python notebook execution | create_notebook, execute_cell, list_cells, get_output, install_package, upload_file |
✅ Production Ready |
🏗️ Architecture Overview
┌─────────────────┐
│ Amplify App │
└────────┬────────┘
│
│ HTTP POST
│
┌────────▼────────┐
│ API Gateway │
└────────┬────────┘
│
│ Invoke
│
┌────────▼────────────────┐
│ Lambda Function │
│ (MCP Server) │
│ ┌──────────────────┐ │
│ │ Docker Container │ │
│ │ - Python 3.12 │ │
│ │ - MCP Protocol │ │
│ │ - Tool Logic │ │
│ └──────────────────┘ │
└─────────┬───────────────┘
│
│ S3 (optional)
│ for file storage
│
┌─────────▼───────────┐
│ S3 Bucket │
│ - Processed Files │
│ - Presigned URLs │
└─────────────────────┘
How It Works
- Frontend Request: User interacts with Amplify app, triggering an MCP tool request
- API Gateway: Routes the request to the appropriate Lambda function
- Lambda Execution:
- Receives JSON-RPC 2.0 formatted request
- Executes the requested tool with provided parameters
- Processes data (transform, execute code, process image, etc.)
- Response:
- Returns results in MCP protocol format
- Includes presigned S3 URLs for large files (24-hour expiry)
- Frontend Display: Amplify app receives and displays the results to user
🚀 Quick Start
Prerequisites
-
AWS Account with appropriate permissions:
- Lambda function creation and management
- ECR repository creation and image push
- S3 bucket access (for file storage)
- DynamoDB access (for Amplify MCP configuration)
-
AWS CLI configured:
aws configure # Enter your Access Key ID, Secret Access Key, Region (us-east-1), and output format (json) -
Docker Desktop installed and running
-
Git for cloning this repository
Deployment Steps
Each server follows the same deployment pattern:
-
Navigate to the server directory:
cd servers/[server-name] -
Build the Docker image:
docker build --platform linux/amd64 -t [server-name]-mcp-server -f Dockerfile.lambda . -
Create ECR repository (if it doesn't exist):
aws ecr create-repository --repository-name [server-name]-mcp-server --region us-east-1 -
Tag and push to ECR:
# Use the provided push-to-ecr.sh script ./push-to-ecr.sh -
Deploy Lambda function:
# Use the deploy script ./deploy-lambda-ecr.sh -
Configure in Amplify:
- Lambda function URL is automatically created with CORS enabled
- Add the function URL to your Amplify app's DynamoDB MCP configuration
📖 Detailed Server Documentation
1. Data Transformation MCP Server
Location: servers/data-transformation/
Description: Converts data between common formats (CSV, JSON, XML, YAML) with S3 persistence for large files.
Tools
| Tool | Input | Output | Use Case |
|---|---|---|---|
csv_to_json |
CSV string | JSON string | Parse CSV data for processing |
json_to_csv |
JSON string | CSV string | Export data to spreadsheet format |
xml_to_json |
XML string | JSON string | Parse XML APIs/configs |
json_to_xml |
JSON string | XML string | Generate XML for legacy systems |
yaml_to_json |
YAML string | JSON string | Parse config files |
json_to_yaml |
JSON string | YAML string | Generate human-readable configs |
Environment Variables
S3_BUCKET=your-bucket-name # Optional: for storing large files
Deployment
cd servers/data-transformation
# Build Docker image
docker build --platform linux/amd64 -t data-transformation-mcp-server -f Dockerfile.lambda .
# Create ECR repository
aws ecr create-repository --repository-name data-transformation-mcp-server --region us-east-1
# Push to ECR
./push-to-ecr.sh
# Deploy Lambda
./deploy-lambda-ecr.sh
Example Usage
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "csv_to_json",
"arguments": {
"csv_data": "name,age,city\nJohn,30,NYC\nJane,25,LA"
}
},
"id": 1
}
Response:
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "Converted 2 rows from CSV to JSON"
},
{
"type": "text",
"text": "[{\"name\":\"John\",\"age\":\"30\",\"city\":\"NYC\"},{\"name\":\"Jane\",\"age\":\"25\",\"city\":\"LA\"}]"
}
]
},
"id": 1
}
2. Image Processing MCP Server
Location: servers/image-processing/
Description: Comprehensive image manipulation including resize, crop, rotate, filters, format conversion, and thumbnail generation.
Tools
| Tool | Parameters | Description |
|---|---|---|
resize_image |
image_data, width, height, maintain_aspect |
Resize with aspect ratio preservation |
crop_image |
image_data, left, top, right, bottom |
Crop to specific region |
rotate_image |
image_data, degrees, expand |
Rotate by angle |
apply_filter |
image_data, filter_type, intensity |
Apply filters (grayscale, blur, sharpen, etc.) |
convert_format |
image_data, target_format, quality |
Convert between PNG, JPEG, WebP, GIF, BMP |
create_thumbnail |
image_data, max_size |
Generate thumbnail |
Supported Filters
grayscale: Convert to black and whiteblur: Gaussian blur with intensity controlsharpen: Enhance edgesedge_enhance: Emphasize edgescontour: Extract contoursbrightness: Adjust brightness (intensity: 0.5 = darker, 1.5 = brighter)contrast: Adjust contrast (intensity: 0.5 = lower, 1.5 = higher)
Environment Variables
S3_BUCKET=your-bucket-name # Optional: for storing processed images
Deployment
cd servers/image-processing
# Build Docker image
docker build --platform linux/amd64 -t image-processing-mcp-server -f Dockerfile.lambda .
# Create ECR repository
aws ecr create-repository --repository-name image-processing-mcp-server --region us-east-1
# Push to ECR
./push-to-ecr.sh
# Deploy Lambda
./deploy-lambda-ecr.sh
Example Usage
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "rotate_image",
"arguments": {
"image_data": "iVBORw0KGgoAAAANSUhEUgAAAAUA...",
"degrees": 90,
"expand": true
}
},
"id": 1
}
Response:
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "Rotated by 90 degrees"
},
{
"type": "text",
"text": "\n\n[Image] 800x600 PNG"
},
{
"type": "image",
"data": "iVBORw0KGgoAAAANSUhEUgAAA...",
"mimeType": "image/png"
},
{
"type": "text",
"text": "\n\n[Download] 245 KB:\nhttps://bucket.s3.amazonaws.com/..."
}
]
},
"id": 1
}
Important Notes
Base64 Encoding:
- Input images must be base64 encoded
- Data URI prefix (
data:image/png;base64,) is automatically stripped - Whitespace and newlines are automatically removed
- Padding is automatically added if needed
Size Limits:
- Images under 4MB: Returned as base64 in response
- Images over 4MB: Only S3 presigned URL provided (24-hour expiry)
3. Node.js Execution MCP Server
Location: servers/nodejs-execution/
Description: Executes JavaScript code in a safe, sandboxed environment with timeout protection.
Tools
| Tool | Parameters | Description |
|---|---|---|
execute_javascript |
code, timeout |
Execute JS code with optional timeout (default: 5000ms) |
Features
- Safe Execution: Runs in isolated VM context
- Timeout Protection: Prevents infinite loops (default 5 seconds, max 30 seconds)
- Console Capture: Captures
console.log()output - Error Handling: Returns clear error messages with stack traces
- Return Value: Captures and returns the last expression value
Deployment
cd servers/nodejs-execution
# Build Docker image
docker build --platform linux/amd64 -t nodejs-execution-mcp-server -f Dockerfile.lambda .
# Create ECR repository
aws ecr create-repository --repository-name nodejs-execution-mcp-server --region us-east-1
# Push to ECR
./push-to-ecr.sh
# Deploy Lambda
./deploy-lambda-ecr.sh
Example Usage
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "execute_javascript",
"arguments": {
"code": "function fibonacci(n) { return n <= 1 ? n : fibonacci(n-1) + fibonacci(n-2); }\nfibonacci(10);",
"timeout": 5000
}
},
"id": 1
}
Response:
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "Execution completed successfully"
},
{
"type": "text",
"text": "Result: 55\n\nExecution time: 12ms"
}
]
},
"id": 1
}
Security Considerations
- Code runs in Node.js VM sandbox
- Limited to 30-second maximum timeout
- No filesystem access
- No network access from executed code
- Memory limited by Lambda constraints (configurable)
4. Jupyter Notebook MCP Server
Location: servers/jupyter/
Description: Interactive Python notebook execution with Jupyter kernel management, matplotlib plotting, and package installation.
🚨 CRITICAL SECURITY NOTE
AWS Credentials Exposure Issue (FIXED): Lambda functions receive AWS credentials via environment variables. Without protection, user code executing os.environ could access:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN
Fix Applied: The kernel manager now strips AWS credentials and sensitive Lambda metadata from the environment before starting the Jupyter kernel. User code cannot access Lambda execution role credentials.
Production Requirements: This example still needs extensive hardening including user authentication, per-user kernel isolation, resource limits, code sandboxing, audit logging, and network restrictions. See servers/jupyter/README.md for detailed security considerations.
Tools
| Tool | Parameters | Description |
|---|---|---|
create_notebook |
notebook_name |
Create new notebook with kernel |
execute_cell |
notebook_id, code |
Execute Python code cell |
list_cells |
notebook_id |
List all executed cells |
get_output |
notebook_id, cell_index |
Get specific cell output |
install_package |
notebook_id, package_name |
Install Python package |
upload_file |
notebook_id, filename, content |
Upload file to notebook workspace |
Features
- Persistent Kernels: Each notebook maintains state across executions
- Matplotlib Support: Generates PNG images for plots
- Package Management: Install packages on-the-fly with pip
- File Upload: Upload data files to notebook workspace
- S3 Integration: Large outputs stored in S3 with presigned URLs
- Output Capture: Returns stdout, stderr, and display data
Environment Variables
S3_BUCKET=your-bucket-name # Required for storing notebooks and outputs
Deployment
cd servers/jupyter
# Build Docker image
docker build --platform linux/amd64 -t jupyter-mcp-server -f Dockerfile.lambda .
# Create ECR repository
aws ecr create-repository --repository-name jupyter-mcp-server --region us-east-1
# Push to ECR
./push-to-ecr.sh
# Deploy Lambda
./deploy-lambda-ecr.sh
Example Usage
1. Create Notebook:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_notebook",
"arguments": {
"notebook_name": "data_analysis"
}
},
"id": 1
}
2. Execute Code:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "execute_cell",
"arguments": {
"notebook_id": "nb_abc123",
"code": "import matplotlib.pyplot as plt\nimport numpy as np\nx = np.linspace(0, 10, 100)\ny = np.sin(x)\nplt.plot(x, y)\nplt.title('Sine Wave')\nplt.show()"
}
},
"id": 2
}
Response:
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "Cell executed successfully (520ms)"
},
{
"type": "image",
"data": "iVBORw0KGgoAAAANSUhEUg...",
"mimeType": "image/png"
},
{
"type": "text",
"text": "[Download Full Notebook]\nhttps://bucket.s3.amazonaws.com/..."
}
]
},
"id": 2
}
Lambda Configuration
- Memory: 1024 MB (increase for data-intensive workloads)
- Timeout: 900 seconds (15 minutes maximum)
- Ephemeral Storage: 512 MB (for temporary files)
🔧 Amplify Integration
DynamoDB MCP Server Configuration
After deploying your Lambda functions, you need to register them in your Amplify application's DynamoDB table.
Table Structure
Table Name: amplify-v6-lambda-dev-user-data-storage (or your configured table)
Partition Key (PK): {user_id}#amplify-mcp#mcp_servers
Item Structure:
{
"PK": "84484458-a081-7063-5367-6f05668660ea#amplify-mcp#mcp_servers",
"servers": {
"data-transformation": {
"name": "Data Transformation",
"url": "https://[lambda-url].lambda-url.us-east-1.on.aws/",
"enabled": true,
"tools": [
{
"name": "csv_to_json",
"description": "Convert CSV to JSON format",
"inputSchema": {
"type": "object",
"properties": {
"csv_data": {
"type": "string",
"description": "CSV formatted data"
}
},
"required": ["csv_data"]
}
}
// ... other tools
]
},
"image-processing": {
"name": "Image Processing",
"url": "https://[lambda-url].lambda-url.us-east-1.on.aws/",
"enabled": true,
"tools": [
// ... image tools
]
},
"nodejs-execution": {
"name": "JavaScript Executor",
"url": "https://[lambda-url].lambda-url.us-east-1.on.aws/",
"enabled": true,
"tools": [
// ... nodejs tools
]
},
"jupyter": {
"name": "Jupyter Notebooks",
"url": "https://[lambda-url].lambda-url.us-east-1.on.aws/",
"enabled": true,
"tools": [
// ... jupyter tools
]
}
}
}
Getting Lambda Function URLs
After deployment, retrieve the function URL:
aws lambda get-function-url-config \
--function-name [function-name]-mcp-lambda \
--region us-east-1 \
--query 'FunctionUrl' \
--output text
Or check in AWS Console:
- Go to Lambda → Functions
- Select your function
- Go to Configuration → Function URL
- Copy the URL
Tool Schema Registration
Each tool needs its schema registered in DynamoDB. The schema follows the MCP protocol specification:
{
"name": "tool_name",
"description": "What the tool does",
"inputSchema": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Parameter description"
},
"param2": {
"type": "integer",
"description": "Another parameter",
"default": 100
}
},
"required": ["param1"]
}
}
Important: Do NOT use float types in schema - use integer with description of allowed range.
🐛 Troubleshooting
Common Issues
1. Lambda 502 Errors
Symptoms: HTTP 502 Bad Gateway when calling Lambda
Causes & Solutions:
-
Python Syntax Errors:
# Validate syntax before deploying python3 -m py_compile server.py -
Unicode/Encoding Issues: Avoid emoji or special characters in source code
-
Missing Dependencies: Check Dockerfile includes all required packages
-
Cold Start Timeout: Increase Lambda timeout configuration
Debugging:
# Check Lambda logs
aws logs tail /aws/lambda/[function-name] --follow --region us-east-1
# Get recent errors
aws logs filter-log-events \
--log-group-name /aws/lambda/[function-name] \
--filter-pattern "ERROR" \
--region us-east-1
2. Base64 Decoding Errors
Symptoms: "Invalid base64-encoded string: number of data characters cannot be 1 more than a multiple of 4"
Solution: Already handled in image-processing server - strips whitespace and adds padding
Verification:
# Ensure your base64 string is clean
image_data = image_data.strip().replace('\n', '').replace('\r', '').replace(' ', '')
padding_needed = len(image_data) % 4
if padding_needed:
image_data += '=' * (4 - padding_needed)
3. DynamoDB Float Type Error
Symptoms: "Float types are not supported. Use Decimal types instead."
Solution: Remove default float values from tool schemas
Wrong:
{
"intensity": {
"type": "number",
"default": 1.0 // ❌ This causes error
}
}
Correct:
{
"intensity": {
"type": "number",
"description": "Intensity value (default: 1.0)" // ✅ Document in description
}
}
4. Docker Build Failures
Symptoms: Permission denied, unable to connect to Docker daemon
Solutions:
- Start Docker Desktop
- Run as administrator (Windows)
- Add user to docker group (Linux):
sudo usermod -aG docker $USER
5. ECR Push Authentication
Symptoms: "no basic auth credentials"
Solution:
# Re-authenticate with ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
[account-id].dkr.ecr.us-east-1.amazonaws.com
6. S3 Access Denied
Symptoms: S3 upload fails with 403 Forbidden
Solution: Update Lambda execution role with S3 permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
📊 Performance Optimization
Lambda Configuration
| Server | Memory | Timeout | Concurrent Executions |
|---|---|---|---|
| Data Transformation | 512 MB | 60s | 100 |
| Image Processing | 1024 MB | 120s | 50 |
| Node.js Execution | 512 MB | 60s | 100 |
| Jupyter | 1024 MB | 900s | 10 |
Cold Start Mitigation
-
Provisioned Concurrency: Keep Lambda instances warm
aws lambda put-provisioned-concurrency-config \ --function-name [function-name] \ --provisioned-concurrent-executions 2 \ --region us-east-1 -
Keep-Alive Pings: Send periodic requests to prevent cold starts
-
Optimize Docker Images:
- Use multi-stage builds
- Minimize image size
- Pre-compile Python bytecode
S3 Optimization
- Presigned URL Expiry: Default 24 hours (86400 seconds)
- Lifecycle Policies: Auto-delete temporary files after 7 days
- Transfer Acceleration: Enable for faster uploads (optional)
🔒 Security Best Practices
Lambda Security
-
Least Privilege IAM Roles: Only grant necessary permissions
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject" ], "Resource": "arn:aws:s3:::your-bucket/*" } ] } -
VPC Configuration: Deploy Lambda in VPC for internal resources
-
Environment Variables: Use AWS Secrets Manager for sensitive data
-
Function URLs: Enable IAM authentication if needed (currently using NONE for Amplify integration)
Input Validation
All servers implement input validation:
- Type checking: Ensures parameters match expected types
- Size limits: Prevents memory exhaustion
- Timeout enforcement: Prevents infinite execution
- Sanitization: Cleans user input before processing
Code Execution Safety
Node.js Execution Server:
- Runs in isolated VM context
- No filesystem access
- No network access from executed code
- 30-second maximum timeout
Jupyter Server:
- Kernel isolation per notebook
- Package installation limited to pip
- Execution timeout enforced
- S3-only file persistence
📈 Monitoring & Logging
CloudWatch Logs
Each Lambda function logs to CloudWatch:
# Tail logs in real-time
aws logs tail /aws/lambda/[function-name] --follow
# Filter errors
aws logs filter-log-events \
--log-group-name /aws/lambda/[function-name] \
--filter-pattern "ERROR"
# Get specific time range
aws logs filter-log-events \
--log-group-name /aws/lambda/[function-name] \
--start-time $(date -d '1 hour ago' +%s)000
Metrics to Monitor
- Invocations: Number of requests
- Duration: Execution time (optimize if consistently high)
- Errors: Failed executions (investigate immediately)
- Throttles: Rate limiting (increase concurrent executions)
- Cold Starts: Initial invocation delays (consider provisioned concurrency)
CloudWatch Alarms
Set up alarms for critical metrics:
aws cloudwatch put-metric-alarm \
--alarm-name "[function-name]-errors" \
--alarm-description "Alert on Lambda errors" \
--metric-name Errors \
--namespace AWS/Lambda \
--statistic Sum \
--period 300 \
--evaluation-periods 1 \
--threshold 5 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=FunctionName,Value=[function-name]
🧪 Testing
Local Testing
Each server includes test files. Run locally before deploying:
# Data Transformation
cd servers/data-transformation
python3 -c "from data_mcp_server.server import handle_tools_call; print(handle_tools_call({'name': 'csv_to_json', 'arguments': {'csv_data': 'a,b\n1,2'}}))"
# Image Processing
cd servers/image-processing
python3 -c "from image_mcp_server.image_manager import ImageManager; print('✓ ImageManager imports')"
# Node.js Execution
cd servers/nodejs-execution
python3 -c "from nodejs_mcp_server.server import handle_tools_call; print(handle_tools_call({'name': 'execute_javascript', 'arguments': {'code': '2+2'}}))"
# Jupyter
cd servers/jupyter
python3 -c "from jupyter_mcp_server.kernel_manager import KernelManager; print('✓ KernelManager imports')"
Lambda Testing
After deployment, test via AWS Console:
- Go to Lambda → Functions → [your-function]
- Click "Test" tab
- Create test event:
{ "body": "{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"csv_to_json\",\"arguments\":{\"csv_data\":\"a,b\\n1,2\"}},\"id\":1}" } - Execute and check response
Integration Testing
Test via Amplify frontend:
- Ensure tool is registered in DynamoDB
- Refresh Amplify app to load tools
- Use LLM to invoke tool naturally
- Verify results in UI
🚢 Deployment Scripts Reference
deploy-lambda-ecr.sh
Purpose: Deploy Lambda function using ECR container image
Usage:
./deploy-lambda-ecr.sh
What it does:
- Checks if Lambda function exists
- If exists: Updates function code with latest ECR image
- If not: Creates new function with:
- Container image from ECR
- 512 MB memory (configurable)
- 60-second timeout (configurable)
- IAM role with necessary permissions
- Function URL with CORS enabled
Environment Variables:
AWS_REGION: AWS region (default: us-east-1)S3_BUCKET: S3 bucket name (optional)
push-to-ecr.sh
Purpose: Push Docker image to AWS ECR
Usage:
./push-to-ecr.sh
What it does:
- Gets AWS account ID
- Authenticates Docker with ECR
- Tags image with ECR repository URL
- Pushes image to ECR
Full Deployment Example
# 1. Navigate to server directory
cd servers/image-processing
# 2. Build Docker image
docker build --platform linux/amd64 -t image-processing-mcp-server -f Dockerfile.lambda .
# 3. Create ECR repository (first time only)
aws ecr create-repository \
--repository-name image-processing-mcp-server \
--region us-east-1
# 4. Push to ECR
./push-to-ecr.sh
# 5. Deploy Lambda
./deploy-lambda-ecr.sh
# 6. Get Function URL
aws lambda get-function-url-config \
--function-name image-processing-mcp-lambda \
--region us-east-1 \
--query 'FunctionUrl' \
--output text
# 7. Test the function
curl -X POST [function-url] \
-H "Content-Type: application/json" \
-d '{"body":"{\"jsonrpc\":\"2.0\",\"method\":\"tools/list\",\"id\":1}"}'
📝 Example Use Cases
1. Data Analysis Pipeline
Scenario: User uploads CSV, transforms to JSON, analyzes with Jupyter, visualizes results
Flow:
- User: "Analyze this sales data: [pastes CSV]"
- LLM uses
csv_to_jsontool - LLM uses
create_notebooktool - LLM uses
execute_cellwith pandas analysis - LLM uses
execute_cellwith matplotlib visualization - User sees chart and insights
2. Image Batch Processing
Scenario: User needs to resize and watermark 10 product images
Flow:
- User: "Resize these product images to 800x600 and apply a blur filter"
- LLM iterates over images using
resize_imagetool - LLM applies
apply_filtertool with blur - User receives S3 download links for all processed images
3. Code Execution and Testing
Scenario: User wants to test a JavaScript algorithm
Flow:
- User: "Test this sorting algorithm with sample data"
- LLM uses
execute_javascripttool with algorithm code - LLM analyzes output
- User sees results and performance metrics
4. Interactive Data Science
Scenario: User explores machine learning model performance
Flow:
- User: "Train a simple neural network on MNIST data"
- LLM uses
create_notebooktool - LLM uses
install_packagefor TensorFlow - LLM uses
upload_filefor dataset - LLM uses
execute_cellfor training code - LLM uses
execute_cellfor visualization - User sees training curves and accuracy metrics
🔄 Updating Deployed Functions
Code Changes
- Modify source code in server directory
- Rebuild Docker image:
docker build --platform linux/amd64 -t [server-name] -f Dockerfile.lambda . - Push to ECR:
./push-to-ecr.sh - Update Lambda:
aws lambda update-function-code \ --function-name [function-name] \ --image-uri [account-id].dkr.ecr.us-east-1.amazonaws.com/[server-name]:latest
Configuration Changes
Update Lambda function configuration:
# Increase memory
aws lambda update-function-configuration \
--function-name [function-name] \
--memory-size 1024
# Increase timeout
aws lambda update-function-configuration \
--function-name [function-name] \
--timeout 120
# Add environment variables
aws lambda update-function-configuration \
--function-name [function-name] \
--environment "Variables={S3_BUCKET=my-bucket,DEBUG=true}"
Rollback to Previous Version
# List versions
aws lambda list-versions-by-function --function-name [function-name]
# Rollback using image digest
aws lambda update-function-code \
--function-name [function-name] \
--image-uri [account-id].dkr.ecr.us-east-1.amazonaws.com/[server-name]@sha256:[digest]
🛠️ Development Guide
Adding a New Tool
-
Define tool schema in
TOOLSarray:{ "name": "my_new_tool", "description": "What it does", "inputSchema": { "type": "object", "properties": { "param1": {"type": "string"} }, "required": ["param1"] } } -
Implement handler in
handle_tools_call():elif tool_name == "my_new_tool": result = manager.my_new_method( arguments.get("param1") ) -
Implement method in manager class:
def my_new_method(self, param1: str) -> Dict[str, Any]: try: # Your logic here return { "success": True, "output": "Result description", "data": result_data } except Exception as e: return {"success": False, "error": str(e)} -
Test locally before deploying
-
Deploy using standard deployment process
Creating a New MCP Server
-
Create directory structure:
servers/my-new-server/ ├── my_mcp_server/ │ ├── __init__.py │ ├── server.py │ └── manager.py ├── Dockerfile.lambda ├── lambda_handler.py ├── pyproject.toml ├── deploy-lambda-ecr.sh └── push-to-ecr.sh -
Implement MCP protocol in
server.py:- Handle
tools/listmethod - Handle
tools/callmethod - Return proper JSON-RPC 2.0 responses
- Handle
-
Create Lambda handler in
lambda_handler.py:from my_mcp_server import server def lambda_handler(event, context): return server.handle_lambda(event) -
Define Dockerfile:
FROM public.ecr.aws/lambda/python:3.12 COPY requirements.txt . RUN pip install -r requirements.txt COPY my_mcp_server ${LAMBDA_TASK_ROOT}/my_mcp_server COPY lambda_handler.py ${LAMBDA_TASK_ROOT} CMD ["lambda_handler.lambda_handler"] -
Create deployment scripts (copy from existing servers)
-
Test and deploy following standard process
📚 Additional Resources
MCP Protocol
AWS Documentation
Python Libraries
- Pillow (PIL) - Image processing
- Pandas - Data manipulation
- Jupyter Client - Kernel management
- Beautiful Soup - XML/HTML parsing
🤝 Contributing
This repository contains example implementations. To contribute:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request with detailed description
Guidelines
- Follow existing code structure and naming conventions
- Add comprehensive documentation for new tools
- Include deployment scripts for new servers
- Test both locally and on AWS Lambda
- Update this README with any new features or changes
📄 License
MIT License - See individual server directories for specific licensing information.
🆘 Support
For issues and questions:
- Check Troubleshooting Section: Most common issues covered above
- Review CloudWatch Logs: Detailed error information
- Test Locally: Isolate Lambda-specific vs code issues
- AWS Support: For infrastructure issues
🎯 Summary
This repository provides example MCP server templates for Amplify integration:
✅ 4 Complete Example Servers: Data Transformation, Image Processing, Node.js Execution, Jupyter ✅ AWS Lambda Deployment: Containerized, scalable, serverless architecture ✅ S3 Integration: Large file handling with presigned URLs ✅ Comprehensive Documentation: Deployment, usage, troubleshooting, customization ideas ✅ Extensible Foundation: Add authentication, user isolation, custom features, and more ✅ Production-Ready Architecture: Handles edge cases, errors, and performance optimization
Remember: These are starting templates! Extend them with your own security layers, user-specific storage, custom business logic, and production features to meet your specific requirements.
Quick Start: Pick a server, run ./deploy-lambda-ecr.sh, get the Function URL, add to Amplify DynamoDB config, customize as needed, and start using powerful LLM tools!
📄 License & Disclaimer
License: MIT License - See individual server directories for specific licensing information.
Disclaimer: These MCP servers are provided as educational examples and starting templates. They are functional demonstrations but not hardened for production use without additional security, monitoring, and customization. Users are responsible for implementing appropriate security measures, compliance requirements, and production best practices before deploying to production environments.
Use at your own risk: Always review, test, and secure the code according to your organization's requirements and industry standards before deploying to production.