This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
AWS CDK project that deploys RapidAPI Football API as an OpenAPI target to AWS Bedrock AgentCore Gateway. Enables AI agents to query European football leagues, Champions League data, and player statistics through a standardized MCP interface.
# Install CDK dependencies
npm install
# Build TypeScript
npm run build
# Watch mode (auto-rebuild on changes)
npm run watch
# CDK commands
cdk list # List all stacks
cdk diff # Show changes to be deployed
cdk synth # Generate CloudFormation template
cdk deploy --profile default # Deploy to AWS
cdk destroy --profile default # Remove deployment- Copy
.env.exampleto.env.local - Configure the following required variables:
GATEWAY_IDENTIFIER: Gateway identifier from AWS (e.g.,my-gateway-abc123xyz)CREDENTIAL_PROVIDER_NAME: Credential provider name (e.g.,FootballAPICredentialProvider)
- Optional variables (auto-detected if not provided):
GATEWAY_NAME: Gateway name for resource naming/tagging (auto-extracted fromGATEWAY_IDENTIFIERprefix if not provided)AWS_REGION: AWS region (default:us-west-2)API_KEY_SECRET_ARN: Secret ARN for output reference only
- AWS account ID is automatically detected from your AWS credentials (profile/environment variables/IAM role)
Important: RapidAPI key is NOT configured in .env file. It must be stored in AWS Secrets Manager through the credential provider setup (see Prerequisites below).
To deploy the same target to different gateways:
-
Create separate environment files for each gateway:
cp .env.example .env.gateway-a cp .env.example .env.gateway-b
-
Configure each file with gateway-specific values:
Using Shared Provider (Recommended):
# .env.gateway-a GATEWAY_IDENTIFIER=gateway-a-abc123xyz CREDENTIAL_PROVIDER_NAME=FootballAPICredentialProvider # Shared # .env.gateway-b GATEWAY_IDENTIFIER=gateway-b-def456uvw CREDENTIAL_PROVIDER_NAME=FootballAPICredentialProvider # Shared
Using Isolated Providers:
# .env.gateway-a GATEWAY_IDENTIFIER=gateway-a-abc123xyz CREDENTIAL_PROVIDER_NAME=GatewayAFootballAPICredentialProvider # Unique # .env.gateway-b GATEWAY_IDENTIFIER=gateway-b-def456uvw CREDENTIAL_PROVIDER_NAME=GatewayBFootballAPICredentialProvider # Unique
-
Deploy to specific gateway using the deployment script:
# Deploy to gateway-a ./deploy.sh .env.gateway-a # Deploy to gateway-b ./deploy.sh .env.gateway-b
Or manually with environment variables:
# Manual deployment export AWS_PROFILE=default export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query Account --output text) export GATEWAY_IDENTIFIER=gateway-a-abc123xyz export CREDENTIAL_PROVIDER_NAME=FootballAPICredentialProvider export AWS_REGION=us-west-2 npm run build && cdk deploy --require-approval never
-
Stack names are auto-generated from gateway identifier prefix:
gateway-a-abc123xyzβGatewayAFootballAPITargetgateway-b-def456uvwβGatewayBFootballAPITargetmy-gateway-xyz789βMyFootballAPITarget- Can override with
GATEWAY_NAMEif needed
- Stack Name: Auto-generated from
GATEWAY_IDENTIFIERprefix (e.g.,my-gateway-xxxβMyFootballAPITarget) - Target Gateway: Configurable via
GATEWAY_IDENTIFIERenvironment variable - Resource Pattern: Uses L1 CloudFormation construct (
CfnGatewayTarget) + Custom Resource for IAM updates - Asset Management: OpenAPI schema automatically uploaded to CDK-managed S3 staging bucket
- Automatic IAM Updates: Custom Resource automatically updates Gateway service role with required permissions
-
Gateway Role Updater (
GatewayRoleUpdater- Custom Resource)- Purpose: Automatically updates Gateway service role IAM policy during deployment
- Implementation: Lambda-backed Custom Resource (
lib/constructs/gateway-role-updater.ts) - Required Permissions Added:
bedrock-agentcore:GetResourceApiKey- Access credential providerbedrock-agentcore:GetWorkloadAccessToken- Get workload tokenssecretsmanager:GetSecretValue- Read API keys from Secrets Manager
- Features:
- Idempotent - checks existing permissions before adding
- Version management - auto-cleans old IAM policy versions (keeps 3 + default)
- Scoped IAM permissions - Lambda only has access to Gateway service roles
- On deletion - keeps permissions for other targets
- Lambda Logs:
/aws/lambda/<StackName>-GatewayRoleUpdaterUpdateFunction
-
OpenAPI Schema Asset (
s3assets.Asset)- Source:
schemas/football-api-openapi.yaml - Automatically uploaded to CDK staging bucket
- S3 URI passed to gateway target configuration
- Source:
-
Pre-created Credential Provider
- ARN: Dynamically generated from
CREDENTIAL_PROVIDER_NAMEenvironment variable - Format:
arn:aws:bedrock-agentcore:{region}:{account}:token-vault/default/apikeycredentialprovider/{provider-name} - Created OUTSIDE CDK via AWS CLI (manual setup required for each gateway)
- Type: API_KEY with header location (
x-rapidapi-key)
- ARN: Dynamically generated from
-
Gateway Target (
CfnGatewayTarget)- References existing gateway by identifier
- Configures OpenAPI schema from S3
- Links to pre-created credential provider
- Outputs: TargetId, Status, GatewayArn, SchemaS3Uri
The schema embeds common league IDs in operation descriptions:
- Purpose: Reduce API calls by 50% for typical queries
- Implementation: League IDs in
info.descriptionand parameter descriptions - Benefit: AI agents can use IDs directly without calling
getLeaguesfirst
Common league IDs embedded:
- Premier League: 39
- La Liga: 140
- Serie A: 135
- Bundesliga: 78
- Ligue 1: 61
- Champions League: 2
-
Existing Gateway: Target gateway must exist in the configured region
-
Gateway Service Role Permissions: β AUTOMATICALLY CONFIGURED
- CDK stack now includes a Custom Resource that automatically updates Gateway service role with required permissions
- No manual IAM policy updates needed
- Permissions are idempotent - safe to run multiple times
- Required permissions added:
bedrock-agentcore:GetResourceApiKeybedrock-agentcore:GetWorkloadAccessTokensecretsmanager:GetSecretValue
-
Credential Provider: Create credential provider (one-time or per-gateway):
Option A: Shared Provider (Recommended - create once)
# Create one provider, use for all gateway targets aws bedrock-agentcore-control create-api-key-credential-provider \ --name FootballAPICredentialProvider \ --description "RapidAPI Football API Key (shared)" \ --profile default --region <YOUR_REGION>
Option B: Isolated Provider (create per gateway)
# Create unique provider for each gateway aws bedrock-agentcore-control create-api-key-credential-provider \ --name <GATEWAY_NAME>FootballAPICredentialProvider \ --description "RapidAPI Football API Key for <GATEWAY_NAME>" \ --profile default --region <YOUR_REGION>
-
Secret Setup: Store RapidAPI key using the credential provider:
# IMPORTANT: Use bedrock-agentcore-control to update the API key # DO NOT use secretsmanager put-secret-value directly # Get your RapidAPI key from: https://rapidapi.com/api-sports/api/api-football aws bedrock-agentcore-control update-api-key-credential-provider \ --name FootballAPICredentialProvider \ --api-key "YOUR_RAPID_API_KEY" \ --profile default --region <YOUR_REGION>
Why use update-api-key-credential-provider?
- The secret is managed by the
bedrock-agentcore-identityservice - Direct Secrets Manager operations may fail due to service ownership
- This command ensures proper formatting (
{"apiKey": "..."}) automatically - Provides better error messages for invalid keys
Important: This is a one-time setup per credential provider. The API key is stored in AWS Secrets Manager and retrieved automatically at runtime by the Gateway Target. You do NOT need to provide the API key as an environment variable during CDK deployment.
- The secret is managed by the
After credential provider is created (shared or isolated), configure .env file:
- Set
GATEWAY_IDENTIFIERto your target gateway ID - Set
CREDENTIAL_PROVIDER_NAMEto match the provider you created - Deploy:
cdk deploy --profile default
Each gateway deployment requires:
- Required: Unique
GATEWAY_IDENTIFIER(provided by AWS when gateway is created) - Required:
CREDENTIAL_PROVIDER_NAME(can be shared or unique, see strategies below) - Optional:
GATEWAY_NAME(auto-extracted from identifier prefix if not provided) - Auto-detected: AWS account ID from credentials (no configuration needed)
Note: RapidAPI key is stored in AWS Secrets Manager (not in environment variables)
Strategy 1: Shared Provider (Recommended)
- Create ONE credential provider, share across all gateway targets
- Simpler management, single API key to rotate
- All targets use:
CREDENTIAL_PROVIDER_NAME=FootballAPICredentialProvider
Strategy 2: Isolated Provider
- Create UNIQUE credential provider per gateway
- Better isolation, independent key rotation
- Each target uses:
CREDENTIAL_PROVIDER_NAME=Gateway{Name}FootballAPICredentialProvider
After deployment, the gateway exposes these tools:
Basic Tools:
getFixtures- Match fixtures, results, schedulesgetStandings- League tables/standingsgetTopScorers- Top goal scorersgetTopAssists- Top assists leadersgetLeagues- Search leagues by name or country (essential for finding league IDs)
Match Statistics Tools:
getFixtureStatistics- Detailed match statistics (shots, possession, passes, fouls, cards)getFixtureEvents- Match events timeline (goals with scorer/assist, cards, substitutions, VAR)getFixtureLineups- Team lineups, formations, and substitutesgetFixturePlayers- Individual player performance statistics
When to use getLeagues:
- For leagues NOT listed in the embedded common leagues (Premier League, La Liga, Serie A, Bundesliga, Ligue 1, Champions League)
- For qualification tournaments (World Cup Qualifiers, Euro Qualifiers, etc.)
- For lower divisions or regional competitions
- When you need to confirm the exact league ID
Example: World Cup Qualifiers Europe
-
Search by name to find the league:
getLeagues(name="World Cup", current=true) β Returns: World Cup - Qualification Europe (ID: 32) -
Use the league ID in other tools:
getFixtures(league=32, season=2024, last=10) β Returns: Recent World Cup Qualifier matches getStandings(league=32, season=2024) β Returns: Qualification group standings
Search options:
- By name:
getLeagues(name="Championship")- finds English Championship - By country:
getLeagues(country="Portugal")- finds all Portuguese leagues - By current status:
getLeagues(current=true)- only active leagues
- Use
getFixturesto find the fixture ID for your desired match - Use fixture-specific tools with that ID:
getFixtureEvents- Who scored? Who assisted? Timeline of eventsgetFixtureStatistics- Team-level stats (possession, shots, etc.)getFixturePlayers- Player-level performance ratings and statsgetFixtureLineups- Team formations and starting lineups
Replace placeholders with your actual values from environment configuration.
# List all targets on the gateway
aws bedrock-agentcore-control list-gateway-targets \
--gateway-identifier <YOUR_GATEWAY_IDENTIFIER> \
--profile default --region <YOUR_REGION>
# Get specific target details (after deployment)
aws bedrock-agentcore-control get-gateway-target \
--gateway-identifier <YOUR_GATEWAY_IDENTIFIER> \
--target-identifier <TARGET_ID_FROM_CDK_OUTPUT> \
--profile default --region <YOUR_REGION>- No Resource Naming: CDK resource names are auto-generated from
GATEWAY_NAME - Gateway Must Pre-exist: Target gateway must be created before deploying this stack
- Manual Credential Setup: Credential provider and secret must be created manually before deployment (can be shared across gateways or unique per gateway)
- Schema Validation: OpenAPI schema must have
operationIdfor each operation. AvoidoneOf/anyOf/allOfconstructs - Rate Limits: RapidAPI free tier is 100 requests/day. Monitor usage to avoid quota exhaustion
lib/
football-gateway-stack.ts # Main CDK stack with CfnGatewayTarget
bin/
football-gateway-app.ts # CDK app entry point, loads .env
schemas/
football-api-openapi.yaml # OpenAPI 3.0 schema with embedded league IDs
deploy.sh # CDK deployment script
.env.example # Environment template
.env.*.local # Gateway-specific configs (git-ignored)
- Check CDK bootstrap is complete:
cdk bootstrap - Verify IAM permissions for S3 asset upload
- Confirm gateway exists using
aws bedrock-agentcore-control get-gateway --gateway-identifier <YOUR_GATEWAY_IDENTIFIER> - Verify credential provider exists and has correct name
- Check CloudWatch Logs for detailed errors
Symptom: API calls fail with permission error mentioning Gateway service role lacks credential provider access
Root Cause: Gateway service role missing permissions to access credential provider and secrets
β
Automated Solution (CDK v2+): The stack now includes a Custom Resource (GatewayRoleUpdater) that automatically adds required permissions during deployment. No manual steps needed!
How it works:
- Lambda-backed Custom Resource checks Gateway service role
- Adds missing permissions:
GetResourceApiKey,GetWorkloadAccessToken,secretsmanager:GetSecretValue - Idempotent - safe to deploy multiple times
- Auto-handles IAM policy version limits (max 5)
- Logs to CloudWatch:
/aws/lambda/<StackName>-GatewayRoleUpdaterUpdateFunction
Manual Solution (if Custom Resource fails):
# 1. Identify the Gateway service role
aws bedrock-agentcore-control get-gateway \
--gateway-identifier <GATEWAY_ID> \
--query 'roleArn' --output text
# 2. Get the policy ARN from the role
aws iam list-attached-role-policies \
--role-name <ROLE_NAME> \
--query 'AttachedPolicies[0].PolicyArn' --output text
# 3. Update the policy to include credential provider permissions
cat > /tmp/gateway-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetGateway",
"Effect": "Allow",
"Action": ["bedrock-agentcore:GetGateway"],
"Resource": ["arn:aws:bedrock-agentcore:<region>:<account>:gateway/<gateway-prefix>-*"]
},
{
"Sid": "GetWorkloadAccessToken",
"Effect": "Allow",
"Action": ["bedrock-agentcore:GetWorkloadAccessToken"],
"Resource": "*"
},
{
"Sid": "GetResourceApiKey",
"Effect": "Allow",
"Action": ["bedrock-agentcore:GetResourceApiKey"],
"Resource": "*"
},
{
"Sid": "GetCredentials",
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": ["arn:aws:secretsmanager:<region>:<account>:secret:bedrock-agentcore-identity!*"]
}
]
}
EOF
# 4. Create new policy version
aws iam create-policy-version \
--policy-arn <POLICY_ARN> \
--policy-document file:///tmp/gateway-policy.json \
--set-as-defaultWhy CDK handles this now: As of v2.0, CDK includes a Custom Resource to automatically manage Gateway permissions. See "Gateway Role Updater" component above for details.
- Verify RapidAPI key in Secrets Manager
- Check RapidAPI subscription is active
- Ensure
x-rapidapi-hostheader matches endpoint
- AgentCore Gateway: Pay per tool invocation (pricing subject to AWS billing)
- Lambda (GatewayRoleUpdater): ~$0.01 per deployment, covered by free tier (1M requests/month)
- CloudWatch Logs: Negligible with 7-day retention
- Secrets Manager: ~$0.40/month per secret
- S3 Asset Storage: Negligible (<$0.01/month for schema file)
- CloudFormation: No charge
- RapidAPI: Free tier 100 requests/day, paid tiers from $10/month