From bbeierle12-skill-mcp-claude
AWS development with CDK best practices, serverless patterns, cost optimization, and event-driven architecture. Use when deploying to AWS, writing Lambda functions, configuring API Gateway, working with DynamoDB, S3, or any AWS service.
npx claudepluginhub joshuarweaver/cascade-code-languages-misc-1 --plugin bbeierle12-skill-mcp-claudeThis skill uses the workspace's default tool permissions.
```
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
infrastructure/
├── bin/
│ └── app.ts # CDK app entry point
├── lib/
│ ├── stacks/
│ │ ├── api-stack.ts
│ │ ├── database-stack.ts
│ │ └── storage-stack.ts
│ ├── constructs/
│ │ ├── lambda-function.ts
│ │ └── api-gateway.ts
│ └── config/
│ └── environment.ts
├── lambda/
│ └── handlers/
├── cdk.json
└── package.json
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { Construct } from 'constructs';
interface ApiStackProps extends cdk.StackProps {
environment: string;
domainName?: string;
}
export class ApiStack extends cdk.Stack {
public readonly api: apigateway.RestApi;
constructor(scope: Construct, id: string, props: ApiStackProps) {
super(scope, id, props);
const handler = new lambda.Function(this, 'ApiHandler', {
runtime: lambda.Runtime.NODEJS_18_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('lambda/handlers'),
environment: { NODE_ENV: props.environment },
memorySize: 256,
timeout: cdk.Duration.seconds(30),
});
this.api = new apigateway.RestApi(this, 'Api', {
restApiName: `${props.environment}-api`,
deployOptions: {
stageName: props.environment,
throttlingRateLimit: 1000,
throttlingBurstLimit: 500,
},
});
const integration = new apigateway.LambdaIntegration(handler);
this.api.root.addMethod('GET', integration);
}
}
import { APIGatewayProxyHandler } from 'aws-lambda';
// Initialize outside handler for connection reuse
const dynamodb = new DynamoDB.DocumentClient();
export const handler: APIGatewayProxyHandler = async (event) => {
try {
const body = JSON.parse(event.body || '{}');
const result = await processRequest(body);
return response(200, result);
} catch (error) {
console.error('Error:', error);
return response(500, { error: 'Internal server error' });
}
};
function response(statusCode: number, body: any) {
return {
statusCode,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify(body),
};
}
const table = new dynamodb.Table(this, 'Table', {
partitionKey: { name: 'PK', type: dynamodb.AttributeType.STRING },
sortKey: { name: 'SK', type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
});
// Access patterns
// User by ID: PK=USER#123, SK=PROFILE
// User's orders: PK=USER#123, SK=ORDER#timestamp
// Order by ID: GSI1PK=ORDER#456, GSI1SK=ORDER#456
const rule = new events.Rule(this, 'OrderCreatedRule', {
eventPattern: {
source: ['orders'],
detailType: ['OrderCreated'],
},
});
rule.addTarget(new targets.LambdaFunction(processOrderHandler));
rule.addTarget(new targets.SqsQueue(notificationQueue));
const dlq = new sqs.Queue(this, 'DeadLetterQueue');
const queue = new sqs.Queue(this, 'ProcessingQueue', {
visibilityTimeout: cdk.Duration.seconds(300),
deadLetterQueue: { queue: dlq, maxReceiveCount: 3 },
});
processor.addEventSource(new SqsEventSource(queue, {
batchSize: 10,
maxBatchingWindow: cdk.Duration.seconds(5),
}));
const handler = new lambda.Function(this, 'Handler', {
memorySize: 256,
timeout: cdk.Duration.seconds(10),
architecture: lambda.Architecture.ARM_64, // Cost savings
});
const bucket = new s3.Bucket(this, 'Bucket', {
lifecycleRules: [{
transitions: [
{ storageClass: s3.StorageClass.INFREQUENT_ACCESS, transitionAfter: cdk.Duration.days(30) },
{ storageClass: s3.StorageClass.GLACIER, transitionAfter: cdk.Duration.days(90) },
],
expiration: cdk.Duration.days(365),
}],
});
// Grant methods (preferred)
table.grantReadWriteData(handler);
bucket.grantRead(handler);
const secret = secretsmanager.Secret.fromSecretNameV2(this, 'DbSecret', 'prod/db/credentials');
secret.grantRead(handler);
new cloudwatch.Alarm(this, 'LambdaErrors', {
metric: handler.metricErrors(),
threshold: 1,
evaluationPeriods: 1,
});
const handler = new lambda.Function(this, 'Handler', {
tracing: lambda.Tracing.ACTIVE,
});