awslabs.cdk-mcp-server 0.0.10417__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.
- awslabs_cdk_mcp_server-0.0.10417/.gitignore +59 -0
- awslabs_cdk_mcp_server-0.0.10417/.pre-commit-config.yaml +14 -0
- awslabs_cdk_mcp_server-0.0.10417/.python-version +1 -0
- awslabs_cdk_mcp_server-0.0.10417/CHANGELOG.md +12 -0
- awslabs_cdk_mcp_server-0.0.10417/PKG-INFO +14 -0
- awslabs_cdk_mcp_server-0.0.10417/README.md +3 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/__init__.py +2 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/__init__.py +8 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/core/__init__.py +1 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/core/resources.py +271 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/core/search_utils.py +182 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/core/server.py +74 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/core/tools.py +324 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/__init__.py +1 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/cdk_nag_parser.py +331 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/construct_descriptions.py +32 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/genai_cdk_loader.py +423 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/lambda_powertools_loader.py +48 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/schema_generator.py +666 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/data/solutions_constructs_parser.py +782 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/server.py +7 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/CDK_GENERAL_GUIDANCE.md +232 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/CDK_NAG_GUIDANCE.md +192 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/__init__.py +5 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/actiongroups.md +137 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/alias.md +39 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/collaboration.md +91 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/creation.md +149 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/custom_orchestration.md +74 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/overview.md +78 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/agent/prompt_override.md +70 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/bedrockguardrails.md +188 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/chunking.md +137 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/datasources.md +225 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/kendra.md +81 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/overview.md +116 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/parsing.md +36 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/transformation.md +30 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/vector/aurora.md +185 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/vector/creation.md +80 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/vector/opensearch.md +56 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/knowledgebases/vector/pinecone.md +66 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/bedrock/profiles.md +153 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/actiongroups.md +137 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/alias.md +39 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/collaboration.md +91 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/creation.md +149 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/custom_orchestration.md +74 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/overview.md +78 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/prompt_override.md +70 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/bedrockguardrails.md +188 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/chunking.md +137 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/datasources.md +225 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/kendra.md +81 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/overview.md +116 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/parsing.md +36 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/transformation.md +30 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/aurora.md +185 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/creation.md +80 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/opensearch.md +56 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/pinecone.md +66 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/profiles.md +153 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/opensearch-vectorindex/overview.md +135 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/genai_cdk/opensearchserverless/overview.md +17 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/bedrock.md +127 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/cdk.md +99 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/dependencies.md +45 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/index.md +36 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/insights.md +95 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/logging.md +43 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/metrics.md +93 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/lambda_powertools/tracing.md +63 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/opensearch-vectorindex/overview.md +135 -0
- awslabs_cdk_mcp_server-0.0.10417/awslabs/cdk_mcp_server/static/opensearchserverless/overview.md +17 -0
- awslabs_cdk_mcp_server-0.0.10417/pyproject.toml +81 -0
- awslabs_cdk_mcp_server-0.0.10417/uv.lock +692 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
# Virtual environments
|
|
26
|
+
.venv
|
|
27
|
+
env/
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
|
|
31
|
+
# IDE
|
|
32
|
+
.idea/
|
|
33
|
+
.vscode/
|
|
34
|
+
*.swp
|
|
35
|
+
*.swo
|
|
36
|
+
|
|
37
|
+
# Testing
|
|
38
|
+
.tox/
|
|
39
|
+
.coverage
|
|
40
|
+
.coverage.*
|
|
41
|
+
htmlcov/
|
|
42
|
+
.pytest_cache/
|
|
43
|
+
|
|
44
|
+
# Ruff
|
|
45
|
+
.ruff_cache/
|
|
46
|
+
|
|
47
|
+
# Build
|
|
48
|
+
*.manifest
|
|
49
|
+
*.spec
|
|
50
|
+
.pybuilder/
|
|
51
|
+
target/
|
|
52
|
+
|
|
53
|
+
# Environments
|
|
54
|
+
.env
|
|
55
|
+
.env.local
|
|
56
|
+
.env.*.local
|
|
57
|
+
|
|
58
|
+
# PyPI
|
|
59
|
+
.pypirc
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.9.6
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/commitizen-tools/commitizen
|
|
10
|
+
rev: v3.13.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: commitizen
|
|
13
|
+
- id: commitizen-branch
|
|
14
|
+
stages: [push]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial project setup
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: awslabs.cdk-mcp-server
|
|
3
|
+
Version: 0.0.10417
|
|
4
|
+
Summary: An AWS CDK MCP server that provides guidance on AWS Cloud Development Kit best practices, infrastructure as code patterns, and security compliance with CDK Nag. This server offers tools to validate infrastructure designs, explain CDK Nag rules, analyze suppressions, generate Bedrock Agent schemas, and discover Solutions Constructs patterns.
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
|
+
Requires-Dist: aws-lambda-powertools>=2.30.0
|
|
7
|
+
Requires-Dist: httpx>=0.27.0
|
|
8
|
+
Requires-Dist: mcp[cli]>=1.6.0
|
|
9
|
+
Requires-Dist: pydantic>=2.10.6
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# awslabs MCP CDK Expert
|
|
13
|
+
|
|
14
|
+
An AWS CDK expert MCP server that provides guidance on AWS Cloud Development Kit best practices, infrastructure as code patterns, and security compliance with CDK Nag. This server offers tools to validate infrastructure designs, explain CDK Nag rules, analyze suppressions, generate Bedrock Agent schemas, and discover Solutions Constructs patterns.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# awslabs MCP CDK Expert
|
|
2
|
+
|
|
3
|
+
An AWS CDK expert MCP server that provides guidance on AWS Cloud Development Kit best practices, infrastructure as code patterns, and security compliance with CDK Nag. This server offers tools to validate infrastructure designs, explain CDK Nag rules, analyze suppressions, generate Bedrock Agent schemas, and discover Solutions Constructs patterns.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Core modules for the AWS CDK MCP server."""
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"""AWS CDK MCP resource handlers."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from awslabs.cdk_mcp_server.data.cdk_nag_parser import get_errors, get_rule_pack, get_warnings
|
|
5
|
+
from awslabs.cdk_mcp_server.data.genai_cdk_loader import (
|
|
6
|
+
get_genai_cdk_construct,
|
|
7
|
+
get_genai_cdk_construct_section,
|
|
8
|
+
get_genai_cdk_overview,
|
|
9
|
+
list_available_sections,
|
|
10
|
+
)
|
|
11
|
+
from awslabs.cdk_mcp_server.data.lambda_powertools_loader import get_lambda_powertools_section
|
|
12
|
+
from awslabs.cdk_mcp_server.data.solutions_constructs_parser import get_pattern_raw
|
|
13
|
+
from enum import Enum
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Set up logging
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class RulePack(str, Enum):
|
|
21
|
+
"""CDK Nag rule packs."""
|
|
22
|
+
|
|
23
|
+
AWS_SOLUTIONS = 'AWS Solutions'
|
|
24
|
+
HIPAA_SECURITY = 'HIPAA Security'
|
|
25
|
+
NIST_800_53_REV4 = 'NIST 800-53 rev 4'
|
|
26
|
+
NIST_800_53_REV5 = 'NIST 800-53 rev 5'
|
|
27
|
+
PCI_DSS_321 = 'PCI DSS 3.2.1'
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def get_all_cdk_nag_rules(rule_pack: str) -> str:
|
|
31
|
+
"""Get all rules for a specific CDK Nag rule pack.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
rule_pack: The CDK Nag rule pack name (e.g., "AWS Solutions", "HIPAA Security")
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
String containing the rule description and details
|
|
38
|
+
"""
|
|
39
|
+
# Convert string to enum value
|
|
40
|
+
try:
|
|
41
|
+
rule_pack_enum = RulePack(rule_pack)
|
|
42
|
+
return await get_rule_pack(rule_pack_enum)
|
|
43
|
+
except ValueError:
|
|
44
|
+
return f'Invalid rule pack: {rule_pack}. Valid values are: {", ".join([p.value for p in RulePack])}'
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def get_cdk_nag_warnings(rule_pack: str) -> str:
|
|
48
|
+
"""Get only the warnings section for a specific CDK Nag rule pack.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
rule_pack: The CDK Nag rule pack name (e.g., "AWS Solutions", "HIPAA Security")
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
String containing the warnings section of the rule pack
|
|
55
|
+
"""
|
|
56
|
+
# Convert string to enum value
|
|
57
|
+
try:
|
|
58
|
+
rule_pack_enum = RulePack(rule_pack)
|
|
59
|
+
return await get_warnings(rule_pack_enum)
|
|
60
|
+
except ValueError:
|
|
61
|
+
return f'Invalid rule pack: {rule_pack}. Valid values are: {", ".join([p.value for p in RulePack])}'
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
async def get_cdk_nag_errors(rule_pack: str) -> str:
|
|
65
|
+
"""Get only the errors section for a specific CDK Nag rule pack.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
rule_pack: The CDK Nag rule pack name (e.g., "AWS Solutions", "HIPAA Security")
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
String containing the errors section of the rule pack
|
|
72
|
+
"""
|
|
73
|
+
# Convert string to enum value
|
|
74
|
+
try:
|
|
75
|
+
rule_pack_enum = RulePack(rule_pack)
|
|
76
|
+
return await get_errors(rule_pack_enum)
|
|
77
|
+
except ValueError:
|
|
78
|
+
return f'Invalid rule pack: {rule_pack}. Valid values are: {", ".join([p.value for p in RulePack])}'
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
async def get_lambda_powertools_guidance(topic: str = '') -> str:
|
|
82
|
+
"""Get Lambda Powertools guidance on a specific topic.
|
|
83
|
+
|
|
84
|
+
Lambda Powertools provides three core capabilities:
|
|
85
|
+
- Structured Logging: Transform text logs into JSON objects with consistent fields
|
|
86
|
+
- Tracing: Gain visibility into request flows across distributed services
|
|
87
|
+
- Metrics: Collect quantitative data about your application's behavior
|
|
88
|
+
|
|
89
|
+
Available topics:
|
|
90
|
+
- logging: Structured logging implementation
|
|
91
|
+
- tracing: Tracing implementation
|
|
92
|
+
- metrics: Metrics implementation
|
|
93
|
+
- cdk: CDK integration patterns
|
|
94
|
+
- dependencies: Dependencies management
|
|
95
|
+
- insights: Lambda Insights integration
|
|
96
|
+
- bedrock: Bedrock Agent integration
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
topic: Topic to get guidance on
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
String containing the guidance for the specified topic
|
|
103
|
+
"""
|
|
104
|
+
return get_lambda_powertools_section(topic)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
async def get_lambda_powertools_index() -> str:
|
|
108
|
+
"""Get Lambda Powertools guidance overview.
|
|
109
|
+
|
|
110
|
+
Lambda Powertools provides three core capabilities:
|
|
111
|
+
- Structured Logging: Transform text logs into JSON objects with consistent fields
|
|
112
|
+
- Tracing: Gain visibility into request flows across distributed services
|
|
113
|
+
- Metrics: Collect quantitative data about your application's behavior
|
|
114
|
+
|
|
115
|
+
Available topics:
|
|
116
|
+
- logging: Structured logging implementation
|
|
117
|
+
- tracing: Tracing implementation
|
|
118
|
+
- metrics: Metrics implementation
|
|
119
|
+
- cdk: CDK integration patterns
|
|
120
|
+
- dependencies: Dependencies management
|
|
121
|
+
- insights: Lambda Insights integration
|
|
122
|
+
- bedrock: Bedrock Agent integration
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
String containing the Lambda Powertools guidance overview
|
|
126
|
+
"""
|
|
127
|
+
return get_lambda_powertools_section('index')
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
async def get_solutions_construct_pattern_resource(pattern_name: str) -> str:
|
|
131
|
+
"""Get complete documentation for an AWS Solutions Constructs pattern.
|
|
132
|
+
|
|
133
|
+
This resource returns the full documentation for a pattern including:
|
|
134
|
+
- Code examples in multiple languages (TypeScript, Python, Java)
|
|
135
|
+
- Props tables with all configuration options
|
|
136
|
+
- Pattern properties and default settings
|
|
137
|
+
- Architecture diagrams
|
|
138
|
+
|
|
139
|
+
Common pattern categories include:
|
|
140
|
+
- Serverless API (aws-apigateway-lambda, aws-apigateway-lambda-dynamodb)
|
|
141
|
+
- Event-Driven (aws-s3-lambda, aws-sns-lambda, aws-sqs-lambda)
|
|
142
|
+
- Storage (aws-s3-dynamodb, aws-kinesisfirehose-s3)
|
|
143
|
+
- Web Application (aws-cloudfront-s3, aws-cloudfront-apigateway)
|
|
144
|
+
|
|
145
|
+
Integration with other best practices:
|
|
146
|
+
- Solutions Constructs implement many security best practices by default
|
|
147
|
+
- They work well with Lambda Powertools for observability
|
|
148
|
+
- They reduce the number of CDK Nag warnings in your code
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
pattern_name: The name of the pattern (e.g., 'aws-lambda-dynamodb')
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
String containing the complete pattern documentation as markdown
|
|
155
|
+
"""
|
|
156
|
+
# Get the raw pattern documentation directly
|
|
157
|
+
pattern_raw = await get_pattern_raw(pattern_name)
|
|
158
|
+
|
|
159
|
+
if 'error' in pattern_raw:
|
|
160
|
+
from awslabs.cdk_mcp_server.data.solutions_constructs_parser import fetch_pattern_list
|
|
161
|
+
|
|
162
|
+
return f"Pattern '{pattern_name}' not found. Available patterns: {', '.join(await fetch_pattern_list())}"
|
|
163
|
+
|
|
164
|
+
# Return the raw content directly
|
|
165
|
+
return pattern_raw['content']
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
async def get_genai_cdk_construct_section_resource(
|
|
169
|
+
construct_type: str, construct_name: str, section: str
|
|
170
|
+
) -> str:
|
|
171
|
+
"""Get a specific section of documentation for a GenAI CDK construct.
|
|
172
|
+
|
|
173
|
+
Example URIs:
|
|
174
|
+
- genai-cdk-constructs://bedrock/agent/actiongroups
|
|
175
|
+
- genai-cdk-constructs://bedrock/agent/alias
|
|
176
|
+
- genai-cdk-constructs://bedrock/knowledgebases/chunking
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
construct_type: Type of the construct (e.g., 'bedrock')
|
|
180
|
+
construct_name: Name of the construct (e.g., 'agent', 'knowledgebases')
|
|
181
|
+
section: Section of the documentation (e.g., 'actiongroups', 'chunking')
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
String containing the requested section of documentation
|
|
185
|
+
"""
|
|
186
|
+
return get_genai_cdk_construct_section(construct_type, construct_name, section)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def get_genai_cdk_construct_nested_section_resource(
|
|
190
|
+
construct_type: str, construct_name: str, parent: str, child: str
|
|
191
|
+
) -> str:
|
|
192
|
+
"""Get a nested section of documentation for a GenAI CDK construct.
|
|
193
|
+
|
|
194
|
+
Example URIs:
|
|
195
|
+
- genai-cdk-constructs://bedrock/knowledgebases/vector/opensearch
|
|
196
|
+
- genai-cdk-constructs://bedrock/knowledgebases/vector/aurora
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
construct_type: Type of the construct (e.g., 'bedrock')
|
|
200
|
+
construct_name: Name of the construct (e.g., 'knowledgebases')
|
|
201
|
+
parent: Parent section (e.g., 'vector')
|
|
202
|
+
child: Child section (e.g., 'opensearch')
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
String containing the requested nested section of documentation
|
|
206
|
+
"""
|
|
207
|
+
section = f'{parent}/{child}'
|
|
208
|
+
return get_genai_cdk_construct_section(construct_type, construct_name, section)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
async def get_available_sections_resource(construct_type: str, construct_name: str) -> str:
|
|
212
|
+
"""Get available sections for a specific construct.
|
|
213
|
+
|
|
214
|
+
Example URI:
|
|
215
|
+
- genai-cdk-constructs://bedrock/agent/sections
|
|
216
|
+
- genai-cdk-constructs://bedrock/knowledgebases/sections
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
construct_type: Type of the construct (e.g., 'bedrock')
|
|
220
|
+
construct_name: Name of the construct (e.g., 'agent', 'knowledgebases')
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
String containing available sections in markdown format
|
|
224
|
+
"""
|
|
225
|
+
sections = list_available_sections(construct_type, construct_name)
|
|
226
|
+
|
|
227
|
+
if not sections:
|
|
228
|
+
return f'No sections found for {construct_name} in {construct_type}.'
|
|
229
|
+
|
|
230
|
+
result = f'# Available Sections for {construct_name.capitalize()} in {construct_type.capitalize()}\n\n'
|
|
231
|
+
|
|
232
|
+
for section in sorted(sections):
|
|
233
|
+
result += (
|
|
234
|
+
f'- [{section}](genai-cdk-constructs://{construct_type}/{construct_name}/{section})\n'
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
return result
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
async def get_genai_cdk_construct_resource(construct_type: str, construct_name: str) -> str:
|
|
241
|
+
"""Get essential information about a GenAI CDK construct.
|
|
242
|
+
|
|
243
|
+
Example URIs:
|
|
244
|
+
- genai-cdk-constructs://bedrock/Agent
|
|
245
|
+
- genai-cdk-constructs://bedrock/KnowledgeBase
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
construct_type: Type of the construct (e.g., 'bedrock')
|
|
249
|
+
construct_name: Name of the construct (e.g., 'Agent', 'KnowledgeBase')
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
String containing formatted properties and code examples in markdown
|
|
253
|
+
"""
|
|
254
|
+
return get_genai_cdk_construct(construct_type, construct_name)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
async def get_genai_cdk_overview_resource(construct_type: str) -> str:
|
|
258
|
+
"""Get overview of a GenAI CDK construct type.
|
|
259
|
+
|
|
260
|
+
Example URIs:
|
|
261
|
+
- genai-cdk-constructs://bedrock
|
|
262
|
+
- genai-cdk-constructs://opensearchserverless
|
|
263
|
+
- genai-cdk-constructs://opensearch-vectorindex
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
construct_type: Type of the construct (e.g., 'bedrock')
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
String containing overview documentation in markdown
|
|
270
|
+
"""
|
|
271
|
+
return get_genai_cdk_overview(construct_type)
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""Common search utilities for AWS CDK MCP Server."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import urllib.parse
|
|
5
|
+
from typing import Any, Callable, Dict, List, Optional, TypeVar
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
T = TypeVar('T') # Generic type for search items
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def normalize_term(term: str) -> str:
|
|
12
|
+
"""Normalize a term for consistent matching.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
term: The term to normalize
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
Normalized term (lowercase, with spaces preserved for word boundaries)
|
|
19
|
+
"""
|
|
20
|
+
# Decode URL-encoded strings
|
|
21
|
+
term = urllib.parse.unquote(term).lower()
|
|
22
|
+
|
|
23
|
+
# Replace hyphens and underscores with spaces
|
|
24
|
+
term = re.sub(r'[-_]', ' ', term)
|
|
25
|
+
|
|
26
|
+
# Remove other special characters but preserve spaces
|
|
27
|
+
term = re.sub(r'[^a-z0-9 ]', '', term)
|
|
28
|
+
|
|
29
|
+
# Normalize multiple spaces
|
|
30
|
+
term = re.sub(r'\s+', ' ', term).strip()
|
|
31
|
+
|
|
32
|
+
return term
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_term_variations(term: str) -> List[str]:
|
|
36
|
+
"""Get common variations of a term.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
term: The term to get variations for
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
List of term variations
|
|
43
|
+
"""
|
|
44
|
+
term = term.lower()
|
|
45
|
+
variations = [term]
|
|
46
|
+
|
|
47
|
+
# Common singular/plural mappings
|
|
48
|
+
term_variations = {
|
|
49
|
+
'knowledgebase': ['knowledgebases', 'knowledge-base', 'knowledge-bases'],
|
|
50
|
+
'knowledgebases': ['knowledgebase', 'knowledge-base', 'knowledge-bases'],
|
|
51
|
+
'agent': ['agents'],
|
|
52
|
+
'agents': ['agent'],
|
|
53
|
+
'actiongroup': ['actiongroups', 'action-group', 'action-groups'],
|
|
54
|
+
'actiongroups': ['actiongroup', 'action-group', 'action-groups'],
|
|
55
|
+
'apigateway': ['api-gateway', 'api gateway', 'apigatewayv2', 'api-gateway-v2'],
|
|
56
|
+
'lambda': ['lambdas', 'lambda-function', 'lambda-functions'],
|
|
57
|
+
'dynamodb': ['dynamo-db', 'dynamo db'],
|
|
58
|
+
's3': ['s3-bucket', 's3 bucket', 'simple storage service'],
|
|
59
|
+
'sqs': ['simple-queue-service', 'simple queue service'],
|
|
60
|
+
'sns': ['simple-notification-service', 'simple notification service'],
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Add variations if they exist
|
|
64
|
+
if term in term_variations:
|
|
65
|
+
variations.extend(term_variations[term])
|
|
66
|
+
|
|
67
|
+
return variations
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def expand_search_terms(terms: List[str]) -> List[str]:
|
|
71
|
+
"""Expand a list of search terms with variations.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
terms: List of search terms
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Expanded list of normalized search terms with variations
|
|
78
|
+
"""
|
|
79
|
+
expanded_terms = []
|
|
80
|
+
|
|
81
|
+
for term in terms:
|
|
82
|
+
# Normalize the term
|
|
83
|
+
norm_term = normalize_term(term)
|
|
84
|
+
if norm_term and norm_term not in expanded_terms:
|
|
85
|
+
expanded_terms.append(norm_term)
|
|
86
|
+
|
|
87
|
+
# Add variations
|
|
88
|
+
for variation in get_term_variations(term):
|
|
89
|
+
norm_variation = normalize_term(variation)
|
|
90
|
+
if norm_variation and norm_variation not in expanded_terms:
|
|
91
|
+
expanded_terms.append(norm_variation)
|
|
92
|
+
|
|
93
|
+
return expanded_terms
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def calculate_match_score(
|
|
97
|
+
item_text: str,
|
|
98
|
+
search_terms: List[str],
|
|
99
|
+
name_parts: Optional[List[str]] = None,
|
|
100
|
+
) -> Dict[str, Any]:
|
|
101
|
+
"""Calculate a match score for an item against search terms.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
item_text: The text to search in (e.g., description)
|
|
105
|
+
search_terms: List of search terms to match
|
|
106
|
+
name_parts: Optional list of name parts for higher-weight matching
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Dictionary with score and matched terms
|
|
110
|
+
"""
|
|
111
|
+
matched_terms = []
|
|
112
|
+
score = 0
|
|
113
|
+
|
|
114
|
+
for term in search_terms:
|
|
115
|
+
term_matched = False
|
|
116
|
+
|
|
117
|
+
# Check name parts first (highest weight)
|
|
118
|
+
if name_parts:
|
|
119
|
+
for part in name_parts:
|
|
120
|
+
if term in normalize_term(part):
|
|
121
|
+
score += 10
|
|
122
|
+
if term not in matched_terms:
|
|
123
|
+
matched_terms.append(term)
|
|
124
|
+
term_matched = True
|
|
125
|
+
break
|
|
126
|
+
|
|
127
|
+
# If not matched in name parts, check in full text
|
|
128
|
+
if not term_matched and term in item_text:
|
|
129
|
+
score += 5
|
|
130
|
+
if term not in matched_terms:
|
|
131
|
+
matched_terms.append(term)
|
|
132
|
+
|
|
133
|
+
# Bonus for matching multiple terms
|
|
134
|
+
if len(matched_terms) > 1:
|
|
135
|
+
score += len(matched_terms) * 3
|
|
136
|
+
|
|
137
|
+
return {'score': score, 'matched_terms': matched_terms, 'has_match': len(matched_terms) > 0}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def search_items_with_terms(
|
|
141
|
+
items: List[T],
|
|
142
|
+
search_terms: List[str],
|
|
143
|
+
get_text_fn: Callable[[T], str],
|
|
144
|
+
get_name_parts_fn: Optional[Callable[[T], List[str]]] = None,
|
|
145
|
+
) -> List[Dict[str, Any]]:
|
|
146
|
+
"""Generic function to search items with search terms.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
items: List of items to search
|
|
150
|
+
search_terms: List of search terms
|
|
151
|
+
get_text_fn: Function to extract searchable text from an item
|
|
152
|
+
get_name_parts_fn: Optional function to extract name parts from an item
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
List of matched items with scores
|
|
156
|
+
"""
|
|
157
|
+
# Expand search terms with variations
|
|
158
|
+
expanded_terms = expand_search_terms(search_terms)
|
|
159
|
+
|
|
160
|
+
# Calculate scores for each item
|
|
161
|
+
scored_items = []
|
|
162
|
+
|
|
163
|
+
for item in items:
|
|
164
|
+
item_text = normalize_term(get_text_fn(item))
|
|
165
|
+
name_parts = get_name_parts_fn(item) if get_name_parts_fn else None
|
|
166
|
+
|
|
167
|
+
match_result = calculate_match_score(item_text, expanded_terms, name_parts)
|
|
168
|
+
|
|
169
|
+
# Only include items with at least one match
|
|
170
|
+
if match_result['has_match']:
|
|
171
|
+
scored_items.append(
|
|
172
|
+
{
|
|
173
|
+
'item': item,
|
|
174
|
+
'score': match_result['score'],
|
|
175
|
+
'matched_terms': match_result['matched_terms'],
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# Sort by score (descending)
|
|
180
|
+
scored_items.sort(key=lambda x: x['score'], reverse=True)
|
|
181
|
+
|
|
182
|
+
return scored_items
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""AWS CDK MCP server implementation."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import logging
|
|
5
|
+
from awslabs.cdk_mcp_server.core import resources, tools
|
|
6
|
+
from mcp.server.fastmcp import FastMCP
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Set up logging
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Create MCP server
|
|
14
|
+
mcp = FastMCP(
|
|
15
|
+
'AWS CDK MCP Server',
|
|
16
|
+
dependencies=[
|
|
17
|
+
'pydantic',
|
|
18
|
+
'aws-lambda-powertools',
|
|
19
|
+
'httpx',
|
|
20
|
+
],
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Register resources
|
|
25
|
+
mcp.resource('cdk-nag://rules/{rule_pack}')(resources.get_all_cdk_nag_rules)
|
|
26
|
+
mcp.resource('cdk-nag://warnings/{rule_pack}')(resources.get_cdk_nag_warnings)
|
|
27
|
+
mcp.resource('cdk-nag://errors/{rule_pack}')(resources.get_cdk_nag_errors)
|
|
28
|
+
mcp.resource('lambda-powertools://{topic}')(resources.get_lambda_powertools_guidance)
|
|
29
|
+
mcp.resource('lambda-powertools://')(resources.get_lambda_powertools_index)
|
|
30
|
+
mcp.resource('aws-solutions-constructs://{pattern_name}')(
|
|
31
|
+
resources.get_solutions_construct_pattern_resource
|
|
32
|
+
)
|
|
33
|
+
mcp.resource('genai-cdk-constructs://{construct_type}/{construct_name}/{section}')(
|
|
34
|
+
resources.get_genai_cdk_construct_section_resource
|
|
35
|
+
)
|
|
36
|
+
mcp.resource('genai-cdk-constructs://{construct_type}/{construct_name}/{parent}/{child}')(
|
|
37
|
+
resources.get_genai_cdk_construct_nested_section_resource
|
|
38
|
+
)
|
|
39
|
+
mcp.resource('genai-cdk-constructs://{construct_type}/{construct_name}/sections')(
|
|
40
|
+
resources.get_available_sections_resource
|
|
41
|
+
)
|
|
42
|
+
mcp.resource('genai-cdk-constructs://{construct_type}/{construct_name}')(
|
|
43
|
+
resources.get_genai_cdk_construct_resource
|
|
44
|
+
)
|
|
45
|
+
mcp.resource('genai-cdk-constructs://{construct_type}')(resources.get_genai_cdk_overview_resource)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# Register tools
|
|
49
|
+
mcp.tool(name='CDKGeneralGuidance')(tools.cdk_guidance)
|
|
50
|
+
mcp.tool(name='ExplainCDKNagRule')(tools.explain_cdk_nag_rule)
|
|
51
|
+
mcp.tool(name='CheckCDKNagSuppressions')(tools.check_cdk_nag_suppressions_tool)
|
|
52
|
+
mcp.tool(name='GenerateBedrockAgentSchemaFromFile')(tools.bedrock_schema_generator_from_file)
|
|
53
|
+
mcp.tool(name='GetAwsSolutionsConstructPattern')(tools.get_aws_solutions_construct_pattern)
|
|
54
|
+
mcp.tool(name='SearchGenAICDKConstructs')(tools.search_genai_cdk_constructs)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def main():
|
|
58
|
+
"""Run the MCP server with CLI argument support."""
|
|
59
|
+
parser = argparse.ArgumentParser(description='AWS CDK MCP Server')
|
|
60
|
+
parser.add_argument('--sse', action='store_true', help='Use SSE transport')
|
|
61
|
+
parser.add_argument('--port', type=int, default=8888, help='Port to run the server on')
|
|
62
|
+
|
|
63
|
+
args = parser.parse_args()
|
|
64
|
+
|
|
65
|
+
# Run server with appropriate transport
|
|
66
|
+
if args.sse:
|
|
67
|
+
mcp.settings.port = args.port
|
|
68
|
+
mcp.run(transport='sse')
|
|
69
|
+
else:
|
|
70
|
+
mcp.run()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == '__main__':
|
|
74
|
+
main()
|