Skip to content

Latest commit

Β 

History

History
432 lines (343 loc) Β· 17 KB

File metadata and controls

432 lines (343 loc) Β· 17 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

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.

Build and Development Commands

# 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

Environment Setup

  1. Copy .env.example to .env.local
  2. 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)
  3. Optional variables (auto-detected if not provided):
    • GATEWAY_NAME: Gateway name for resource naming/tagging (auto-extracted from GATEWAY_IDENTIFIER prefix if not provided)
    • AWS_REGION: AWS region (default: us-west-2)
    • API_KEY_SECRET_ARN: Secret ARN for output reference only
  4. 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).

Deploying to Multiple Gateways

To deploy the same target to different gateways:

  1. Create separate environment files for each gateway:

    cp .env.example .env.gateway-a
    cp .env.example .env.gateway-b
  2. 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
  3. 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
  4. Stack names are auto-generated from gateway identifier prefix:

    • gateway-a-abc123xyz β†’ GatewayAFootballAPITarget
    • gateway-b-def456uvw β†’ GatewayBFootballAPITarget
    • my-gateway-xyz789 β†’ MyFootballAPITarget
    • Can override with GATEWAY_NAME if needed

Architecture

CDK Stack Pattern

  • Stack Name: Auto-generated from GATEWAY_IDENTIFIER prefix (e.g., my-gateway-xxx β†’ MyFootballAPITarget)
  • Target Gateway: Configurable via GATEWAY_IDENTIFIER environment 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

Key Components

  1. 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 provider
      • bedrock-agentcore:GetWorkloadAccessToken - Get workload tokens
      • secretsmanager: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
  2. OpenAPI Schema Asset (s3assets.Asset)

    • Source: schemas/football-api-openapi.yaml
    • Automatically uploaded to CDK staging bucket
    • S3 URI passed to gateway target configuration
  3. Pre-created Credential Provider

    • ARN: Dynamically generated from CREDENTIAL_PROVIDER_NAME environment 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)
  4. Gateway Target (CfnGatewayTarget)

    • References existing gateway by identifier
    • Configures OpenAPI schema from S3
    • Links to pre-created credential provider
    • Outputs: TargetId, Status, GatewayArn, SchemaS3Uri

OpenAPI Schema Optimization

The schema embeds common league IDs in operation descriptions:

  • Purpose: Reduce API calls by 50% for typical queries
  • Implementation: League IDs in info.description and parameter descriptions
  • Benefit: AI agents can use IDs directly without calling getLeagues first

Common league IDs embedded:

  • Premier League: 39
  • La Liga: 140
  • Serie A: 135
  • Bundesliga: 78
  • Ligue 1: 61
  • Champions League: 2

Deployment Prerequisites

One-Time Setup (Before First Deployment)

  1. Existing Gateway: Target gateway must exist in the configured region

  2. 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:GetResourceApiKey
      • bedrock-agentcore:GetWorkloadAccessToken
      • secretsmanager:GetSecretValue
  3. 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>
  4. 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-identity service
    • 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.

Per-Gateway Deployment

After credential provider is created (shared or isolated), configure .env file:

  • Set GATEWAY_IDENTIFIER to your target gateway ID
  • Set CREDENTIAL_PROVIDER_NAME to match the provider you created
  • Deploy: cdk deploy --profile default

Configuration Matrix

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)

Credential Provider Strategies

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

Available MCP Tools

After deployment, the gateway exposes these tools:

Basic Tools:

  • getFixtures - Match fixtures, results, schedules
  • getStandings - League tables/standings
  • getTopScorers - Top goal scorers
  • getTopAssists - Top assists leaders
  • getLeagues - 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 substitutes
  • getFixturePlayers - Individual player performance statistics

Finding Unknown League IDs

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

  1. Search by name to find the league:

    getLeagues(name="World Cup", current=true)
    β†’ Returns: World Cup - Qualification Europe (ID: 32)
    
  2. 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

Typical Workflow for Match Statistics

  1. Use getFixtures to find the fixture ID for your desired match
  2. Use fixture-specific tools with that ID:
    • getFixtureEvents - Who scored? Who assisted? Timeline of events
    • getFixtureStatistics - Team-level stats (possession, shots, etc.)
    • getFixturePlayers - Player-level performance ratings and stats
    • getFixtureLineups - Team formations and starting lineups

Verification Commands

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>

Important Constraints

  1. No Resource Naming: CDK resource names are auto-generated from GATEWAY_NAME
  2. Gateway Must Pre-exist: Target gateway must be created before deploying this stack
  3. Manual Credential Setup: Credential provider and secret must be created manually before deployment (can be shared across gateways or unique per gateway)
  4. Schema Validation: OpenAPI schema must have operationId for each operation. Avoid oneOf/anyOf/allOf constructs
  5. Rate Limits: RapidAPI free tier is 100 requests/day. Monitor usage to avoid quota exhaustion

File Structure

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)

Troubleshooting

Schema Upload Fails

  • Check CDK bootstrap is complete: cdk bootstrap
  • Verify IAM permissions for S3 asset upload

Target Creation Fails

  • 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

Gateway Permission Error: "User is not authorized to perform: bedrock-agentcore:GetResourceApiKey"

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-default

Why 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.

API Calls Return 403

  • Verify RapidAPI key in Secrets Manager
  • Check RapidAPI subscription is active
  • Ensure x-rapidapi-host header matches endpoint

Cost Considerations

  • 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