awslabs.cdk-mcp-server 0.0.81650__tar.gz → 0.0.101004__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.81650 → awslabs_cdk_mcp_server-0.0.101004}/.pre-commit-config.yaml +1 -1
- awslabs_cdk_mcp_server-0.0.101004/CHANGELOG.md +29 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/PKG-INFO +42 -20
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/README.md +40 -19
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/core/server.py +1 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/core/tools.py +53 -0
- awslabs_cdk_mcp_server-0.0.101004/awslabs/cdk_mcp_server/data/lambda_layer_parser.py +231 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/solutions_constructs_parser.py +1 -1
- awslabs_cdk_mcp_server-0.0.101004/awslabs/cdk_mcp_server/static/CDK_GENERAL_GUIDANCE.md +204 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/pinecone.md +2 -2
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/bedrock.md +21 -36
- awslabs_cdk_mcp_server-0.0.101004/awslabs/cdk_mcp_server/static/lambda_powertools/cdk.md +53 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/insights.md +12 -21
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/metrics.md +5 -36
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/pyproject.toml +3 -2
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/uv.lock +37 -1
- awslabs_cdk_mcp_server-0.0.81650/CHANGELOG.md +0 -12
- awslabs_cdk_mcp_server-0.0.81650/awslabs/cdk_mcp_server/static/CDK_GENERAL_GUIDANCE.md +0 -280
- awslabs_cdk_mcp_server-0.0.81650/awslabs/cdk_mcp_server/static/lambda_powertools/cdk.md +0 -99
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/.gitignore +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/.python-version +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/__init__.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/__init__.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/core/__init__.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/core/resources.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/core/search_utils.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/__init__.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/cdk_nag_parser.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/construct_descriptions.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/genai_cdk_loader.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/lambda_powertools_loader.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/data/schema_generator.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/server.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/CDK_NAG_GUIDANCE.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/__init__.py +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/actiongroups.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/alias.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/collaboration.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/creation.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/custom_orchestration.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/overview.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/agent/prompt_override.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/bedrockguardrails.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/chunking.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/datasources.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/kendra.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/overview.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/parsing.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/transformation.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/aurora.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/creation.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/knowledgebases/vector/opensearch.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/bedrock/profiles.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/opensearch-vectorindex/overview.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/genai_cdk/opensearchserverless/overview.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/dependencies.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/index.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/logging.md +0 -0
- {awslabs_cdk_mcp_server-0.0.81650 → awslabs_cdk_mcp_server-0.0.101004}/awslabs/cdk_mcp_server/static/lambda_powertools/tracing.md +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
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
|
|
13
|
+
- New `GenerateLambdaLayerCode` tool for creating properly configured Lambda layers
|
|
14
|
+
- Extracts data directly from AWS documentation
|
|
15
|
+
- Provides smart fallback mechanisms for various AWS doc formats
|
|
16
|
+
- Integrates with CDK General Guidance flow
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Reorganized CDK_GENERAL_GUIDANCE.md to eliminate duplication
|
|
22
|
+
- Created unified Implementation Approach and Workflow section
|
|
23
|
+
- Added clear separation between common and GenAI patterns
|
|
24
|
+
- Added section showing how both approaches can be used together
|
|
25
|
+
- Improved Lambda Powertools documentation
|
|
26
|
+
- Centralized CDK integration guidance
|
|
27
|
+
- Added explicit Lambda layer requirement notices
|
|
28
|
+
- Removed duplicate code examples from feature-specific files
|
|
29
|
+
- Updated Bedrock integration examples with proper layer creation patterns
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: awslabs.cdk-mcp-server
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.101004
|
|
4
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
5
|
Requires-Python: >=3.10
|
|
6
6
|
Requires-Dist: aws-lambda-powertools>=2.30.0
|
|
7
|
+
Requires-Dist: bs4>=0.0.2
|
|
7
8
|
Requires-Dist: httpx>=0.27.0
|
|
8
9
|
Requires-Dist: mcp[cli]>=1.6.0
|
|
9
10
|
Requires-Dist: pydantic>=2.10.6
|
|
@@ -39,6 +40,13 @@ MCP server for AWS Cloud Development Kit (CDK) best practices, infrastructure as
|
|
|
39
40
|
- Discover specialized constructs for AI/ML workloads
|
|
40
41
|
- Get implementation guidance for generative AI applications
|
|
41
42
|
|
|
43
|
+
### Lambda Layer Documentation Provider
|
|
44
|
+
|
|
45
|
+
- Access comprehensive documentation for AWS Lambda layers
|
|
46
|
+
- Get code examples for generic Lambda layers and Python-specific layers
|
|
47
|
+
- Retrieve directory structure information and implementation best practices
|
|
48
|
+
- Seamless integration with AWS Documentation MCP Server for detailed documentation
|
|
49
|
+
|
|
42
50
|
### Amazon Bedrock Agent Schema Generation
|
|
43
51
|
|
|
44
52
|
- Use this tool when creating Bedrock Agents with Action Groups that use Lambda functions
|
|
@@ -57,20 +65,21 @@ This diagram provides a comprehensive view of the recommended CDK implementation
|
|
|
57
65
|
|
|
58
66
|
```mermaid
|
|
59
67
|
graph TD
|
|
60
|
-
Start([Start]) -->
|
|
61
|
-
|
|
68
|
+
Start([Start]) --> A["CDKGeneralGuidance"]
|
|
69
|
+
A --> Init["cdk init app"]
|
|
70
|
+
|
|
62
71
|
Init --> B{Choose Approach}
|
|
63
72
|
B -->|"Common Patterns"| C1["GetAwsSolutionsConstructPattern"]
|
|
64
73
|
B -->|"GenAI Features"| C2["SearchGenAICDKConstructs"]
|
|
65
74
|
B -->|"Custom Needs"| C3["Custom CDK Code"]
|
|
66
|
-
|
|
75
|
+
|
|
67
76
|
C1 --> D1["Implement Solutions Construct"]
|
|
68
77
|
C2 --> D2["Implement GenAI Constructs"]
|
|
69
78
|
C3 --> D3["Implement Custom Resources"]
|
|
70
|
-
|
|
79
|
+
|
|
71
80
|
%% Bedrock Agent with Action Groups specific flow
|
|
72
81
|
D2 -->|"For Bedrock Agents<br/>with Action Groups"| BA["Create Lambda with<br/>BedrockAgentResolver"]
|
|
73
|
-
|
|
82
|
+
|
|
74
83
|
%% Schema generation flow
|
|
75
84
|
BA --> BS["GenerateBedrockAgentSchema"]
|
|
76
85
|
BS -->|"Success"| JSON["openapi.json created"]
|
|
@@ -78,28 +87,30 @@ graph TD
|
|
|
78
87
|
BSF -->|"Missing dependencies?"| InstallDeps["Install dependencies"]
|
|
79
88
|
InstallDeps --> BSR["Run script manually:<br/>python generate_schema.py"]
|
|
80
89
|
BSR --> JSON["openapi.json created"]
|
|
81
|
-
|
|
90
|
+
|
|
82
91
|
%% Use schema in Agent CDK
|
|
83
92
|
JSON --> AgentCDK["Use schema in<br/>Agent CDK code"]
|
|
84
93
|
AgentCDK --> D2
|
|
85
|
-
|
|
94
|
+
|
|
86
95
|
%% Conditional Lambda Powertools implementation
|
|
87
96
|
D1 & D2 & D3 --> HasLambda{"Using Lambda<br/>Functions?"}
|
|
88
|
-
HasLambda
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
HasLambda --> UseLayer{"Using Lambda<br/>Layers?"}
|
|
98
|
+
UseLayer -->|"Yes"| LLDP["LambdaLayerDocumentationProvider"]
|
|
99
|
+
|
|
100
|
+
HasLambda -->|"No"| SkipL["Skip"]
|
|
101
|
+
|
|
91
102
|
%% Rest of workflow
|
|
92
|
-
|
|
103
|
+
LLDP["LambdaLayerDocumentationProvider"] --> Synth["cdk synth"]
|
|
93
104
|
SkipL --> Synth
|
|
94
|
-
|
|
105
|
+
|
|
95
106
|
Synth --> Nag{"CDK Nag<br/>warnings?"}
|
|
96
107
|
Nag -->|Yes| E["ExplainCDKNagRule"]
|
|
97
108
|
Nag -->|No| Deploy["cdk deploy"]
|
|
98
|
-
|
|
109
|
+
|
|
99
110
|
E --> Fix["Fix or Add Suppressions"]
|
|
100
111
|
Fix --> CN["CheckCDKNagSuppressions"]
|
|
101
112
|
CN --> Synth
|
|
102
|
-
|
|
113
|
+
|
|
103
114
|
%% Styling with darker colors
|
|
104
115
|
classDef default fill:#424242,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
105
116
|
classDef cmd fill:#4a148c,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
@@ -107,24 +118,35 @@ graph TD
|
|
|
107
118
|
classDef note fill:#1b5e20,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
108
119
|
classDef output fill:#006064,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
109
120
|
classDef decision fill:#5d4037,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
110
|
-
|
|
121
|
+
|
|
111
122
|
class Init,Synth,Deploy,BSR cmd;
|
|
112
|
-
class C1,C2,BS,E,CN tool;
|
|
123
|
+
class A,C1,C2,BS,E,CN,LLDP tool;
|
|
113
124
|
class JSON output;
|
|
114
|
-
class HasLambda,Nag decision;
|
|
125
|
+
class HasLambda,UseLayer,Nag decision;
|
|
115
126
|
```
|
|
116
127
|
|
|
117
|
-
##
|
|
128
|
+
## Available MCP Tools
|
|
129
|
+
|
|
130
|
+
- **CDKGeneralGuidance**: Get prescriptive advice for building AWS applications with CDK
|
|
131
|
+
- **GetAwsSolutionsConstructPattern**: Find vetted architecture patterns combining AWS services
|
|
132
|
+
- **SearchGenAICDKConstructs**: Discover GenAI CDK constructs by name or features
|
|
133
|
+
- **GenerateBedrockAgentSchema**: Create OpenAPI schemas for Bedrock Agent action groups
|
|
134
|
+
- **LambdaLayerDocumentationProvider**: Access documentation for Lambda layers implementation
|
|
135
|
+
- **ExplainCDKNagRule**: Get detailed guidance on CDK Nag security rules
|
|
136
|
+
- **CheckCDKNagSuppressions**: Validate CDK Nag suppressions in your code
|
|
137
|
+
|
|
138
|
+
## Available MCP Resources
|
|
118
139
|
|
|
119
140
|
- **CDK Nag Rules**: Access rule packs via `cdk-nag://rules/{rule_pack}`
|
|
120
|
-
- **Lambda Powertools**: Get guidance on Lambda Powertools via `lambda-powertools://{topic}`
|
|
121
141
|
- **AWS Solutions Constructs**: Access patterns via `aws-solutions-constructs://{pattern_name}`
|
|
122
142
|
- **GenAI CDK Constructs**: Access documentation via `genai-cdk-constructs://{construct_type}/{construct_name}`
|
|
143
|
+
- **Lambda Powertools**: Get guidance on Lambda Powertools via `lambda-powertools://{topic}`
|
|
123
144
|
|
|
124
145
|
## Prerequisites
|
|
125
146
|
|
|
126
147
|
1. Install `uv` from [Astral](https://docs.astral.sh/uv/getting-started/installation/) or the [GitHub README](https://github.com/astral-sh/uv#installation)
|
|
127
148
|
2. Install Python using `uv python install 3.10`
|
|
149
|
+
3. Install AWS CDK CLI using `npm install -g aws-cdk` (Note: The MCP server itself doesn't use the CDK CLI directly, but it guides users through CDK application development that requires the CLI)
|
|
128
150
|
|
|
129
151
|
## Installation
|
|
130
152
|
|
|
@@ -28,6 +28,13 @@ MCP server for AWS Cloud Development Kit (CDK) best practices, infrastructure as
|
|
|
28
28
|
- Discover specialized constructs for AI/ML workloads
|
|
29
29
|
- Get implementation guidance for generative AI applications
|
|
30
30
|
|
|
31
|
+
### Lambda Layer Documentation Provider
|
|
32
|
+
|
|
33
|
+
- Access comprehensive documentation for AWS Lambda layers
|
|
34
|
+
- Get code examples for generic Lambda layers and Python-specific layers
|
|
35
|
+
- Retrieve directory structure information and implementation best practices
|
|
36
|
+
- Seamless integration with AWS Documentation MCP Server for detailed documentation
|
|
37
|
+
|
|
31
38
|
### Amazon Bedrock Agent Schema Generation
|
|
32
39
|
|
|
33
40
|
- Use this tool when creating Bedrock Agents with Action Groups that use Lambda functions
|
|
@@ -46,20 +53,21 @@ This diagram provides a comprehensive view of the recommended CDK implementation
|
|
|
46
53
|
|
|
47
54
|
```mermaid
|
|
48
55
|
graph TD
|
|
49
|
-
Start([Start]) -->
|
|
50
|
-
|
|
56
|
+
Start([Start]) --> A["CDKGeneralGuidance"]
|
|
57
|
+
A --> Init["cdk init app"]
|
|
58
|
+
|
|
51
59
|
Init --> B{Choose Approach}
|
|
52
60
|
B -->|"Common Patterns"| C1["GetAwsSolutionsConstructPattern"]
|
|
53
61
|
B -->|"GenAI Features"| C2["SearchGenAICDKConstructs"]
|
|
54
62
|
B -->|"Custom Needs"| C3["Custom CDK Code"]
|
|
55
|
-
|
|
63
|
+
|
|
56
64
|
C1 --> D1["Implement Solutions Construct"]
|
|
57
65
|
C2 --> D2["Implement GenAI Constructs"]
|
|
58
66
|
C3 --> D3["Implement Custom Resources"]
|
|
59
|
-
|
|
67
|
+
|
|
60
68
|
%% Bedrock Agent with Action Groups specific flow
|
|
61
69
|
D2 -->|"For Bedrock Agents<br/>with Action Groups"| BA["Create Lambda with<br/>BedrockAgentResolver"]
|
|
62
|
-
|
|
70
|
+
|
|
63
71
|
%% Schema generation flow
|
|
64
72
|
BA --> BS["GenerateBedrockAgentSchema"]
|
|
65
73
|
BS -->|"Success"| JSON["openapi.json created"]
|
|
@@ -67,28 +75,30 @@ graph TD
|
|
|
67
75
|
BSF -->|"Missing dependencies?"| InstallDeps["Install dependencies"]
|
|
68
76
|
InstallDeps --> BSR["Run script manually:<br/>python generate_schema.py"]
|
|
69
77
|
BSR --> JSON["openapi.json created"]
|
|
70
|
-
|
|
78
|
+
|
|
71
79
|
%% Use schema in Agent CDK
|
|
72
80
|
JSON --> AgentCDK["Use schema in<br/>Agent CDK code"]
|
|
73
81
|
AgentCDK --> D2
|
|
74
|
-
|
|
82
|
+
|
|
75
83
|
%% Conditional Lambda Powertools implementation
|
|
76
84
|
D1 & D2 & D3 --> HasLambda{"Using Lambda<br/>Functions?"}
|
|
77
|
-
HasLambda
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
HasLambda --> UseLayer{"Using Lambda<br/>Layers?"}
|
|
86
|
+
UseLayer -->|"Yes"| LLDP["LambdaLayerDocumentationProvider"]
|
|
87
|
+
|
|
88
|
+
HasLambda -->|"No"| SkipL["Skip"]
|
|
89
|
+
|
|
80
90
|
%% Rest of workflow
|
|
81
|
-
|
|
91
|
+
LLDP["LambdaLayerDocumentationProvider"] --> Synth["cdk synth"]
|
|
82
92
|
SkipL --> Synth
|
|
83
|
-
|
|
93
|
+
|
|
84
94
|
Synth --> Nag{"CDK Nag<br/>warnings?"}
|
|
85
95
|
Nag -->|Yes| E["ExplainCDKNagRule"]
|
|
86
96
|
Nag -->|No| Deploy["cdk deploy"]
|
|
87
|
-
|
|
97
|
+
|
|
88
98
|
E --> Fix["Fix or Add Suppressions"]
|
|
89
99
|
Fix --> CN["CheckCDKNagSuppressions"]
|
|
90
100
|
CN --> Synth
|
|
91
|
-
|
|
101
|
+
|
|
92
102
|
%% Styling with darker colors
|
|
93
103
|
classDef default fill:#424242,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
94
104
|
classDef cmd fill:#4a148c,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
@@ -96,24 +106,35 @@ graph TD
|
|
|
96
106
|
classDef note fill:#1b5e20,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
97
107
|
classDef output fill:#006064,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
98
108
|
classDef decision fill:#5d4037,stroke:#ffffff,stroke-width:1px,color:#ffffff;
|
|
99
|
-
|
|
109
|
+
|
|
100
110
|
class Init,Synth,Deploy,BSR cmd;
|
|
101
|
-
class C1,C2,BS,E,CN tool;
|
|
111
|
+
class A,C1,C2,BS,E,CN,LLDP tool;
|
|
102
112
|
class JSON output;
|
|
103
|
-
class HasLambda,Nag decision;
|
|
113
|
+
class HasLambda,UseLayer,Nag decision;
|
|
104
114
|
```
|
|
105
115
|
|
|
106
|
-
##
|
|
116
|
+
## Available MCP Tools
|
|
117
|
+
|
|
118
|
+
- **CDKGeneralGuidance**: Get prescriptive advice for building AWS applications with CDK
|
|
119
|
+
- **GetAwsSolutionsConstructPattern**: Find vetted architecture patterns combining AWS services
|
|
120
|
+
- **SearchGenAICDKConstructs**: Discover GenAI CDK constructs by name or features
|
|
121
|
+
- **GenerateBedrockAgentSchema**: Create OpenAPI schemas for Bedrock Agent action groups
|
|
122
|
+
- **LambdaLayerDocumentationProvider**: Access documentation for Lambda layers implementation
|
|
123
|
+
- **ExplainCDKNagRule**: Get detailed guidance on CDK Nag security rules
|
|
124
|
+
- **CheckCDKNagSuppressions**: Validate CDK Nag suppressions in your code
|
|
125
|
+
|
|
126
|
+
## Available MCP Resources
|
|
107
127
|
|
|
108
128
|
- **CDK Nag Rules**: Access rule packs via `cdk-nag://rules/{rule_pack}`
|
|
109
|
-
- **Lambda Powertools**: Get guidance on Lambda Powertools via `lambda-powertools://{topic}`
|
|
110
129
|
- **AWS Solutions Constructs**: Access patterns via `aws-solutions-constructs://{pattern_name}`
|
|
111
130
|
- **GenAI CDK Constructs**: Access documentation via `genai-cdk-constructs://{construct_type}/{construct_name}`
|
|
131
|
+
- **Lambda Powertools**: Get guidance on Lambda Powertools via `lambda-powertools://{topic}`
|
|
112
132
|
|
|
113
133
|
## Prerequisites
|
|
114
134
|
|
|
115
135
|
1. Install `uv` from [Astral](https://docs.astral.sh/uv/getting-started/installation/) or the [GitHub README](https://github.com/astral-sh/uv#installation)
|
|
116
136
|
2. Install Python using `uv python install 3.10`
|
|
137
|
+
3. Install AWS CDK CLI using `npm install -g aws-cdk` (Note: The MCP server itself doesn't use the CDK CLI directly, but it guides users through CDK application development that requires the CLI)
|
|
117
138
|
|
|
118
139
|
## Installation
|
|
119
140
|
|
|
@@ -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',
|