awslabs.elasticache-mcp-server 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. awslabs/__init__.py +16 -0
  2. awslabs/elasticache_mcp_server/__init__.py +17 -0
  3. awslabs/elasticache_mcp_server/common/__init__.py +15 -0
  4. awslabs/elasticache_mcp_server/common/connection.py +117 -0
  5. awslabs/elasticache_mcp_server/common/decorators.py +41 -0
  6. awslabs/elasticache_mcp_server/common/server.py +30 -0
  7. awslabs/elasticache_mcp_server/context.py +39 -0
  8. awslabs/elasticache_mcp_server/main.py +52 -0
  9. awslabs/elasticache_mcp_server/tools/__init__.py +15 -0
  10. awslabs/elasticache_mcp_server/tools/cc/__init__.py +31 -0
  11. awslabs/elasticache_mcp_server/tools/cc/connect.py +444 -0
  12. awslabs/elasticache_mcp_server/tools/cc/create.py +212 -0
  13. awslabs/elasticache_mcp_server/tools/cc/delete.py +65 -0
  14. awslabs/elasticache_mcp_server/tools/cc/describe.py +80 -0
  15. awslabs/elasticache_mcp_server/tools/cc/modify.py +159 -0
  16. awslabs/elasticache_mcp_server/tools/cc/parsers.py +78 -0
  17. awslabs/elasticache_mcp_server/tools/cc/processors.py +74 -0
  18. awslabs/elasticache_mcp_server/tools/ce/__init__.py +19 -0
  19. awslabs/elasticache_mcp_server/tools/ce/get_cost_and_usage.py +76 -0
  20. awslabs/elasticache_mcp_server/tools/cw/__init__.py +19 -0
  21. awslabs/elasticache_mcp_server/tools/cw/get_metric_statistics.py +85 -0
  22. awslabs/elasticache_mcp_server/tools/cwlogs/__init__.py +29 -0
  23. awslabs/elasticache_mcp_server/tools/cwlogs/create_log_group.py +68 -0
  24. awslabs/elasticache_mcp_server/tools/cwlogs/describe_log_groups.py +123 -0
  25. awslabs/elasticache_mcp_server/tools/cwlogs/describe_log_streams.py +120 -0
  26. awslabs/elasticache_mcp_server/tools/cwlogs/filter_log_events.py +122 -0
  27. awslabs/elasticache_mcp_server/tools/cwlogs/get_log_events.py +99 -0
  28. awslabs/elasticache_mcp_server/tools/firehose/__init__.py +19 -0
  29. awslabs/elasticache_mcp_server/tools/firehose/list_delivery_streams.py +63 -0
  30. awslabs/elasticache_mcp_server/tools/misc/__init__.py +31 -0
  31. awslabs/elasticache_mcp_server/tools/misc/batch_apply_update_action.py +62 -0
  32. awslabs/elasticache_mcp_server/tools/misc/batch_stop_update_action.py +62 -0
  33. awslabs/elasticache_mcp_server/tools/misc/describe_cache_engine_versions.py +79 -0
  34. awslabs/elasticache_mcp_server/tools/misc/describe_engine_default_parameters.py +64 -0
  35. awslabs/elasticache_mcp_server/tools/misc/describe_events.py +86 -0
  36. awslabs/elasticache_mcp_server/tools/misc/describe_service_updates.py +71 -0
  37. awslabs/elasticache_mcp_server/tools/rg/__init__.py +54 -0
  38. awslabs/elasticache_mcp_server/tools/rg/complete_migration.py +94 -0
  39. awslabs/elasticache_mcp_server/tools/rg/connect.py +537 -0
  40. awslabs/elasticache_mcp_server/tools/rg/create.py +318 -0
  41. awslabs/elasticache_mcp_server/tools/rg/delete.py +68 -0
  42. awslabs/elasticache_mcp_server/tools/rg/describe.py +68 -0
  43. awslabs/elasticache_mcp_server/tools/rg/modify.py +236 -0
  44. awslabs/elasticache_mcp_server/tools/rg/parsers.py +268 -0
  45. awslabs/elasticache_mcp_server/tools/rg/processors.py +227 -0
  46. awslabs/elasticache_mcp_server/tools/rg/start_migration.py +151 -0
  47. awslabs/elasticache_mcp_server/tools/rg/test_migration.py +139 -0
  48. awslabs/elasticache_mcp_server/tools/serverless/__init__.py +37 -0
  49. awslabs/elasticache_mcp_server/tools/serverless/connect.py +451 -0
  50. awslabs/elasticache_mcp_server/tools/serverless/create.py +174 -0
  51. awslabs/elasticache_mcp_server/tools/serverless/delete.py +49 -0
  52. awslabs/elasticache_mcp_server/tools/serverless/describe.py +69 -0
  53. awslabs/elasticache_mcp_server/tools/serverless/models.py +160 -0
  54. awslabs/elasticache_mcp_server/tools/serverless/modify.py +95 -0
  55. awslabs_elasticache_mcp_server-0.1.1.dist-info/METADATA +257 -0
  56. awslabs_elasticache_mcp_server-0.1.1.dist-info/RECORD +60 -0
  57. awslabs_elasticache_mcp_server-0.1.1.dist-info/WHEEL +4 -0
  58. awslabs_elasticache_mcp_server-0.1.1.dist-info/entry_points.txt +2 -0
  59. awslabs_elasticache_mcp_server-0.1.1.dist-info/licenses/LICENSE +175 -0
  60. awslabs_elasticache_mcp_server-0.1.1.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,174 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Create serverless cache operations."""
16
+
17
+ from ...common.connection import ElastiCacheConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from ...context import Context
21
+ from .models import CreateServerlessCacheRequest
22
+ from typing import Dict
23
+
24
+
25
+ @mcp.tool(name='create_serverless_cache')
26
+ @handle_exceptions
27
+ async def create_serverless_cache(request: CreateServerlessCacheRequest) -> Dict:
28
+ """Create a new Amazon ElastiCache serverless cache.
29
+
30
+ This tool creates a new serverless cache with specified configuration including:
31
+ - Serverless cache name and capacity
32
+ - Optional VPC and security settings
33
+ - Optional encryption settings
34
+ - Optional snapshot restoration and backup settings
35
+ - Optional usage limits and user groups
36
+ - Optional tags
37
+
38
+ Parameters:
39
+ serverless_cache_name (str): Name of the serverless cache.
40
+ engine (str): Cache engine type.
41
+ description (Optional[str]): Description for the cache.
42
+ kms_key_id (Optional[str]): KMS key ID for encryption.
43
+ major_engine_version (Optional[str]): Major engine version.
44
+ snapshot_arns_to_restore (Optional[List[str]]): List of snapshot ARNs to restore from.
45
+ subnet_ids (Optional[List[str]]): List of subnet IDs for VPC configuration.
46
+ tags (Optional[Union[str, List[Dict[str, Optional[str]]], Dict[str, Optional[str]]]]): Tags to apply to the cache.
47
+ Tag requirements:
48
+ - Key: (string) Required. The key for the tag. Must not be empty.
49
+ - Value: (string) Optional. The tag's value. May be null.
50
+
51
+ Supports three formats:
52
+ 1. Shorthand syntax: "Key=value,Key2=value2" or "Key=,Key2=" for null values
53
+ 2. Dictionary: {"key": "value", "key2": null}
54
+ 3. JSON array: [{"Key": "string", "Value": "string"}, {"Key": "string2", "Value": null}]
55
+
56
+ Can be None if no tags are needed.
57
+ vpc_security_group_ids (Optional[List[str]]): List of VPC security group IDs.
58
+ cache_usage_limits (Optional[CacheUsageLimits]): Usage limits for the cache. Structure:
59
+ {
60
+ "DataStorage": {
61
+ "Maximum": int, # Maximum storage in GB
62
+ "Minimum": int, # Minimum storage in GB
63
+ "Unit": "GB" # Storage unit (currently only GB is supported)
64
+ },
65
+ "ECPUPerSecond": {
66
+ "Maximum": int, # Maximum ECPU per second
67
+ "Minimum": int # Minimum ECPU per second
68
+ }
69
+ }
70
+ user_group_id (Optional[str]): ID of the user group to associate with the cache.
71
+ snapshot_retention_limit (Optional[int]): Number of days for which ElastiCache retains automatic snapshots.
72
+ daily_snapshot_time (Optional[str]): Time range (in UTC) when daily snapshots are taken (e.g., '04:00-05:00').
73
+
74
+ Returns:
75
+ Dict containing information about the created serverless cache.
76
+ """
77
+ """Create a new Amazon ElastiCache serverless cache.
78
+
79
+ This tool creates a new serverless cache with specified configuration including:
80
+ - Serverless cache name and capacity
81
+ - Optional VPC and security settings
82
+ - Optional encryption settings
83
+ - Optional snapshot restoration and backup settings
84
+ - Optional usage limits and user groups
85
+ - Optional tags
86
+
87
+ Args:
88
+ request: The CreateServerlessCacheRequest object containing all parameters
89
+
90
+ Returns:
91
+ Dict containing information about the created serverless cache.
92
+ """
93
+ # Check if readonly mode is enabled
94
+ if Context.readonly_mode():
95
+ raise ValueError(
96
+ 'You have configured this tool in readonly mode. To make this change you will have to update your configuration.'
97
+ )
98
+
99
+ # Get ElastiCache client
100
+ elasticache_client = ElastiCacheConnectionManager.get_connection()
101
+
102
+ # Build AWS API request
103
+ create_request = {}
104
+
105
+ # Required parameters
106
+ create_request['ServerlessCacheName'] = request.serverless_cache_name
107
+ create_request['Engine'] = request.engine
108
+
109
+ # Optional string parameters
110
+ for param_name, value in [
111
+ ('Description', request.description),
112
+ ('KmsKeyId', request.kms_key_id),
113
+ ('MajorEngineVersion', request.major_engine_version),
114
+ ('UserGroupId', request.user_group_id),
115
+ ('DailySnapshotTime', request.daily_snapshot_time),
116
+ ]:
117
+ if value:
118
+ create_request[param_name] = str(value)
119
+
120
+ # Optional list parameters
121
+ for param_name, value in [
122
+ ('SnapshotArnsToRestore', request.snapshot_arns_to_restore),
123
+ ('SubnetIds', request.subnet_ids),
124
+ ('VpcSecurityGroupIds', request.vpc_security_group_ids),
125
+ ]:
126
+ if value:
127
+ create_request[param_name] = list(map(str, value))
128
+
129
+ # Optional numeric parameters
130
+ if request.snapshot_retention_limit is not None:
131
+ create_request['SnapshotRetentionLimit'] = str(request.snapshot_retention_limit)
132
+
133
+ # Cache usage limits
134
+ if request.cache_usage_limits:
135
+ limits_dict = request.cache_usage_limits.model_dump()
136
+ # Ensure numeric values are properly formatted
137
+ if 'DataStorage' in limits_dict:
138
+ limits_dict['DataStorage']['Maximum'] = int(limits_dict['DataStorage']['Maximum'])
139
+ limits_dict['DataStorage']['Minimum'] = int(limits_dict['DataStorage']['Minimum'])
140
+ if 'ECPUPerSecond' in limits_dict:
141
+ limits_dict['ECPUPerSecond']['Maximum'] = int(limits_dict['ECPUPerSecond']['Maximum'])
142
+ limits_dict['ECPUPerSecond']['Minimum'] = int(limits_dict['ECPUPerSecond']['Minimum'])
143
+ create_request['CacheUsageLimits'] = limits_dict
144
+
145
+ # Tags
146
+ if request.tags:
147
+ if isinstance(request.tags, str):
148
+ # Parse string format "key=value,key2=value2"
149
+ tags = []
150
+ for pair in request.tags.split(','):
151
+ key, value = pair.split('=')
152
+ tags.append(
153
+ {
154
+ 'Key': str(key.strip()),
155
+ 'Value': str(value.strip()) if value.strip() else None,
156
+ }
157
+ )
158
+ create_request['Tags'] = tags
159
+ elif isinstance(request.tags, dict):
160
+ # Convert dict format to list of Tag objects
161
+ create_request['Tags'] = [
162
+ {'Key': str(k), 'Value': str(v) if v is not None else None}
163
+ for k, v in request.tags.items()
164
+ ]
165
+ else:
166
+ # Convert Tag objects to dict format
167
+ create_request['Tags'] = [
168
+ {'Key': str(tag.Key), 'Value': str(tag.Value) if tag.Value is not None else None}
169
+ for tag in request.tags
170
+ ]
171
+
172
+ # Create the cache
173
+ response = elasticache_client.create_serverless_cache(**create_request)
174
+ return response
@@ -0,0 +1,49 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Delete serverless cache operations."""
16
+
17
+ from ...common.connection import ElastiCacheConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from typing import Dict, Optional
21
+
22
+
23
+ @mcp.tool(name='delete_serverless_cache')
24
+ @handle_exceptions
25
+ async def delete_serverless_cache(
26
+ serverless_cache_name: str,
27
+ final_snapshot_name: Optional[str] = None,
28
+ ) -> Dict:
29
+ """Delete an Amazon ElastiCache serverless cache.
30
+
31
+ This tool deletes a specified serverless cache from your AWS account.
32
+ The cache must exist and be in a deletable state.
33
+
34
+ Parameters:
35
+ serverless_cache_name (str): Name of the serverless cache to delete.
36
+ final_snapshot_name (Optional[str]): Name of the final snapshot to create before deletion.
37
+
38
+ Returns:
39
+ Dict containing the deletion response or error information.
40
+ """
41
+ # Get ElastiCache client
42
+ elasticache_client = ElastiCacheConnectionManager.get_connection()
43
+
44
+ delete_request = {'ServerlessCacheName': serverless_cache_name}
45
+ if final_snapshot_name:
46
+ delete_request['FinalSnapshotName'] = str(final_snapshot_name)
47
+
48
+ response = elasticache_client.delete_serverless_cache(**delete_request)
49
+ return response
@@ -0,0 +1,69 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Describe serverless cache operations."""
16
+
17
+ from ...common.connection import ElastiCacheConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from typing import Dict, Optional
21
+
22
+
23
+ @mcp.tool(name='describe-serverless-caches')
24
+ @handle_exceptions
25
+ async def describe_serverless_caches(
26
+ serverless_cache_name: Optional[str] = None,
27
+ max_items: Optional[int] = None,
28
+ starting_token: Optional[str] = None,
29
+ page_size: Optional[int] = None,
30
+ ) -> Dict:
31
+ """Describe Amazon ElastiCache serverless caches in your AWS account.
32
+
33
+ This tool retrieves detailed information about serverless caches including:
34
+ - Cache configuration
35
+ - Cache endpoints
36
+ - Cache status
37
+ - Cache size
38
+ - Cache connections
39
+
40
+ Parameters:
41
+ serverless_cache_name (Optional[str]): Name of the serverless cache to describe. If not provided, describes all caches.
42
+ max_items (Optional[int]): Maximum number of results to return.
43
+ starting_token (Optional[str]): Token to start the list from a specific page.
44
+ page_size (Optional[int]): Number of records to include in each page.
45
+
46
+ Returns:
47
+ Dict containing information about the serverless cache(s).
48
+ """
49
+ # Get ElastiCache client
50
+ elasticache_client = ElastiCacheConnectionManager.get_connection()
51
+
52
+ if serverless_cache_name:
53
+ # Get specific cache details
54
+ response = elasticache_client.describe_serverless_caches(
55
+ ServerlessCacheName=serverless_cache_name
56
+ )
57
+ return response
58
+ else:
59
+ # List all caches with optional pagination
60
+ kwargs = {}
61
+ if max_items:
62
+ kwargs['MaxItems'] = max_items
63
+ if starting_token:
64
+ kwargs['StartingToken'] = starting_token
65
+ if page_size:
66
+ kwargs['PageSize'] = page_size
67
+
68
+ response = elasticache_client.describe_serverless_caches(**kwargs)
69
+ return response
@@ -0,0 +1,160 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Models for serverless cache operations."""
16
+
17
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
18
+ from typing import Dict, List, Optional, Union
19
+
20
+
21
+ class DataStorageLimits(BaseModel):
22
+ """Limits for data storage capacity in serverless configuration."""
23
+
24
+ Maximum: int = Field(..., description='Maximum storage in GB', gt=0)
25
+ Minimum: int = Field(..., description='Minimum storage in GB', gt=0)
26
+ Unit: str = Field(..., description='Storage unit (currently only GB is supported)')
27
+
28
+ @field_validator('Unit')
29
+ def validate_unit(cls, v):
30
+ """Validate that Unit is 'GB'."""
31
+ if v != 'GB':
32
+ raise ValueError("Unit must be 'GB'")
33
+ return v
34
+
35
+ @field_validator('Minimum')
36
+ def minimum_less_than_maximum(cls, v, values):
37
+ """Validate that Minimum is less than or equal to Maximum."""
38
+ if hasattr(values, 'data') and 'Maximum' in values.data and v > values.data['Maximum']:
39
+ raise ValueError('Minimum must be less than or equal to Maximum')
40
+ return v
41
+
42
+
43
+ class ECPULimits(BaseModel):
44
+ """Limits for ECPU (ElastiCache Processing Units) in serverless configuration."""
45
+
46
+ Maximum: int = Field(..., description='Maximum ECPU per second', gt=0)
47
+ Minimum: int = Field(..., description='Minimum ECPU per second', gt=0)
48
+
49
+ @field_validator('Minimum')
50
+ def minimum_less_than_maximum(cls, v, values):
51
+ """Validate that Minimum is less than or equal to Maximum."""
52
+ if hasattr(values, 'data') and 'Maximum' in values.data and v > values.data['Maximum']:
53
+ raise ValueError('Minimum must be less than or equal to Maximum')
54
+ return v
55
+
56
+
57
+ class CacheUsageLimits(BaseModel):
58
+ """Combined limits for data storage and ECPU in serverless configuration."""
59
+
60
+ DataStorage: DataStorageLimits = Field(..., description='Data storage limits configuration')
61
+ ECPUPerSecond: ECPULimits = Field(..., description='ECPU limits configuration')
62
+
63
+
64
+ class Tag(BaseModel):
65
+ """Tag model for ElastiCache resources."""
66
+
67
+ Key: str = Field(..., description='The key for the tag')
68
+ Value: Optional[str] = Field(None, description="The tag's value")
69
+
70
+
71
+ class CreateServerlessCacheRequest(BaseModel):
72
+ """Request model for creating an ElastiCache serverless cache."""
73
+
74
+ serverless_cache_name: str = Field(..., description='The identifier of the serverless cache')
75
+ engine: str = Field(..., description='The name of the cache engine')
76
+ description: Optional[str] = Field(None, description='Description for the cache')
77
+ kms_key_id: Optional[str] = Field(None, description='KMS key ID for encryption')
78
+ major_engine_version: Optional[str] = Field(None, description='Major engine version')
79
+ snapshot_arns_to_restore: Optional[List[str]] = Field(
80
+ None, description='List of snapshot ARNs to restore from'
81
+ )
82
+ subnet_ids: Optional[List[str]] = Field(
83
+ None, description='List of subnet IDs for VPC configuration'
84
+ )
85
+ tags: Optional[Union[str, List[Tag], Dict[str, Optional[str]]]] = Field(
86
+ None,
87
+ description=(
88
+ 'Tags to apply. Can be a string in Key=value format, '
89
+ 'a list of Tag objects, or a dict of key-value pairs'
90
+ ),
91
+ )
92
+ vpc_security_group_ids: Optional[List[str]] = Field(
93
+ None, description='List of VPC security group IDs'
94
+ )
95
+ cache_usage_limits: Optional[CacheUsageLimits] = Field(
96
+ None, description='Usage limits for the cache'
97
+ )
98
+ user_group_id: Optional[str] = Field(
99
+ None, description='ID of the user group to associate with the cache'
100
+ )
101
+ snapshot_retention_limit: Optional[int] = Field(
102
+ None, description='Number of days to retain automatic snapshots', ge=0
103
+ )
104
+ daily_snapshot_time: Optional[str] = Field(
105
+ None,
106
+ description="Time range (in UTC) when daily snapshots are taken (e.g., '04:00-05:00')",
107
+ )
108
+
109
+ @field_validator('daily_snapshot_time')
110
+ def validate_snapshot_time(cls, v):
111
+ """Validate snapshot time format."""
112
+ if v is not None:
113
+ import re
114
+
115
+ if not re.match(r'^([0-1][0-9]|2[0-3]):[0-5][0-9]-([0-1][0-9]|2[0-3]):[0-5][0-9]$', v):
116
+ raise ValueError('Invalid time range format. Must be in format HH:MM-HH:MM')
117
+ return v
118
+
119
+ model_config = ConfigDict(validate_by_name=True, arbitrary_types_allowed=True)
120
+
121
+
122
+ class ModifyServerlessCacheRequest(BaseModel):
123
+ """Request model for modifying an ElastiCache serverless cache."""
124
+
125
+ serverless_cache_name: str = Field(
126
+ ..., description='The name of the serverless cache to modify'
127
+ )
128
+ description: Optional[str] = Field(None, description='New description for the cache')
129
+ major_engine_version: Optional[str] = Field(None, description='New major engine version')
130
+ snapshot_retention_limit: Optional[int] = Field(
131
+ None, description='Number of days to retain automatic snapshots', ge=0
132
+ )
133
+ daily_snapshot_time: Optional[str] = Field(
134
+ None,
135
+ description="Time range (in UTC) when daily snapshots are taken (e.g., '04:00-05:00')",
136
+ )
137
+ cache_usage_limits: Optional[CacheUsageLimits] = Field(
138
+ None, description='New usage limits for the cache'
139
+ )
140
+ remove_user_group: Optional[bool] = Field(
141
+ None, description='Whether to remove the user group association'
142
+ )
143
+ user_group_id: Optional[str] = Field(
144
+ None, description='ID of the user group to associate with the cache'
145
+ )
146
+ vpc_security_group_ids: Optional[List[str]] = Field(
147
+ None, description='List of VPC security group IDs'
148
+ )
149
+
150
+ @field_validator('daily_snapshot_time')
151
+ def validate_snapshot_time(cls, v):
152
+ """Validate snapshot time format."""
153
+ if v is not None:
154
+ import re
155
+
156
+ if not re.match(r'^([0-1][0-9]|2[0-3]):[0-5][0-9]-([0-1][0-9]|2[0-3]):[0-5][0-9]$', v):
157
+ raise ValueError('Invalid time range format. Must be in format HH:MM-HH:MM')
158
+ return v
159
+
160
+ model_config = ConfigDict(validate_by_name=True, arbitrary_types_allowed=True)
@@ -0,0 +1,95 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Modify serverless cache operations."""
16
+
17
+ from ...common.connection import ElastiCacheConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from .models import ModifyServerlessCacheRequest
21
+ from typing import Dict
22
+
23
+
24
+ @mcp.tool(name='modify_serverless_cache')
25
+ @handle_exceptions
26
+ async def modify_serverless_cache(request: ModifyServerlessCacheRequest) -> Dict:
27
+ """Modify an Amazon ElastiCache serverless cache.
28
+
29
+ This tool modifies the configuration of an existing serverless cache including:
30
+ - Cache description
31
+ - Engine version
32
+ - Snapshot settings
33
+ - Usage limits
34
+ - Security groups
35
+ - User groups
36
+
37
+ Parameters:
38
+ serverless_cache_name (str): Name of the serverless cache to modify.
39
+ apply_immediately (Optional[bool]): Whether to apply changes immediately or during maintenance window.
40
+ description (Optional[str]): New description for the cache.
41
+ major_engine_version (Optional[str]): New major engine version.
42
+ snapshot_retention_limit (Optional[int]): Number of days for which ElastiCache retains automatic snapshots.
43
+ daily_snapshot_time (Optional[str]): Time range (in UTC) when daily snapshots are taken (e.g., '04:00-05:00').
44
+ cache_usage_limits (Optional[CacheUsageLimits]): New usage limits for the cache. Structure:
45
+ {
46
+ "DataStorage": {
47
+ "Maximum": int, # Maximum storage in GB
48
+ "Minimum": int, # Minimum storage in GB
49
+ "Unit": "GB" # Storage unit (currently only GB is supported)
50
+ },
51
+ "ECPUPerSecond": {
52
+ "Maximum": int, # Maximum ECPU per second
53
+ "Minimum": int # Minimum ECPU per second
54
+ }
55
+ }
56
+ security_group_ids (Optional[List[str]]): List of VPC security group IDs.
57
+ user_group_id (Optional[str]): ID of the user group to associate with the cache.
58
+
59
+ Returns:
60
+ Dict containing information about the modified serverless cache.
61
+ """
62
+ """Modify an Amazon ElastiCache serverless cache.
63
+
64
+ This tool modifies the configuration of an existing serverless cache including:
65
+ - Cache description
66
+ - Engine version
67
+ - Snapshot settings
68
+ - Usage limits
69
+ - Security groups
70
+ - User groups
71
+
72
+ Args:
73
+ request: ModifyServerlessCacheRequest object containing modification parameters
74
+
75
+ Returns:
76
+ Dict containing information about the modified serverless cache.
77
+ """
78
+ # Get ElastiCache client
79
+ elasticache_client = ElastiCacheConnectionManager.get_connection()
80
+
81
+ # Convert request to dict and remove None values
82
+ modify_request = {k: v for k, v in request.model_dump().items() if v is not None}
83
+
84
+ # Convert snake_case to PascalCase for AWS API
85
+ aws_request = {}
86
+ for key, value in modify_request.items():
87
+ # Special handling for boolean values
88
+ if isinstance(value, bool):
89
+ aws_request[key.title().replace('_', '')] = str(value).lower()
90
+ else:
91
+ aws_request[key.title().replace('_', '')] = value
92
+
93
+ # Modify the cache
94
+ response = elasticache_client.modify_serverless_cache(**aws_request)
95
+ return response