A remote HTTP Model Context Protocol (MCP) server that provides access to AWS services including DynamoDB and S3. This server now uses the official MCP SDK for JSON-RPC handling and exposes prompts, resources, and tools via both JSON-RPC and legacy HTTP endpoints with bearer token authentication.
- POST /mcp: Primary JSON-RPC endpoint using MCP SDK for all operations
- Supports all MCP operations: prompts, resources, and tools
- Proper JSON-RPC 2.0 protocol compliance
- Batch request support
- GET /: Server information and capabilities
- GET /health: Health check endpoint
- GET /mcp/prompts: List available prompts (deprecated)
- POST /mcp/prompts/:name: Get specific prompt content (deprecated)
- GET /mcp/resources: List S3 resources (deprecated, requires auth)
- GET /mcp/resources/*: Read specific S3 resource (deprecated, requires auth)
- GET /mcp/tools: List available tools (deprecated)
- POST /mcp/tools/:name: Execute specific tool (deprecated, requires auth)
- Uses Bearer token authentication
- AWS_SECRET_ACCESS_KEY is passed via
Authorization: Bearer <secret_key>
header - Other AWS credentials are configured via environment variables
- analyze-data: Analyze data from DynamoDB and S3 resources
- data-summary: Generate a summary of available data sources
- S3 Objects: Access and read objects from your S3 bucket
- Automatic MIME type detection
- Object metadata (size, last modified)
- dynamodb-get: Get an item by key
- dynamodb-put: Store an item
- dynamodb-delete: Delete an item by key
- dynamodb-query: Query items with conditions
- s3-get: Download object content
- s3-put: Upload object content
- s3-delete: Delete an object
- s3-move: Move/rename an object
Set the following environment variables on your Val Town:
AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=your-access-key-id S3_BUCKET=your-bucket-name DYNAMODB_TABLE=your-table-name MCP_SERVER_NAME=aws-mcp-server MCP_SERVER_VERSION=1.0.0
Note: AWS_SECRET_ACCESS_KEY
is NOT set as an environment variable. Instead, it's passed via the Authorization header for security.
- Deploy to Val Town as an HTTP val
- Set the required environment variables
- The server will be available at your Val Town URL
All authenticated endpoints require the Authorization header:
Authorization: Bearer your-aws-secret-access-key
curl https://your-val-town-url.web.val.run/
curl https://your-val-town-url.web.val.run/mcp/prompts
curl -X POST https://your-val-town-url.web.val.run/mcp/prompts/analyze-data \ -H "Content-Type: application/json" \ -d '{"table_key": "user123", "s3_key": "data/analytics.json"}'
curl https://your-val-town-url.web.val.run/mcp/resources \ -H "Authorization: Bearer your-aws-secret-access-key"
curl "https://your-val-town-url.web.val.run/mcp/resources/s3://your-bucket/path/to/file.txt" \ -H "Authorization: Bearer your-aws-secret-access-key"
curl https://your-val-town-url.web.val.run/mcp/tools
# Get an item curl -X POST https://your-val-town-url.web.val.run/mcp/tools/dynamodb-get \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"key": {"id": "user123"}}' # Put an item curl -X POST https://your-val-town-url.web.val.run/mcp/tools/dynamodb-put \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"item": {"id": "user123", "name": "John Doe", "email": "john@example.com"}}' # Query items curl -X POST https://your-val-town-url.web.val.run/mcp/tools/dynamodb-query \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"keyConditionExpression": "id = :id", "expressionAttributeValues": {":id": "user123"}}' # Delete an item curl -X POST https://your-val-town-url.web.val.run/mcp/tools/dynamodb-delete \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"key": {"id": "user123"}}'
# Get object content curl -X POST https://your-val-town-url.web.val.run/mcp/tools/s3-get \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"key": "documents/report.txt"}' # Upload content curl -X POST https://your-val-town-url.web.val.run/mcp/tools/s3-put \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"key": "documents/new-file.txt", "content": "Hello, World!", "contentType": "text/plain"}' # Move/rename object curl -X POST https://your-val-town-url.web.val.run/mcp/tools/s3-move \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"sourceKey": "old-location/file.txt", "destinationKey": "new-location/file.txt"}' # Delete object curl -X POST https://your-val-town-url.web.val.run/mcp/tools/s3-delete \ -H "Authorization: Bearer your-aws-secret-access-key" \ -H "Content-Type: application/json" \ -d '{"key": "documents/old-file.txt"}'
To integrate with MCP clients like Claude Desktop, you can create a client that makes HTTP requests to these endpoints. Here's an example configuration:
{ "mcpServers": { "aws-http-mcp-server": { "command": "node", "args": ["mcp-http-client.js"], "env": { "MCP_SERVER_URL": "https://your-val-town-url.web.val.run", "AWS_SECRET_ACCESS_KEY": "${AWS_SECRET_ACCESS_KEY}" } } } }
- Bearer Token Authentication: AWS_SECRET_ACCESS_KEY is passed via Authorization header, not stored in environment variables
- HTTPS Only: Always use HTTPS in production to protect the bearer token
- IAM Permissions: Use IAM roles with minimal required permissions
- Token Rotation: Regularly rotate your AWS secret access keys
- Rate Limiting: Consider implementing rate limiting for production use
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*" ] } ] }
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:Query", "dynamodb:Scan" ], "Resource": "arn:aws:dynamodb:region:account:table/your-table-name" } ] }
The server includes comprehensive error handling for:
- Missing or invalid Authorization headers
- AWS service errors
- Invalid parameters
- Network connectivity issues
All errors are properly formatted and returned as JSON with appropriate HTTP status codes:
401
: Authentication errors400
: Bad request (invalid parameters)404
: Resource or tool not found500
: Server errors (AWS service errors, etc.)
{ "content": [ { "type": "text", "text": "Response content here" } ] }
{ "error": "Error message description" }
The server provides a health check endpoint:
curl https://your-val-town-url.web.val.run/health
Response:
{ "status": "healthy", "timestamp": "2024-01-01T00:00:00.000Z" }