Starter template for deploying AI agents with Amazon Bedrock AgentCore. Complete infrastructure scaffolding with authentication, API, and web interface - deployment automated in one command.
The example agent is built with the Strands Agents framework and includes calculator and weather tools to demonstrate tool integration. The focus is on deployment automation - you can easily swap the agent implementation or extend its capabilities.
Flow: 1. Browser loads React app from CloudFront/S3 2. User authenticates with Cognito, receives JWT token 3. Browser calls AgentCore directly with JWT Bearer token 4. AgentCore validates JWT and processes agent requests
aws --versionaws configure (access key/secret key)aws sso login --profile <profile-name>AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYAmazon Bedrock AgentCore is only available in specific AWS regions.
Before deploying, verify AgentCore availability in your target region by checking the AWS AgentCore Regions Documentation.
Windows (PowerShell):
.\deploy-all.ps1
macOS/Linux (Bash):
chmod +x deploy-all.sh scripts/build-frontend.sh
./deploy-all.sh
Platform Notes: - Windows users: Use the PowerShell script (
.ps1) - macOS/Linux users: Use the bash script (.sh) - Both scripts perform identical operations and produce the same infrastructure - If you prefer PowerShell on macOS:brew install --cask powershellthen runpwsh deploy-all.ps1
Time: ~10 minutes (most time is CodeBuild creating the container image)
Done! Your app is live at the CloudFront URL shown in the output.
Architecture Note: This demo uses a simple architecture where the React frontend calls AgentCore directly with JWT authentication.
Try these prompts: - "What's the weather like today?" - "Calculate 123 * 456" - "What is 2 to the power of 10?"
For rapid development without AWS deployment:
Prerequisites:
- Python 3.8+ with pip
- Node.js 18+ with npm
- AWS credentials configured with permissions for Bedrock model invocation. The default example invokes Anthropic Claude Haiku 4.5, model id global.anthropic.claude-haiku-4-5-20251001-v1:0.
Start Local Development:
macOS/Linux:
chmod +x dev-local.sh
./dev-local.sh
Windows (PowerShell):
.\dev-local.ps1
This will:
1. Create a Python virtual environment and install agent dependencies
2. Install frontend dependencies
3. Start the AgentCore agent locally on http://localhost:8080
4. Start the frontend dev server on http://localhost:5173
5. Configure the frontend to call the local agent (no authentication required)
Local Development Features: - ✅ Frontend hot reload (Vite dev server) - ✅ Fast agent restart cycle (no deployment needed) - ✅ Authentication with Cognito is bypassed - ✅ Same agent code as production - ✅ Rapid iteration without AWS deployment
How Local Development Works:
- python strands_agent.py starts your agent as a regular Python process
- app.run() in strands_agent.py creates HTTP server on localhost:8080 (via bedrock-agentcore library)
- Frontend sends POST requests to /api/invocations
- Agent executes directly in Python, calls AWS Bedrock APIs
- No Docker, no containers needed - just Python + web server
Development Workflow:
- Frontend changes (frontend/ files): Hot reload automatically via Vite
- Agent changes (agent/ files): Restart required - Ctrl+C then re-run script
Note: Agent restart takes ~10 seconds vs ~10 minutes for production deployment.
| Stack Name | Purpose | Key Resources |
|---|---|---|
| AgentCoreInfra | Build infrastructure | ECR Repository, CodeBuild Project, IAM Roles, S3 Bucket |
| AgentCoreAuth | Authentication | Cognito User Pool, User Pool Client |
| AgentCoreRuntime | Agent runtime with built-in auth | AgentCore Runtime with Cognito JWT Authorizer, Lambda Waiter |
| AgentCoreFrontend | Web UI | S3 Bucket, CloudFront Distribution, React App with Auth |
project-root/
├── agent/ # Agent runtime code
│ ├── strands_agent.py # Agent implementation (Strands framework)
│ ├── requirements.txt # Python dependencies
│ ├── Dockerfile # ARM64 container definition
│ └── .dockerignore # Docker ignore patterns
│
├── cdk/ # Infrastructure as Code
│ ├── bin/
│ │ └── app.ts # CDK app entry point
│ ├── lib/
│ │ ├── infra-stack.ts # Build infrastructure (ECR, IAM, CodeBuild)
│ │ ├── runtime-stack.ts # AgentCore runtime + API
│ │ └── frontend-stack.ts # CloudFront + S3
│ ├── cdk.json # CDK configuration
│ ├── tsconfig.json # TypeScript configuration
│ └── package.json # CDK dependencies
│
├── frontend/ # React app (Vite)
│ ├── src/
│ │ ├── App.tsx # Main UI component with auth
│ │ ├── AuthModal.tsx # Login/signup modal
│ │ ├── auth.ts # Cognito authentication logic
│ │ ├── agentcore.ts # Direct AgentCore invocation
│ │ └── main.tsx # React entry point
│ ├── dist/ # Build output (gitignored)
│ └── package.json # Frontend dependencies
│
├── scripts/
│ ├── build-frontend.ps1 # Builds React app with AgentCore ARN injection (Windows)
│ └── build-frontend.sh # Builds React app with AgentCore ARN injection (macOS/Linux)
│
├── deploy-all.ps1 # Main deployment orchestration (Windows)
├── deploy-all.sh # Main deployment orchestration (macOS/Linux)
├── dev-local.ps1 # Local development mode (Windows)
├── dev-local.sh # Local development mode (macOS/Linux)
└── README.md # This file
The deploy-all.ps1 script orchestrates the complete deployment:
/runtimes/{arn}/invocations with JWT Bearer tokenAgentCoreAuth stack)agent/strands_agent.py)@BedrockAgentCoreApp decoratorbatchGetBuilds response exceeds CloudFormation's 4KB Custom Resource limitThe execution role includes: - Bedrock model invocation - ECR image access - CloudWatch Logs & Metrics - X-Ray tracing - AgentCore Identity (workload access tokens)
/aws/bedrock-agentcore/runtimes/strands_agent-*bedrock-agentcore namespace/aws/codebuild/bedrock-agentcore-strands-agent-builderIf you prefer to deploy stacks individually:
cd cdk
npx cdk bootstrap --no-cli-pager
cd cdk
npx cdk deploy AgentCoreInfra --no-cli-pager
cd cdk
npx cdk deploy AgentCoreAuth --no-cli-pager
cd cdk
npx cdk deploy AgentCoreRuntime --no-cli-pager
Note: This will pause for 5-10 minutes while CodeBuild runs
Windows (PowerShell):
$agentRuntimeArn = aws cloudformation describe-stacks --stack-name AgentCoreRuntime --query "Stacks[0].Outputs[?OutputKey=='AgentRuntimeArn'].OutputValue" --output text --no-cli-pager
$region = aws cloudformation describe-stacks --stack-name AgentCoreRuntime --query "Stacks[0].Outputs[?OutputKey=='Region'].OutputValue" --output text --no-cli-pager
$userPoolId = aws cloudformation describe-stacks --stack-name AgentCoreAuth --query "Stacks[0].Outputs[?OutputKey=='UserPoolId'].OutputValue" --output text --no-cli-pager
$userPoolClientId = aws cloudformation describe-stacks --stack-name AgentCoreAuth --query "Stacks[0].Outputs[?OutputKey=='UserPoolClientId'].OutputValue" --output text --no-cli-pager
.\scripts\build-frontend.ps1 -UserPoolId $userPoolId -UserPoolClientId $userPoolClientId -AgentRuntimeArn $agentRuntimeArn -Region $region
cd cdk
npx cdk deploy AgentCoreFrontend --no-cli-pager
macOS/Linux (Bash): ```bash AGENT_RUNTIME_ARN=$(aws cloudformation describe-stacks --stack-name AgentCoreRuntime --query "Stacks[0].Outputs[?OutputKey=='AgentRuntimeArn'].OutputValue" --output text --no-cli-pager) REGION=$(aws cloudformation describe-stacks --stack-name AgentCoreRuntime --query "Stacks[0].Outputs[?OutputKey=='Region'].OutputValue" --output text --no-cli-pager) USER_POOL_ID=$(aws cloudformation describe-stacks --stack-name AgentCoreAuth --query "Stacks[0].Outputs[?OutputKey=='UserPoolId'].OutputValue" --output text --no-cli-pager) USER_POOL_CLIENT_ID=$(aws cloudformation describe-stacks --stack-name AgentCoreAuth --query "Stacks[0].Outputs[?OutputKey=='UserPoolClientId'].OutputValue" --output text --no-cli-pager) ./scripts/build-frontend.sh "$USER_POOL_ID" "$USER_POOL_CLIENT_ID" "$AGENT_RUNTIME_ARN" "$REGION" cd cdk npx cdk deploy AgentCo
$ claude mcp add sample-amazon-bedrock-agentcore-fullstack-webapp \
-- python -m otcore.mcp_server <graph>