awslabs.cdk-mcp-server 0.0.91005__py3-none-any.whl → 0.0.2025141004__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/cdk_mcp_server/core/server.py +1 -0
- awslabs/cdk_mcp_server/core/tools.py +53 -0
- awslabs/cdk_mcp_server/data/lambda_layer_parser.py +231 -0
- awslabs/cdk_mcp_server/data/solutions_constructs_parser.py +1 -1
- awslabs/cdk_mcp_server/static/CDK_GENERAL_GUIDANCE.md +96 -172
- awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/pinecone.md +2 -2
- awslabs/cdk_mcp_server/static/lambda_powertools/bedrock.md +21 -36
- awslabs/cdk_mcp_server/static/lambda_powertools/cdk.md +30 -76
- awslabs/cdk_mcp_server/static/lambda_powertools/insights.md +12 -21
- awslabs/cdk_mcp_server/static/lambda_powertools/metrics.md +5 -36
- {awslabs_cdk_mcp_server-0.0.91005.dist-info → awslabs_cdk_mcp_server-0.0.2025141004.dist-info}/METADATA +49 -9
- {awslabs_cdk_mcp_server-0.0.91005.dist-info → awslabs_cdk_mcp_server-0.0.2025141004.dist-info}/RECORD +16 -13
- awslabs_cdk_mcp_server-0.0.2025141004.dist-info/licenses/LICENSE +175 -0
- awslabs_cdk_mcp_server-0.0.2025141004.dist-info/licenses/NOTICE +2 -0
- {awslabs_cdk_mcp_server-0.0.91005.dist-info → awslabs_cdk_mcp_server-0.0.2025141004.dist-info}/WHEEL +0 -0
- {awslabs_cdk_mcp_server-0.0.91005.dist-info → awslabs_cdk_mcp_server-0.0.2025141004.dist-info}/entry_points.txt +0 -0
|
@@ -63,6 +63,7 @@ mcp.tool(name='CheckCDKNagSuppressions')(tools.check_cdk_nag_suppressions_tool)
|
|
|
63
63
|
mcp.tool(name='GenerateBedrockAgentSchema')(tools.bedrock_schema_generator_from_file)
|
|
64
64
|
mcp.tool(name='GetAwsSolutionsConstructPattern')(tools.get_aws_solutions_construct_pattern)
|
|
65
65
|
mcp.tool(name='SearchGenAICDKConstructs')(tools.search_genai_cdk_constructs)
|
|
66
|
+
mcp.tool(name='LambdaLayerDocumentationProvider')(tools.lambda_layer_documentation_provider)
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
def main():
|
|
@@ -22,6 +22,7 @@ from awslabs.cdk_mcp_server.data.cdk_nag_parser import (
|
|
|
22
22
|
from awslabs.cdk_mcp_server.data.genai_cdk_loader import (
|
|
23
23
|
list_available_constructs,
|
|
24
24
|
)
|
|
25
|
+
from awslabs.cdk_mcp_server.data.lambda_layer_parser import LambdaLayerParser
|
|
25
26
|
from awslabs.cdk_mcp_server.data.schema_generator import generate_bedrock_schema_from_file
|
|
26
27
|
from awslabs.cdk_mcp_server.data.solutions_constructs_parser import (
|
|
27
28
|
fetch_pattern_list,
|
|
@@ -476,3 +477,55 @@ async def search_genai_cdk_constructs(
|
|
|
476
477
|
}
|
|
477
478
|
except Exception as e:
|
|
478
479
|
return {'error': f'Error searching constructs: {str(e)}', 'status': 'error'}
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
async def lambda_layer_documentation_provider(
|
|
483
|
+
ctx: Context,
|
|
484
|
+
layer_type: str, # "generic" or "python"
|
|
485
|
+
) -> Dict[str, Any]:
|
|
486
|
+
"""Provide documentation sources for Lambda layers.
|
|
487
|
+
|
|
488
|
+
This tool returns information about where to find documentation for Lambda layers
|
|
489
|
+
and instructs the MCP Client to fetch and process this documentation.
|
|
490
|
+
|
|
491
|
+
Args:
|
|
492
|
+
ctx: MCP context
|
|
493
|
+
layer_type: Type of layer ("generic" or "python")
|
|
494
|
+
|
|
495
|
+
Returns:
|
|
496
|
+
Dictionary with documentation source information
|
|
497
|
+
"""
|
|
498
|
+
if layer_type.lower() == 'python':
|
|
499
|
+
# For Python layers, use AWS Documentation MCP Server
|
|
500
|
+
return {
|
|
501
|
+
'layer_type': 'python',
|
|
502
|
+
'documentation_source': {
|
|
503
|
+
'server': 'awslabs.aws-documentation-mcp-server',
|
|
504
|
+
'tool': 'read_documentation',
|
|
505
|
+
'parameters': {'url': LambdaLayerParser.PYTHON_LAYER_URL, 'max_length': 10000},
|
|
506
|
+
},
|
|
507
|
+
'documentation_usage_guide': {
|
|
508
|
+
'when_to_fetch_full_docs': 'Fetch full documentation to view detailed property definitions, learn about optional parameters, and find additional code examples',
|
|
509
|
+
'contains_sample_code': True,
|
|
510
|
+
'contains_props_documentation': True,
|
|
511
|
+
},
|
|
512
|
+
'code_generation_guidance': {
|
|
513
|
+
'imports': [
|
|
514
|
+
"import { PythonLayerVersion } from '@aws-cdk/aws-lambda-python-alpha'"
|
|
515
|
+
],
|
|
516
|
+
'construct_types': {'python': 'PythonLayerVersion'},
|
|
517
|
+
'required_properties': {'python': ['entry']},
|
|
518
|
+
'sample_code': "new python.PythonLayerVersion(this, 'MyLayer', {\n entry: '/path/to/my/layer', // point this to your library's directory\n})",
|
|
519
|
+
},
|
|
520
|
+
}
|
|
521
|
+
else:
|
|
522
|
+
# For all other layer types (including generic), use the existing parser
|
|
523
|
+
docs = await LambdaLayerParser.fetch_lambda_layer_docs()
|
|
524
|
+
layer_docs = docs['generic_layers']
|
|
525
|
+
|
|
526
|
+
return {
|
|
527
|
+
'layer_type': 'generic',
|
|
528
|
+
'code_examples': layer_docs['examples'],
|
|
529
|
+
'directory_structure': layer_docs['directory_structure'],
|
|
530
|
+
'source_url': layer_docs['url'],
|
|
531
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
|
|
4
|
+
# with the License. A copy of the License is located at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
|
|
9
|
+
# OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
|
|
10
|
+
# and limitations under the License.
|
|
11
|
+
|
|
12
|
+
"""Lambda layer documentation parser module."""
|
|
13
|
+
|
|
14
|
+
import httpx
|
|
15
|
+
import logging
|
|
16
|
+
from bs4 import BeautifulSoup
|
|
17
|
+
from bs4.element import Tag
|
|
18
|
+
from typing import Any, Dict, List, Optional
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Set up logging
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class LambdaLayerParser:
|
|
26
|
+
"""Parser for Lambda layer documentation from AWS docs."""
|
|
27
|
+
|
|
28
|
+
# Documentation URLs
|
|
29
|
+
GENERIC_LAYER_URL = (
|
|
30
|
+
'https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html#layers'
|
|
31
|
+
)
|
|
32
|
+
PYTHON_LAYER_URL = 'https://docs.aws.amazon.com/cdk/api/v2/docs/@aws-cdk_aws-lambda-python-alpha.PythonLayerVersion.html'
|
|
33
|
+
|
|
34
|
+
# Search patterns to directly find sections when headers aren't working
|
|
35
|
+
LAYER_SECTION_PATTERNS = ['layers', 'layer version', 'layerversion']
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
async def fetch_page(cls, url: str) -> Optional[str]:
|
|
39
|
+
"""Fetch a page from AWS documentation."""
|
|
40
|
+
try:
|
|
41
|
+
async with httpx.AsyncClient() as client:
|
|
42
|
+
response = await client.get(url)
|
|
43
|
+
if response.status_code == 200:
|
|
44
|
+
return response.text
|
|
45
|
+
else:
|
|
46
|
+
logger.error(f'Failed to fetch {url}: HTTP {response.status_code}')
|
|
47
|
+
return None
|
|
48
|
+
except Exception as e:
|
|
49
|
+
logger.error(f'Error fetching {url}: {str(e)}')
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def extract_code_examples(cls, html_section: Optional[str]) -> List[Dict[str, str]]:
|
|
54
|
+
"""Extract code examples from an HTML section."""
|
|
55
|
+
if not html_section:
|
|
56
|
+
return []
|
|
57
|
+
|
|
58
|
+
soup = BeautifulSoup(html_section, 'html.parser')
|
|
59
|
+
code_blocks = soup.find_all('pre')
|
|
60
|
+
|
|
61
|
+
examples = []
|
|
62
|
+
for block in code_blocks:
|
|
63
|
+
# Make sure we're working with a Tag
|
|
64
|
+
if not isinstance(block, Tag):
|
|
65
|
+
continue
|
|
66
|
+
|
|
67
|
+
# Try to determine the language
|
|
68
|
+
language = 'typescript' # Default
|
|
69
|
+
classes = block.attrs.get('class', [])
|
|
70
|
+
|
|
71
|
+
# Make sure classes is a list of strings
|
|
72
|
+
if not isinstance(classes, list):
|
|
73
|
+
classes = [str(classes)]
|
|
74
|
+
|
|
75
|
+
class_str = ' '.join(classes)
|
|
76
|
+
|
|
77
|
+
if 'python' in class_str.lower():
|
|
78
|
+
language = 'python'
|
|
79
|
+
elif 'javascript' in class_str.lower():
|
|
80
|
+
language = 'javascript'
|
|
81
|
+
|
|
82
|
+
# Get the code content
|
|
83
|
+
code = block.get_text()
|
|
84
|
+
examples.append({'language': language, 'code': code})
|
|
85
|
+
|
|
86
|
+
return examples
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
def extract_directory_structure(cls, html_section: Optional[str]) -> Optional[str]:
|
|
90
|
+
"""Extract directory structure information from HTML section."""
|
|
91
|
+
if not html_section:
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
soup = BeautifulSoup(html_section, 'html.parser')
|
|
95
|
+
|
|
96
|
+
# Look for pre blocks that might contain directory structure
|
|
97
|
+
pre_blocks = soup.find_all('pre')
|
|
98
|
+
for block in pre_blocks:
|
|
99
|
+
text = block.get_text()
|
|
100
|
+
if '/' in text and (
|
|
101
|
+
'directory' in text.lower()
|
|
102
|
+
or 'structure' in text.lower()
|
|
103
|
+
or 'layer' in text.lower()
|
|
104
|
+
):
|
|
105
|
+
return text
|
|
106
|
+
|
|
107
|
+
# Look for paragraphs that might describe directory structure
|
|
108
|
+
paragraphs = soup.find_all('p')
|
|
109
|
+
for p in paragraphs:
|
|
110
|
+
text = p.get_text()
|
|
111
|
+
if (
|
|
112
|
+
'directory' in text.lower() and 'structure' in text.lower()
|
|
113
|
+
) or 'layer' in text.lower():
|
|
114
|
+
return text
|
|
115
|
+
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
@classmethod
|
|
119
|
+
def find_layer_content(cls, html: Optional[str]) -> Optional[str]:
|
|
120
|
+
"""Find Lambda layer content using multiple strategies."""
|
|
121
|
+
if not html:
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
soup = BeautifulSoup(html, 'html.parser')
|
|
125
|
+
|
|
126
|
+
# Strategy 1: Find section by id
|
|
127
|
+
section = soup.find(id='layers')
|
|
128
|
+
if section and isinstance(section, Tag):
|
|
129
|
+
# If we found an anchor, get its parent and look for the actual content
|
|
130
|
+
if section.name == 'a':
|
|
131
|
+
parent = section.parent
|
|
132
|
+
if parent and isinstance(parent, Tag) and parent.name and parent.name[0] == 'h':
|
|
133
|
+
# We found a header, extract all content until the next header of same or higher level
|
|
134
|
+
content = []
|
|
135
|
+
content.append(str(parent))
|
|
136
|
+
|
|
137
|
+
header_level = int(parent.name[1])
|
|
138
|
+
sibling = parent.next_sibling
|
|
139
|
+
|
|
140
|
+
while sibling:
|
|
141
|
+
if (
|
|
142
|
+
isinstance(sibling, Tag)
|
|
143
|
+
and sibling.name
|
|
144
|
+
and sibling.name[0] == 'h'
|
|
145
|
+
and int(sibling.name[1]) <= header_level
|
|
146
|
+
):
|
|
147
|
+
break
|
|
148
|
+
if isinstance(sibling, Tag) and sibling.name:
|
|
149
|
+
content.append(str(sibling))
|
|
150
|
+
sibling = sibling.next_sibling
|
|
151
|
+
|
|
152
|
+
return ''.join(content)
|
|
153
|
+
|
|
154
|
+
# Strategy 2: Look for headers containing layer keywords
|
|
155
|
+
for tag in ['h1', 'h2', 'h3', 'h4']:
|
|
156
|
+
headers = soup.find_all(tag)
|
|
157
|
+
for header in headers:
|
|
158
|
+
if not isinstance(header, Tag):
|
|
159
|
+
continue
|
|
160
|
+
|
|
161
|
+
text = header.get_text().lower()
|
|
162
|
+
if any(pattern in text for pattern in cls.LAYER_SECTION_PATTERNS):
|
|
163
|
+
# Found a relevant header, extract all content until the next header of same or higher level
|
|
164
|
+
content = []
|
|
165
|
+
content.append(str(header))
|
|
166
|
+
|
|
167
|
+
if not header.name:
|
|
168
|
+
continue
|
|
169
|
+
|
|
170
|
+
header_level = int(header.name[1])
|
|
171
|
+
sibling = header.next_sibling
|
|
172
|
+
|
|
173
|
+
while sibling:
|
|
174
|
+
if (
|
|
175
|
+
isinstance(sibling, Tag)
|
|
176
|
+
and sibling.name
|
|
177
|
+
and sibling.name[0] == 'h'
|
|
178
|
+
and int(sibling.name[1]) <= header_level
|
|
179
|
+
):
|
|
180
|
+
break
|
|
181
|
+
if isinstance(sibling, Tag) and sibling.name:
|
|
182
|
+
content.append(str(sibling))
|
|
183
|
+
sibling = sibling.next_sibling
|
|
184
|
+
|
|
185
|
+
return ''.join(content)
|
|
186
|
+
|
|
187
|
+
# Strategy 3: Look for content div with class="api" or class="props"
|
|
188
|
+
content_divs = soup.find_all('div', class_=['api', 'props'])
|
|
189
|
+
if content_divs:
|
|
190
|
+
return ''.join(str(div) for div in content_divs)
|
|
191
|
+
|
|
192
|
+
# Strategy 4: Look for table with class containing 'cdk'
|
|
193
|
+
tables = soup.find_all('table')
|
|
194
|
+
for table in tables:
|
|
195
|
+
if not isinstance(table, Tag):
|
|
196
|
+
continue
|
|
197
|
+
|
|
198
|
+
classes = table.attrs.get('class', [])
|
|
199
|
+
if not isinstance(classes, list):
|
|
200
|
+
classes = [str(classes)]
|
|
201
|
+
|
|
202
|
+
if any('cdk' in str(cls_name) for cls_name in classes):
|
|
203
|
+
return str(table)
|
|
204
|
+
|
|
205
|
+
return None
|
|
206
|
+
|
|
207
|
+
@classmethod
|
|
208
|
+
async def fetch_lambda_layer_docs(cls) -> Dict[str, Any]:
|
|
209
|
+
"""Fetch Lambda layer documentation from AWS docs."""
|
|
210
|
+
logger.info('Fetching Lambda layer documentation from AWS')
|
|
211
|
+
|
|
212
|
+
# Fetch only the generic page
|
|
213
|
+
generic_html = await cls.fetch_page(cls.GENERIC_LAYER_URL)
|
|
214
|
+
|
|
215
|
+
# Extract relevant sections using our specialized finder
|
|
216
|
+
generic_layers_section = cls.find_layer_content(generic_html)
|
|
217
|
+
|
|
218
|
+
# Extract code examples and directory structure
|
|
219
|
+
generic_examples = cls.extract_code_examples(generic_layers_section)
|
|
220
|
+
generic_dir_structure = cls.extract_directory_structure(generic_layers_section)
|
|
221
|
+
|
|
222
|
+
# Compile the results
|
|
223
|
+
result = {
|
|
224
|
+
'generic_layers': {
|
|
225
|
+
'examples': generic_examples,
|
|
226
|
+
'directory_structure': generic_dir_structure,
|
|
227
|
+
'url': cls.GENERIC_LAYER_URL,
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return result
|
|
@@ -288,7 +288,7 @@ def extract_services_from_pattern_name(pattern_name: str) -> List[str]:
|
|
|
288
288
|
'iot': 'IoT Core',
|
|
289
289
|
'elasticsearch': 'Elasticsearch',
|
|
290
290
|
'opensearch': 'OpenSearch',
|
|
291
|
-
'secretsmanager': 'Secrets Manager',
|
|
291
|
+
'secretsmanager': 'Secrets Manager', # pragma: allowlist secret
|
|
292
292
|
'sagemakerendpoint': 'SageMaker Endpoint',
|
|
293
293
|
'stepfunctions': 'Step Functions',
|
|
294
294
|
'wafwebacl': 'WAF Web ACL',
|
|
@@ -45,84 +45,106 @@ cdk diff
|
|
|
45
45
|
- Generates CloudFormation templates for inspection
|
|
46
46
|
- Provides more informative error messages for debugging
|
|
47
47
|
|
|
48
|
-
##
|
|
49
|
-
|
|
50
|
-
When implementing AWS infrastructure with CDK, consider these complementary approaches:
|
|
51
|
-
|
|
52
|
-
1. **For Common Architecture Patterns: AWS Solutions Constructs**
|
|
53
|
-
- Use the `GetAwsSolutionsConstructPattern` tool to search for patterns that match your use case
|
|
54
|
-
- Example: `GetAwsSolutionsConstructPattern(services=["lambda", "dynamodb"])`
|
|
55
|
-
- AWS Solutions Constructs implement AWS best practices by default
|
|
56
|
-
- For complete documentation: `aws-solutions-constructs://{pattern_name}`
|
|
57
|
-
- Ideal for REST APIs, serverless backends, data processing pipelines, etc.
|
|
58
|
-
|
|
59
|
-
2. **For GenAI/AI/ML Use Cases: GenAI CDK Constructs**
|
|
60
|
-
- Use the `SearchGenAICDKConstructs` tool for specialized AI/ML constructs
|
|
61
|
-
- These simplify implementation of Bedrock, SageMaker, and other AI services
|
|
62
|
-
- Perfect for agents, knowledge bases, vector stores, and other GenAI components
|
|
63
|
-
|
|
64
|
-
**Installation:**
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
// TypeScript
|
|
68
|
-
// Create or use an existing CDK application
|
|
69
|
-
cdk init app --language typescript
|
|
70
|
-
// Install the package
|
|
71
|
-
npm install @cdklabs/generative-ai-cdk-constructs
|
|
72
|
-
// Import the library
|
|
73
|
-
import * as genai from '@cdklabs/generative-ai-cdk-constructs';
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
```python
|
|
77
|
-
# Python
|
|
78
|
-
# Create or use an existing CDK application
|
|
79
|
-
cdk init app --language python
|
|
80
|
-
# Install the package
|
|
81
|
-
pip install cdklabs.generative-ai-cdk-constructs
|
|
82
|
-
# Import the library
|
|
83
|
-
import cdklabs.generative_ai_cdk_constructs
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
3. **For All Projects: Apply CDK Nag**
|
|
87
|
-
- Always apply CDK Nag to ensure security best practices
|
|
88
|
-
- Use the `ExplainCDKNagRule` tool to understand specific rules
|
|
48
|
+
## CDK Implementation Approach and Workflow
|
|
89
49
|
|
|
90
|
-
|
|
91
|
-
- Create custom CDK code when no suitable constructs exist
|
|
92
|
-
- Follow AWS Well-Architected best practices
|
|
50
|
+
# Compare deployed stack with current state
|
|
93
51
|
|
|
94
|
-
|
|
52
|
+
### Common Architecture Patterns
|
|
95
53
|
|
|
96
|
-
|
|
54
|
+
**For standard application architectures:**
|
|
97
55
|
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
- **Use Vetted Patterns**: Prefer AWS Solutions Constructs over custom implementations
|
|
104
|
-
- **Regional Awareness**: Consider regional availability and constraints for services
|
|
56
|
+
- Use the `GetAwsSolutionsConstructPattern` tool to find pre-built patterns
|
|
57
|
+
- AWS Solutions Constructs implement AWS best practices by default
|
|
58
|
+
- Ideal for REST APIs, serverless backends, data processing pipelines, etc.
|
|
59
|
+
- Example: `GetAwsSolutionsConstructPattern(services=["lambda", "dynamodb"])`
|
|
60
|
+
- For complete documentation: `aws-solutions-constructs://{pattern_name}`
|
|
105
61
|
|
|
106
|
-
|
|
62
|
+
**Key benefits:**
|
|
63
|
+
- Accelerated development with vetted patterns
|
|
64
|
+
- Built-in security and best practices
|
|
65
|
+
- Reduced complexity for multi-service architectures
|
|
107
66
|
|
|
108
|
-
|
|
67
|
+
### GenAI/AI/ML Implementations
|
|
109
68
|
|
|
110
|
-
|
|
69
|
+
**For AI/ML and generative AI workloads:**
|
|
111
70
|
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
- **Implementation**: Use the `CrossRegionInferenceProfile` class from the GenAI CDK constructs
|
|
71
|
+
- Use the `SearchGenAICDKConstructs` tool for specialized AI/ML constructs
|
|
72
|
+
- These simplify implementation of Bedrock, SageMaker, and other AI services
|
|
73
|
+
- Perfect for agents, knowledge bases, vector stores, and other GenAI components
|
|
116
74
|
|
|
117
|
-
|
|
75
|
+
**Installation:**
|
|
118
76
|
|
|
119
|
-
|
|
77
|
+
```typescript
|
|
78
|
+
// TypeScript
|
|
79
|
+
npm install @cdklabs/generative-ai-cdk-constructs
|
|
80
|
+
import * as genai from '@cdklabs/generative-ai-cdk-constructs';
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# Python
|
|
85
|
+
pip install cdklabs.generative-ai-cdk-constructs
|
|
86
|
+
import cdklabs.generative_ai_cdk_constructs
|
|
87
|
+
```
|
|
120
88
|
|
|
121
|
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
89
|
+
**Regional considerations for Bedrock:**
|
|
90
|
+
- Many foundation models require inference profiles in specific regions
|
|
91
|
+
- Use `CrossRegionInferenceProfile` class for proper configuration
|
|
92
|
+
- For details: `genai-cdk-constructs://bedrock/profiles`
|
|
124
93
|
|
|
125
|
-
|
|
94
|
+
### Combined Implementation Patterns
|
|
95
|
+
|
|
96
|
+
**Important:** AWS Solutions Constructs and GenAI CDK Constructs can be used together in the same project:
|
|
97
|
+
|
|
98
|
+
- Use GenAI CDK Constructs for Bedrock components (agents, knowledge bases)
|
|
99
|
+
- Use AWS Solutions Constructs for REST APIs, databases, and other infrastructure
|
|
100
|
+
- Apply CDK Nag across all components for security validation
|
|
101
|
+
|
|
102
|
+
**Example combined architecture:**
|
|
103
|
+
- REST API backend using aws-apigateway-lambda-dynamodb construct
|
|
104
|
+
- Bedrock Agent using GenAI CDK constructs for natural language processing
|
|
105
|
+
- Shared data layer between traditional and AI components
|
|
106
|
+
|
|
107
|
+
### Implementation Workflow
|
|
108
|
+
|
|
109
|
+
Follow this step-by-step workflow for developing AWS CDK applications:
|
|
110
|
+
|
|
111
|
+
1. **Get CDK Guidance**: Start with the **CDKGeneralGuidance** tool to understand best practices.
|
|
112
|
+
|
|
113
|
+
2. **Initialize CDK Project**: Use `cdk init app` to create your project with proper structure.
|
|
114
|
+
|
|
115
|
+
3. **Choose Implementation Approach**:
|
|
116
|
+
- For common patterns: Use **GetAwsSolutionsConstructPattern** tool
|
|
117
|
+
- For GenAI applications: Use **SearchGenAICDKConstructs** tool
|
|
118
|
+
- For custom requirements: Develop custom CDK code following best practices
|
|
119
|
+
|
|
120
|
+
4. **For Lambda Functions**:
|
|
121
|
+
- For observability: Implement Lambda Powertools (see `lambda-powertools://cdk` for details)
|
|
122
|
+
- For Lambda layers: Use **LambdaLayerDocumentationProvider** tool
|
|
123
|
+
|
|
124
|
+
5. **For Bedrock Agents with Action Groups**:
|
|
125
|
+
- Create Lambda function with BedrockAgentResolver from Lambda Powertools
|
|
126
|
+
- Use **GenerateBedrockAgentSchema** tool to generate OpenAPI schema
|
|
127
|
+
- Integrate schema into Agent CDK code
|
|
128
|
+
|
|
129
|
+
6. **Apply Security Best Practices**:
|
|
130
|
+
- Always apply CDK Nag to ensure security best practices
|
|
131
|
+
- Use **ExplainCDKNagRule** tool to understand specific rules
|
|
132
|
+
- Validate suppressions with **CheckCDKNagSuppressions** tool
|
|
133
|
+
|
|
134
|
+
7. **Validate and Deploy**:
|
|
135
|
+
- Run `cdk synth` to check for errors and generate CloudFormation
|
|
136
|
+
- Ensure all CDK Nag warnings are resolved or properly justified
|
|
137
|
+
- Deploy using `cdk deploy`
|
|
138
|
+
|
|
139
|
+
## Key Principles
|
|
140
|
+
|
|
141
|
+
- **Security First**: Always implement security best practices by default
|
|
142
|
+
- **Cost Optimization**: Design resources to minimize costs while meeting requirements
|
|
143
|
+
- **Operational Excellence**: Implement proper monitoring, logging, and observability
|
|
144
|
+
- **Serverless-First**: Prefer serverless services when possible
|
|
145
|
+
- **Infrastructure as Code**: Use CDK to define all infrastructure
|
|
146
|
+
- **Use Vetted Patterns**: Prefer AWS Solutions Constructs over custom implementations
|
|
147
|
+
- **Regional Awareness**: Consider regional availability and constraints for services
|
|
126
148
|
|
|
127
149
|
## AWS Solutions Constructs
|
|
128
150
|
|
|
@@ -148,10 +170,12 @@ To discover available patterns, use the `GetAwsSolutionsConstructPattern` tool.
|
|
|
148
170
|
CDK Nag ensures your CDK applications follow AWS security best practices. **Always apply CDK Nag to all stacks.**
|
|
149
171
|
|
|
150
172
|
**When to use CDK Nag tools:**
|
|
173
|
+
|
|
151
174
|
- **ExplainCDKNagRule**: When encountering warnings that need remediation
|
|
152
175
|
- **CheckCDKNagSuppressions**: During code reviews to verify suppression justifications
|
|
153
176
|
|
|
154
177
|
Key security practices:
|
|
178
|
+
|
|
155
179
|
- Follow least privilege for IAM
|
|
156
180
|
- Secure S3 buckets with encryption and access controls
|
|
157
181
|
- Implement secure authentication with Cognito
|
|
@@ -161,6 +185,10 @@ Key security practices:
|
|
|
161
185
|
|
|
162
186
|
**Always implement Lambda Powertools** for structured logging, tracing, and metrics. For detailed guidance, use the `lambda-powertools://cdk` resource.
|
|
163
187
|
|
|
188
|
+
> **CRITICAL**: Lambda Powertools libraries are NOT included in the default Lambda runtime. You MUST create a Lambda layer to include these dependencies. Use the **LambdaLayerDocumentationProvider** tool for comprehensive guidance on creating and configuring Lambda layers.
|
|
189
|
+
|
|
190
|
+
**Critical for Bedrock Agents**: When creating Bedrock Agents with Action Groups, use BedrockAgentResolver from Lambda Powertools with the **GenerateBedrockAgentSchema** tool to generate the required OpenAPI schema.
|
|
191
|
+
|
|
164
192
|
## Tool Selection Guide
|
|
165
193
|
|
|
166
194
|
Match CDK tasks to appropriate tools:
|
|
@@ -171,110 +199,6 @@ Match CDK tasks to appropriate tools:
|
|
|
171
199
|
| Understand CDK Nag rules | ExplainCDKNagRule | ❌ Ignoring security warnings without understanding remediation steps |
|
|
172
200
|
| Find architecture patterns | GetAwsSolutionsConstructPattern | ❌ Building common patterns from scratch instead of using vetted constructs |
|
|
173
201
|
| Implement GenAI features | SearchGenAICDKConstructs | ❌ Building GenAI components without specialized constructs |
|
|
174
|
-
|
|
|
202
|
+
| Access Lambda layer docs | LambdaLayerDocumentationProvider | ❌ Missing proper Lambda layer structure or configuration |
|
|
203
|
+
| Add Lambda observability | lambda-powertools://cdk | ❌ Missing Lambda layer for Powertools or incomplete monitoring setup |
|
|
175
204
|
| Audit CDK Nag suppressions | CheckCDKNagSuppressions | ❌ Insufficient documentation for security suppressions |
|
|
176
|
-
|
|
177
|
-
## Lambda Powertools Implementation
|
|
178
|
-
|
|
179
|
-
> **CRITICAL:** All Lambda functions should implement Lambda Powertools for proper observability.
|
|
180
|
-
|
|
181
|
-
**Key requirements:**
|
|
182
|
-
- Use language-specific constructs (PythonFunction, NodejsFunction)
|
|
183
|
-
- Include Powertools dependencies with appropriate extras
|
|
184
|
-
- Configure required environment variables
|
|
185
|
-
- Create Lambda layers when needed
|
|
186
|
-
|
|
187
|
-
**Example Lambda layer for Python:**
|
|
188
|
-
```typescript
|
|
189
|
-
const lambdaPowertoolsLayer = new PythonLayerVersion(this, "LambdaPowertoolsLayer", {
|
|
190
|
-
entry: path.join("src", "layers", "aws_lambda_powertools"),
|
|
191
|
-
compatibleRuntimes: [Runtime.PYTHON_3_13],
|
|
192
|
-
description: "Lambda Powertools for Python",
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
For complete implementation details and examples for all languages, see the [lambda-powertools://cdk](lambda-powertools://cdk) resource.
|
|
197
|
-
|
|
198
|
-
## CDK Implementation Workflow
|
|
199
|
-
|
|
200
|
-
```mermaid
|
|
201
|
-
graph TD
|
|
202
|
-
Start([Start]) --> Init["cdk init app"]
|
|
203
|
-
|
|
204
|
-
Init --> B{Choose Approach}
|
|
205
|
-
B -->|"Common Patterns"| C1["GetAwsSolutionsConstructPattern"]
|
|
206
|
-
B -->|"GenAI Features"| C2["SearchGenAICDKConstructs"]
|
|
207
|
-
B -->|"Custom Needs"| C3["Custom CDK Code"]
|
|
208
|
-
|
|
209
|
-
C1 --> D1["Implement Solutions Construct"]
|
|
210
|
-
C2 --> D2["Implement GenAI Constructs"]
|
|
211
|
-
C3 --> D3["Implement Custom Resources"]
|
|
212
|
-
|
|
213
|
-
%% Bedrock Agent with Action Groups specific flow
|
|
214
|
-
D2 -->|"For Bedrock Agents<br/>with Action Groups"| BA["Create Lambda with<br/>BedrockAgentResolver"]
|
|
215
|
-
|
|
216
|
-
%% Schema generation flow
|
|
217
|
-
BA --> BS["GenerateBedrockAgentSchema"]
|
|
218
|
-
BS -->|"Success"| JSON["openapi.json created"]
|
|
219
|
-
BS -->|"Import Errors"| BSF["Tool generates<br/>generate_schema.py"]
|
|
220
|
-
BSF --> BSR["Run script manually:<br/>python generate_schema.py"]
|
|
221
|
-
BSR --> JSON["openapi.json created"]
|
|
222
|
-
|
|
223
|
-
%% Use schema in Agent CDK
|
|
224
|
-
JSON --> AgentCDK["Use schema in<br/>Agent CDK code"]
|
|
225
|
-
AgentCDK --> D2
|
|
226
|
-
|
|
227
|
-
%% Conditional Lambda Powertools implementation
|
|
228
|
-
D1 & D2 & D3 --> HasLambda{"Using Lambda<br/>Functions?"}
|
|
229
|
-
HasLambda -->|"Yes"| L["Add Lambda Powertools<br/>and create Layer"]
|
|
230
|
-
HasLambda -->|"No"| SkipL["Skip Lambda<br/>Powertools"]
|
|
231
|
-
|
|
232
|
-
%% Rest of workflow
|
|
233
|
-
L --> Synth["cdk synth"]
|
|
234
|
-
SkipL --> Synth
|
|
235
|
-
|
|
236
|
-
Synth --> Nag{"CDK Nag<br/>warnings?"}
|
|
237
|
-
Nag -->|Yes| E["ExplainCDKNagRule"]
|
|
238
|
-
Nag -->|No| Deploy["cdk deploy"]
|
|
239
|
-
|
|
240
|
-
E --> Fix["Fix or Add Suppressions"]
|
|
241
|
-
Fix --> CN["CheckCDKNagSuppressions"]
|
|
242
|
-
CN --> Synth
|
|
243
|
-
|
|
244
|
-
%% Styling with darker colors
|
|
245
|
-
classDef default fill:#424242,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
246
|
-
classDef cmd fill:#4a148c,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
247
|
-
classDef tool fill:#01579b,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
248
|
-
classDef note fill:#1b5e20,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
249
|
-
classDef output fill:#006064,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
250
|
-
classDef decision fill:#5d4037,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
251
|
-
|
|
252
|
-
class Init,Synth,Deploy,BSR cmd;
|
|
253
|
-
class C1,C2,BS,E,CN tool;
|
|
254
|
-
class JSON output;
|
|
255
|
-
class HasLambda,Nag decision;
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
## Available MCP Tools
|
|
259
|
-
|
|
260
|
-
This MCP server provides several tools to help you implement AWS CDK best practices:
|
|
261
|
-
|
|
262
|
-
1. **CDKGeneralGuidance**: This document - general CDK best practices
|
|
263
|
-
2. **ExplainCDKNagRule**: Explain a specific CDK Nag rule with AWS Well-Architected guidance
|
|
264
|
-
3. **CheckCDKNagSuppressions**: Check if CDK code contains Nag suppressions that require human review
|
|
265
|
-
4. **GenerateBedrockAgentSchema**: Generate OpenAPI schema for Bedrock Agent Action Groups from Lambda functions
|
|
266
|
-
5. **GetAwsSolutionsConstructPattern**: Search and discover AWS Solutions Constructs patterns
|
|
267
|
-
6. **SearchGenAICDKConstructs**: Search for GenAI CDK constructs by name or type
|
|
268
|
-
|
|
269
|
-
## Available MCP Resources
|
|
270
|
-
|
|
271
|
-
This MCP server also provides several resources for accessing documentation:
|
|
272
|
-
|
|
273
|
-
1. **cdk-nag://rules/{rule_pack}**: Get all rules for a specific CDK Nag rule pack
|
|
274
|
-
2. **cdk-nag://warnings/{rule_pack}**: Get warnings for a specific CDK Nag rule pack
|
|
275
|
-
3. **cdk-nag://errors/{rule_pack}**: Get errors for a specific CDK Nag rule pack
|
|
276
|
-
4. **lambda-powertools://{topic}**: Get Lambda Powertools guidance on a specific topic
|
|
277
|
-
5. **aws-solutions-constructs://{pattern_name}**: Get complete documentation for an AWS Solutions Constructs pattern
|
|
278
|
-
6. **genai-cdk-constructs://{construct_type}/{construct_name}**: Get documentation for a GenAI CDK construct
|
|
279
|
-
|
|
280
|
-
Always check for these tools and resources when implementing CDK infrastructure to ensure you're following AWS best practices.
|
|
@@ -8,7 +8,7 @@ import { pinecone, bedrock } from '@cdklabs/generative-ai-cdk-constructs';
|
|
|
8
8
|
|
|
9
9
|
const pineconeds = new pinecone.PineconeVectorStore({
|
|
10
10
|
connectionString: 'https://your-index-1234567.svc.gcp-starter.pinecone.io',
|
|
11
|
-
credentialsSecretArn: 'arn:aws:secretsmanager:your-region:123456789876:secret:your-key-name',
|
|
11
|
+
credentialsSecretArn: 'arn:aws:secretsmanager:your-region:123456789876:secret:your-key-name', # pragma: allowlist secret
|
|
12
12
|
textField: 'question',
|
|
13
13
|
metadataField: 'metadata',
|
|
14
14
|
});
|
|
@@ -43,7 +43,7 @@ from cdklabs.generative_ai_cdk_constructs import (
|
|
|
43
43
|
|
|
44
44
|
pineconevs = pinecone.PineconeVectorStore(
|
|
45
45
|
connection_string='https://your-index-1234567.svc.gcp-starter.pinecone.io',
|
|
46
|
-
credentials_secret_arn='arn:aws:secretsmanager:your-region:123456789876:secret:your-key-name',
|
|
46
|
+
credentials_secret_arn='arn:aws:secretsmanager:your-region:123456789876:secret:your-key-name', # pragma: allowlist secret
|
|
47
47
|
text_field='question',
|
|
48
48
|
metadata_field='metadata'
|
|
49
49
|
)
|