ask_ravira
Send a patient question to Ravira's AI receptionist and receive a realistic response covering hours, services, pricing, insurance, and appointment booking for any dental practice.
Instructions
Ask Ravira a patient question and see the AI receptionist's response.
This demonstrates how Ravira handles real patient inquiries — including questions about hours, services, pricing, insurance, and appointment booking.
Args: patient_question: The patient's question (e.g. "Do you accept Delta Dental?", "I have a toothache — can I get seen today?", "How much does a cleaning cost?") practice_name: The dental practice name (default: Seattle Family Dentistry)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| patient_question | Yes | ||
| practice_name | No | Seattle Family Dentistry |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- server.py:62-107 (handler)The `ask_ravira` async function is the tool handler registered via `@mcp.tool()`. It takes a patient_question and optional practice_name, then either calls the Ravira API or falls back to a simulated response.
@mcp.tool() async def ask_ravira( patient_question: str, practice_name: str = "Seattle Family Dentistry", ) -> str: """ Ask Ravira a patient question and see the AI receptionist's response. This demonstrates how Ravira handles real patient inquiries — including questions about hours, services, pricing, insurance, and appointment booking. Args: patient_question: The patient's question (e.g. "Do you accept Delta Dental?", "I have a toothache — can I get seen today?", "How much does a cleaning cost?") practice_name: The dental practice name (default: Seattle Family Dentistry) """ if not DEMO_WIDGET_KEY: # Return a realistic simulated response when no demo key is configured return _simulate_ravira_response(patient_question, practice_name) session_id = str(uuid.uuid4()) try: async with httpx.AsyncClient(timeout=15.0) as client: resp = await client.post( f"{RAVIRA_API}/api/chat/message", json={ "widget_api_key": DEMO_WIDGET_KEY, "message": patient_question, "session_id": session_id, "channel": "chat", }, ) resp.raise_for_status() data = resp.json() return ( f"**Ravira's Response:**\n\n" f"{data.get('response', 'No response received.')}\n\n" f"_Intent detected: {data.get('intent', 'unknown')}_" ) except httpx.HTTPStatusError as e: log.error("API error: %s", e) return _simulate_ravira_response(patient_question, practice_name) except Exception as e: log.error("Unexpected error: %s", e) return _simulate_ravira_response(patient_question, practice_name) - server.py:110-158 (helper)Helper function `_simulate_ravira_response` that generates realistic simulated Ravira responses based on keyword matching of the patient's question (hours, insurance, cost, appointments, emergencies).
def _simulate_ravira_response(question: str, practice_name: str) -> str: """Return a realistic simulated Ravira response for demo purposes.""" q = question.lower() if any(w in q for w in ["hour", "open", "close", "when"]): answer = ( f"Hi there! {practice_name} is open Monday–Friday 8am–5pm and " f"Saturday 9am–2pm. We're closed on Sundays. Would you like to " f"schedule an appointment during those hours?" ) elif any(w in q for w in ["insurance", "delta", "accept", "plan", "coverage"]): answer = ( f"Great question! {practice_name} accepts most major dental insurance plans " f"including Delta Dental, Aetna, Cigna, and MetLife. I'd recommend calling " f"us to confirm your specific plan. Would you like to book an appointment?" ) elif any(w in q for w in ["cost", "price", "how much", "fee", "pay"]): answer = ( f"At {practice_name}, a routine cleaning and exam starts at $150 without insurance. " f"With insurance, your out-of-pocket cost is often much lower. Would you like " f"to schedule a consultation so we can give you an exact quote?" ) elif any(w in q for w in ["appointment", "book", "schedule", "available"]): answer = ( f"I'd love to help you book an appointment at {practice_name}! " f"Could you let me know your preferred day and time, and what type of " f"service you need? (e.g. cleaning, exam, emergency visit)" ) elif any(w in q for w in ["pain", "hurt", "emergency", "toothache", "broken"]): answer = ( f"I'm sorry to hear you're in pain! For dental emergencies, please call " f"{practice_name} directly at our front desk — we keep same-day emergency " f"slots available. If it's after hours and severe, please go to your nearest " f"urgent care. Is there anything else I can help with?" ) else: answer = ( f"Thanks for reaching out to {practice_name}! I'm Ravira, the AI assistant here. " f"I can help with appointment scheduling, insurance questions, pricing, and general " f"information about our services. Is there anything specific I can help you with today?" ) return ( f"**Ravira's Response for {practice_name}:**\n\n" f"{answer}\n\n" f"---\n" f"_This is Ravira's 24/7 AI receptionist. Real responses are powered by your " f"practice's own knowledge base._" ) - server.py:62-63 (registration)Registration via the `@mcp.tool()` decorator on the `ask_ravira` async function, which registers it as an MCP tool named 'ask_ravira' with FastMCP.
@mcp.tool() async def ask_ravira( - server.py:63-78 (schema)The function signature defines input schema: `patient_question: str` (required) and `practice_name: str` (optional, default 'Seattle Family Dentistry'). Return type is `str`.
async def ask_ravira( patient_question: str, practice_name: str = "Seattle Family Dentistry", ) -> str: """ Ask Ravira a patient question and see the AI receptionist's response. This demonstrates how Ravira handles real patient inquiries — including questions about hours, services, pricing, insurance, and appointment booking. Args: patient_question: The patient's question (e.g. "Do you accept Delta Dental?", "I have a toothache — can I get seen today?", "How much does a cleaning cost?") practice_name: The dental practice name (default: Seattle Family Dentistry) """