Skip to main content
Glama

aws-pricing-mcp

LAMBDA.md19.6 kB
# AWS Pricing MCP Lambda Handler This document provides comprehensive documentation for the AWS Pricing MCP Lambda handler implementation, including deployment, usage, and technical details. ## Table of Contents 1. [Overview](#overview) 2. [Quick Start](#quick-start) 3. [Architecture](#architecture) 4. [Usage](#usage) 5. [Deployment](#deployment) 6. [Configuration](#configuration) 7. [Testing](#testing) 8. [Monitoring](#monitoring) 9. [Troubleshooting](#troubleshooting) 10. [Implementation Details](#implementation-details) 11. [Performance](#performance) 12. [Security](#security) 13. [Future Enhancements](#future-enhancements) ## Overview The Lambda handler implements the Model Context Protocol (MCP) specification as described in the `MCP.md` file, providing a serverless way to access AWS EC2 pricing data through JSON-RPC 2.0 requests. The function automatically downloads the latest pricing data from S3 and caches it for optimal performance. It's deployed using AWS SAM with a Function URL for direct HTTP access. ### Key Features - **JSON-RPC 2.0**: Full compliance with JSON-RPC 2.0 specification - **Dynamic Pricing Data**: Downloads latest pricing data from S3 at runtime - **HTTP Function URL**: Direct HTTP access with no authentication required - **CORS Support**: Full CORS headers for web browser access - **Caching**: Intelligent caching for optimal performance - **Error Handling**: Comprehensive error handling and validation - **No Dependencies**: Uses only Python standard library modules ## Quick Start ### Prerequisites 1. **AWS CLI** installed and configured 2. **AWS SAM CLI** installed 3. **Python 3.9+** installed 4. **AWS Account** with appropriate permissions ### Install Prerequisites ```bash # Install AWS CLI curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install # Install AWS SAM CLI pip install aws-sam-cli # Configure AWS CLI aws configure ``` ### Deploy the Function ```bash # From the project root directory sam build sam deploy --guided ``` The guided deployment will prompt for configuration values. Use the defaults or customize as needed. ### Get the Function URL After deployment, get the Function URL: ```bash aws cloudformation describe-stacks \ --stack-name aws-pricing-mcp \ --query 'Stacks[0].Outputs[?OutputKey==`InvokeUrl`].OutputValue' \ --output text ``` ### Test the Function ```bash # Test with curl curl -X POST YOUR_FUNCTION_URL \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": { "name": "TestClient", "version": "1.0.0" } } }' ``` ## Architecture ### Components 1. **Lambda Function**: Processes MCP protocol requests 2. **Function URL**: Provides HTTP access without authentication 3. **IAM Role**: Provides execution permissions 4. **CloudWatch Logs**: Stores function logs ### Request/Response Flow ``` Client Request (JSON-RPC 2.0) ↓ Lambda Handler (lambda_handler function) ↓ Method Router (based on "method" field) ↓ Specific Handler Function ↓ JSON-RPC 2.0 Response ``` ### Function URL Features - **No Authentication**: Public access - **CORS Enabled**: Web browser compatible - **HTTP Methods**: GET, POST, OPTIONS - **Direct Access**: No API Gateway required ## Usage ### Local Testing ```bash cd src/lambda python test_lambda.py ``` ### HTTP API Usage Once deployed, the function is accessible via HTTP POST requests: ```bash # Get the Function URL from SAM outputs FUNCTION_URL=$(aws cloudformation describe-stacks --stack-name aws-pricing-mcp --query 'Stacks[0].Outputs[?OutputKey==`InvokeUrl`].OutputValue' --output text) # Test the function curl -X POST $FUNCTION_URL \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": { "name": "TestClient", "version": "1.0.0" } } }' ``` ### Supported MCP Methods | Method | Handler Function | Status | |--------|------------------|--------| | `initialize` | `handle_initialize()` | ✅ Implemented | | `ping` | `handle_ping()` | ✅ Implemented | | `tools/list` | `handle_tools_list()` | ✅ Implemented | | `tools/call` | `handle_tools_call()` | ✅ Implemented | | `resources/list` | `handle_resources_list()` | ✅ Empty implementation | | `resources/read` | `handle_resources_read()` | ✅ Empty implementation | | `prompts/list` | `handle_prompts_list()` | ✅ Empty implementation | | `prompts/get` | `handle_prompts_get()` | ✅ Empty implementation | ### Sample MCP Requests #### Initialize ```json { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": { "name": "TestClient", "version": "1.0.0" } } } ``` #### Get Tools List ```json { "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} } ``` #### Call EC2 Pricing Tool ```json { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "ec2_instances_pricing", "arguments": { "filter_region": "us-east-1", "filter_platform": "Linux/UNIX", "filter_min_vcpu": 2, "filter_min_ram": 4.0, "filter_max_price_per_hour": 0.1, "sort_by": "Price", "sort_order": "Ascending" } } } ``` ### EC2 Pricing Tool The main tool provided is `ec2_instances_pricing` which allows filtering and searching EC2 instances based on: - **Region**: AWS region (default: us-east-1) - **Platform**: OS platform (Linux/UNIX, Windows, Red Hat, etc.) - **Tenancy**: Shared or Dedicated - **Pricing Model**: On Demand, Reserved Instances, etc. - **Specifications**: vCPU, RAM, GPU, network performance, etc. - **Cost**: Maximum price per hour - **Sorting**: By price, specifications, etc. - **Pagination**: 5 results per page ## Deployment ### SAM Template Parameters The `template.yaml` file supports the following parameters: | Parameter | Default | Description | |-----------|---------|-------------| | `FunctionName` | `aws-pricing-mcp` | Name of the Lambda function | | `Runtime` | `python3.12` | Python runtime version | | `Architecture` | `x86_64` | Lambda function architecture (x86_64 or arm64) | | `Timeout` | `30` | Function timeout in seconds | | `MemorySize` | `512` | Function memory size in MB | ### Custom Deployment ```bash # Deploy with custom parameters sam deploy \ --stack-name my-pricing-mcp \ --parameter-overrides \ FunctionName=my-pricing-function \ Runtime=python3.12 \ Architecture=arm64 \ Timeout=60 \ MemorySize=1024 ``` ### SAM Template The deployment uses `template.yaml` in the project root which defines: - Lambda function with Function URL - IAM roles and policies - CORS configuration - Output values for Function URL ## Configuration ### Lambda Function Settings - **Runtime**: Python 3.12 - **Handler**: `lambda_handler.lambda_handler` - **Timeout**: 30 seconds (configurable) - **Memory**: 512 MB (increased for pricing data processing) - **Architecture**: x86_64 or arm64 (configurable) ### Environment Variables No environment variables are required. ### IAM Permissions The Lambda function requires: - **CloudWatch Logs** for logging - **Internet access** to download pricing data from S3 - **Basic execution permissions** ### Pricing Data Configuration - **Download URL**: https://cloudfix-public-aws-pricing.s3.us-east-1.amazonaws.com/pricing/ec2_pricing.json.gz - **Cache Location**: In-memory (global variable) - **Cache Duration**: 1 hour (3600 seconds) - **Compression**: Gzip compressed JSON (decompressed in memory) ### Function URL Configuration - **Auth Type**: NONE (no authentication required) - **CORS**: Enabled for all origins - **Methods**: GET, POST, OPTIONS - **Headers**: All headers allowed ## Testing The `test_lambda.py` script provides comprehensive testing of all MCP methods with sample requests and expected responses. ### Testing Results The test script successfully validates: 1. **Initialize**: Returns proper MCP capabilities and server info 2. **Tools List**: Returns complete tool schema with all parameters 3. **Tools Call**: Successfully executes pricing queries and returns results 4. **Ping**: Returns empty result (health check) 5. **Error Handling**: Properly handles invalid methods Sample successful query returned 5 EC2 instances matching criteria: - t4g.medium ($0.0336/hour) - t3a.medium ($0.0376/hour) - t3.medium ($0.0416/hour) - t2.medium ($0.0464/hour) - a1.large ($0.051/hour) ## Monitoring ### CloudWatch Logs ```bash # View function logs aws logs tail /aws/lambda/aws-pricing-mcp --follow ``` ### CloudWatch Metrics Monitor key metrics: - **Invocations**: Number of function calls - **Duration**: Function execution time - **Errors**: Number of errors - **Throttles**: Number of throttled requests ### Custom Metrics The function logs important events: - Pricing data download attempts - Cache hits/misses - Error conditions ### Key Metrics to Monitor - **Download Success Rate**: Percentage of successful pricing data downloads - **Cache Hit Rate**: Percentage of requests using cached data - **Response Time**: Time to process requests - **Error Rate**: Percentage of failed requests - **HTTP Status Codes**: Monitor 4xx and 5xx errors ## Troubleshooting ### Common Issues 1. **Deployment Fails** ```bash # Check SAM build sam build --debug # Check CloudFormation events aws cloudformation describe-stack-events --stack-name aws-pricing-mcp ``` 2. **Function URL Not Working** ```bash # Verify Function URL exists aws lambda get-function-url-config --function-name aws-pricing-mcp # Test with curl curl -v YOUR_FUNCTION_URL ``` 3. **Pricing Data Download Fails** ```bash # Check function logs aws logs tail /aws/lambda/aws-pricing-mcp --since 1h # Verify internet access # Ensure Lambda is not in a private VPC without NAT Gateway ``` 4. **CORS Issues** - Verify CORS headers in function response - Check browser console for CORS errors - Ensure preflight OPTIONS requests are handled ### Debugging Tips - Check CloudWatch logs for detailed error messages - Monitor pricing data download events - Verify cache file existence and size - Test with simple requests first - Use curl or Postman to test HTTP endpoints ## Implementation Details ### Protocol Implementation **Original Server (fastmcp-based):** - Uses `fastmcp` library for MCP protocol handling - HTTP/SSE-based communication - Stateful server with session management - Complex dependency management **Lambda Handler (standard library):** - Manual JSON-RPC 2.0 implementation - Stateless request handling - Direct method routing - No external dependencies ### Lambda Handler Function The `lambda_handler` function is the entry point that: 1. Handles HTTP requests from Function URL 2. Parses incoming JSON-RPC requests 3. Validates request format 4. Routes to appropriate handler based on method 5. Returns HTTP response with JSON-RPC response ### Handler Functions Each MCP method has a dedicated handler function: - `handle_initialize()` - Protocol initialization - `handle_tools_list()` - Tool discovery - `handle_tools_call()` - Tool execution - `handle_ping()` - Health check - etc. ### Pricing Data Management The pricing data is managed through: - `download_and_cache_pricing_data()` - Downloads and caches pricing data in memory - **Source**: https://cloudfix-public-aws-pricing.s3.us-east-1.amazonaws.com/pricing/ec2_pricing.json.gz - **Cache Location**: In-memory global variable - **Cache Duration**: 1 hour (3600 seconds) - **Fallback**: Uses cached data if download fails ### Pricing Logic The `ec2_instances_pricing()` function contains the core pricing logic: - Ensures pricing data is loaded (downloads if needed) - Applies filters based on parameters - Calculates pricing for different models - Sorts and paginates results ### Error Handling **JSON-RPC Error Codes:** - `-32700`: Parse error (invalid JSON) - `-32600`: Invalid request (wrong jsonrpc version) - `-32601`: Method not found - `-32603`: Internal error **Validation:** - Input parameter validation - Platform/tenancy/pricing model validation - Graceful handling of missing pricing data ### Dependencies The Lambda handler uses only Python standard library modules: - `json` - JSON parsing and serialization - `os` - File system operations - `sys` - System-specific parameters - `traceback` - Exception handling - `typing` - Type hints - `datetime` - Date/time operations - `gzip` - Gzip file decompression - `urllib.request` - HTTP downloads - `time` - Time-based operations - `pathlib` - Path operations No external dependencies are required, making deployment simple and lightweight. ## Performance ### Lambda Configuration - **Cold Start**: ~100-500ms (first request, includes data download) - **Warm Start**: ~10-50ms (subsequent requests use cached data) - **Memory Usage**: ~100-200 MB for pricing data in memory - **Concurrency**: Handles multiple concurrent requests ### Caching Strategy - **Cache Duration**: 1 hour balances freshness with performance - **Cache Location**: In-memory global variable - **Cache Size**: ~100MB uncompressed in memory - **Cache Hit Rate**: High for typical usage patterns ### Network Considerations - **Download Time**: ~2-5 seconds for initial data download - **Retry Logic**: Falls back to cached data if download fails - **Bandwidth**: ~25MB download per cache refresh ### HTTP Performance - **Function URL**: Direct HTTP access without API Gateway - **CORS**: Pre-configured for web browser access - **Response Time**: Fast JSON-RPC responses ### Performance Characteristics #### Download Performance - **Download Time**: ~2-5 seconds for initial download - **Decompression**: ~1-2 seconds for gzip extraction - **File Size**: ~25MB compressed, ~100MB uncompressed - **Network**: Requires internet access from Lambda #### Caching Performance - **Cache Hit**: ~10-50ms response time - **Cache Miss**: ~3-7 seconds (includes download) - **Memory Usage**: ~100-200 MB for pricing data - **Storage**: ~100MB in memory ## Security ### Function URL Security - **No Authentication**: Function URL is publicly accessible - **CORS**: Configured for all origins (customize as needed) - **Rate Limiting**: Consider adding rate limiting for production use ### IAM Permissions The function uses minimal IAM permissions: - CloudWatch Logs access - Basic Lambda execution permissions - No additional AWS service access required ### Network Security - **Internet Access**: Required for pricing data download - **VPC**: If using VPC, ensure NAT Gateway for internet access - **Security Groups**: Allow outbound HTTPS traffic ## Cost Optimization ### Lambda Costs - **Memory**: 512 MB (adjust based on usage) - **Timeout**: 30 seconds (sufficient for most requests) - **Concurrency**: Auto-scaling based on demand ### Optimization Tips 1. **Memory Tuning**: Monitor memory usage and adjust 2. **Timeout Tuning**: Set appropriate timeout values 3. **Caching**: Function caches pricing data for 1 hour 4. **Concurrency**: Monitor and adjust if needed ## Updates and Maintenance ### Updating the Function ```bash # Deploy updates sam build sam deploy ``` ### Updating Configuration ```bash # Update parameters sam deploy --parameter-overrides Timeout=60 MemorySize=1024 ``` ### Monitoring Updates - Monitor pricing data freshness - Check for new AWS instance types - Review CloudWatch metrics regularly ## Production Considerations ### High Availability - **Multi-Region**: Deploy to multiple regions if needed - **Backup**: Consider backup strategies for critical data - **Monitoring**: Set up comprehensive monitoring and alerting ### Performance - **Caching**: Function caches pricing data for optimal performance - **Cold Starts**: Consider provisioned concurrency for consistent performance - **Memory**: Monitor and optimize memory usage ### Security - **Authentication**: Consider adding authentication for production use - **Rate Limiting**: Implement rate limiting to prevent abuse - **Monitoring**: Set up security monitoring and alerting ## Future Enhancements ### Potential Improvements 1. **Multi-Region Support**: Download pricing data for multiple regions 2. **Incremental Updates**: Only download changed pricing data 3. **Compression**: Use more efficient compression formats 4. **CDN Integration**: Use CloudFront for faster downloads 5. **Background Updates**: Update cache in background threads 6. **API Gateway**: Add API Gateway for additional features 7. **Custom Domain**: Use custom domain with Function URL ### Monitoring Enhancements 1. **Custom Metrics**: Track download performance and cache efficiency 2. **Alerts**: Set up CloudWatch alarms for download failures 3. **Dashboard**: Create comprehensive monitoring dashboard 4. **Health Checks**: Implement pricing data freshness checks 5. **Performance Monitoring**: Track HTTP response times ## Support For issues and questions: 1. Check CloudWatch Logs for error details 2. Review this documentation 3. Check AWS Lambda documentation 4. Review SAM documentation ## Cleanup To remove the deployment: ```bash sam delete ``` This will remove: - Lambda function - Function URL - IAM role - CloudWatch log group - All associated resources ## File Structure ``` src/lambda/ ├── __init__.py # Package initialization ├── lambda_handler.py # Main Lambda handler ├── test_lambda.py # Test script ├── test_event.json # Test event for local testing ├── requirements.txt # Dependencies (empty) └── README.md # Documentation (merged into this file) ``` ## Migration Path ### From Original Server 1. **Replace fastmcp calls** with direct JSON-RPC handling 2. **Update deployment** to use Lambda instead of HTTP server 3. **Modify client code** to call Lambda function instead of HTTP endpoint 4. **Update monitoring** to use CloudWatch instead of server logs ### Client Integration ```python # Example client code import boto3 import json lambda_client = boto3.client('lambda') def call_mcp_server(method, params=None): request = { "jsonrpc": "2.0", "id": 1, "method": method, "params": params or {} } response = lambda_client.invoke( FunctionName='aws-pricing-mcp', Payload=json.dumps(request) ) return json.loads(response['Payload'].read()) ``` ## Conclusion The Lambda handler implementation successfully provides the same functionality as the original fastmcp-based server while offering significant advantages in terms of deployment simplicity, cost-effectiveness, and scalability. The implementation is production-ready and can be deployed immediately to AWS Lambda. The dynamic pricing data download implementation provides significant benefits: - **Always up-to-date pricing data** - **Reduced deployment complexity** - **Improved reliability and error handling** - **Better performance through intelligent caching** - **Simplified maintenance and updates** The implementation is production-ready and provides a robust foundation for serving current AWS EC2 pricing data through the MCP protocol.

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/trilogy-group/aws-pricing-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server