AI-powered booking agent for WhatsApp built with AWS Bedrock AgentCore and Strands Agents.
- Model: DeepSeek R1 (via AWS Bedrock)
- Framework: Strands Agents
- Platform: AWS Bedrock AgentCore
- Session Management: S3SessionManager (persists conversations per phone number)
- API Integration: AgentCore Gateway (wraps TempoBook API as MCP tools)
- API: TempoBook booking API
- User requests service via WhatsApp
- Agent shows available services
- User selects service(s)
- Agent shows establishments and available dates
- Agent displays time slots
- User chooses time
- Agent collects customer info (name, email, phone)
- Agent creates booking and sends confirmation
AgentCore Gateway automatically wraps the TempoBook API as MCP tools for the agent.
uv sync
uv run python create_gateway.pyThis will:
- Create IAM role for Gateway
- Create AgentCore Gateway with MCP protocol
- Add TempoBook API as a target using the OpenAPI spec
- Output the Gateway MCP endpoint URL
Save the Gateway MCP URL for the next step.
uv sync
aws configure- Create S3 bucket for sessions:
aws s3 mb s3://tempobook-sessions- Set Gateway MCP URL as environment variable:
export GATEWAY_MCP_URL="<your-gateway-mcp-url>"- Configure AgentCore (use agent_with_gateway.py for Gateway integration):
uv run agentcore configure -e agent_with_gateway.py- Deploy:
uv run agentcore deployNote: If you prefer using direct API calls without Gateway, use agent.py instead of agent_with_gateway.py.
Invoke from your WhatsApp webhook:
import boto3
import json
client = boto3.client('bedrock-agentcore')
response = client.invoke_agent_runtime(
agentRuntimeArn="<your-agent-arn>",
runtimeSessionId=f"whatsapp-{phone_number}",
payload=json.dumps({
"phone": phone_number,
"message": user_message
}).encode()
)
reply = json.loads(response['payload'].read())['response']AgentCore Gateway automatically exposes these tools via MCP from the TempoBook API:
getServices
- Lists all available services with duration and pricing
- Mapped from: GET /api/services
getEstablishmentsByServices
- Finds establishments offering selected services
- Args: comma-separated service IDs
- Mapped from: GET /api/establishments/establishments-by-services
getAvailableTimes
- Shows available time slots for specific date
- Args: date (ISO), establishment ID, service IDs, total duration (minutes)
- Mapped from: POST /api/bookings/availableTime
createBooking
- Creates the booking
- Args: customer info, service IDs, establishment, date, time, duration
- Mapped from: POST /api/bookings/
The OpenAPI specification is in tempobook-api-spec.yaml.
Set in AgentCore configuration:
GATEWAY_MCP_URL: MCP endpoint URL from Gateway setup- S3 bucket name:
tempobook-sessions(hardcoded in agent code)
uv run agentcore devOr test directly:
uv run agentcore invoke '{"phone": "+593995604584", "message": "I want to book a service"}'GET /api/servicesGET /api/establishments/establishments-by-servicesPOST /api/bookings/availableTimePOST /api/bookings/
Each WhatsApp conversation is isolated by phone number:
- Session ID:
whatsapp-{phone_number} - Storage: S3 (auto-persisted by S3SessionManager)
- Conversation window: 20 messages (SlidingWindowConversationManager)
- DeepSeek R1 is cost-effective for this use case
- Sessions persist across message invocations
- Agent maintains conversation context automatically
- All dates use ISO 8601 format
- Phone codes default to international format (e.g., "+593")