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,29 @@
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
+ """CloudWatch Logs tools."""
16
+
17
+ from .get_log_events import get_log_events
18
+ from .create_log_group import create_log_group
19
+ from .describe_log_groups import describe_log_groups
20
+ from .describe_log_streams import describe_log_streams
21
+ from .filter_log_events import filter_log_events
22
+
23
+ __all__ = [
24
+ 'get_log_events',
25
+ 'create_log_group',
26
+ 'describe_log_groups',
27
+ 'describe_log_streams',
28
+ 'filter_log_events',
29
+ ]
@@ -0,0 +1,68 @@
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
+ """Tool for creating a CloudWatch Logs log group."""
16
+
17
+ from ...common.connection import CloudWatchLogsConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from ...context import Context
21
+ from typing import Any, Dict, Optional
22
+
23
+
24
+ @mcp.tool(name='create-log-group')
25
+ @handle_exceptions
26
+ async def create_log_group(
27
+ log_group_name: str,
28
+ kms_key_id: Optional[str] = None,
29
+ tags: Optional[Dict[str, str]] = None,
30
+ log_group_class: Optional[str] = None,
31
+ ) -> Dict[str, Any]:
32
+ """Create a new CloudWatch Logs log group.
33
+
34
+ Args:
35
+ log_group_name: The name of the log group to create
36
+ kms_key_id: The Amazon Resource Name (ARN) of the KMS key to use for encryption
37
+ tags: The key-value pairs to use for the tags
38
+ log_group_class: Specify one of the following classes:
39
+ STANDARD - Standard log events (default)
40
+ INFREQUENT_ACCESS - Infrequent Access log events
41
+
42
+ Returns:
43
+ Dict containing success message or error details
44
+ """
45
+ # Check if readonly mode is enabled
46
+ if Context.readonly_mode():
47
+ raise ValueError(
48
+ 'You have configured this tool in readonly mode. To make this change you will have to update your configuration.'
49
+ )
50
+
51
+ client = CloudWatchLogsConnectionManager.get_connection()
52
+
53
+ # Build request parameters
54
+ params: Dict[str, Any] = {
55
+ 'logGroupName': log_group_name,
56
+ }
57
+
58
+ # Add optional parameters
59
+ if kms_key_id:
60
+ params['kmsKeyId'] = kms_key_id
61
+ if tags:
62
+ params['tags'] = tags
63
+ if log_group_class:
64
+ params['logGroupClass'] = log_group_class
65
+
66
+ # Make API call
67
+ client.create_log_group(**params)
68
+ return {'message': f'Successfully created log group: {log_group_name}'}
@@ -0,0 +1,123 @@
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
+ """Tool for describing CloudWatch Logs log groups."""
16
+
17
+ from ...common.connection import CloudWatchLogsConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from typing import Any, Dict, List, Optional
21
+
22
+
23
+ @mcp.tool(name='describe-log-groups')
24
+ @handle_exceptions
25
+ async def describe_log_groups(
26
+ account_identifiers: Optional[List[str]] = None,
27
+ log_group_name_prefix: Optional[str] = None,
28
+ log_group_name_pattern: Optional[str] = None,
29
+ include_linked_accounts: Optional[bool] = None,
30
+ log_group_class: Optional[str] = None,
31
+ log_group_identifiers: Optional[List[str]] = None,
32
+ starting_token: Optional[str] = None,
33
+ page_size: Optional[int] = None,
34
+ max_items: Optional[int] = None,
35
+ ) -> Dict[str, Any]:
36
+ """Describe CloudWatch Logs log groups.
37
+
38
+ Args:
39
+ account_identifiers: List of account IDs to filter log groups
40
+ log_group_name_prefix: Prefix to filter log groups by name
41
+ log_group_name_pattern: Pattern to match log group names
42
+ include_linked_accounts: Whether to include log groups from linked accounts
43
+ log_group_class: Filter by log group class (STANDARD or INFREQUENT_ACCESS)
44
+ log_group_identifiers: List of log group identifiers to describe
45
+ starting_token: Token for starting the list from a specific page
46
+ page_size: Number of records to include in each page
47
+ max_items: Maximum number of records to return in total
48
+
49
+ Returns:
50
+ Dict containing log groups information or error details
51
+ """
52
+ client = CloudWatchLogsConnectionManager.get_connection()
53
+
54
+ # Build request parameters
55
+ params: Dict[str, Any] = {}
56
+
57
+ # Add optional parameters
58
+ if account_identifiers:
59
+ params['accountIdentifiers'] = account_identifiers
60
+ if log_group_name_prefix:
61
+ params['logGroupNamePrefix'] = log_group_name_prefix
62
+ if log_group_name_pattern:
63
+ params['logGroupNamePattern'] = log_group_name_pattern
64
+ if include_linked_accounts is not None:
65
+ params['includeLinkedAccounts'] = include_linked_accounts
66
+ if log_group_class:
67
+ params['logGroupClass'] = log_group_class
68
+ if log_group_identifiers:
69
+ params['logGroupIdentifiers'] = log_group_identifiers
70
+ if starting_token:
71
+ params['nextToken'] = starting_token
72
+ if page_size:
73
+ params['limit'] = page_size
74
+
75
+ # If max_items is set, we need to handle pagination manually
76
+ if max_items is not None:
77
+ log_groups = []
78
+ items_remaining = max_items
79
+
80
+ while True:
81
+ # Adjust limit if we're close to max_items
82
+ if page_size and items_remaining < page_size:
83
+ params['limit'] = items_remaining
84
+
85
+ # Make API call
86
+ response = client.describe_log_groups(**params)
87
+ current_groups = response.get('logGroups', [])
88
+
89
+ # Add groups up to max_items
90
+ if len(current_groups) > items_remaining:
91
+ log_groups.extend(current_groups[:items_remaining])
92
+ next_token = response.get('nextToken') # Save for result
93
+ break
94
+ else:
95
+ log_groups.extend(current_groups)
96
+ items_remaining -= len(current_groups)
97
+
98
+ # Check if we need to continue
99
+ if 'nextToken' not in response or items_remaining <= 0:
100
+ next_token = response.get('nextToken')
101
+ break
102
+
103
+ # Update token for next iteration
104
+ params['nextToken'] = response['nextToken']
105
+
106
+ result = {'logGroups': log_groups}
107
+ if next_token:
108
+ result['nextToken'] = next_token
109
+ return result
110
+
111
+ # If max_items is not set, make a single API call
112
+ response = client.describe_log_groups(**params)
113
+
114
+ # Extract relevant information
115
+ log_groups = response.get('logGroups', [])
116
+ next_token = response.get('nextToken')
117
+
118
+ result = {'logGroups': log_groups}
119
+
120
+ if next_token:
121
+ result['nextToken'] = next_token
122
+
123
+ return result
@@ -0,0 +1,120 @@
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
+ """Tool for describing CloudWatch Logs log streams."""
16
+
17
+ from ...common.connection import CloudWatchLogsConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from typing import Any, Dict, Optional
21
+
22
+
23
+ @mcp.tool(name='describe-log-streams')
24
+ @handle_exceptions
25
+ async def describe_log_streams(
26
+ log_group_name: Optional[str] = None,
27
+ log_group_identifier: Optional[str] = None,
28
+ log_stream_name_prefix: Optional[str] = None,
29
+ order_by: Optional[str] = None,
30
+ descending: Optional[bool] = None,
31
+ starting_token: Optional[str] = None,
32
+ page_size: Optional[int] = None,
33
+ max_items: Optional[int] = None,
34
+ ) -> Dict[str, Any]:
35
+ """Describe CloudWatch Logs log streams.
36
+
37
+ Args:
38
+ log_group_name: The name of the log group containing the log streams to describe.
39
+ log_group_identifier: The unique identifier of the log group.
40
+ log_stream_name_prefix: The prefix to match when describing log streams.
41
+ order_by: The parameter to sort by (LogStreamName or LastEventTime).
42
+ descending: If true, results are returned in descending order.
43
+ starting_token: Token for starting the list from a specific page.
44
+ page_size: Number of records to include in each page.
45
+ max_items: Maximum number of records to return in total.
46
+
47
+ Returns:
48
+ Dict containing information about the log streams or error details.
49
+ """
50
+ client = CloudWatchLogsConnectionManager.get_connection()
51
+
52
+ # Build request parameters
53
+ params: Dict[str, Any] = {}
54
+
55
+ # Add optional parameters
56
+ if log_group_name:
57
+ params['logGroupName'] = log_group_name
58
+ if log_group_identifier:
59
+ params['logGroupIdentifier'] = log_group_identifier
60
+ if log_stream_name_prefix:
61
+ params['logStreamNamePrefix'] = log_stream_name_prefix
62
+ if order_by:
63
+ params['orderBy'] = order_by
64
+ if descending is not None:
65
+ params['descending'] = descending
66
+ if starting_token:
67
+ params['nextToken'] = starting_token
68
+ if page_size:
69
+ params['limit'] = page_size
70
+
71
+ # If max_items is set, we need to handle pagination manually
72
+ if max_items is not None:
73
+ log_streams = []
74
+ items_remaining = max_items
75
+
76
+ while True:
77
+ # Adjust limit if we're close to max_items
78
+ if page_size and items_remaining < page_size:
79
+ params['limit'] = items_remaining
80
+
81
+ # Make API call
82
+ response = client.describe_log_streams(**params)
83
+ current_streams = response.get('logStreams', [])
84
+
85
+ # Add streams up to max_items
86
+ if len(current_streams) > items_remaining:
87
+ log_streams.extend(current_streams[:items_remaining])
88
+ next_token = response.get('nextToken') # Save for result
89
+ break
90
+ else:
91
+ log_streams.extend(current_streams)
92
+ items_remaining -= len(current_streams)
93
+
94
+ # Check if we need to continue
95
+ if 'nextToken' not in response or items_remaining <= 0:
96
+ next_token = response.get('nextToken')
97
+ break
98
+
99
+ # Update token for next iteration
100
+ params['nextToken'] = response['nextToken']
101
+
102
+ result = {'logStreams': log_streams}
103
+ if next_token:
104
+ result['nextToken'] = next_token
105
+ return result
106
+
107
+ # If max_items is not set, make a single API call
108
+ # Make API call
109
+ response = client.describe_log_streams(**params)
110
+
111
+ # Extract relevant information
112
+ log_streams = response.get('logStreams', [])
113
+ next_token = response.get('nextToken')
114
+
115
+ result = {'logStreams': log_streams}
116
+
117
+ if next_token:
118
+ result['nextToken'] = next_token
119
+
120
+ return result
@@ -0,0 +1,122 @@
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
+ """Tool for filtering log events from CloudWatch Logs."""
16
+
17
+ from ...common.connection import CloudWatchLogsConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from datetime import datetime
21
+ from typing import Any, Dict, List, Optional
22
+
23
+
24
+ @mcp.tool(name='filter-log-events')
25
+ @handle_exceptions
26
+ async def filter_log_events(
27
+ log_group_name: Optional[str] = None,
28
+ log_group_identifier: Optional[str] = None,
29
+ log_stream_names: Optional[List[str]] = None,
30
+ log_stream_name_prefix: Optional[str] = None,
31
+ start_time: Optional[datetime] = None,
32
+ end_time: Optional[datetime] = None,
33
+ filter_pattern: Optional[str] = None,
34
+ interleaved: Optional[bool] = None,
35
+ unmask: Optional[bool] = None,
36
+ starting_token: Optional[str] = None,
37
+ page_size: Optional[int] = None,
38
+ max_items: Optional[int] = None,
39
+ ) -> Dict[str, Any]:
40
+ """Filter log events from CloudWatch Logs.
41
+
42
+ Args:
43
+ log_group_name: The name of the log group
44
+ log_group_identifier: The unique identifier of the log group
45
+ log_stream_names: Optional list of log stream names to search
46
+ log_stream_name_prefix: Optional prefix to match log stream names
47
+ start_time: The start of the time range, inclusive
48
+ end_time: The end of the time range, inclusive
49
+ filter_pattern: The filter pattern to use
50
+ interleaved: If true, multiple log streams are interleaved
51
+ unmask: If true, unmask sensitive log data
52
+ starting_token: Token for getting the next set of events
53
+ page_size: Number of events to return per page
54
+ max_items: Maximum number of events to return in total
55
+
56
+ Returns:
57
+ Dict containing:
58
+ - events: List of filtered log events
59
+ - searchedLogStreams: List of log streams that were searched
60
+ - nextToken: Token for getting the next set of events
61
+ """
62
+ client = CloudWatchLogsConnectionManager.get_connection()
63
+
64
+ # Build request parameters
65
+ params: Dict[str, Any] = {}
66
+
67
+ # Add required parameters
68
+ if log_group_name:
69
+ params['logGroupName'] = log_group_name
70
+ if log_group_identifier:
71
+ params['logGroupIdentifier'] = log_group_identifier
72
+
73
+ # Add optional parameters
74
+ if log_stream_names:
75
+ params['logStreamNames'] = log_stream_names
76
+ if log_stream_name_prefix:
77
+ params['logStreamNamePrefix'] = log_stream_name_prefix
78
+ if start_time:
79
+ params['startTime'] = int(start_time.timestamp() * 1000)
80
+ if end_time:
81
+ params['endTime'] = int(end_time.timestamp() * 1000)
82
+ if filter_pattern:
83
+ params['filterPattern'] = filter_pattern
84
+ if interleaved is not None:
85
+ params['interleaved'] = interleaved
86
+ if unmask is not None:
87
+ params['unmask'] = unmask
88
+ if starting_token:
89
+ params['nextToken'] = starting_token
90
+ if page_size:
91
+ params['limit'] = page_size
92
+
93
+ # Make API call
94
+ response = client.filter_log_events(**params)
95
+
96
+ # Format response
97
+ events = []
98
+ for event in response.get('events', []):
99
+ events.append(
100
+ {
101
+ 'timestamp': event['timestamp'],
102
+ 'message': event['message'],
103
+ 'ingestionTime': event.get('ingestionTime'),
104
+ 'eventId': event.get('eventId'),
105
+ 'logStreamName': event.get('logStreamName'),
106
+ }
107
+ )
108
+
109
+ searched_streams = []
110
+ for stream in response.get('searchedLogStreams', []):
111
+ searched_streams.append(
112
+ {
113
+ 'logStreamName': stream.get('logStreamName'),
114
+ 'searchedCompletely': stream.get('searchedCompletely', False),
115
+ }
116
+ )
117
+
118
+ return {
119
+ 'events': events,
120
+ 'searchedLogStreams': searched_streams,
121
+ 'nextToken': response.get('nextToken'),
122
+ }
@@ -0,0 +1,99 @@
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
+ """Tool for retrieving log events from CloudWatch Logs."""
16
+
17
+ from ...common.connection import CloudWatchLogsConnectionManager
18
+ from ...common.decorators import handle_exceptions
19
+ from ...common.server import mcp
20
+ from datetime import datetime
21
+ from typing import Any, Dict, Optional
22
+
23
+
24
+ @mcp.tool(name='get-log-events')
25
+ @handle_exceptions
26
+ async def get_log_events(
27
+ log_stream_name: str,
28
+ log_group_name: Optional[str] = None,
29
+ log_group_identifier: Optional[str] = None,
30
+ start_time: Optional[datetime] = None,
31
+ end_time: Optional[datetime] = None,
32
+ next_token: Optional[str] = None,
33
+ limit: Optional[int] = None,
34
+ start_from_head: Optional[bool] = None,
35
+ unmask: Optional[bool] = None,
36
+ ) -> Dict[str, Any]:
37
+ """Get log events from CloudWatch Logs.
38
+
39
+ Args:
40
+ log_group_name: The name of the log group
41
+ log_group_identifier: The unique identifier of the log group
42
+ log_stream_name: The name of the log stream
43
+ start_time: The start of the time range, inclusive
44
+ end_time: The end of the time range, inclusive
45
+ next_token: The token for the next set of items to return
46
+ limit: The maximum number of log events to return
47
+ start_from_head: If true, read from oldest to newest
48
+ unmask: If true, unmask sensitive log data
49
+
50
+ Returns:
51
+ Dict containing:
52
+ - events: List of log events
53
+ - nextForwardToken: Token for getting the next set of events
54
+ - nextBackwardToken: Token for getting the previous set of events
55
+ """
56
+ client = CloudWatchLogsConnectionManager.get_connection()
57
+
58
+ # Build request parameters
59
+ params: Dict[str, Any] = {
60
+ 'logStreamName': log_stream_name,
61
+ }
62
+
63
+ # Add optional parameters
64
+ if log_group_name:
65
+ params['logGroupName'] = log_group_name
66
+ if log_group_identifier:
67
+ params['logGroupIdentifier'] = log_group_identifier
68
+ if start_time:
69
+ params['startTime'] = int(start_time.timestamp() * 1000)
70
+ if end_time:
71
+ params['endTime'] = int(end_time.timestamp() * 1000)
72
+ if next_token:
73
+ params['nextToken'] = next_token
74
+ if limit:
75
+ params['limit'] = limit
76
+ if start_from_head is not None:
77
+ params['startFromHead'] = start_from_head
78
+ if unmask is not None:
79
+ params['unmask'] = unmask
80
+
81
+ # Make API call
82
+ response = client.get_log_events(**params)
83
+
84
+ # Format response
85
+ events = []
86
+ for event in response.get('events', []):
87
+ events.append(
88
+ {
89
+ 'timestamp': event['timestamp'],
90
+ 'message': event['message'],
91
+ 'ingestionTime': event.get('ingestionTime'),
92
+ }
93
+ )
94
+
95
+ return {
96
+ 'events': events,
97
+ 'nextForwardToken': response.get('nextForwardToken'),
98
+ 'nextBackwardToken': response.get('nextBackwardToken'),
99
+ }
@@ -0,0 +1,19 @@
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
+ """Tools for working with Amazon Kinesis Data Firehose."""
16
+
17
+ from .list_delivery_streams import list_delivery_streams
18
+
19
+ __all__ = ['list_delivery_streams']
@@ -0,0 +1,63 @@
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
+ """Tool for listing Kinesis Firehose delivery streams."""
16
+
17
+ from __future__ import annotations
18
+
19
+ from ...common.connection import FirehoseConnectionManager
20
+ from ...common.decorators import handle_exceptions
21
+ from ...common.server import mcp
22
+ from typing import Any, Dict
23
+
24
+
25
+ @mcp.tool(name='list-delivery-streams')
26
+ @handle_exceptions
27
+ async def list_delivery_streams(
28
+ limit: Any = None,
29
+ delivery_stream_type: Any = None,
30
+ exclusive_start_delivery_stream_name: Any = None,
31
+ ) -> Dict[str, Any]:
32
+ """List your delivery streams.
33
+
34
+ Args:
35
+ limit: The maximum number of delivery streams to list
36
+ delivery_stream_type: The delivery stream type. This can be one of the following values:
37
+ DirectPut - Provider data is sent directly to the Firehose stream
38
+ KinesisStreamAsSource - Data is sourced from an existing Kinesis stream
39
+ exclusive_start_delivery_stream_name: The name of the delivery stream to start the list after
40
+
41
+ Returns:
42
+ Dict containing the list of delivery streams and whether there are more streams available
43
+ """
44
+ client = FirehoseConnectionManager.get_connection()
45
+
46
+ # Build request parameters
47
+ params: Dict[str, Any] = {}
48
+ if limit is not None:
49
+ params['Limit'] = limit
50
+ if delivery_stream_type is not None:
51
+ params['DeliveryStreamType'] = delivery_stream_type
52
+ if exclusive_start_delivery_stream_name is not None:
53
+ params['ExclusiveStartDeliveryStreamName'] = exclusive_start_delivery_stream_name
54
+
55
+ # Make API call
56
+ try:
57
+ response = client.list_delivery_streams(**params)
58
+ return {
59
+ 'DeliveryStreamNames': response.get('DeliveryStreamNames', []),
60
+ 'HasMoreDeliveryStreams': response.get('HasMoreDeliveryStreams', False),
61
+ }
62
+ except Exception as e:
63
+ return {'error': str(e)}
@@ -0,0 +1,31 @@
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
+ """Miscellaneous ElastiCache tools."""
16
+
17
+ from .batch_apply_update_action import batch_apply_update_action
18
+ from .batch_stop_update_action import batch_stop_update_action
19
+ from .describe_cache_engine_versions import describe_cache_engine_versions
20
+ from .describe_engine_default_parameters import describe_engine_default_parameters
21
+ from .describe_events import describe_events
22
+ from .describe_service_updates import describe_service_updates
23
+
24
+ __all__ = [
25
+ 'batch_apply_update_action',
26
+ 'batch_stop_update_action',
27
+ 'describe_cache_engine_versions',
28
+ 'describe_engine_default_parameters',
29
+ 'describe_events',
30
+ 'describe_service_updates',
31
+ ]