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.
- awslabs/__init__.py +16 -0
- awslabs/elasticache_mcp_server/__init__.py +17 -0
- awslabs/elasticache_mcp_server/common/__init__.py +15 -0
- awslabs/elasticache_mcp_server/common/connection.py +117 -0
- awslabs/elasticache_mcp_server/common/decorators.py +41 -0
- awslabs/elasticache_mcp_server/common/server.py +30 -0
- awslabs/elasticache_mcp_server/context.py +39 -0
- awslabs/elasticache_mcp_server/main.py +52 -0
- awslabs/elasticache_mcp_server/tools/__init__.py +15 -0
- awslabs/elasticache_mcp_server/tools/cc/__init__.py +31 -0
- awslabs/elasticache_mcp_server/tools/cc/connect.py +444 -0
- awslabs/elasticache_mcp_server/tools/cc/create.py +212 -0
- awslabs/elasticache_mcp_server/tools/cc/delete.py +65 -0
- awslabs/elasticache_mcp_server/tools/cc/describe.py +80 -0
- awslabs/elasticache_mcp_server/tools/cc/modify.py +159 -0
- awslabs/elasticache_mcp_server/tools/cc/parsers.py +78 -0
- awslabs/elasticache_mcp_server/tools/cc/processors.py +74 -0
- awslabs/elasticache_mcp_server/tools/ce/__init__.py +19 -0
- awslabs/elasticache_mcp_server/tools/ce/get_cost_and_usage.py +76 -0
- awslabs/elasticache_mcp_server/tools/cw/__init__.py +19 -0
- awslabs/elasticache_mcp_server/tools/cw/get_metric_statistics.py +85 -0
- awslabs/elasticache_mcp_server/tools/cwlogs/__init__.py +29 -0
- awslabs/elasticache_mcp_server/tools/cwlogs/create_log_group.py +68 -0
- awslabs/elasticache_mcp_server/tools/cwlogs/describe_log_groups.py +123 -0
- awslabs/elasticache_mcp_server/tools/cwlogs/describe_log_streams.py +120 -0
- awslabs/elasticache_mcp_server/tools/cwlogs/filter_log_events.py +122 -0
- awslabs/elasticache_mcp_server/tools/cwlogs/get_log_events.py +99 -0
- awslabs/elasticache_mcp_server/tools/firehose/__init__.py +19 -0
- awslabs/elasticache_mcp_server/tools/firehose/list_delivery_streams.py +63 -0
- awslabs/elasticache_mcp_server/tools/misc/__init__.py +31 -0
- awslabs/elasticache_mcp_server/tools/misc/batch_apply_update_action.py +62 -0
- awslabs/elasticache_mcp_server/tools/misc/batch_stop_update_action.py +62 -0
- awslabs/elasticache_mcp_server/tools/misc/describe_cache_engine_versions.py +79 -0
- awslabs/elasticache_mcp_server/tools/misc/describe_engine_default_parameters.py +64 -0
- awslabs/elasticache_mcp_server/tools/misc/describe_events.py +86 -0
- awslabs/elasticache_mcp_server/tools/misc/describe_service_updates.py +71 -0
- awslabs/elasticache_mcp_server/tools/rg/__init__.py +54 -0
- awslabs/elasticache_mcp_server/tools/rg/complete_migration.py +94 -0
- awslabs/elasticache_mcp_server/tools/rg/connect.py +537 -0
- awslabs/elasticache_mcp_server/tools/rg/create.py +318 -0
- awslabs/elasticache_mcp_server/tools/rg/delete.py +68 -0
- awslabs/elasticache_mcp_server/tools/rg/describe.py +68 -0
- awslabs/elasticache_mcp_server/tools/rg/modify.py +236 -0
- awslabs/elasticache_mcp_server/tools/rg/parsers.py +268 -0
- awslabs/elasticache_mcp_server/tools/rg/processors.py +227 -0
- awslabs/elasticache_mcp_server/tools/rg/start_migration.py +151 -0
- awslabs/elasticache_mcp_server/tools/rg/test_migration.py +139 -0
- awslabs/elasticache_mcp_server/tools/serverless/__init__.py +37 -0
- awslabs/elasticache_mcp_server/tools/serverless/connect.py +451 -0
- awslabs/elasticache_mcp_server/tools/serverless/create.py +174 -0
- awslabs/elasticache_mcp_server/tools/serverless/delete.py +49 -0
- awslabs/elasticache_mcp_server/tools/serverless/describe.py +69 -0
- awslabs/elasticache_mcp_server/tools/serverless/models.py +160 -0
- awslabs/elasticache_mcp_server/tools/serverless/modify.py +95 -0
- awslabs_elasticache_mcp_server-0.1.1.dist-info/METADATA +257 -0
- awslabs_elasticache_mcp_server-0.1.1.dist-info/RECORD +60 -0
- awslabs_elasticache_mcp_server-0.1.1.dist-info/WHEEL +4 -0
- awslabs_elasticache_mcp_server-0.1.1.dist-info/entry_points.txt +2 -0
- awslabs_elasticache_mcp_server-0.1.1.dist-info/licenses/LICENSE +175 -0
- 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
|
+
]
|