- Complete serverless AI-powered AWS operations platform - Multi-Lambda architecture with Function URL deployment - Bedrock AgentCore Gateway integration with MCP protocol - 20 AWS service tools for comprehensive operations - Dual authentication: AWS SigV4 + Okta JWT - Natural language interface with streaming responses - DynamoDB conversation persistence - Docker-based MCP Tool Lambda with Strands framework - Production-ready with enterprise security patterns - Comprehensive documentation and setup guides - Read-only operations by default with write enablement guide - Interactive client with CLI interface - Complete Okta OAuth2 PKCE setup - Management scripts for gateway and target operations - Sanitized configuration with dummy data for public sharing
11 KiB
Setup Guide - Bedrock AgentCore Gateway MCP Integration
📋 Navigation
🏠 README | 📖 Setup Guide | 🏗️ Architecture | 🔧 Scripts | 🤖 Client | ⚙️ Config | 🔐 Okta Setup
Prerequisites
- AWS CLI: Configured with
demo1
profile, regionus-east-1
- Python 3.11+: For Lambda functions and scripts
- AWS SAM CLI: For Lambda deployment
- Docker: For container builds (required for Lambda deployments)
- Okta Access Token: For Bedrock AgentCore Gateway authentication
- Latest boto3/botocore: Install the latest wheel files for boto3/botocore (required for Bedrock AgentCore Gateway APIs)
Step 1: Environment Setup
cd 07-Operational-Support-Lambda-Web-Adapter
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
pip install boto3 python-dotenv requests
# Verify AWS setup
aws sts get-caller-identity --profile demo1
Step 2: Configuration Setup
🔧 MANUAL STEP: Update Account ID
# Get your AWS account ID
ACCOUNT_ID=$(aws sts get-caller-identity --profile demo1 --query Account --output text)
echo "Your Account ID: $ACCOUNT_ID"
# Edit configuration file
nano configs/bedrock-agentcore-config.json
Replace all instances of YOUR_ACCOUNT_ID
with your actual account ID in:
aws.default_account
environments.dev.aws_account
environments.dev.bedrock_agentcore_role_arn
environments.dev.lambda_arn
(will update after Lambda deployment)
Step 3: Deploy AWS Operations Agent Lambda
🔧 MANUAL STEP: Record Lambda ARN and Function URL
cd agent-lambda
# Build and deploy
sam build --use-container
./deploy.sh dev
# Get Lambda ARN
LAMBDA_ARN=$(aws lambda get-function --function-name aws-operations-agent-dev --profile demo1 --query 'Configuration.FunctionArn' --output text)
echo "AWS Operations Agent Lambda ARN: $LAMBDA_ARN"
# Get Function URL
FUNCTION_URL=$(aws lambda get-function-url-config --function-name aws-operations-agent-dev --profile demo1 --query 'FunctionUrl' --output text)
echo "Function URL: $FUNCTION_URL"
🔧 MANUAL STEP: Update Configuration
cd .. # Back to project root
nano configs/bedrock-agentcore-config.json
# Update the following values:
# 1. environments.dev.lambda_arn with the ARN from above
# 2. environments.dev.function_url with the URL from above (without /stream suffix)
🧪 VALIDATION: Test AWS Operations Agent Lambda Deployment
Before proceeding to MCP Tool Lambda deployment, verify the AWS Operations Agent Lambda is working correctly:
# Test basic Lambda invocation
aws lambda invoke \
--function-name aws-operations-agent-dev \
--payload '{"message": "Hello test"}' \
--cli-binary-format raw-in-base64-out \
--profile demo1 \
--region us-east-1 \
/tmp/agent-test-response.json
# Check the response
cat /tmp/agent-test-response.json
Expected Response: You should see:
- StatusCode: 200 - This confirms the Lambda executed successfully
- Response body with 404 Not Found - This is expected since we're sending a basic test payload to a FastAPI application
The important part is the StatusCode: 200, which means the Lambda is deployed and running correctly. The 404 error in the response body is normal for this test.
If you see errors: Check the CloudWatch logs:
aws logs tail /aws/lambda/aws-operations-agent-dev --follow --profile demo1
Step 4: Deploy MCP Tool Lambda
🔧 MANUAL STEP: Record MCP Lambda ARN
cd mcp-tool-lambda
# Build and deploy Docker-based Lambda
./deploy-mcp-tool.sh
# Get MCP Tool Lambda ARN
MCP_LAMBDA_ARN=$(aws lambda get-function --function-name dev-bedrock-agentcore-mcp-tool --profile demo1 --query 'Configuration.FunctionArn' --output text)
echo "MCP Tool Lambda ARN: $MCP_LAMBDA_ARN"
🧪 VALIDATION: Test MCP Tool Lambda Deployment
Before proceeding to Bedrock AgentCore Gateway setup, verify the MCP Tool Lambda is working correctly:
# Test basic Lambda invocation
aws lambda invoke \
--function-name dev-bedrock-agentcore-mcp-tool \
--payload '{"test": "hello"}' \
--cli-binary-format raw-in-base64-out \
--profile demo1 \
--region us-east-1 \
/tmp/mcp-test-response.json
# Check the response
cat /tmp/mcp-test-response.json
Expected Response: You should see:
- StatusCode: 200 - This confirms the Lambda executed successfully
- Response body containing
available_tools
with a list of 20 AWS service tools:{ "success": false, "error": "Unable to determine tool name from context or event", "available_tools": ["hello_world", "get_time", "ec2_read_operations", "s3_read_operations", ...], "timestamp": "..." }
The key indicators of success are:
- StatusCode: 200 (Lambda executed)
available_tools
array containing 20 tools (MCP tools are loaded correctly)
If you see an error like "exec format error" or "Runtime.InvalidEntrypoint": This indicates a Docker architecture mismatch (ARM64 vs x86_64). Follow the troubleshooting steps in the Docker Architecture Issues section below.
Step 5: Bedrock AgentCore Gateway Setup
⚠️ IMPORTANT: 64-Character Name Limit
Bedrock AgentCore Gateway and Target names have a 64-character limit. The scripts use short names to avoid this constraint:
- Gateway names:
dev-aws-resource-inspector-gateway-{random}
(auto-generated)- Target names:
bac-tool
(Bedrock AgentCore tool - 8 chars)Target names get prepended to tool names during invocation, so keeping them short is critical for longer tool names like
cloudformation_read_operations
.
🔧 MANUAL STEP: Create Gateway and Update Configuration
cd ../scripts
source ../.venv/bin/activate
# List existing gateways (optional)
python list-gateways.py
# Create new gateway
python create-gateway.py --environment dev
After gateway creation, note the Gateway ID and URL from the output, then:
# Update bedrock-agentcore-config.json with the new gateway ID and URL
# The create-gateway.py script should automatically update these values
Create Target
cd scripts
# Create target pointing to MCP Tool Lambda with SHORT name (critical for 64-char limit)
python create-target.py --environment dev --lambda-arn $MCP_LAMBDA_ARN --name "bac-tool"
# Verify target creation
python list-targets.py
⚠️ CRITICAL: Target Name Length
The target name gets prepended to tool names when invoking tools. With tool names like
cloudformation_read_operations
(28 chars), using a short target name likebac-tool
(8 chars) ensures we stay well under the 64-character limit (8 + 28 = 36 chars).bac-tool = Bedrock AgentCore tool (short and descriptive)
Step 6: Okta Authentication
🔧 MANUAL STEP: Setup Okta Token
cd client
# Option 1: Use save_token.py script
python src/save_token.py
# Option 2: Create token file manually
echo "YOUR_OKTA_ACCESS_TOKEN" > ~/.okta_token
# Verify token file
ls -la ~/.okta_token
Step 7: Testing
Pre-Test Verification
# Verify all components are deployed
aws lambda get-function --function-name aws-operations-agent-dev --profile demo1 > /dev/null && echo "✅ AWS Operations Agent Lambda"
aws lambda get-function --function-name dev-bedrock-agentcore-mcp-tool --profile demo1 > /dev/null && echo "✅ MCP Tool Lambda"
[ -f "~/.okta_token" ] && echo "✅ Okta token file" || echo "❌ Missing Okta token"
🔧 MANUAL STEP: Interactive Testing
cd client
python src/main.py --verbose
# Test these commands:
# 1. "What time is it? Use the get_time tool."
# 2. "List my S3 buckets"
# 3. "Show me EC2 instances"
# 4. "What Lambda functions do I have?"
Verify Architecture Flow
The complete flow should work as:
- Client → Function URL (SigV4 + Okta token)
- Function URL → AWS Operations Agent Lambda (aws-operations-agent-dev)
- AWS Operations Agent Lambda → DynamoDB (conversation persistence)
- AWS Operations Agent Lambda → Bedrock AgentCore Gateway (MCP + Okta token)
- Bedrock AgentCore Gateway → MCP Tool Lambda (validates Okta token)
- MCP Tool Lambda → 20 AWS Tools (EC2, S3, Lambda, etc.)
Troubleshooting
Common Issues
Configuration Mismatch (Most Common):
# Check configuration has actual values (not templates)
cd scripts
python -c "
import json
config = json.load(open('../configs/bedrock-agentcore-config.json'))
gateway_id = config['bedrock_agentcore']['production_endpoints']['gateway_id']
if '<' in gateway_id:
print('❌ Configuration still has template values')
else:
print('✅ Configuration updated with actual values')
"
Authentication Errors:
# Check Okta token
if [ -f "~/.okta_token" ] && [ $(wc -c < ~/.okta_token) -gt 100 ]; then
echo "✅ Okta token appears valid"
else
echo "❌ Okta token missing or invalid"
fi
Lambda Deployment Issues:
# Check Lambda logs
aws logs tail /aws/lambda/aws-operations-agent-dev --follow --profile demo1
aws logs tail /aws/lambda/dev-bedrock-agentcore-mcp-tool --follow --profile demo1
Docker Architecture Issues (Critical for Mac/ARM64 users):
# If you see "Runtime.InvalidEntrypoint" or "exec format error"
# This means Docker built for ARM64 but Lambda needs x86_64
# Fix: Rebuild with correct platform
cd mcp-tool-lambda/lambda
docker build --platform linux/amd64 -t mcp-tool-lambda:latest .
# Then redeploy
cd ..
sam deploy --template-file mcp-tool-template.yaml --stack-name dev-bedrock-agentcore-mcp-tool \
--region us-east-1 --parameter-overrides Environment=dev \
--capabilities CAPABILITY_IAM --no-confirm-changeset --no-fail-on-empty-changeset \
--resolve-s3 --resolve-image-repos --profile demo1
# Verify fix
aws lambda invoke --function-name dev-bedrock-agentcore-mcp-tool \
--payload '{"test": "hello"}' --cli-binary-format raw-in-base64-out \
--profile demo1 --region us-east-1 /tmp/test-response.json
cat /tmp/test-response.json
# Should show available_tools list, not exec format error
Bedrock AgentCore Gateway Issues:
cd scripts
python get-gateway.py # Should show Status: READY
python get-target.py # Should show Status: READY
Quick Verification Commands
# Get your specific setup values
cd scripts
echo "Gateway ID: $(python list-gateways.py | grep 'Gateway ID' | head -1)"
echo "Target ID: $(python list-targets.py | grep 'Target ID' | head -1)"
echo "Function URL: $(aws lambda get-function-url-config --function-name aws-operations-agent-dev --profile demo1 --query 'FunctionUrl' --output text)"
Dynamic Values Reference
These values are unique per deployment:
- Gateway ID:
dev-aws-resource-inspector-gateway-<random>
- Target ID:
<random-alphanumeric>
- Function URL:
https://<unique-id>.lambda-url.us-east-1.on.aws/
Always use YOUR specific values, not template placeholders like <gateway-id>
.
Setup Complete! 🎉
Your Bedrock AgentCore Gateway MCP integration is ready for natural language AWS operations through the AWS Operations Agent interface.