#!/usr/bin/env bash # AgentCore setup (steps 3-4-7). Terraform's AgentCore coverage lags, so this # stage uses the AWS CLI's `bedrock-agentcore-control` API. Verified against the # CLI on 2026-07-01; the surface moves fast, so re-check with # `aws bedrock-agentcore-control help` if a call rejects. # # T4 (implemented below): create an MCP Gateway and register the RAG Lambda as a # tool. Inbound auth is AWS_IAM (SigV4) -- no Cognito needed. The Gateway assumes # the IAM role from Terraform (`terraform output -raw gateway_role_arn`) to invoke # the Lambda. set -euo pipefail cd "$(dirname "$0")" : "${REGION:?set REGION}" : "${RAG_LAMBDA_ARN:?set RAG_LAMBDA_ARN (from: terraform -chdir=terraform output -raw rag_lambda_arn)}" : "${GATEWAY_ROLE_ARN:?set GATEWAY_ROLE_ARN (from: terraform -chdir=terraform output -raw gateway_role_arn)}" : "${BEDROCK_MODEL_ID:=anthropic.claude-3-5-sonnet-20241022-v2:0}" GW_NAME="${GW_NAME:-hncb-rag-gateway}" TAG='conan hncb demo' export AWS_PAGER="" echo "==> 1. Create the MCP Gateway (AWS_IAM inbound auth)" GW_JSON="$(aws bedrock-agentcore-control create-gateway \ --region "$REGION" \ --name "$GW_NAME" \ --role-arn "$GATEWAY_ROLE_ARN" \ --protocol-type MCP \ --authorizer-type AWS_IAM \ --tags "Owner=$TAG" 2>/dev/null \ || aws bedrock-agentcore-control list-gateways --region "$REGION" \ --query "items[?name=='$GW_NAME']|[0]" --output json)" GW_ID="$(echo "$GW_JSON" | python3 -c 'import sys,json;print(json.load(sys.stdin)["gatewayId"])')" echo " gatewayId=$GW_ID" echo "==> 2. Wait for the Gateway to be READY" for i in $(seq 1 20); do ST="$(aws bedrock-agentcore-control get-gateway --region "$REGION" --gateway-identifier "$GW_ID" --query status --output text)" echo " [$i] status=$ST" [ "$ST" = "READY" ] && break sleep 6 done GW_URL="$(aws bedrock-agentcore-control get-gateway --region "$REGION" --gateway-identifier "$GW_ID" --query gatewayUrl --output text)" echo "==> 3. Register the RAG Lambda as an MCP tool target" # Build the target config: mcp.lambda with the tool schema from agent/tool_schema.json # (wrapped in the inlinePayload list). The Gateway's inputSchema is a RESTRICTED # JSON-Schema subset (only type/properties/required/items/description), so we strip # anything else (e.g. the "default" on period_days) recursively. python3 - "$RAG_LAMBDA_ARN" > /tmp/hncb_target.json <<'PY' import json, sys, os ALLOWED = {"type", "properties", "required", "items", "description"} def clean(s): if not isinstance(s, dict): return s out = {k: v for k, v in s.items() if k in ALLOWED} if "properties" in out: out["properties"] = {k: clean(v) for k, v in out["properties"].items()} if "items" in out: out["items"] = clean(out["items"]) return out lambda_arn = sys.argv[1] schema = json.load(open(os.path.join("..", "agent", "tool_schema.json"))) schema["inputSchema"] = clean(schema["inputSchema"]) if "outputSchema" in schema: schema["outputSchema"] = clean(schema["outputSchema"]) print(json.dumps({ "mcp": {"lambda": {"lambdaArn": lambda_arn, "toolSchema": {"inlinePayload": [schema]}}} })) PY if aws bedrock-agentcore-control list-gateway-targets --region "$REGION" \ --gateway-identifier "$GW_ID" --query 'items[?name==`rag`]' --output text | grep -q rag; then echo " target 'rag' already exists -- reusing" else aws bedrock-agentcore-control create-gateway-target \ --region "$REGION" \ --gateway-identifier "$GW_ID" \ --name "rag" \ --target-configuration file:///tmp/hncb_target.json \ --credential-provider-configurations '[{"credentialProviderType":"GATEWAY_IAM_ROLE"}]' \ --query '{target:targetId,status:status}' --output json fi echo "" echo "Gateway ready. MCP URL:" echo " $GW_URL" echo "Export it for the agent + the invoke test:" echo " export AGENTCORE_GATEWAY_URL=$GW_URL" echo "" echo "Verify T4 (manual invoke returns the evidence package):" echo " REGION=$REGION AGENTCORE_GATEWAY_URL=$GW_URL python3 scripts/gateway_invoke_test.py CUST_000123" ######################################## # T5: deploy the agent to AgentCore Runtime (uses the starter toolkit CLI). # In ap-southeast-1 Claude 3.5 Sonnet v2 is INFERENCE_PROFILE-only -> use the # apac.* profile id, not the raw model id. ######################################## APAC_MODEL="apac.anthropic.claude-3-5-sonnet-20241022-v2:0" echo "" echo "==> (T5) Deploy the agent to AgentCore Runtime:" cat < note the printed Runtime ARN (Fusion / the UI will invoke this). # REQUIRED post-launch: the auto-created execution role can't call the Gateway # yet. Grant it (role name is printed by launch as AmazonBedrockAgentCoreSDKRuntime-*): ROLE=\$(aws iam list-roles --query "Roles[?starts_with(RoleName,'AmazonBedrockAgentCoreSDKRuntime-${REGION}')].RoleName | [0]" --output text) GW_ARN=\$(aws bedrock-agentcore-control get-gateway --region ${REGION} --gateway-identifier ${GW_ID} --query gatewayArn --output text) aws iam put-role-policy --role-name "\$ROLE" --policy-name hncb-gateway-invoke \\ --policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"bedrock-agentcore:InvokeGateway\"],\"Resource\":[\"\$GW_ARN\",\"\$GW_ARN/*\"]}]}" # Verify: agentcore invoke '{"prompt":"talking points for CUST_000123"}' EOF echo "Fill AGENTCORE_GATEWAY_URL + Runtime ARN into fusion/POLICY_SETUP.md."