awslabs.cloudwatch-mcp-server 0.0.15__tar.gz → 0.0.17__tar.gz

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 (51) hide show
  1. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/Dockerfile +19 -22
  2. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/PKG-INFO +7 -7
  3. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/README.md +6 -6
  4. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/__init__.py +1 -1
  5. awslabs_cloudwatch_mcp_server-0.0.17/awslabs/cloudwatch_mcp_server/aws_common.py +55 -0
  6. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_alarms/tools.py +29 -29
  7. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_logs/tools.py +62 -49
  8. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/tools.py +39 -39
  9. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/docker-healthcheck.sh +1 -1
  10. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/pyproject.toml +1 -1
  11. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_alarms/test_active_alarms.py +15 -43
  12. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_alarms/test_alarm_history.py +13 -50
  13. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_alarms/test_alarm_history_integration.py +9 -25
  14. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_alarms/test_alarms_error_handling.py +20 -28
  15. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_logs/test_logs_error_handling.py +55 -120
  16. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_logs/test_logs_server.py +30 -38
  17. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_analyze_metric.py +33 -17
  18. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_metrics_error_handling.py +31 -36
  19. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_metrics_server.py +37 -27
  20. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_validation_error.py +1 -3
  21. awslabs_cloudwatch_mcp_server-0.0.17/tests/test_aws_common.py +185 -0
  22. awslabs_cloudwatch_mcp_server-0.0.17/uv-requirements.txt +23 -0
  23. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/uv.lock +11 -10
  24. awslabs_cloudwatch_mcp_server-0.0.15/uv-requirements.txt +0 -27
  25. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/.gitignore +0 -0
  26. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/.python-version +0 -0
  27. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/CHANGELOG.md +0 -0
  28. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/LICENSE +0 -0
  29. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/NOTICE +0 -0
  30. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/__init__.py +0 -0
  31. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_alarms/models.py +0 -0
  32. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_logs/models.py +0 -0
  33. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/cloudformation_template_generator.py +0 -0
  34. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/constants.py +0 -0
  35. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/data/metric_metadata.json +0 -0
  36. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/metric_analyzer.py +0 -0
  37. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/metric_data_decomposer.py +0 -0
  38. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/cloudwatch_metrics/models.py +0 -0
  39. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/common.py +0 -0
  40. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/awslabs/cloudwatch_mcp_server/server.py +0 -0
  41. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_logs/test_logs_models.py +0 -0
  42. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_cloudformation_template_generator.py +0 -0
  43. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_decomposer_trend.py +0 -0
  44. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_metric_analyzer.py +0 -0
  45. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_metrics_models.py +0 -0
  46. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_seasonal_detector.py +0 -0
  47. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_seasonality_enum.py +0 -0
  48. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/cloudwatch_metrics/test_utils.py +0 -0
  49. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/test_common_and_server.py +0 -0
  50. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/test_init.py +0 -0
  51. {awslabs_cloudwatch_mcp_server-0.0.15 → awslabs_cloudwatch_mcp_server-0.0.17}/tests/test_main.py +0 -0
@@ -13,7 +13,11 @@
13
13
  # limitations under the License.
14
14
 
15
15
  # dependabot should continue to update this to the latest hash.
16
- FROM public.ecr.aws/docker/library/python:3.13-alpine@sha256:070342a0cc1011532c0e69972cce2bbc6cc633eba294bae1d12abea8bd05303b AS uv
16
+ FROM public.ecr.aws/amazonlinux/amazonlinux@sha256:e27a70c006c68f0d194cc9b9624714d6ed8d979a94f60f7d31392f4c8294155b AS uv
17
+
18
+ # Install build dependencies needed for compiling packages
19
+ RUN dnf install -y shadow-utils python3 python3-devel gcc && \
20
+ dnf clean all
17
21
 
18
22
  # Install the project into `/app`
19
23
  WORKDIR /app
@@ -25,7 +29,7 @@ ENV UV_COMPILE_BYTECODE=1
25
29
  ENV UV_LINK_MODE=copy
26
30
 
27
31
  # Prefer the system python
28
- ENV UV_PYTHON_PREFERENCE=only-system
32
+ ENV UV_PYTHON_PREFERENCE=only-managed
29
33
 
30
34
  # Run without updating the uv.lock file like running with `--frozen`
31
35
  ENV UV_FROZEN=true
@@ -37,19 +41,10 @@ COPY pyproject.toml uv.lock uv-requirements.txt ./
37
41
  ENV PIP_NO_CACHE_DIR=1 \
38
42
  PIP_DISABLE_PIP_VERSION_CHECK=1
39
43
 
40
- # Install system dependencies and Python package manager
41
- RUN apk update && \
42
- apk add --no-cache --virtual .build-deps \
43
- build-base \
44
- gcc \
45
- musl-dev \
46
- libffi-dev \
47
- openssl-dev \
48
- cargo
49
-
50
44
  # Install the project's dependencies using the lockfile and settings
51
45
  RUN --mount=type=cache,target=/root/.cache/uv \
52
- pip install --require-hashes --requirement uv-requirements.txt --no-cache-dir && \
46
+ python3 -m ensurepip && \
47
+ python3 -m pip install --require-hashes --requirement uv-requirements.txt --no-cache-dir && \
53
48
  uv sync --python 3.13 --frozen --no-install-project --no-dev --no-editable
54
49
 
55
50
  # Then, add the rest of the project source code and install it
@@ -61,20 +56,22 @@ RUN --mount=type=cache,target=/root/.cache/uv \
61
56
  # Make the directory just in case it doesn't exist
62
57
  RUN mkdir -p /root/.local
63
58
 
64
- FROM public.ecr.aws/docker/library/python:3.13-alpine@sha256:070342a0cc1011532c0e69972cce2bbc6cc633eba294bae1d12abea8bd05303b
59
+ FROM public.ecr.aws/amazonlinux/amazonlinux@sha256:e27a70c006c68f0d194cc9b9624714d6ed8d979a94f60f7d31392f4c8294155b
65
60
 
66
61
  # Place executables in the environment at the front of the path and include other binaries
67
- ENV PATH="/app/.venv/bin:$PATH" \
62
+ ENV PATH="/app/.venv/bin:$PATH:/usr/sbin" \
68
63
  PYTHONUNBUFFERED=1
69
64
 
70
- # Install runtime dependencies and create application user
71
- RUN apk update && \
72
- apk add --no-cache ca-certificates && \
73
- update-ca-certificates && \
74
- addgroup -S app && \
75
- adduser -S app -G app -h /app
65
+ # Install other tools as needed for the MCP server
66
+ # Add non-root user and ability to change directory into /root
67
+ RUN dnf install -y shadow-utils procps && \
68
+ dnf clean all && \
69
+ groupadd --force --system app && \
70
+ useradd app -g app -d /app && \
71
+ chmod o+x /root
76
72
 
77
- # Copy application artifacts from build stage
73
+ # Get the project from the uv layer
74
+ COPY --from=uv --chown=app:app /root/.local /root/.local
78
75
  COPY --from=uv --chown=app:app /app/.venv /app/.venv
79
76
 
80
77
  # Get healthcheck script
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awslabs.cloudwatch-mcp-server
3
- Version: 0.0.15
3
+ Version: 0.0.17
4
4
  Summary: An AWS Labs Model Context Protocol (MCP) server for cloudwatch
5
5
  Project-URL: homepage, https://awslabs.github.io/mcp/
6
6
  Project-URL: docs, https://awslabs.github.io/mcp/servers/cloudwatch-mcp-server/
@@ -97,12 +97,12 @@ Alarm Recommendations - Suggests recommended alarm configurations for CloudWatch
97
97
 
98
98
  #### One Click Install
99
99
 
100
- | Cursor | VS Code |
101
- |:------:|:-------:|
102
- | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/en/install-mcp?name=awslabs.cloudwatch-mcp-server&config=ewogICAgImF1dG9BcHByb3ZlIjogW10sCiAgICAiZGlzYWJsZWQiOiBmYWxzZSwKICAgICJjb21tYW5kIjogInV2eCBhd3NsYWJzLmNsb3Vkd2F0Y2gtbWNwLXNlcnZlckBsYXRlc3QiLAogICAgImVudiI6IHsKICAgICAgIkFXU19QUk9GSUxFIjogIltUaGUgQVdTIFByb2ZpbGUgTmFtZSB0byB1c2UgZm9yIEFXUyBhY2Nlc3NdIiwKICAgICAgIkZBU1RNQ1BfTE9HX0xFVkVMIjogIkVSUk9SIgogICAgfSwKICAgICJ0cmFuc3BvcnRUeXBlIjogInN0ZGlvIgp9) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=CloudWatch%20MCP%20Server&config=%7B%22autoApprove%22%3A%5B%5D%2C%22disabled%22%3Afalse%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.cloudwatch-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22AWS_PROFILE%22%3A%22%5BThe%20AWS%20Profile%20Name%20to%20use%20for%20AWS%20access%5D%22%2C%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%2C%22transportType%22%3A%22stdio%22%7D) |
100
+ | Kiro | Cursor | VS Code |
101
+ |:----:|:------:|:-------:|
102
+ | [![Add to Kiro](https://kiro.dev/images/add-to-kiro.svg)](https://kiro.dev/launch/mcp/add?name=awslabs.cloudwatch-mcp-server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.cloudwatch-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22AWS_PROFILE%22%3A%22%5BThe%20AWS%20Profile%20Name%20to%20use%20for%20AWS%20access%5D%22%2C%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%7D) | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/en/install-mcp?name=awslabs.cloudwatch-mcp-server&config=ewogICAgImF1dG9BcHByb3ZlIjogW10sCiAgICAiZGlzYWJsZWQiOiBmYWxzZSwKICAgICJjb21tYW5kIjogInV2eCBhd3NsYWJzLmNsb3Vkd2F0Y2gtbWNwLXNlcnZlckBsYXRlc3QiLAogICAgImVudiI6IHsKICAgICAgIkFXU19QUk9GSUxFIjogIltUaGUgQVdTIFByb2ZpbGUgTmFtZSB0byB1c2UgZm9yIEFXUyBhY2Nlc3NdIiwKICAgICAgIkZBU1RNQ1BfTE9HX0xFVkVMIjogIkVSUk9SIgogICAgfSwKICAgICJ0cmFuc3BvcnRUeXBlIjogInN0ZGlvIgp9) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=CloudWatch%20MCP%20Server&config=%7B%22autoApprove%22%3A%5B%5D%2C%22disabled%22%3Afalse%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.cloudwatch-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22AWS_PROFILE%22%3A%22%5BThe%20AWS%20Profile%20Name%20to%20use%20for%20AWS%20access%5D%22%2C%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%2C%22transportType%22%3A%22stdio%22%7D) |
103
103
 
104
- #### MCP Config (Q CLI, Cline)
105
- * For Q CLI, update MCP Config Amazon Q Developer CLI (~/.aws/amazonq/mcp.json)
104
+ #### MCP Config (Kiro, Cline)
105
+ * For Kiro, update MCP Config (~/.kiro/settings/mcp.json)
106
106
  * For Cline click on "Configure MCP Servers" option from MCP tab
107
107
  ```json
108
108
  {
@@ -166,7 +166,7 @@ Build and install docker image locally on the same host of your LLM client
166
166
  #### One Click Cursor Install
167
167
  [![Install CloudWatch MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://www.cursor.com/install-mcp?name=awslabs.cloudwatch-mcp-server&config=ewogICAgICAgICJjb21tYW5kIjogImRvY2tlciIsCiAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAicnVuIiwKICAgICAgICAgICItLXJtIiwKICAgICAgICAgICItLWludGVyYWN0aXZlIiwKICAgICAgICAgICItZSBBV1NfUFJPRklMRT1bVGhlIEFXUyBQcm9maWxlIE5hbWVdIiwKICAgICAgICAgICJhd3NsYWJzL2Nsb3Vkd2F0Y2gtbWNwLXNlcnZlcjpsYXRlc3QiCiAgICAgICAgXSwKICAgICAgICAiZW52Ijoge30sCiAgICAgICAgImRpc2FibGVkIjogZmFsc2UsCiAgICAgICAgImF1dG9BcHByb3ZlIjogW10KfQ==)
168
168
 
169
- #### MCP Config using Docker image(Q CLI, Cline)
169
+ #### MCP Config using Docker image(Kiro, Cline)
170
170
  ```json
171
171
  {
172
172
  "mcpServers": {
@@ -65,12 +65,12 @@ Alarm Recommendations - Suggests recommended alarm configurations for CloudWatch
65
65
 
66
66
  #### One Click Install
67
67
 
68
- | Cursor | VS Code |
69
- |:------:|:-------:|
70
- | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/en/install-mcp?name=awslabs.cloudwatch-mcp-server&config=ewogICAgImF1dG9BcHByb3ZlIjogW10sCiAgICAiZGlzYWJsZWQiOiBmYWxzZSwKICAgICJjb21tYW5kIjogInV2eCBhd3NsYWJzLmNsb3Vkd2F0Y2gtbWNwLXNlcnZlckBsYXRlc3QiLAogICAgImVudiI6IHsKICAgICAgIkFXU19QUk9GSUxFIjogIltUaGUgQVdTIFByb2ZpbGUgTmFtZSB0byB1c2UgZm9yIEFXUyBhY2Nlc3NdIiwKICAgICAgIkZBU1RNQ1BfTE9HX0xFVkVMIjogIkVSUk9SIgogICAgfSwKICAgICJ0cmFuc3BvcnRUeXBlIjogInN0ZGlvIgp9) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=CloudWatch%20MCP%20Server&config=%7B%22autoApprove%22%3A%5B%5D%2C%22disabled%22%3Afalse%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.cloudwatch-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22AWS_PROFILE%22%3A%22%5BThe%20AWS%20Profile%20Name%20to%20use%20for%20AWS%20access%5D%22%2C%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%2C%22transportType%22%3A%22stdio%22%7D) |
68
+ | Kiro | Cursor | VS Code |
69
+ |:----:|:------:|:-------:|
70
+ | [![Add to Kiro](https://kiro.dev/images/add-to-kiro.svg)](https://kiro.dev/launch/mcp/add?name=awslabs.cloudwatch-mcp-server&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.cloudwatch-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22AWS_PROFILE%22%3A%22%5BThe%20AWS%20Profile%20Name%20to%20use%20for%20AWS%20access%5D%22%2C%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%7D) | [![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://cursor.com/en/install-mcp?name=awslabs.cloudwatch-mcp-server&config=ewogICAgImF1dG9BcHByb3ZlIjogW10sCiAgICAiZGlzYWJsZWQiOiBmYWxzZSwKICAgICJjb21tYW5kIjogInV2eCBhd3NsYWJzLmNsb3Vkd2F0Y2gtbWNwLXNlcnZlckBsYXRlc3QiLAogICAgImVudiI6IHsKICAgICAgIkFXU19QUk9GSUxFIjogIltUaGUgQVdTIFByb2ZpbGUgTmFtZSB0byB1c2UgZm9yIEFXUyBhY2Nlc3NdIiwKICAgICAgIkZBU1RNQ1BfTE9HX0xFVkVMIjogIkVSUk9SIgogICAgfSwKICAgICJ0cmFuc3BvcnRUeXBlIjogInN0ZGlvIgp9) | [![Install on VS Code](https://img.shields.io/badge/Install_on-VS_Code-FF9900?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=CloudWatch%20MCP%20Server&config=%7B%22autoApprove%22%3A%5B%5D%2C%22disabled%22%3Afalse%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22awslabs.cloudwatch-mcp-server%40latest%22%5D%2C%22env%22%3A%7B%22AWS_PROFILE%22%3A%22%5BThe%20AWS%20Profile%20Name%20to%20use%20for%20AWS%20access%5D%22%2C%22FASTMCP_LOG_LEVEL%22%3A%22ERROR%22%7D%2C%22transportType%22%3A%22stdio%22%7D) |
71
71
 
72
- #### MCP Config (Q CLI, Cline)
73
- * For Q CLI, update MCP Config Amazon Q Developer CLI (~/.aws/amazonq/mcp.json)
72
+ #### MCP Config (Kiro, Cline)
73
+ * For Kiro, update MCP Config (~/.kiro/settings/mcp.json)
74
74
  * For Cline click on "Configure MCP Servers" option from MCP tab
75
75
  ```json
76
76
  {
@@ -134,7 +134,7 @@ Build and install docker image locally on the same host of your LLM client
134
134
  #### One Click Cursor Install
135
135
  [![Install CloudWatch MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)](https://www.cursor.com/install-mcp?name=awslabs.cloudwatch-mcp-server&config=ewogICAgICAgICJjb21tYW5kIjogImRvY2tlciIsCiAgICAgICAgImFyZ3MiOiBbCiAgICAgICAgICAicnVuIiwKICAgICAgICAgICItLXJtIiwKICAgICAgICAgICItLWludGVyYWN0aXZlIiwKICAgICAgICAgICItZSBBV1NfUFJPRklMRT1bVGhlIEFXUyBQcm9maWxlIE5hbWVdIiwKICAgICAgICAgICJhd3NsYWJzL2Nsb3Vkd2F0Y2gtbWNwLXNlcnZlcjpsYXRlc3QiCiAgICAgICAgXSwKICAgICAgICAiZW52Ijoge30sCiAgICAgICAgImRpc2FibGVkIjogZmFsc2UsCiAgICAgICAgImF1dG9BcHByb3ZlIjogW10KfQ==)
136
136
 
137
- #### MCP Config using Docker image(Q CLI, Cline)
137
+ #### MCP Config using Docker image(Kiro, Cline)
138
138
  ```json
139
139
  {
140
140
  "mcpServers": {
@@ -14,5 +14,5 @@
14
14
 
15
15
  """awslabs.cloudwatch-mcp-server"""
16
16
 
17
- __version__ = '0.0.15'
17
+ __version__ = '0.0.17'
18
18
  MCP_SERVER_VERSION = __version__
@@ -0,0 +1,55 @@
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
+ """AWS client utilities for CloudWatch MCP Server with multi-profile support."""
16
+
17
+ from awslabs.cloudwatch_mcp_server import MCP_SERVER_VERSION
18
+ from boto3 import Session
19
+ from botocore.config import Config
20
+ from os import getenv
21
+
22
+
23
+ def get_aws_client(
24
+ service_name: str,
25
+ region_name: str | None = None,
26
+ profile_name: str | None = None,
27
+ ):
28
+ """AWS Client handler with multi-profile support.
29
+
30
+ Args:
31
+ service_name: AWS service name (e.g., 'logs', 'cloudwatch')
32
+ region_name: AWS region. Defaults to AWS_REGION env var or us-east-1 if not set
33
+ profile_name: AWS CLI profile name. Falls back to AWS_PROFILE env var if not specified,
34
+ or uses default AWS credential chain
35
+
36
+ Returns:
37
+ boto3 client for the specified service
38
+ """
39
+ # Set profile from parameter or environment
40
+ if profile_name is None:
41
+ profile_name = getenv('AWS_PROFILE', None)
42
+
43
+ # Configure user agent
44
+ config = Config(user_agent_extra=f'awslabs/mcp/cloudwatch-mcp-server/{MCP_SERVER_VERSION}')
45
+
46
+ # Create session with or without profile
47
+ if profile_name:
48
+ session = Session(profile_name=profile_name)
49
+ else:
50
+ session = Session()
51
+
52
+ # Use provided region, or session's region, or fallback to us-east-1
53
+ region = region_name or session.region_name or 'us-east-1'
54
+
55
+ return session.client(service_name, region_name=region, config=config)
@@ -14,10 +14,8 @@
14
14
 
15
15
  """CloudWatch Alarms tools for MCP server."""
16
16
 
17
- import boto3
18
17
  import json
19
- import os
20
- from awslabs.cloudwatch_mcp_server import MCP_SERVER_VERSION
18
+ from awslabs.cloudwatch_mcp_server.aws_common import get_aws_client
21
19
  from awslabs.cloudwatch_mcp_server.cloudwatch_alarms.models import (
22
20
  ActiveAlarmsResponse,
23
21
  AlarmDetails,
@@ -28,7 +26,6 @@ from awslabs.cloudwatch_mcp_server.cloudwatch_alarms.models import (
28
26
  MetricAlarmSummary,
29
27
  TimeRangeSuggestion,
30
28
  )
31
- from botocore.config import Config
32
29
  from datetime import datetime, timedelta
33
30
  from loguru import logger
34
31
  from mcp.server.fastmcp import Context
@@ -43,21 +40,6 @@ class CloudWatchAlarmsTools:
43
40
  """Initialize the CloudWatch Alarms tools."""
44
41
  pass
45
42
 
46
- def _get_cloudwatch_client(self, region: str):
47
- """Create a CloudWatch client for the specified region."""
48
- config = Config(user_agent_extra=f'awslabs/mcp/cloudwatch-mcp-server/{MCP_SERVER_VERSION}')
49
-
50
- try:
51
- if aws_profile := os.environ.get('AWS_PROFILE'):
52
- return boto3.Session(profile_name=aws_profile, region_name=region).client(
53
- 'cloudwatch', config=config
54
- )
55
- else:
56
- return boto3.Session(region_name=region).client('cloudwatch', config=config)
57
- except Exception as e:
58
- logger.error(f'Error creating cloudwatch client for region {region}: {str(e)}')
59
- raise
60
-
61
43
  def register(self, mcp):
62
44
  """Register all CloudWatch Alarms tools with the MCP server."""
63
45
  # Register get_active_alarms tool
@@ -76,9 +58,17 @@ class CloudWatchAlarmsTools:
76
58
  ),
77
59
  ] = 50,
78
60
  region: Annotated[
79
- str,
80
- Field(description='AWS region to query. Defaults to us-east-1.'),
81
- ] = 'us-east-1',
61
+ str | None,
62
+ Field(
63
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
64
+ ),
65
+ ] = None,
66
+ profile_name: Annotated[
67
+ str | None,
68
+ Field(
69
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
70
+ ),
71
+ ] = None,
82
72
  ) -> ActiveAlarmsResponse:
83
73
  """Gets all CloudWatch Alarms currently in ALARM state.
84
74
 
@@ -92,7 +82,8 @@ class CloudWatchAlarmsTools:
92
82
  Args:
93
83
  ctx: The MCP context object for error handling and logging.
94
84
  max_items: Maximum number of alarms to return (default: 50).
95
- region: AWS region to query. Defaults to 'us-east-1'.
85
+ region: AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.
86
+ profile_name: AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.
96
87
 
97
88
  Returns:
98
89
  ActiveAlarmsResponse: Response containing active alarms.
@@ -118,7 +109,7 @@ class CloudWatchAlarmsTools:
118
109
  raise ValueError('max_items must be at least 1')
119
110
 
120
111
  # Create CloudWatch client for the specified region
121
- cloudwatch_client = self._get_cloudwatch_client(region)
112
+ cloudwatch_client = get_aws_client('cloudwatch', region, profile_name)
122
113
 
123
114
  # Fetch active alarms using paginator
124
115
  logger.info(f'Fetching up to {max_items} active alarms')
@@ -220,9 +211,17 @@ class CloudWatchAlarmsTools:
220
211
  ),
221
212
  ] = False,
222
213
  region: Annotated[
223
- str,
224
- Field(description='AWS region to query. Defaults to us-east-1.'),
225
- ] = 'us-east-1',
214
+ str | None,
215
+ Field(
216
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
217
+ ),
218
+ ] = None,
219
+ profile_name: Annotated[
220
+ str | None,
221
+ Field(
222
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
223
+ ),
224
+ ] = None,
226
225
  ) -> Union[AlarmHistoryResponse, CompositeAlarmComponentResponse]:
227
226
  """Gets the history for a CloudWatch alarm with time range suggestions for investigation.
228
227
 
@@ -237,13 +236,14 @@ class CloudWatchAlarmsTools:
237
236
 
238
237
  Args:
239
238
  ctx: The MCP context object for error handling and logging.
240
- region: AWS region to query. Defaults to 'us-east-1'.
239
+ region: AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.
241
240
  alarm_name: Name of the alarm to retrieve history for.
242
241
  start_time: Optional start time for the history query. Defaults to 24 hours ago.
243
242
  end_time: Optional end time for the history query. Defaults to current time.
244
243
  history_item_type: Optional type of history items to retrieve. Defaults to 'StateUpdate'.
245
244
  max_items: Maximum number of history items to return. Defaults to 50.
246
245
  include_component_alarms: For composite alarms, whether to include details about component alarms.
246
+ profile_name: AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.
247
247
 
248
248
  Returns:
249
249
  Union[AlarmHistoryResponse, CompositeAlarmComponentResponse]: Either a response containing
@@ -271,7 +271,7 @@ class CloudWatchAlarmsTools:
271
271
  history_item_type = 'StateUpdate'
272
272
 
273
273
  # Create CloudWatch client for the specified region
274
- cloudwatch_client = self._get_cloudwatch_client(region)
274
+ cloudwatch_client = get_aws_client('cloudwatch', region, profile_name)
275
275
 
276
276
  # Set up default time range (last 24 hours)
277
277
  if end_time is None or not isinstance(end_time, str):
@@ -15,10 +15,8 @@
15
15
  """CloudWatch Logs tools for MCP server."""
16
16
 
17
17
  import asyncio
18
- import boto3
19
18
  import datetime
20
- import os
21
- from awslabs.cloudwatch_mcp_server import MCP_SERVER_VERSION
19
+ from awslabs.cloudwatch_mcp_server.aws_common import get_aws_client
22
20
  from awslabs.cloudwatch_mcp_server.cloudwatch_logs.models import (
23
21
  LogAnomaly,
24
22
  LogAnomalyDetector,
@@ -34,7 +32,6 @@ from awslabs.cloudwatch_mcp_server.common import (
34
32
  filter_by_prefixes,
35
33
  remove_null_values,
36
34
  )
37
- from botocore.config import Config
38
35
  from loguru import logger
39
36
  from mcp.server.fastmcp import Context
40
37
  from pydantic import Field
@@ -47,31 +44,7 @@ class CloudWatchLogsTools:
47
44
 
48
45
  def __init__(self):
49
46
  """Initialize the CloudWatch Logs tools."""
50
- self._logs_client = None
51
- self._logs_client_region = None
52
-
53
- @property
54
- def logs_client(self):
55
- """Get the logs client for the default region (us-east-1)."""
56
- if self._logs_client is None or self._logs_client_region != 'us-east-1':
57
- self._logs_client = self._get_logs_client('us-east-1')
58
- self._logs_client_region = 'us-east-1'
59
- return self._logs_client
60
-
61
- def _get_logs_client(self, region: str):
62
- """Create a CloudWatch Logs client for the specified region."""
63
- config = Config(user_agent_extra=f'awslabs/mcp/cloudwatch-mcp-server/{MCP_SERVER_VERSION}')
64
-
65
- try:
66
- if aws_profile := os.environ.get('AWS_PROFILE'):
67
- return boto3.Session(profile_name=aws_profile, region_name=region).client(
68
- 'logs', config=config
69
- )
70
- else:
71
- return boto3.Session(region_name=region).client('logs', config=config)
72
- except Exception as e:
73
- logger.error(f'Error creating cloudwatch logs client for region {region}: {str(e)}')
74
- raise
47
+ pass
75
48
 
76
49
  def _validate_log_group_parameters(
77
50
  self, log_group_names: Optional[List[str]], log_group_identifiers: Optional[List[str]]
@@ -267,9 +240,17 @@ class CloudWatchLogsTools:
267
240
  int | None, Field(description=('The maximum number of log groups to return.'))
268
241
  ] = None,
269
242
  region: Annotated[
270
- str,
271
- Field(description='AWS region to query. Defaults to us-east-1.'),
272
- ] = 'us-east-1',
243
+ str | None,
244
+ Field(
245
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
246
+ ),
247
+ ] = None,
248
+ profile_name: Annotated[
249
+ str | None,
250
+ Field(
251
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
252
+ ),
253
+ ] = None,
273
254
  ) -> LogsMetadata:
274
255
  """Lists AWS CloudWatch log groups and saved queries associated with them, optionally filtering by a name prefix.
275
256
 
@@ -295,7 +276,7 @@ class CloudWatchLogsTools:
295
276
  Any saved queries that are applicable to the returned log groups are also included.
296
277
  """
297
278
  # Create logs client for the specified region
298
- logs_client = self._get_logs_client(region)
279
+ logs_client = get_aws_client('logs', region, profile_name)
299
280
 
300
281
  def describe_log_groups() -> List[LogGroupMetadata]:
301
282
  paginator = logs_client.get_paginator('describe_log_groups')
@@ -379,9 +360,17 @@ class CloudWatchLogsTools:
379
360
  ),
380
361
  ),
381
362
  region: Annotated[
382
- str,
383
- Field(description='AWS region to query. Defaults to us-east-1.'),
384
- ] = 'us-east-1',
363
+ str | None,
364
+ Field(
365
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
366
+ ),
367
+ ] = None,
368
+ profile_name: Annotated[
369
+ str | None,
370
+ Field(
371
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
372
+ ),
373
+ ] = None,
385
374
  ) -> LogsAnalysisResult:
386
375
  """Analyzes a CloudWatch log group for anomalies, message patterns, and error patterns within a specified time window.
387
376
 
@@ -426,7 +415,7 @@ class CloudWatchLogsTools:
426
415
  return log_group_arn in anomaly.logGroupArnList
427
416
 
428
417
  # Create logs client for the specified region
429
- logs_client = self._get_logs_client(region)
418
+ logs_client = get_aws_client('logs', region, profile_name)
430
419
 
431
420
  async def get_applicable_anomalies() -> LogAnomalyResults:
432
421
  detectors: List[LogAnomalyDetector] = []
@@ -552,9 +541,17 @@ class CloudWatchLogsTools:
552
541
  ),
553
542
  ] = 30,
554
543
  region: Annotated[
555
- str,
556
- Field(description='AWS region to query. Defaults to us-east-1.'),
557
- ] = 'us-east-1',
544
+ str | None,
545
+ Field(
546
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
547
+ ),
548
+ ] = None,
549
+ profile_name: Annotated[
550
+ str | None,
551
+ Field(
552
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
553
+ ),
554
+ ] = None,
558
555
  ) -> Dict:
559
556
  """Executes a CloudWatch Logs Insights query and waits for the results to be available.
560
557
 
@@ -590,7 +587,7 @@ class CloudWatchLogsTools:
590
587
  )
591
588
 
592
589
  # Create logs client for the specified region
593
- logs_client = self._get_logs_client(region)
590
+ logs_client = get_aws_client('logs', region, profile_name)
594
591
 
595
592
  # Start the query
596
593
  start_response = logs_client.start_query(**remove_null_values(kwargs))
@@ -621,9 +618,17 @@ class CloudWatchLogsTools:
621
618
  description='The unique ID of the query to retrieve the results for. CRITICAL: This ID is returned by the execute_log_insights_query tool.',
622
619
  ),
623
620
  region: Annotated[
624
- str,
625
- Field(description='AWS region to query. Defaults to us-east-1.'),
626
- ] = 'us-east-1',
621
+ str | None,
622
+ Field(
623
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
624
+ ),
625
+ ] = None,
626
+ profile_name: Annotated[
627
+ str | None,
628
+ Field(
629
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
630
+ ),
631
+ ] = None,
627
632
  ) -> Dict:
628
633
  """Retrieves the results of a previously started CloudWatch Logs Insights query.
629
634
 
@@ -640,7 +645,7 @@ class CloudWatchLogsTools:
640
645
  """
641
646
  try:
642
647
  # Create logs client for the specified region
643
- logs_client = self._get_logs_client(region)
648
+ logs_client = get_aws_client('logs', region, profile_name)
644
649
 
645
650
  response = logs_client.get_query_results(queryId=query_id)
646
651
 
@@ -675,9 +680,17 @@ class CloudWatchLogsTools:
675
680
  description='The unique ID of the ongoing query to cancel. CRITICAL: This ID is returned by the execute_log_insights_query tool.',
676
681
  ),
677
682
  region: Annotated[
678
- str,
679
- Field(description='AWS region to query. Defaults to us-east-1.'),
680
- ] = 'us-east-1',
683
+ str | None,
684
+ Field(
685
+ description='AWS region to query. Defaults to AWS_REGION environment variable or us-east-1 if not set.'
686
+ ),
687
+ ] = None,
688
+ profile_name: Annotated[
689
+ str | None,
690
+ Field(
691
+ description='AWS CLI Profile Name to use for AWS access. Falls back to AWS_PROFILE environment variable if not specified, or uses default AWS credential chain.'
692
+ ),
693
+ ] = None,
681
694
  ) -> LogsQueryCancelResult:
682
695
  """Cancels an ongoing CloudWatch Logs Insights query. If the query has already ended, returns an error that the given query is not running.
683
696
 
@@ -690,7 +703,7 @@ class CloudWatchLogsTools:
690
703
  """
691
704
  try:
692
705
  # Create logs client for the specified region
693
- logs_client = self._get_logs_client(region)
706
+ logs_client = get_aws_client('logs', region, profile_name)
694
707
 
695
708
  response = logs_client.stop_query(queryId=query_id)
696
709
  return LogsQueryCancelResult.model_validate(response)