diff --git a/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 0000000..0efac37 --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,16 @@ +{ + "servers": { + "attractions": { + "command": "uv", + "args": ["run", "main.py", "--port", "8008"], + "cwd": "./src/mcp/weather-mcp", + "env": {} + }, + "weather": { + "command": "uv", + "args": ["run", "main.py", "--port", "8009"], + "cwd": "./src/mcp/weather-mcp", + "env": {} + } + } +} diff --git a/attractions.sh b/attractions.sh new file mode 100644 index 0000000..15344b5 --- /dev/null +++ b/attractions.sh @@ -0,0 +1,2 @@ +cd ./src/mcp/attractions-mcp +uv run main.py \ No newline at end of file diff --git a/demo/team_gemini_2025.pptx b/demo/team_gemini_2025.pptx new file mode 100644 index 0000000..c63c7bf Binary files /dev/null and b/demo/team_gemini_2025.pptx differ diff --git a/src/agent/attractions.ipynb b/src/agent/attractions.ipynb index 7d7a7de..dfdaf44 100644 --- a/src/agent/attractions.ipynb +++ b/src/agent/attractions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "4a8c1aa1", "metadata": {}, "outputs": [ @@ -10,8 +10,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "python: c:\\WorkSpace\\Hackathon\\Hackathon-2025\\.venv\\Scripts\\python.exe\n", - "uv: c:\\WorkSpace\\Hackathon\\Hackathon-2025\\.venv\\Scripts\\uv.EXE\n" + "python: /workspaces/No-Hackathon-2025/.venv/bin/python\n", + "uv: /workspaces/No-Hackathon-2025/.venv/bin/uv\n" ] } ], @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "7c3a1676", "metadata": {}, "outputs": [ @@ -32,16 +32,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: uv in c:\\workspace\\hackathon\\hackathon-2025\\.venv\\lib\\site-packages (0.8.20)\n", - "Note: you may need to restart the kernel to use updated packages.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[2mUsing Python 3.13.3 environment at: c:\\WorkSpace\\Hackathon\\Hackathon-2025\\.venv\u001b[0m\n", - "\u001b[2mAudited \u001b[1m13 packages\u001b[0m \u001b[2min 19ms\u001b[0m\u001b[0m\n" + "Requirement already satisfied: uv in /workspaces/No-Hackathon-2025/.venv/lib/python3.12/site-packages (0.8.22)\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "\u001b[2mUsing Python 3.12.3 environment at: /workspaces/No-Hackathon-2025/.venv\u001b[0m\n", + "\u001b[2mAudited \u001b[1m13 packages\u001b[0m \u001b[2min 23ms\u001b[0m\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "\u001b[2mUsing Python 3.12.3 environment at: /workspaces/No-Hackathon-2025/.venv\u001b[0m\n", + "\u001b[2mAudited \u001b[1m13 packages\u001b[0m \u001b[2min 23ms\u001b[0m\u001b[0m\n" ] } ], @@ -54,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "f6fdf3d8", "metadata": {}, "outputs": [ @@ -94,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "f9bc6177", "metadata": {}, "outputs": [ @@ -145,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "id": "5deceb6f", "metadata": {}, "outputs": [ @@ -166,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "ab1bb59a", "metadata": {}, "outputs": [ @@ -204,17 +201,21 @@ " print(f\"Loaded {len(tools)} MCP tools: {[tool.name for tool in tools]}\")\n", " \n", " # Create system prompt\n", - " system_prompt = \"\"\"You are a helpful travel assistant that can help users find and book attractions including weather.\n", - " \n", - " You have access to multiple MCP tools for tourist attractions, including:\n", - " - Searching for attractions by location and category\n", - " - Getting detailed attraction information\n", - " - Booking attractions for visitors\n", - " - Getting random attraction suggestions\n", - " - And more...\n", - " \n", - " When users ask about travel plans, use these tools to provide comprehensive information.\n", - " Always be helpful and provide practical advice.\"\"\"\n", + " system_prompt = \"\"\"You are a helpful travel assistant that can help users find and book attractions, including weather information.\n", + "\n", + "You have access to multiple MCP tools for tourist attractions, including:\n", + "- Searching for attractions by location and category\n", + "- Getting detailed attraction information\n", + "- Booking attractions for visitors\n", + "- Getting random attraction suggestions\n", + "- And more...\n", + "\n", + "IMPORTANT:\n", + "- Only use the information and data provided by the MCP tools and datasets. Do NOT make up or hallucinate any facts, details, or recommendations that are not present in the data.\n", + "- If you do not have enough information to answer a question, say so clearly and do not invent details.\n", + "- Always cite the source of your information (e.g., \"Based on the available dataset...\").\n", + "- When users ask about travel plans, use these tools to provide comprehensive information.\n", + "- Always be helpful and provide practical advice, but never fabricate or guess information outside the provided data.\"\"\"\n", " \n", " # Create prompt template\n", " prompt = ChatPromptTemplate.from_messages([\n", @@ -242,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "881d1451", "metadata": {}, "outputs": [ @@ -253,6 +254,9 @@ "Initializing agent with MCP tools...\n", "Loaded 7 MCP tools: ['get_attraction_details', 'search_attractions', 'get_random_attraction', 'book_attraction', 'search_and_format_attractions', 'get_current_weather', 'get_weather_forecast']\n", "Loaded 7 MCP tools: ['get_attraction_details', 'search_attractions', 'get_random_attraction', 'book_attraction', 'search_and_format_attractions', 'get_current_weather', 'get_weather_forecast']\n", + "LangChain agent with MCP tools ready!\n", + "Loaded 7 MCP tools: ['get_attraction_details', 'search_attractions', 'get_random_attraction', 'book_attraction', 'search_and_format_attractions', 'get_current_weather', 'get_weather_forecast']\n", + "Loaded 7 MCP tools: ['get_attraction_details', 'search_attractions', 'get_random_attraction', 'book_attraction', 'search_and_format_attractions', 'get_current_weather', 'get_weather_forecast']\n", "LangChain agent with MCP tools ready!\n" ] }, @@ -260,7 +264,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "C:\\Users\\JayGregory\\AppData\\Local\\Temp\\ipykernel_51000\\3851623357.py:50: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/\n", + "/tmp/ipykernel_12508/373215986.py:54: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/\n", " memory = ConversationBufferMemory(memory_key=\"chat_history\", return_messages=True)\n" ] } @@ -283,7 +287,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "ba56fc7e", "metadata": {}, "outputs": [ @@ -347,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "4d4447a3", "metadata": {}, "outputs": [ @@ -447,7 +451,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "id": "57dcf6ff", "metadata": {}, "outputs": [ @@ -461,36 +465,138 @@ "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m\n", - "Invoking: `search_and_format_attractions` with `{'location': 'Paris', 'limit': 10}`\n", + "Invoking: `search_attractions` with `{'location': 'Paris', 'limit': 6}`\n", "\n", "\n", "\u001b[0m\u001b[32;1m\u001b[1;3m\n", "Invoking: `get_current_weather` with `{'location': 'Paris'}`\n", "\n", "\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m🎯 Found 2 attractions in Paris:\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"category\": \"All Categories\",\n", + " \"location\": \"Paris\",\n", + " \"total_count\": 2,\n", + " \"attractions\": [\n", + " {\n", + " \"id\": 1,\n", + " \"name\": \"Eiffel Tower\",\n", + " \"description\": \"Iconic iron lattice tower located on the Champ de Mars in Paris, France\",\n", + " \"category\": \"architecture\",\n", + " \"location\": {\n", + " \"city\": \"Paris\",\n", + " \"country\": \"France\",\n", + " \"region\": \"Île-de-France\",\n", + " \"coordinates\": null\n", + " },\n", + " \"rating\": 4.6,\n", + " \"image_url\": \"https://example.com/eiffel-tower.jpg\",\n", + " \"website\": \"https://www.toureiffel.paris\",\n", + " \"opening_hours\": \"9:30 AM - 11:45 PM\",\n", + " \"entry_fee\": \"€29.40 - €73.30\"\n", + " },\n", + " {\n", + " \"id\": 5,\n", + " \"name\": \"Louvre Museum\",\n", + " \"description\": \"World's largest art museum and historic monument in Paris\",\n", + " \"category\": \"museums\",\n", + " \"location\": {\n", + " \"city\": \"Paris\",\n", + " \"country\": \"France\",\n", + " \"region\": \"Île-de-France\",\n", + " \"coordinates\": null\n", + " },\n", + " \"rating\": 4.4,\n", + " \"image_url\": \"https://example.com/louvre.jpg\",\n", + " \"website\": \"https://www.louvre.fr\",\n", + " \"opening_hours\": \"9:00 AM - 6:00 PM\",\n", + " \"entry_fee\": \"€17\"\n", + " }\n", + " ]\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `search_attractions` with `{'location': 'Paris', 'limit': 6}`\n", + "\n", "\n", - "1. 🏛️ **Eiffel Tower**\n", - " 📍 Paris, France\n", - " 🏷️ Architecture\n", - " ⭐ 4.6/5.0\n", - " 💰 €29.40 - €73.30\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_current_weather` with `{'location': 'Paris'}`\n", "\n", - "2. 🏛️ **Louvre Museum**\n", - " 📍 Paris, France\n", - " 🏷️ Museums\n", - " ⭐ 4.4/5.0\n", - " 💰 €17\n", "\n", "\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"category\": \"All Categories\",\n", + " \"location\": \"Paris\",\n", + " \"total_count\": 2,\n", + " \"attractions\": [\n", + " {\n", + " \"id\": 1,\n", + " \"name\": \"Eiffel Tower\",\n", + " \"description\": \"Iconic iron lattice tower located on the Champ de Mars in Paris, France\",\n", + " \"category\": \"architecture\",\n", + " \"location\": {\n", + " \"city\": \"Paris\",\n", + " \"country\": \"France\",\n", + " \"region\": \"Île-de-France\",\n", + " \"coordinates\": null\n", + " },\n", + " \"rating\": 4.6,\n", + " \"image_url\": \"https://example.com/eiffel-tower.jpg\",\n", + " \"website\": \"https://www.toureiffel.paris\",\n", + " \"opening_hours\": \"9:30 AM - 11:45 PM\",\n", + " \"entry_fee\": \"€29.40 - €73.30\"\n", + " },\n", + " {\n", + " \"id\": 5,\n", + " \"name\": \"Louvre Museum\",\n", + " \"description\": \"World's largest art museum and historic monument in Paris\",\n", + " \"category\": \"museums\",\n", + " \"location\": {\n", + " \"city\": \"Paris\",\n", + " \"country\": \"France\",\n", + " \"region\": \"Île-de-France\",\n", + " \"coordinates\": null\n", + " },\n", + " \"rating\": 4.4,\n", + " \"image_url\": \"https://example.com/louvre.jpg\",\n", + " \"website\": \"https://www.louvre.fr\",\n", + " \"opening_hours\": \"9:00 AM - 6:00 PM\",\n", + " \"entry_fee\": \"€17\"\n", + " }\n", + " ]\n", + "}\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"location\": \"Paris, Île-de-France, France\",\n", + " \"coordinates\": {\n", + " \"lat\": 48.85341,\n", + " \"lon\": 2.3488\n", + " },\n", + " \"temperature\": {\n", + " \"current\": 11.6,\n", + " \"feels_like\": 9.4,\n", + " \"min\": null,\n", + " \"max\": null,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Slight rain\",\n", + " \"code\": 61\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 11.6,\n", + " \"direction\": 7,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": null\n", + " },\n", + " \"humidity\": 86,\n", + " \"pressure\": 1017.9,\n", + " \"precipitation\": 0.6,\n", + " \"timezone\": \"Europe/Paris\",\n", + " \"timestamp\": \"2025-09-24T15:00\"\n", + "}\u001b[0m\u001b[33;1m\u001b[1;3m{\n", " \"location\": \"Paris, Île-de-France, France\",\n", " \"coordinates\": {\n", " \"lat\": 48.85341,\n", " \"lon\": 2.3488\n", " },\n", " \"temperature\": {\n", - " \"current\": 12.0,\n", - " \"feels_like\": 10.2,\n", + " \"current\": 11.6,\n", + " \"feels_like\": 9.4,\n", " \"min\": null,\n", " \"max\": null,\n", " \"unit\": \"°C\"\n", @@ -500,56 +606,139 @@ " \"code\": 61\n", " },\n", " \"wind\": {\n", - " \"speed\": 16.1,\n", - " \"direction\": 20,\n", + " \"speed\": 11.6,\n", + " \"direction\": 7,\n", " \"unit\": \"km/h\",\n", " \"max_gusts\": null\n", " },\n", - " \"humidity\": 64,\n", - " \"pressure\": 1018.1,\n", + " \"humidity\": 86,\n", + " \"pressure\": 1017.9,\n", " \"precipitation\": 0.6,\n", " \"timezone\": \"Europe/Paris\",\n", - " \"timestamp\": \"2025-09-23T11:45\"\n", - "}\u001b[0m\u001b[32;1m\u001b[1;3mHere are a few quick highlights and the current weather for Paris.\n", - "\n", - "Popular attractions (quick overview)\n", - "- Eiffel Tower — Architecture — Rating ~4.6/5 — Typical ticket range €29–€73\n", - " - Tip: Book a timed ticket in advance to avoid long queues; allow 1–2 hours; great at sunset.\n", - "- Louvre Museum — Museums — Rating ~4.4/5 — Typical ticket ~€17\n", - " - Tip: Closed on Tuesdays; get a timed-entry ticket and plan 2–4 hours (Mona Lisa area is busiest).\n", - "\n", - "Current weather in Paris (Île‑de‑France) — as of 2025-09-23 11:45 (local)\n", - "- Temperature: 12.0°C (feels like 10.2°C)\n", - "- Conditions: Slight rain\n", - "- Precipitation: ~0.6 mm\n", - "- Wind: ~16 km/h from ~20° (NNE)\n", - "- Humidity: 64% · Pressure: ~1018 hPa\n", - "\n", - "Practical suggestions\n", - "- Pack a compact umbrella or a waterproof jacket and wear layers — cool and light rain.\n", - "- For outdoor sights (Eiffel Tower, Seine strolls) prioritize mornings or late afternoons to avoid peak crowds.\n", - "- Want me to: find more attractions by neighborhood or category, get detailed info (hours, accessibility), or book tickets for the Eiffel Tower or Louvre? If you want booking, tell me the visit date, number of visitors, and the name/email to use.\u001b[0m\n", + " \"timestamp\": \"2025-09-24T15:00\"\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3mHere’s what I found for Paris:\n", + "\n", + "Popular attractions\n", + "- Eiffel Tower (ID: 1)\n", + " - Category: Architecture\n", + " - Description: Iconic iron lattice tower located on the Champ de Mars in Paris, France\n", + " - Rating: 4.6\n", + " - Opening hours: 9:30 AM – 11:45 PM\n", + " - Entry fee: €29.40 – €73.30\n", + " - Website: https://www.toureiffel.paris\n", + "\n", + "- Louvre Museum (ID: 5)\n", + " - Category: Museums\n", + " - Description: World’s largest art museum and historic monument in Paris\n", + " - Rating: 4.4\n", + " - Opening hours: 9:00 AM – 6:00 PM\n", + " - Entry fee: €17\n", + " - Website: https://www.louvre.fr\n", + "\n", + "Current weather in Paris\n", + "- Description: Slight rain\n", + "- Temperature: 11.6°C (feels like 9.4°C)\n", + "- Humidity: 86%\n", + "- Wind: 11.6 km/h\n", + "- Precipitation: 0.6 (data note: unit not specified)\n", + "- Time: 2025-09-24 15:00 (Europe/Paris)\n", + "\n", + "Would you like me to fetch a 7-day forecast for Paris, or help you plan a day around these attractions (e.g., add tickets or create an itinerary)? \n", + "Source: MCP datasets for attractions in Paris and current weather.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "Here’s what I found for Paris:\n", + "\n", + "Popular attractions\n", + "- Eiffel Tower (ID: 1)\n", + " - Category: Architecture\n", + " - Description: Iconic iron lattice tower located on the Champ de Mars in Paris, France\n", + " - Rating: 4.6\n", + " - Opening hours: 9:30 AM – 11:45 PM\n", + " - Entry fee: €29.40 – €73.30\n", + " - Website: https://www.toureiffel.paris\n", + "\n", + "- Louvre Museum (ID: 5)\n", + " - Category: Museums\n", + " - Description: World’s largest art museum and historic monument in Paris\n", + " - Rating: 4.4\n", + " - Opening hours: 9:00 AM – 6:00 PM\n", + " - Entry fee: €17\n", + " - Website: https://www.louvre.fr\n", + "\n", + "Current weather in Paris\n", + "- Description: Slight rain\n", + "- Temperature: 11.6°C (feels like 9.4°C)\n", + "- Humidity: 86%\n", + "- Wind: 11.6 km/h\n", + "- Precipitation: 0.6 (data note: unit not specified)\n", + "- Time: 2025-09-24 15:00 (Europe/Paris)\n", + "\n", + "Would you like me to fetch a 7-day forecast for Paris, or help you plan a day around these attractions (e.g., add tickets or create an itinerary)? \n", + "Source: MCP datasets for attractions in Paris and current weather.\n", + "\n", + "==================================================\n", + "\n", + "\u001b[32;1m\u001b[1;3mHere’s what I found for Paris:\n", + "\n", + "Popular attractions\n", + "- Eiffel Tower (ID: 1)\n", + " - Category: Architecture\n", + " - Description: Iconic iron lattice tower located on the Champ de Mars in Paris, France\n", + " - Rating: 4.6\n", + " - Opening hours: 9:30 AM – 11:45 PM\n", + " - Entry fee: €29.40 – €73.30\n", + " - Website: https://www.toureiffel.paris\n", + "\n", + "- Louvre Museum (ID: 5)\n", + " - Category: Museums\n", + " - Description: World’s largest art museum and historic monument in Paris\n", + " - Rating: 4.4\n", + " - Opening hours: 9:00 AM – 6:00 PM\n", + " - Entry fee: €17\n", + " - Website: https://www.louvre.fr\n", + "\n", + "Current weather in Paris\n", + "- Description: Slight rain\n", + "- Temperature: 11.6°C (feels like 9.4°C)\n", + "- Humidity: 86%\n", + "- Wind: 11.6 km/h\n", + "- Precipitation: 0.6 (data note: unit not specified)\n", + "- Time: 2025-09-24 15:00 (Europe/Paris)\n", + "\n", + "Would you like me to fetch a 7-day forecast for Paris, or help you plan a day around these attractions (e.g., add tickets or create an itinerary)? \n", + "Source: MCP datasets for attractions in Paris and current weather.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", - "Here are a few quick highlights and the current weather for Paris.\n", - "\n", - "Popular attractions (quick overview)\n", - "- Eiffel Tower — Architecture — Rating ~4.6/5 — Typical ticket range €29–€73\n", - " - Tip: Book a timed ticket in advance to avoid long queues; allow 1–2 hours; great at sunset.\n", - "- Louvre Museum — Museums — Rating ~4.4/5 — Typical ticket ~€17\n", - " - Tip: Closed on Tuesdays; get a timed-entry ticket and plan 2–4 hours (Mona Lisa area is busiest).\n", - "\n", - "Current weather in Paris (Île‑de‑France) — as of 2025-09-23 11:45 (local)\n", - "- Temperature: 12.0°C (feels like 10.2°C)\n", - "- Conditions: Slight rain\n", - "- Precipitation: ~0.6 mm\n", - "- Wind: ~16 km/h from ~20° (NNE)\n", - "- Humidity: 64% · Pressure: ~1018 hPa\n", - "\n", - "Practical suggestions\n", - "- Pack a compact umbrella or a waterproof jacket and wear layers — cool and light rain.\n", - "- For outdoor sights (Eiffel Tower, Seine strolls) prioritize mornings or late afternoons to avoid peak crowds.\n", - "- Want me to: find more attractions by neighborhood or category, get detailed info (hours, accessibility), or book tickets for the Eiffel Tower or Louvre? If you want booking, tell me the visit date, number of visitors, and the name/email to use.\n", + "Here’s what I found for Paris:\n", + "\n", + "Popular attractions\n", + "- Eiffel Tower (ID: 1)\n", + " - Category: Architecture\n", + " - Description: Iconic iron lattice tower located on the Champ de Mars in Paris, France\n", + " - Rating: 4.6\n", + " - Opening hours: 9:30 AM – 11:45 PM\n", + " - Entry fee: €29.40 – €73.30\n", + " - Website: https://www.toureiffel.paris\n", + "\n", + "- Louvre Museum (ID: 5)\n", + " - Category: Museums\n", + " - Description: World’s largest art museum and historic monument in Paris\n", + " - Rating: 4.4\n", + " - Opening hours: 9:00 AM – 6:00 PM\n", + " - Entry fee: €17\n", + " - Website: https://www.louvre.fr\n", + "\n", + "Current weather in Paris\n", + "- Description: Slight rain\n", + "- Temperature: 11.6°C (feels like 9.4°C)\n", + "- Humidity: 86%\n", + "- Wind: 11.6 km/h\n", + "- Precipitation: 0.6 (data note: unit not specified)\n", + "- Time: 2025-09-24 15:00 (Europe/Paris)\n", + "\n", + "Would you like me to fetch a 7-day forecast for Paris, or help you plan a day around these attractions (e.g., add tickets or create an itinerary)? \n", + "Source: MCP datasets for attractions in Paris and current weather.\n", "\n", "==================================================\n", "\n" @@ -560,8 +749,8 @@ "# 🚀 EXAMPLE USAGE - Run this cell after setting up your API key!\n", "\n", "# Simple question\n", - "await ask_assistant(\"What are some popular attractions in Paris? and what is the weather?\")\n", - "print(\"\\n\" + \"=\"*50 + \"\\n\")\n", + "#await ask_assistant(\"What are some popular attractions in Paris? and what is the weather?\")\n", + "#print(\"\\n\" + \"=\"*50 + \"\\n\")\n", "\n", "# Example 2: Weather + attractions\n", "# await ask_assistant(\"I'm planning to visit paris tomorrow. What's the weather like and what attractions should I visit?\")\n", @@ -570,7 +759,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "bd0841c0", "metadata": {}, "outputs": [ @@ -579,283 +768,482 @@ "output_type": "stream", "text": [ "Type 'exit' to quit. Press Enter on an empty line to skip.\n", - "🧳 User: give me a random attraction\n", + "🧳 User: We’re in Rome with our kids this weekend. I use a wheelchair, and we’re looking for something outdoors that’s family-friendly, but it has to be low-cost and not take the whole day.\n", "🤖 Assistant:\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "Invoking: `get_random_attraction` with `{'region': 'famous'}`\n", - "\n", - "\n", - "\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", - " \"id\": 10,\n", - " \"name\": \"Petra\",\n", - " \"description\": \"Archaeological city famous for rock-cut architecture and water conduit system\",\n", - " \"category\": \"historical\",\n", - " \"location\": {\n", - " \"city\": \"Ma'an\",\n", - " \"country\": \"Jordan\",\n", - " \"region\": \"Ma'an\",\n", - " \"coordinates\": null\n", - " },\n", - " \"rating\": 4.7,\n", - " \"image_url\": \"https://example.com/petra.jpg\",\n", - " \"website\": \"https://www.visitpetra.jo\",\n", - " \"opening_hours\": \"6:00 AM - 6:00 PM\",\n", - " \"entry_fee\": \"70 JOD (1 day), 55 JOD (2 days)\"\n", - "}\u001b[0m\u001b[32;1m\u001b[1;3mGreat choice — here’s a random pick:\n", - "\n", - "Petra (Jordan)\n", - "- What it is: Ancient archaeological city famous for its rock-cut architecture (like the Treasury) and ancient water conduit system.\n", - "- Location: Ma'an Governorate, Jordan.\n", - "- Category: Historical.\n", - "- Rating: 4.7.\n", - "- Opening hours: 6:00 AM – 6:00 PM.\n", - "- Entry fee: 70 JOD (1 day), 55 JOD (2 days).\n", - "- Website: https://www.visitpetra.jo\n", - "- Recommended visit length: 4–6 hours (longer if you plan hikes to the Monastery or Al-Khubtha).\n", - "- Best time to visit: Spring or autumn for milder weather; arrive early to avoid crowds and heat.\n", - "- Practical tips: wear sturdy walking shoes, bring plenty of water and sun protection, consider a guided tour to learn the history, and note some trails can be steep. Petra by Night is a special evening experience on some nights — check schedules in advance.\n", - "\n", - "Would you like more details (hours, accessibility, guided tours), help booking a ticket or tour, or another random attraction?\u001b[0m\n", - "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "Great choice — here’s a random pick:\n", - "\n", - "Petra (Jordan)\n", - "- What it is: Ancient archaeological city famous for its rock-cut architecture (like the Treasury) and ancient water conduit system.\n", - "- Location: Ma'an Governorate, Jordan.\n", - "- Category: Historical.\n", - "- Rating: 4.7.\n", - "- Opening hours: 6:00 AM – 6:00 PM.\n", - "- Entry fee: 70 JOD (1 day), 55 JOD (2 days).\n", - "- Website: https://www.visitpetra.jo\n", - "- Recommended visit length: 4–6 hours (longer if you plan hikes to the Monastery or Al-Khubtha).\n", - "- Best time to visit: Spring or autumn for milder weather; arrive early to avoid crowds and heat.\n", - "- Practical tips: wear sturdy walking shoes, bring plenty of water and sun protection, consider a guided tour to learn the history, and note some trails can be steep. Petra by Night is a special evening experience on some nights — check schedules in advance.\n", - "\n", - "Would you like more details (hours, accessibility, guided tours), help booking a ticket or tour, or another random attraction?\n", - "🧳 User: what about attractions in paris\n", + "🧳 User: We’re in Rome with our kids this weekend. I use a wheelchair, and we’re looking for something outdoors that’s family-friendly, but it has to be low-cost and not take the whole day.\n", "🤖 Assistant:\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m\n", - "Invoking: `search_and_format_attractions` with `{'location': 'Paris', 'category': None, 'limit': 10}`\n", + "Invoking: `search_attractions` with `{'location': 'Rome', 'category': 'parks', 'limit': 5}`\n", "\n", "\n", - "\u001b[0m\u001b[36;1m\u001b[1;3m🎯 Found 2 attractions in Paris:\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_weather_forecast` with `{'location': 'Rome', 'days': 3}`\n", "\n", - "1. 🏛️ **Eiffel Tower**\n", - " 📍 Paris, France\n", - " 🏷️ Architecture\n", - " ⭐ 4.6/5.0\n", - " 💰 €29.40 - €73.30\n", "\n", - "2. 🏛️ **Louvre Museum**\n", - " 📍 Paris, France\n", - " 🏷️ Museums\n", - " ⭐ 4.4/5.0\n", - " 💰 €17\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"category\": \"Parks & Gardens\",\n", + " \"location\": \"Rome\",\n", + " \"total_count\": 0,\n", + " \"attractions\": []\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `search_attractions` with `{'location': 'Rome', 'category': 'parks', 'limit': 5}`\n", + "\n", "\n", "\u001b[0m\u001b[32;1m\u001b[1;3m\n", - "Invoking: `search_attractions` with `{'location': 'Paris', 'category': None, 'limit': 10}`\n", + "Invoking: `get_weather_forecast` with `{'location': 'Rome', 'days': 3}`\n", "\n", "\n", "\u001b[0m\u001b[33;1m\u001b[1;3m{\n", - " \"category\": \"All Categories\",\n", - " \"location\": \"Paris\",\n", - " \"total_count\": 2,\n", - " \"attractions\": [\n", - " {\n", - " \"id\": 1,\n", - " \"name\": \"Eiffel Tower\",\n", - " \"description\": \"Iconic iron lattice tower located on the Champ de Mars in Paris, France\",\n", - " \"category\": \"architecture\",\n", - " \"location\": {\n", - " \"city\": \"Paris\",\n", - " \"country\": \"France\",\n", - " \"region\": \"Île-de-France\",\n", - " \"coordinates\": null\n", - " },\n", - " \"rating\": 4.6,\n", - " \"image_url\": \"https://example.com/eiffel-tower.jpg\",\n", - " \"website\": \"https://www.toureiffel.paris\",\n", - " \"opening_hours\": \"9:30 AM - 11:45 PM\",\n", - " \"entry_fee\": \"€29.40 - €73.30\"\n", - " },\n", - " {\n", - " \"id\": 5,\n", - " \"name\": \"Louvre Museum\",\n", - " \"description\": \"World's largest art museum and historic monument in Paris\",\n", - " \"category\": \"museums\",\n", - " \"location\": {\n", - " \"city\": \"Paris\",\n", - " \"country\": \"France\",\n", - " \"region\": \"Île-de-France\",\n", - " \"coordinates\": null\n", - " },\n", - " \"rating\": 4.4,\n", - " \"image_url\": \"https://example.com/louvre.jpg\",\n", - " \"website\": \"https://www.louvre.fr\",\n", - " \"opening_hours\": \"9:00 AM - 6:00 PM\",\n", - " \"entry_fee\": \"€17\"\n", - " }\n", - " ]\n", - "}\u001b[0m\u001b[32;1m\u001b[1;3mGreat — here are popular Paris attractions with quick notes and tips. Tell me which ones you want more details or to book.\n", + " \"category\": \"Parks & Gardens\",\n", + " \"location\": \"Rome\",\n", + " \"total_count\": 0,\n", + " \"attractions\": []\n", + "}\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", + " \"error\": \"Failed to get forecast for Rome: API request failed: HTTPSConnectionPool(host='geocoding-api.open-meteo.com', port=443): Read timed out. (read timeout=10)\"\n", + "}\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", + " \"error\": \"Failed to get forecast for Rome: API request failed: HTTPSConnectionPool(host='geocoding-api.open-meteo.com', port=443): Read timed out. (read timeout=10)\"\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_current_weather` with `{'location': 'Rome'}`\n", "\n", - "- Eiffel Tower (architecture) — Iconic iron tower on the Champ de Mars. Opening hours: ~9:30 AM–11:45 PM. Tickets range ~€29–€73 depending on access/age. Tip: book a timed-entry or summit ticket in advance; sunset or night views are spectacular.\n", "\n", - "- Louvre Museum (museums) — World’s largest art museum (home of the Mona Lisa). Opening hours: ~9:00 AM–6:00 PM; entry ~€17. Tip: closed some weekdays (check before you go), use a timed-entry ticket and allow 2–4 hours (or more).\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_weather_forecast` with `{'location': 'Rome', 'days': 3}`\n", "\n", - "Other top picks to consider:\n", - "- Notre‑Dame Cathedral (historic landmark) — note: restoration work continues after the 2019 fire; access may be limited.\n", - "- Musée d’Orsay — Impressionist and post‑Impressionist masterpieces in a former railway station.\n", - "- Sacré‑Cœur and Montmartre — hilltop basilica with great city views and a bohemian neighborhood to explore.\n", - "- Arc de Triomphe & Champs‑Élysées — climb the Arc for views; stroll the avenue for shopping and cafés.\n", - "- Sainte‑Chapelle — stunning medieval stained-glass chapel on Île de la Cité.\n", - "- Seine river cruise (Bateaux Mouches or similar) — relaxing way to see many riverside monuments.\n", - "- Luxembourg Gardens — peaceful park for a stroll or picnic.\n", - "- Palace of Versailles (day trip) — lavish palace and gardens just outside Paris; allow a full day.\n", "\n", - "Would you like:\n", - "- Details for any specific attraction (hours, accessibility, guided tours)?\n", - "- Help booking tickets (tell me date, number of visitors, name/email)?\n", - "- Current weather for Paris right now or a forecast for your travel dates?\u001b[0m\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_current_weather` with `{'location': 'Rome'}`\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "Great — here are popular Paris attractions with quick notes and tips. Tell me which ones you want more details or to book.\n", - "\n", - "- Eiffel Tower (architecture) — Iconic iron tower on the Champ de Mars. Opening hours: ~9:30 AM–11:45 PM. Tickets range ~€29–€73 depending on access/age. Tip: book a timed-entry or summit ticket in advance; sunset or night views are spectacular.\n", - "\n", - "- Louvre Museum (museums) — World’s largest art museum (home of the Mona Lisa). Opening hours: ~9:00 AM–6:00 PM; entry ~€17. Tip: closed some weekdays (check before you go), use a timed-entry ticket and allow 2–4 hours (or more).\n", - "\n", - "Other top picks to consider:\n", - "- Notre‑Dame Cathedral (historic landmark) — note: restoration work continues after the 2019 fire; access may be limited.\n", - "- Musée d’Orsay — Impressionist and post‑Impressionist masterpieces in a former railway station.\n", - "- Sacré‑Cœur and Montmartre — hilltop basilica with great city views and a bohemian neighborhood to explore.\n", - "- Arc de Triomphe & Champs‑Élysées — climb the Arc for views; stroll the avenue for shopping and cafés.\n", - "- Sainte‑Chapelle — stunning medieval stained-glass chapel on Île de la Cité.\n", - "- Seine river cruise (Bateaux Mouches or similar) — relaxing way to see many riverside monuments.\n", - "- Luxembourg Gardens — peaceful park for a stroll or picnic.\n", - "- Palace of Versailles (day trip) — lavish palace and gardens just outside Paris; allow a full day.\n", - "\n", - "Would you like:\n", - "- Details for any specific attraction (hours, accessibility, guided tours)?\n", - "- Help booking tickets (tell me date, number of visitors, name/email)?\n", - "- Current weather for Paris right now or a forecast for your travel dates?\n", - "🧳 User: book eiffel tower\n", - "🤖 Assistant:\n", "\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_weather_forecast` with `{'location': 'Rome', 'days': 3}`\n", + "\n", + "\n", + "\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", + " \"error\": \"Failed to get forecast for Rome: API request failed: HTTPSConnectionPool(host='api.open-meteo.com', port=443): Read timed out. (read timeout=10)\"\n", + "}\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"error\": \"Failed to get weather for Rome: API request failed: HTTPSConnectionPool(host='geocoding-api.open-meteo.com', port=443): Read timed out. (read timeout=10)\"\n", + "}\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", + " \"error\": \"Failed to get forecast for Rome: API request failed: HTTPSConnectionPool(host='api.open-meteo.com', port=443): Read timed out. (read timeout=10)\"\n", + "}\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"error\": \"Failed to get weather for Rome: API request failed: HTTPSConnectionPool(host='geocoding-api.open-meteo.com', port=443): Read timed out. (read timeout=10)\"\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `search_attractions` with `{'location': 'Rome', 'category': 'parks', 'limit': 10}`\n", + "\n", + "\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_current_weather` with `{'location': 'Rome'}`\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3m\n", - "Invoking: `search_attractions` with `{'location': 'Paris', 'category': 'architecture', 'limit': 20}`\n", + "\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_weather_forecast` with `{'location': 'Rome', 'days': 3}`\n", "\n", "\n", "\u001b[0m\u001b[33;1m\u001b[1;3m{\n", - " \"category\": \"Architecture\",\n", - " \"location\": \"Paris\",\n", - " \"total_count\": 1,\n", - " \"attractions\": [\n", + " \"category\": \"Parks & Gardens\",\n", + " \"location\": \"Rome\",\n", + " \"total_count\": 0,\n", + " \"attractions\": []\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `search_attractions` with `{'location': 'Rome', 'category': 'parks', 'limit': 10}`\n", + "\n", + "\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_current_weather` with `{'location': 'Rome'}`\n", + "\n", + "\n", + "\u001b[0m\u001b[32;1m\u001b[1;3m\n", + "Invoking: `get_weather_forecast` with `{'location': 'Rome', 'days': 3}`\n", + "\n", + "\n", + "\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"category\": \"Parks & Gardens\",\n", + " \"location\": \"Rome\",\n", + " \"total_count\": 0,\n", + " \"attractions\": []\n", + "}\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"location\": \"Rome, Lazio, Italy\",\n", + " \"coordinates\": {\n", + " \"lat\": 41.89193,\n", + " \"lon\": 12.51133\n", + " },\n", + " \"temperature\": {\n", + " \"current\": 23.4,\n", + " \"feels_like\": 23.7,\n", + " \"min\": null,\n", + " \"max\": null,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Partly cloudy\",\n", + " \"code\": 2\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 8.9,\n", + " \"direction\": 249,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": null\n", + " },\n", + " \"humidity\": 90,\n", + " \"pressure\": 1007.6,\n", + " \"precipitation\": 0.7,\n", + " \"timezone\": \"Europe/Rome\",\n", + " \"timestamp\": \"2025-09-24T15:00\"\n", + "}\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", + " \"location\": \"Rome, Lazio, Italy\",\n", + " \"coordinates\": {\n", + " \"lat\": 41.89193,\n", + " \"lon\": 12.51133\n", + " },\n", + " \"timezone\": \"Europe/Rome\",\n", + " \"forecast_days\": 3,\n", + " \"forecasts\": [\n", " {\n", - " \"id\": 1,\n", - " \"name\": \"Eiffel Tower\",\n", - " \"description\": \"Iconic iron lattice tower located on the Champ de Mars in Paris, France\",\n", - " \"category\": \"architecture\",\n", - " \"location\": {\n", - " \"city\": \"Paris\",\n", - " \"country\": \"France\",\n", - " \"region\": \"Île-de-France\",\n", - " \"coordinates\": null\n", + " \"date\": \"2025-09-24\",\n", + " \"temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 19.2,\n", + " \"max\": 24.0,\n", + " \"unit\": \"°C\"\n", " },\n", - " \"rating\": 4.6,\n", - " \"image_url\": \"https://example.com/eiffel-tower.jpg\",\n", - " \"website\": \"https://www.toureiffel.paris\",\n", - " \"opening_hours\": \"9:30 AM - 11:45 PM\",\n", - " \"entry_fee\": \"€29.40 - €73.30\"\n", + " \"apparent_temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 20.3,\n", + " \"max\": 25.2,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Slight thunderstorm\",\n", + " \"code\": 95\n", + " },\n", + " \"precipitation\": {\n", + " \"total\": 7.6,\n", + " \"rain\": 0.0,\n", + " \"showers\": 7.6,\n", + " \"snow\": 0.0,\n", + " \"hours\": 12.0,\n", + " \"unit\": \"mm\"\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 11.6,\n", + " \"direction\": 251,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": 26.6\n", + " }\n", + " },\n", + " {\n", + " \"date\": \"2025-09-25\",\n", + " \"temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 16.9,\n", + " \"max\": 23.7,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"apparent_temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 17.1,\n", + " \"max\": 21.9,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Overcast\",\n", + " \"code\": 3\n", + " },\n", + " \"precipitation\": {\n", + " \"total\": 0.0,\n", + " \"rain\": 0.0,\n", + " \"showers\": 0.0,\n", + " \"snow\": 0.0,\n", + " \"hours\": 0.0,\n", + " \"unit\": \"mm\"\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 15.7,\n", + " \"direction\": 200,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": 34.9\n", + " }\n", + " },\n", + " {\n", + " \"date\": \"2025-09-26\",\n", + " \"temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 16.1,\n", + " \"max\": 24.1,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"apparent_temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 16.4,\n", + " \"max\": 23.8,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Partly cloudy\",\n", + " \"code\": 2\n", + " },\n", + " \"precipitation\": {\n", + " \"total\": 0.0,\n", + " \"rain\": 0.0,\n", + " \"showers\": 0.0,\n", + " \"snow\": 0.0,\n", + " \"hours\": 0.0,\n", + " \"unit\": \"mm\"\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 11.8,\n", + " \"direction\": 256,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": 27.4\n", + " }\n", + " }\n", + " ]\n", + "}\u001b[0m\u001b[33;1m\u001b[1;3m{\n", + " \"location\": \"Rome, Lazio, Italy\",\n", + " \"coordinates\": {\n", + " \"lat\": 41.89193,\n", + " \"lon\": 12.51133\n", + " },\n", + " \"temperature\": {\n", + " \"current\": 23.4,\n", + " \"feels_like\": 23.7,\n", + " \"min\": null,\n", + " \"max\": null,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Partly cloudy\",\n", + " \"code\": 2\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 8.9,\n", + " \"direction\": 249,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": null\n", + " },\n", + " \"humidity\": 90,\n", + " \"pressure\": 1007.6,\n", + " \"precipitation\": 0.7,\n", + " \"timezone\": \"Europe/Rome\",\n", + " \"timestamp\": \"2025-09-24T15:00\"\n", + "}\u001b[0m\u001b[38;5;200m\u001b[1;3m{\n", + " \"location\": \"Rome, Lazio, Italy\",\n", + " \"coordinates\": {\n", + " \"lat\": 41.89193,\n", + " \"lon\": 12.51133\n", + " },\n", + " \"timezone\": \"Europe/Rome\",\n", + " \"forecast_days\": 3,\n", + " \"forecasts\": [\n", + " {\n", + " \"date\": \"2025-09-24\",\n", + " \"temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 19.2,\n", + " \"max\": 24.0,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"apparent_temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 20.3,\n", + " \"max\": 25.2,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Slight thunderstorm\",\n", + " \"code\": 95\n", + " },\n", + " \"precipitation\": {\n", + " \"total\": 7.6,\n", + " \"rain\": 0.0,\n", + " \"showers\": 7.6,\n", + " \"snow\": 0.0,\n", + " \"hours\": 12.0,\n", + " \"unit\": \"mm\"\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 11.6,\n", + " \"direction\": 251,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": 26.6\n", + " }\n", + " },\n", + " {\n", + " \"date\": \"2025-09-25\",\n", + " \"temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 16.9,\n", + " \"max\": 23.7,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"apparent_temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 17.1,\n", + " \"max\": 21.9,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Overcast\",\n", + " \"code\": 3\n", + " },\n", + " \"precipitation\": {\n", + " \"total\": 0.0,\n", + " \"rain\": 0.0,\n", + " \"showers\": 0.0,\n", + " \"snow\": 0.0,\n", + " \"hours\": 0.0,\n", + " \"unit\": \"mm\"\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 15.7,\n", + " \"direction\": 200,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": 34.9\n", + " }\n", + " },\n", + " {\n", + " \"date\": \"2025-09-26\",\n", + " \"temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 16.1,\n", + " \"max\": 24.1,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"apparent_temperature\": {\n", + " \"current\": 0,\n", + " \"feels_like\": null,\n", + " \"min\": 16.4,\n", + " \"max\": 23.8,\n", + " \"unit\": \"°C\"\n", + " },\n", + " \"weather\": {\n", + " \"description\": \"Partly cloudy\",\n", + " \"code\": 2\n", + " },\n", + " \"precipitation\": {\n", + " \"total\": 0.0,\n", + " \"rain\": 0.0,\n", + " \"showers\": 0.0,\n", + " \"snow\": 0.0,\n", + " \"hours\": 0.0,\n", + " \"unit\": \"mm\"\n", + " },\n", + " \"wind\": {\n", + " \"speed\": 11.8,\n", + " \"direction\": 256,\n", + " \"unit\": \"km/h\",\n", + " \"max_gusts\": 27.4\n", + " }\n", " }\n", " ]\n", - "}\u001b[0m\u001b[32;1m\u001b[1;3mI can book the Eiffel Tower for you — I just need a few details first:\n", + "}\u001b[0m\u001b[32;1m\u001b[1;3mThanks for the details—that helps a lot. I can help, but I’m running into a gap in my current Rome park listings. I don’t have specific wheelchair-friendly outdoor parks in Rome to name right now that fit “low-cost, outdoors, family-friendly, not a full day.” I can still help with weather-focused planning and general outdoor options, and I can broaden the search if you’d like.\n", "\n", - "1) Visit date (YYYY-MM-DD) \n", - "2) Number of visitors (1–50) \n", - "3) Primary visitor name (for the booking) \n", - "4) Email for confirmation \n", - "5) Phone number (optional) \n", - "6) Any special requests or ticket preference (e.g., summit access vs 2nd floor only, stairs vs elevator, preferred time window like morning/afternoon/evening)\n", + "Weather outlook for this weekend (Rome)\n", + "- Current: about 23.4°C, feels ~23.7°C, humidity around 90%, partly cloudy.\n", + "- Weekend forecast (based on the latest data): highs around 23–24°C with mostly cloudy to partly cloudy skies. There is some variability, so a light rain shower is possible on at least one day and conditions could shift, so it’s good to have a plan B.\n", "\n", - "Tell me those and I’ll proceed to check availability and make the booking. Would you also like me to include current weather for Paris on your visit date?\u001b[0m\n", + "Practical, outdoorsy, low-cost ideas that are generally kid-friendly and don’t take the whole day\n", + "- Short strolls in iconic outdoor spaces: you can enjoy the atmosphere around famous outdoor spots and fountains, which are free and quick to explore (great for kids and wheelchair users if you pick accessible routes).\n", + "- Waterfront or riverside areas: a scenic, flat, stroller/wheelchair-friendly walk along the Tiber embankments can be relaxing for a couple of hours.\n", + "- City squares and open spaces: large plazas and piazzas with seating areas offer easy, low-effort time outdoors without committing to a full-day excursion.\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "I can book the Eiffel Tower for you — I just need a few details first:\n", + "What I can do next (your choice)\n", + "- Broaden the search to include other outdoor, family-friendly options near Rome (parks, gardens, plazas, easy nature walks) and filter for accessibility and low cost. \n", + "- Look for nearby towns or coastal spots within a short drive from Rome that are known for easy, short outdoor visits (beaches or promenades) that are wheelchair-friendly.\n", + "- Create a 2-hour outdoor-friendly itinerary with a couple of flexible stops and built-in breaks, tailored to wheelchair access and a modest budget.\n", "\n", - "1) Visit date (YYYY-MM-DD) \n", - "2) Number of visitors (1–50) \n", - "3) Primary visitor name (for the booking) \n", - "4) Email for confirmation \n", - "5) Phone number (optional) \n", - "6) Any special requests or ticket preference (e.g., summit access vs 2nd floor only, stairs vs elevator, preferred time window like morning/afternoon/evening)\n", + "A couple of quick questions to tailor recommendations\n", + "- Are you okay with nearby towns along the Lazio coast or would you prefer strictly within Rome?\n", + "- Do you want to focus on parks specifically, or are plazas, gardens, and riverfronts acceptable?\n", + "- Any must-have accessibility features (level paths, seating/rest areas, accessible restrooms)?\n", "\n", - "Tell me those and I’ll proceed to check availability and make the booking. Would you also like me to include current weather for Paris on your visit date?\n", - "🧳 User: 1992-04-2992\n", - "🤖 Assistant:\n", + "If you’d like, I can run a broader search now for wheelchair-friendly, low-cost outdoor options in Rome and nearby areas and bring back a short list with distance, estimated time, and any notes on accessibility.\u001b[0m\n", "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "Thanks for the details—that helps a lot. I can help, but I’m running into a gap in my current Rome park listings. I don’t have specific wheelchair-friendly outdoor parks in Rome to name right now that fit “low-cost, outdoors, family-friendly, not a full day.” I can still help with weather-focused planning and general outdoor options, and I can broaden the search if you’d like.\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3mThe date you sent looks invalid: \"1992-04-2992\" — it has extra characters and/or is in the past. I can’t book a past date. Could you please confirm the booking details using this form?\n", + "Weather outlook for this weekend (Rome)\n", + "- Current: about 23.4°C, feels ~23.7°C, humidity around 90%, partly cloudy.\n", + "- Weekend forecast (based on the latest data): highs around 23–24°C with mostly cloudy to partly cloudy skies. There is some variability, so a light rain shower is possible on at least one day and conditions could shift, so it’s good to have a plan B.\n", "\n", - "1) Visit date (YYYY-MM-DD) — must be a future date \n", - "2) Number of visitors (1–50) \n", - "3) Primary visitor name \n", - "4) Email for confirmation \n", - "5) Phone (optional) \n", - "6) Ticket preference / special requests (e.g., summit access vs 2nd floor only; stairs vs elevator; preferred time of day)\n", + "Practical, outdoorsy, low-cost ideas that are generally kid-friendly and don’t take the whole day\n", + "- Short strolls in iconic outdoor spaces: you can enjoy the atmosphere around famous outdoor spots and fountains, which are free and quick to explore (great for kids and wheelchair users if you pick accessible routes).\n", + "- Waterfront or riverside areas: a scenic, flat, stroller/wheelchair-friendly walk along the Tiber embankments can be relaxing for a couple of hours.\n", + "- City squares and open spaces: large plazas and piazzas with seating areas offer easy, low-effort time outdoors without committing to a full-day excursion.\n", "\n", - "If you want, type everything in one line (for example):\n", - "2025-10-15, 2, Alex Martin, alex@example.com, +33-6-12-34-56-78, summit ticket, evening\n", + "What I can do next (your choice)\n", + "- Broaden the search to include other outdoor, family-friendly options near Rome (parks, gardens, plazas, easy nature walks) and filter for accessibility and low cost. \n", + "- Look for nearby towns or coastal spots within a short drive from Rome that are known for easy, short outdoor visits (beaches or promenades) that are wheelchair-friendly.\n", + "- Create a 2-hour outdoor-friendly itinerary with a couple of flexible stops and built-in breaks, tailored to wheelchair access and a modest budget.\n", "\n", - "Tell me the corrected details and I’ll check availability and proceed. Would you also like the weather forecast for your visit date?\u001b[0m\n", + "A couple of quick questions to tailor recommendations\n", + "- Are you okay with nearby towns along the Lazio coast or would you prefer strictly within Rome?\n", + "- Do you want to focus on parks specifically, or are plazas, gardens, and riverfronts acceptable?\n", + "- Any must-have accessibility features (level paths, seating/rest areas, accessible restrooms)?\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "The date you sent looks invalid: \"1992-04-2992\" — it has extra characters and/or is in the past. I can’t book a past date. Could you please confirm the booking details using this form?\n", + "If you’d like, I can run a broader search now for wheelchair-friendly, low-cost outdoor options in Rome and nearby areas and bring back a short list with distance, estimated time, and any notes on accessibility.\n", + "\u001b[32;1m\u001b[1;3mThanks for the details—that helps a lot. I can help, but I’m running into a gap in my current Rome park listings. I don’t have specific wheelchair-friendly outdoor parks in Rome to name right now that fit “low-cost, outdoors, family-friendly, not a full day.” I can still help with weather-focused planning and general outdoor options, and I can broaden the search if you’d like.\n", "\n", - "1) Visit date (YYYY-MM-DD) — must be a future date \n", - "2) Number of visitors (1–50) \n", - "3) Primary visitor name \n", - "4) Email for confirmation \n", - "5) Phone (optional) \n", - "6) Ticket preference / special requests (e.g., summit access vs 2nd floor only; stairs vs elevator; preferred time of day)\n", + "Weather outlook for this weekend (Rome)\n", + "- Current: about 23.4°C, feels ~23.7°C, humidity around 90%, partly cloudy.\n", + "- Weekend forecast (based on the latest data): highs around 23–24°C with mostly cloudy to partly cloudy skies. There is some variability, so a light rain shower is possible on at least one day and conditions could shift, so it’s good to have a plan B.\n", "\n", - "If you want, type everything in one line (for example):\n", - "2025-10-15, 2, Alex Martin, alex@example.com, +33-6-12-34-56-78, summit ticket, evening\n", + "Practical, outdoorsy, low-cost ideas that are generally kid-friendly and don’t take the whole day\n", + "- Short strolls in iconic outdoor spaces: you can enjoy the atmosphere around famous outdoor spots and fountains, which are free and quick to explore (great for kids and wheelchair users if you pick accessible routes).\n", + "- Waterfront or riverside areas: a scenic, flat, stroller/wheelchair-friendly walk along the Tiber embankments can be relaxing for a couple of hours.\n", + "- City squares and open spaces: large plazas and piazzas with seating areas offer easy, low-effort time outdoors without committing to a full-day excursion.\n", "\n", - "Tell me the corrected details and I’ll check availability and proceed. Would you also like the weather forecast for your visit date?\n", - "🧳 User: escape\n", - "🤖 Assistant:\n", + "What I can do next (your choice)\n", + "- Broaden the search to include other outdoor, family-friendly options near Rome (parks, gardens, plazas, easy nature walks) and filter for accessibility and low cost. \n", + "- Look for nearby towns or coastal spots within a short drive from Rome that are known for easy, short outdoor visits (beaches or promenades) that are wheelchair-friendly.\n", + "- Create a 2-hour outdoor-friendly itinerary with a couple of flexible stops and built-in breaks, tailored to wheelchair access and a modest budget.\n", "\n", + "A couple of quick questions to tailor recommendations\n", + "- Are you okay with nearby towns along the Lazio coast or would you prefer strictly within Rome?\n", + "- Do you want to focus on parks specifically, or are plazas, gardens, and riverfronts acceptable?\n", + "- Any must-have accessibility features (level paths, seating/rest areas, accessible restrooms)?\n", "\n", - "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", - "\u001b[32;1m\u001b[1;3mDo you mean one of the following?\n", + "If you’d like, I can run a broader search now for wheelchair-friendly, low-cost outdoor options in Rome and nearby areas and bring back a short list with distance, estimated time, and any notes on accessibility.\u001b[0m\n", "\n", - "1) Cancel/stop the Eiffel Tower booking process (I’ll drop it and we won’t book). \n", - "2) “Escape rooms” in Paris (I can find and book an escape-room experience). \n", - "3) A short getaway/day‑trip from Paris (ideas like Versailles, Giverny, Fontainebleau). \n", - "4) Something else — please tell me what you mean.\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "Thanks for the details—that helps a lot. I can help, but I’m running into a gap in my current Rome park listings. I don’t have specific wheelchair-friendly outdoor parks in Rome to name right now that fit “low-cost, outdoors, family-friendly, not a full day.” I can still help with weather-focused planning and general outdoor options, and I can broaden the search if you’d like.\n", "\n", - "Reply with the option number (or explain) and I’ll proceed.\u001b[0m\n", + "Weather outlook for this weekend (Rome)\n", + "- Current: about 23.4°C, feels ~23.7°C, humidity around 90%, partly cloudy.\n", + "- Weekend forecast (based on the latest data): highs around 23–24°C with mostly cloudy to partly cloudy skies. There is some variability, so a light rain shower is possible on at least one day and conditions could shift, so it’s good to have a plan B.\n", "\n", - "\u001b[1m> Finished chain.\u001b[0m\n", - "Do you mean one of the following?\n", + "Practical, outdoorsy, low-cost ideas that are generally kid-friendly and don’t take the whole day\n", + "- Short strolls in iconic outdoor spaces: you can enjoy the atmosphere around famous outdoor spots and fountains, which are free and quick to explore (great for kids and wheelchair users if you pick accessible routes).\n", + "- Waterfront or riverside areas: a scenic, flat, stroller/wheelchair-friendly walk along the Tiber embankments can be relaxing for a couple of hours.\n", + "- City squares and open spaces: large plazas and piazzas with seating areas offer easy, low-effort time outdoors without committing to a full-day excursion.\n", "\n", - "1) Cancel/stop the Eiffel Tower booking process (I’ll drop it and we won’t book). \n", - "2) “Escape rooms” in Paris (I can find and book an escape-room experience). \n", - "3) A short getaway/day‑trip from Paris (ideas like Versailles, Giverny, Fontainebleau). \n", - "4) Something else — please tell me what you mean.\n", + "What I can do next (your choice)\n", + "- Broaden the search to include other outdoor, family-friendly options near Rome (parks, gardens, plazas, easy nature walks) and filter for accessibility and low cost. \n", + "- Look for nearby towns or coastal spots within a short drive from Rome that are known for easy, short outdoor visits (beaches or promenades) that are wheelchair-friendly.\n", + "- Create a 2-hour outdoor-friendly itinerary with a couple of flexible stops and built-in breaks, tailored to wheelchair access and a modest budget.\n", "\n", - "Reply with the option number (or explain) and I’ll proceed.\n", - "Goodbye!\n" + "A couple of quick questions to tailor recommendations\n", + "- Are you okay with nearby towns along the Lazio coast or would you prefer strictly within Rome?\n", + "- Do you want to focus on parks specifically, or are plazas, gardens, and riverfronts acceptable?\n", + "- Any must-have accessibility features (level paths, seating/rest areas, accessible restrooms)?\n", + "\n", + "If you’d like, I can run a broader search now for wheelchair-friendly, low-cost outdoor options in Rome and nearby areas and bring back a short list with distance, estimated time, and any notes on accessibility.\n" ] } ], @@ -890,18 +1278,10 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "id": "968731b7", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "🧹 Cleanup function ready!\n" - ] - } - ], + "outputs": [], "source": [ "# Cleanup function for HTTP MCP client\n", "async def cleanup_mcp():\n", @@ -935,7 +1315,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.3" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/src/mcp/attractions-mcp/attractions_service.py b/src/mcp/attractions-mcp/attractions_service.py index 57bcdab..f4acf9a 100644 --- a/src/mcp/attractions-mcp/attractions_service.py +++ b/src/mcp/attractions-mcp/attractions_service.py @@ -304,3 +304,80 @@ def format_search_results(search_data: Dict[str, Any]) -> str: result += f"... and {len(attractions) - 10} more attractions\n" return result + + +def get_recommended_packing_list_data(attraction_id: int) -> Dict[str, Any]: + """Get recommended packing list for a specific attraction + + Args: + attraction_id: Unique ID of the attraction + + Returns: + Dictionary with attraction info and recommended packing list + """ + try: + data = get_attraction_by_id(attraction_id) + if not data: + return {"error": f"Attraction with ID {attraction_id} not found"} + + attraction = parse_attraction_data(data) + packing_list = data.get("recommended_packing_list", []) + + # Enhanced packing recommendations based on attraction attributes + enhanced_packing = [] + + # Add base packing list + enhanced_packing.extend(packing_list) + + # Add context-based recommendations + recommendations = [] + + if data.get("outdoors", True): + recommendations.append("Weather protection (umbrella or raincoat)") + recommendations.append("Sun protection (sunscreen, hat)") + + if data.get("category") == "museums": + recommendations.append("Quiet shoes for museum floors") + recommendations.append("Notebook for taking notes") + + if data.get("category") == "beaches": + if "Swimsuit" not in packing_list: + recommendations.append("Swimsuit") + if "Towel" not in packing_list: + recommendations.append("Towel") + + if data.get("category") == "mountains": + recommendations.append("Warm layers") + recommendations.append("Sturdy footwear") + + if data.get("photogenic", True): + if not any("camera" in item.lower() for item in packing_list): + recommendations.append("Camera or smartphone") + + if data.get("time_needed", "").lower().find("full day") >= 0: + recommendations.append("Snacks and water") + recommendations.append("Portable charger") + + # Remove duplicates and combine lists + all_items = list(dict.fromkeys(enhanced_packing + recommendations)) + + location_str = f"{attraction.location.city}, {attraction.location.country}" + + return { + "attraction_id": attraction_id, + "attraction_name": attraction.name, + "location": location_str, + "category": get_category_display_name(attraction.category), + "recommended_packing_list": all_items, + "original_packing_list": packing_list, + "additional_recommendations": recommendations, + "weather_considerations": { + "outdoors": data.get("outdoors", True), + "season_dependent": data.get("category") in ["beaches", "mountains", "natural"] + }, + "visit_duration": data.get("time_needed", "Unknown"), + "special_notes": f"Pack according to {data.get('mood', 'general')} mood and {data.get('budget', 'medium')} budget expectations" + } + + except Exception as e: + return {"error": f"Failed to get packing list: {str(e)}"} diff --git a/src/mcp/attractions-mcp/config.py b/src/mcp/attractions-mcp/config.py index 7500597..2f7ca6d 100644 --- a/src/mcp/attractions-mcp/config.py +++ b/src/mcp/attractions-mcp/config.py @@ -59,180 +59,1081 @@ "name": "Eiffel Tower", "description": "Iconic iron lattice tower located on the Champ de Mars in Paris, France", "category": "architecture", - "location": {"city": "Paris", "country": "France", "region": "Île-de-France"}, + "location": {"city": "Paris", "country": "France", "region": "Île-de-France", "continent": "Europe"}, "rating": 4.6, "image_url": "https://example.com/eiffel-tower.jpg", "website": "https://www.toureiffel.paris", "opening_hours": "9:30 AM - 11:45 PM", - "entry_fee": "€29.40 - €73.30" + "entry_fee": "€29.40 - €73.30", + "disability_accessible": True, + "outdoors": False, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Romantic", + "recommended_packing_list": ["Camera", "Water bottle", "Sunscreen"] }, { "id": 2, "name": "Taj Mahal", "description": "Ivory-white marble mausoleum on the right bank of the river Yamuna in Agra", "category": "historical", - "location": {"city": "Agra", "country": "India", "region": "Uttar Pradesh"}, + "location": {"city": "Agra", "country": "India", "region": "Uttar Pradesh", "continent": "Asia"}, "rating": 4.8, "image_url": "https://example.com/taj-mahal.jpg", "website": "https://www.tajmahal.gov.in", "opening_hours": "6:00 AM - 7:00 PM", - "entry_fee": "₹1100 (foreigners), ₹50 (Indians)" + "entry_fee": "₹1100 (foreigners), ₹50 (Indians)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-100", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Low", + "time_needed": "2-4 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Hat", "Camera", "Comfortable shoes"] }, { "id": 3, "name": "Colosseum", "description": "Ancient Roman amphitheater in the center of Rome, Italy", "category": "historical", - "location": {"city": "Rome", "country": "Italy", "region": "Lazio"}, + "location": {"city": "Rome", "country": "Italy", "region": "Lazio", "continent": "Europe"}, "rating": 4.5, "image_url": "https://example.com/colosseum.jpg", "website": "https://www.coopculture.it", "opening_hours": "8:30 AM - 7:15 PM", - "entry_fee": "€16 - €22" + "entry_fee": "€16 - €22", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "6+", + "age_restriction": None, + "budget": "Medium", + "time_needed": "1-2 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Water bottle", "Hat", "Guidebook"] }, { "id": 4, "name": "Machu Picchu", "description": "Ancient Incan city set high in the Andes Mountains of Peru", "category": "historical", - "location": {"city": "Cusco", "country": "Peru", "region": "Cusco"}, + "location": {"city": "Cusco", "country": "Peru", "region": "Cusco", "continent": "South America"}, "rating": 4.9, "image_url": "https://example.com/machu-picchu.jpg", "website": "https://www.machupicchu.gob.pe", "opening_hours": "6:00 AM - 5:30 PM", - "entry_fee": "$47 - $62" + "entry_fee": "$47 - $62", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "10+", + "age_restriction": None, + "budget": "High", + "time_needed": "4-6 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Hiking boots", "Raincoat", "Snacks", "Camera"] }, { "id": 5, "name": "Louvre Museum", "description": "World's largest art museum and historic monument in Paris", "category": "museums", - "location": {"city": "Paris", "country": "France", "region": "Île-de-France"}, + "location": {"city": "Paris", "country": "France", "region": "Île-de-France", "continent": "Europe"}, "rating": 4.4, "image_url": "https://example.com/louvre.jpg", "website": "https://www.louvre.fr", "opening_hours": "9:00 AM - 6:00 PM", - "entry_fee": "€17" + "entry_fee": "€17", + "disability_accessible": True, + "outdoors": False, + "group_size": "1-40", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "3-4 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Camera", "Guidebook"] }, { "id": 6, "name": "Great Wall of China", "description": "Ancient fortification built across northern China", "category": "historical", - "location": {"city": "Beijing", "country": "China", "region": "Beijing"}, + "location": {"city": "Beijing", "country": "China", "region": "Beijing", "continent": "Asia"}, "rating": 4.7, "image_url": "https://example.com/great-wall.jpg", "website": "https://www.mutianyu.com", "opening_hours": "7:30 AM - 5:30 PM", - "entry_fee": "¥45 - ¥65" + "entry_fee": "¥45 - ¥65", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-50", + "age_recommendation": "8+", + "age_restriction": None, + "budget": "Medium", + "time_needed": "3-5 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Hiking shoes", "Hat", "Water bottle"] }, { "id": 7, "name": "Santorini", "description": "Beautiful Greek island with white buildings and blue domes", "category": "natural", - "location": {"city": "Santorini", "country": "Greece", "region": "Cyclades"}, + "location": {"city": "Santorini", "country": "Greece", "region": "Cyclades", "continent": "Europe"}, "rating": 4.6, "image_url": "https://example.com/santorini.jpg", "website": "https://www.santorini.com", "opening_hours": "24/7", - "entry_fee": "Free" + "entry_fee": "Free", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "Full day", + "pet_friendly": True, + "wifi_available": True, + "photogenic": True, + "mood": "Relaxing", + "recommended_packing_list": ["Sunscreen", "Swimsuit", "Camera"] }, { "id": 8, "name": "Angkor Wat", "description": "Largest religious monument in the world, originally a Hindu temple", "category": "religious", - "location": {"city": "Siem Reap", "country": "Cambodia", "region": "Siem Reap"}, + "location": {"city": "Siem Reap", "country": "Cambodia", "region": "Siem Reap", "continent": "Asia"}, "rating": 4.8, "image_url": "https://example.com/angkor-wat.jpg", "website": "https://www.angkorwat.com", "opening_hours": "5:00 AM - 6:00 PM", - "entry_fee": "$37 (1 day), $62 (3 days)" + "entry_fee": "$37 (1 day), $62 (3 days)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Spiritual", + "recommended_packing_list": ["Hat", "Water bottle", "Camera"] }, { "id": 9, "name": "Central Park", "description": "Large public park in Manhattan, New York City", "category": "parks", - "location": {"city": "New York", "country": "USA", "region": "New York"}, + "location": {"city": "New York", "country": "USA", "region": "New York", "continent": "North America"}, "rating": 4.3, "image_url": "https://example.com/central-park.jpg", "website": "https://www.centralparknyc.org", "opening_hours": "6:00 AM - 1:00 AM", - "entry_fee": "Free" + "entry_fee": "Free", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-100+", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Free", + "time_needed": "1-4 hours", + "pet_friendly": True, + "wifi_available": True, + "photogenic": True, + "mood": "Relaxing", + "recommended_packing_list": ["Picnic blanket", "Snacks", "Camera"] }, { "id": 10, "name": "Petra", "description": "Archaeological city famous for rock-cut architecture and water conduit system", "category": "historical", - "location": {"city": "Ma'an", "country": "Jordan", "region": "Ma'an"}, + "location": {"city": "Ma'an", "country": "Jordan", "region": "Ma'an", "continent": "Asia"}, "rating": 4.7, "image_url": "https://example.com/petra.jpg", "website": "https://www.visitpetra.jo", "opening_hours": "6:00 AM - 6:00 PM", - "entry_fee": "70 JOD (1 day), 55 JOD (2 days)" + "entry_fee": "70 JOD (1 day), 55 JOD (2 days)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "8+", + "age_restriction": None, + "budget": "Medium", + "time_needed": "3-5 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Hat", "Water bottle", "Camera"] }, { "id": 11, "name": "Statue of Liberty", "description": "Neoclassical sculpture on Liberty Island in New York Harbor", "category": "modern", - "location": {"city": "New York", "country": "USA", "region": "New York"}, + "location": {"city": "New York", "country": "USA", "region": "New York", "continent": "North America"}, "rating": 4.4, "image_url": "https://example.com/statue-liberty.jpg", "website": "https://www.nps.gov/stli", "opening_hours": "8:30 AM - 4:00 PM", - "entry_fee": "$23.80 - $24.30" + "entry_fee": "$23.80 - $24.30", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Patriotic", + "recommended_packing_list": ["Camera", "Water bottle"] }, { "id": 12, "name": "Sagrada Familia", "description": "Unfinished Roman Catholic minor basilica in Barcelona, Spain", "category": "religious", - "location": {"city": "Barcelona", "country": "Spain", "region": "Catalonia"}, + "location": {"city": "Barcelona", "country": "Spain", "region": "Catalonia", "continent": "Europe"}, "rating": 4.6, "image_url": "https://example.com/sagrada-familia.jpg", "website": "https://sagradafamilia.org", "opening_hours": "9:00 AM - 8:00 PM", - "entry_fee": "€26 - €40" + "entry_fee": "€26 - €40", + "disability_accessible": True, + "outdoors": False, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Spiritual", + "recommended_packing_list": ["Camera", "Guidebook"] }, { "id": 13, "name": "Kinkaku-ji", "description": "Golden Pavilion, a Zen temple in Kyoto, Japan", "category": "religious", - "location": {"city": "Kyoto", "country": "Japan", "region": "Kansai"}, + "location": {"city": "Kyoto", "country": "Japan", "region": "Kansai", "continent": "Asia"}, "rating": 4.5, "image_url": "https://example.com/kinkaku-ji.jpg", "website": "https://www.shokoku-ji.jp", "opening_hours": "9:00 AM - 5:00 PM", - "entry_fee": "¥500" + "entry_fee": "¥500", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Low", + "time_needed": "1-2 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Spiritual", + "recommended_packing_list": ["Camera", "Guidebook"] }, { "id": 14, "name": "Sydney Opera House", "description": "Multi-venue performing arts center in Sydney, Australia", "category": "modern", - "location": {"city": "Sydney", "country": "Australia", "region": "New South Wales"}, + "location": {"city": "Sydney", "country": "Australia", "region": "New South Wales", "continent": "Oceania"}, "rating": 4.4, "image_url": "https://example.com/sydney-opera.jpg", "website": "https://www.sydneyoperahouse.com", "opening_hours": "9:00 AM - 8:30 PM", - "entry_fee": "$43 - $175" + "entry_fee": "$43 - $175", + "disability_accessible": True, + "outdoors": False, + "group_size": "1-100+", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "High", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Camera", "Guidebook"] }, { "id": 15, "name": "Christ the Redeemer", "description": "Art Deco statue of Jesus Christ in Rio de Janeiro, Brazil", "category": "religious", - "location": {"city": "Rio de Janeiro", "country": "Brazil", "region": "Rio de Janeiro"}, + "location": {"city": "Rio de Janeiro", "country": "Brazil", "region": "Rio de Janeiro", "continent": "South America"}, "rating": 4.5, "image_url": "https://example.com/christ-redeemer.jpg", "website": "https://www.cristoredentor.com.br", "opening_hours": "8:00 AM - 7:00 PM", - "entry_fee": "R$65 - R$98" + "entry_fee": "R$65 - R$98", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-40", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Spiritual", + "recommended_packing_list": ["Camera", "Water bottle"] + }, + # Additional mock attractions with new fields + { + "id": 16, + "name": "Berlin Zoo", + "description": "One of the world's most famous zoos, home to a wide variety of animals.", + "category": "parks", + "location": {"city": "Berlin", "country": "Germany", "region": "Berlin", "continent": "Europe"}, + "rating": 4.2, + "image_url": "https://example.com/berlin-zoo.jpg", + "website": "https://www.zoo-berlin.de", + "opening_hours": "9:00 AM - 6:30 PM", + "entry_fee": "€16 - €21", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-4 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Family", + "recommended_packing_list": ["Camera", "Snacks", "Water bottle"] + }, + { + "id": 17, + "name": "Mount Fuji Hike", + "description": "Climb Japan's iconic mountain for breathtaking views.", + "category": "mountains", + "location": {"city": "Fujinomiya", "country": "Japan", "region": "Shizuoka", "continent": "Asia"}, + "rating": 4.9, + "image_url": "https://example.com/mount-fuji.jpg", + "website": "https://www.japan-guide.com/e/e6901.html", + "opening_hours": "July - September", + "entry_fee": "¥1000", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-10", + "age_recommendation": "12+", + "age_restriction": "12+ only", + "budget": "Low", + "time_needed": "Full day", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Hiking boots", "Jacket", "Snacks", "Water bottle"] + }, + { + "id": 18, + "name": "Venice Gondola Ride", + "description": "Experience the romantic canals of Venice on a traditional gondola.", + "category": "entertainment", + "location": {"city": "Venice", "country": "Italy", "region": "Veneto", "continent": "Europe"}, + "rating": 4.7, + "image_url": "https://example.com/venice-gondola.jpg", + "website": "https://www.venicegondola.com", + "opening_hours": "9:00 AM - 8:00 PM", + "entry_fee": "€80 - €120", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-6", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "High", + "time_needed": "30-60 min", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Romantic", + "recommended_packing_list": ["Camera", "Sunglasses"] + }, + { + "id": 19, + "name": "London Science Museum", + "description": "Interactive science exhibits for all ages.", + "category": "museums", + "location": {"city": "London", "country": "UK", "region": "England", "continent": "Europe"}, + "rating": 4.5, + "image_url": "https://example.com/london-science-museum.jpg", + "website": "https://www.sciencemuseum.org.uk", + "opening_hours": "10:00 AM - 6:00 PM", + "entry_fee": "Free", + "disability_accessible": True, + "outdoors": False, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Free", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Educational", + "recommended_packing_list": ["Notebook", "Camera"] + }, + { + "id": 20, + "name": "Bondi Beach", + "description": "Famous beach in Sydney, popular for surfing and sunbathing.", + "category": "beaches", + "location": {"city": "Sydney", "country": "Australia", "region": "New South Wales", "continent": "Oceania"}, + "rating": 4.8, + "image_url": "https://example.com/bondi-beach.jpg", + "website": "https://www.bondivillage.com", + "opening_hours": "24/7", + "entry_fee": "Free", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-100+", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Free", + "time_needed": "2-6 hours", + "pet_friendly": True, + "wifi_available": True, + "photogenic": True, + "mood": "Relaxing", + "recommended_packing_list": ["Swimsuit", "Towel", "Sunscreen", "Surfboard"] + }, + { + "id": 21, + "name": "Angkor Thom", + "description": "Last capital city of the Khmer Empire, featuring the iconic Bayon Temple with stone faces.", + "category": "historical", + "location": {"city": "Siem Reap", "country": "Cambodia", "region": "Siem Reap", "continent": "Asia"}, + "rating": 4.7, + "image_url": "https://example.com/angkor-thom.jpg", + "website": "https://www.angkor.org", + "opening_hours": "5:00 AM - 6:00 PM", + "entry_fee": "$37 (1 day), $62 (3 days)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-25", + "age_recommendation": "8+", + "age_restriction": None, + "budget": "Medium", + "time_needed": "3-4 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Spiritual", + "recommended_packing_list": ["Hat", "Water bottle", "Camera", "Comfortable shoes"] + }, + { + "id": 22, + "name": "Forbidden City", + "description": "Imperial palace complex from the Ming dynasty, now a UNESCO World Heritage Site.", + "category": "historical", + "location": {"city": "Beijing", "country": "China", "region": "Beijing", "continent": "Asia"}, + "rating": 4.6, + "image_url": "https://example.com/forbidden-city.jpg", + "website": "https://www.dpm.org.cn", + "opening_hours": "8:30 AM - 5:00 PM", + "entry_fee": "¥60 - ¥80", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-40", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Low", + "time_needed": "3-5 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Camera", "Guidebook", "Water bottle", "Comfortable shoes"] + }, + { + "id": 23, + "name": "Borobudur Temple", + "description": "9th-century Mahayana Buddhist temple and UNESCO World Heritage Site with stunning sunrise views.", + "category": "religious", + "location": {"city": "Yogyakarta", "country": "Indonesia", "region": "Central Java", "continent": "Asia"}, + "rating": 4.8, + "image_url": "https://example.com/borobudur.jpg", + "website": "https://borobudurpark.com", + "opening_hours": "6:00 AM - 5:00 PM", + "entry_fee": "475,000 IDR (foreigners), 50,000 IDR (locals)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "8+", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Spiritual", + "recommended_packing_list": ["Hat", "Sunscreen", "Camera", "Water bottle"] + }, + { + "id": 24, + "name": "Phi Phi Islands", + "description": "Tropical paradise with crystal clear waters, perfect for snorkeling and diving.", + "category": "beaches", + "location": {"city": "Krabi", "country": "Thailand", "region": "Krabi", "continent": "Asia"}, + "rating": 4.5, + "image_url": "https://example.com/phi-phi.jpg", + "website": "https://www.phiphi.com", + "opening_hours": "24/7", + "entry_fee": "Free (boat tour costs extra)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "Full day", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Relaxing", + "recommended_packing_list": ["Swimsuit", "Snorkel gear", "Sunscreen", "Water shoes", "Camera"] + }, + { + "id": 25, + "name": "Marina Bay Sands SkyPark", + "description": "Iconic infinity pool and observation deck offering panoramic views of Singapore skyline.", + "category": "modern", + "location": {"city": "Singapore", "country": "Singapore", "region": "Central Singapore", "continent": "Asia"}, + "rating": 4.4, + "image_url": "https://example.com/marina-bay-sands.jpg", + "website": "https://www.marinabaysands.com", + "opening_hours": "9:30 AM - 10:00 PM", + "entry_fee": "S$26 (observation deck), pool for hotel guests only", + "disability_accessible": True, + "outdoors": False, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "High", + "time_needed": "1-2 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Luxurious", + "recommended_packing_list": ["Camera", "Sunglasses", "Light jacket"] + }, + { + "id": 26, + "name": "Pyramids of Giza", + "description": "Ancient Egyptian pyramids and the Great Sphinx, one of the Seven Wonders of the Ancient World.", + "category": "historical", + "location": {"city": "Giza", "country": "Egypt", "region": "Cairo Governorate", "continent": "Africa"}, + "rating": 4.8, + "image_url": "https://example.com/pyramids-giza.jpg", + "website": "https://www.egypt.travel", + "opening_hours": "8:00 AM - 5:00 PM", + "entry_fee": "400 EGP (foreigners), 80 EGP (locals)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "3-4 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Hat", "Sunscreen", "Water bottle", "Camera", "Comfortable shoes"] + }, + { + "id": 27, + "name": "Serengeti National Park", + "description": "World-famous wildlife reserve known for the Great Migration and diverse African wildlife.", + "category": "natural", + "location": {"city": "Arusha", "country": "Tanzania", "region": "Mara Region", "continent": "Africa"}, + "rating": 4.9, + "image_url": "https://example.com/serengeti.jpg", + "website": "https://www.tanzaniaparks.go.tz", + "opening_hours": "6:00 AM - 6:00 PM", + "entry_fee": "$71 per day (foreigners), 10,000 TSH (locals)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-15", + "age_recommendation": "8+", + "age_restriction": None, + "budget": "High", + "time_needed": "Full day", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Binoculars", "Camera with zoom lens", "Hat", "Safari clothes", "Sunscreen"] + }, + { + "id": 28, + "name": "Table Mountain", + "description": "Flat-topped mountain offering spectacular views of Cape Town and surrounding areas.", + "category": "mountains", + "location": {"city": "Cape Town", "country": "South Africa", "region": "Western Cape", "continent": "Africa"}, + "rating": 4.7, + "image_url": "https://example.com/table-mountain.jpg", + "website": "https://www.tablemountain.net", + "opening_hours": "8:00 AM - 6:00 PM", + "entry_fee": "R395 (cable car), Free (hiking)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-4 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Camera", "Jacket", "Comfortable shoes", "Water bottle"] + }, + { + "id": 29, + "name": "Victoria Falls", + "description": "One of the world's largest waterfalls, known locally as 'Mosi-oa-Tunya' (The Smoke That Thunders).", + "category": "natural", + "location": {"city": "Livingstone", "country": "Zambia", "region": "Southern Province", "continent": "Africa"}, + "rating": 4.8, + "image_url": "https://example.com/victoria-falls.jpg", + "website": "https://www.victoriafalls-guide.net", + "opening_hours": "6:00 AM - 6:00 PM", + "entry_fee": "$30 (foreigners), ZMW 40 (locals)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-40", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Raincoat", "Camera", "Water bottle", "Non-slip shoes"] + }, + { + "id": 30, + "name": "Stone Town", + "description": "Historic quarter of Zanzibar City with unique blend of Arab, Persian, Indian, and European architecture.", + "category": "cultural", + "location": {"city": "Zanzibar", "country": "Tanzania", "region": "Zanzibar", "continent": "Africa"}, + "rating": 4.5, + "image_url": "https://example.com/stone-town.jpg", + "website": "https://www.zanzibartourism.net", + "opening_hours": "24/7", + "entry_fee": "Free", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-25", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Low", + "time_needed": "3-5 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Camera", "Comfortable walking shoes", "Hat", "Water bottle"] + }, + { + "id": 31, + "name": "Grand Canyon", + "description": "Massive canyon carved by the Colorado River, offering breathtaking views and hiking trails.", + "category": "natural", + "location": {"city": "Grand Canyon", "country": "USA", "region": "Arizona", "continent": "North America"}, + "rating": 4.8, + "image_url": "https://example.com/grand-canyon.jpg", + "website": "https://www.nps.gov/grca", + "opening_hours": "24/7 (visitor centers vary)", + "entry_fee": "$35 per vehicle (7 days)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-8 hours", + "pet_friendly": True, + "wifi_available": True, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Camera", "Water bottle", "Hat", "Hiking boots", "Sunscreen"] + }, + { + "id": 32, + "name": "Chichen Itza", + "description": "Pre-Columbian Maya city with the famous El Castillo pyramid, UNESCO World Heritage Site.", + "category": "historical", + "location": {"city": "Yucatan", "country": "Mexico", "region": "Yucatan", "continent": "North America"}, + "rating": 4.6, + "image_url": "https://example.com/chichen-itza.jpg", + "website": "https://www.chichenitza.com", + "opening_hours": "8:00 AM - 5:00 PM", + "entry_fee": "$533 MXN (foreigners), $230 MXN (locals)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-40", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Hat", "Sunscreen", "Camera", "Water bottle", "Comfortable shoes"] + }, + { + "id": 33, + "name": "Iguazu Falls", + "description": "Spectacular waterfalls on the border of Argentina and Brazil, one of the New Seven Wonders of Nature.", + "category": "natural", + "location": {"city": "Puerto Iguazu", "country": "Argentina", "region": "Misiones", "continent": "South America"}, + "rating": 4.9, + "image_url": "https://example.com/iguazu-falls.jpg", + "website": "https://www.iguazuargentina.com", + "opening_hours": "8:00 AM - 6:00 PM", + "entry_fee": "$30 USD (foreigners), $800 ARS (locals)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "4-6 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Raincoat", "Camera", "Water bottle", "Non-slip shoes", "Sunscreen"] + }, + { + "id": 34, + "name": "Banff National Park", + "description": "Canada's oldest national park featuring stunning mountain scenery, lakes, and wildlife.", + "category": "natural", + "location": {"city": "Banff", "country": "Canada", "region": "Alberta", "continent": "North America"}, + "rating": 4.7, + "image_url": "https://example.com/banff.jpg", + "website": "https://www.pc.gc.ca/en/pn-np/ab/banff", + "opening_hours": "24/7", + "entry_fee": "$10.50 CAD per day", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "Full day", + "pet_friendly": True, + "wifi_available": False, + "photogenic": True, + "mood": "Relaxing", + "recommended_packing_list": ["Warm jacket", "Hiking boots", "Camera", "Water bottle", "Bear spray"] + }, + { + "id": 35, + "name": "Easter Island Moai", + "description": "Mysterious ancient stone statues scattered across remote Polynesian island.", + "category": "historical", + "location": {"city": "Hanga Roa", "country": "Chile", "region": "Valparaiso", "continent": "South America"}, + "rating": 4.5, + "image_url": "https://example.com/easter-island.jpg", + "website": "https://www.rapanui.co.cl", + "opening_hours": "9:00 AM - 6:00 PM", + "entry_fee": "$80 USD (foreigners), $20 USD (locals)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "10+", + "age_restriction": None, + "budget": "High", + "time_needed": "3-5 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Mysterious", + "recommended_packing_list": ["Hat", "Sunscreen", "Camera", "Water bottle", "Comfortable walking shoes"] + }, + { + "id": 36, + "name": "Neuschwanstein Castle", + "description": "Fairy-tale castle in the Bavarian Alps that inspired Disney's Sleeping Beauty Castle.", + "category": "architecture", + "location": {"city": "Fussen", "country": "Germany", "region": "Bavaria", "continent": "Europe"}, + "rating": 4.5, + "image_url": "https://example.com/neuschwanstein.jpg", + "website": "https://www.neuschwanstein.de", + "opening_hours": "9:00 AM - 6:00 PM", + "entry_fee": "€15 (adults), €13 (students)", + "disability_accessible": False, + "outdoors": False, + "group_size": "1-35", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-3 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Romantic", + "recommended_packing_list": ["Camera", "Comfortable walking shoes", "Light jacket"] + }, + { + "id": 37, + "name": "Northern Lights in Iceland", + "description": "Natural light display in polar regions, best viewed from Iceland's dark winter skies.", + "category": "natural", + "location": {"city": "Reykjavik", "country": "Iceland", "region": "Capital Region", "continent": "Europe"}, + "rating": 4.9, + "image_url": "https://example.com/northern-lights.jpg", + "website": "https://www.northernlightsiceland.com", + "opening_hours": "September - March (weather dependent)", + "entry_fee": "Free (tour costs extra)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-50", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-4 hours", + "pet_friendly": True, + "wifi_available": False, + "photogenic": True, + "mood": "Magical", + "recommended_packing_list": ["Warm winter clothes", "Camera with tripod", "Hot drinks", "Blanket"] + }, + { + "id": 38, + "name": "Swiss Alps Jungfraujoch", + "description": "Top of Europe with glaciers, snow activities, and panoramic mountain views.", + "category": "mountains", + "location": {"city": "Interlaken", "country": "Switzerland", "region": "Bern", "continent": "Europe"}, + "rating": 4.6, + "image_url": "https://example.com/jungfraujoch.jpg", + "website": "https://www.jungfraujoch.ch", + "opening_hours": "8:00 AM - 5:00 PM", + "entry_fee": "CHF 75 - CHF 150", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-40", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "High", + "time_needed": "6-8 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Warm jacket", "Sunglasses", "Camera", "Sunscreen", "Gloves"] + }, + { + "id": 39, + "name": "Prague Castle", + "description": "Ancient castle complex and UNESCO World Heritage Site overlooking the city of Prague.", + "category": "historical", + "location": {"city": "Prague", "country": "Czech Republic", "region": "Prague", "continent": "Europe"}, + "rating": 4.4, + "image_url": "https://example.com/prague-castle.jpg", + "website": "https://www.hrad.cz", + "opening_hours": "9:00 AM - 5:00 PM", + "entry_fee": "350 CZK - 570 CZK", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "3-4 hours", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Cultural", + "recommended_packing_list": ["Camera", "Comfortable shoes", "Guidebook", "Light jacket"] + }, + { + "id": 40, + "name": "Amalfi Coast", + "description": "Stunning coastal drive with picturesque towns, dramatic cliffs, and Mediterranean views.", + "category": "natural", + "location": {"city": "Amalfi", "country": "Italy", "region": "Campania", "continent": "Europe"}, + "rating": 4.7, + "image_url": "https://example.com/amalfi-coast.jpg", + "website": "https://www.amalficoast.it", + "opening_hours": "24/7", + "entry_fee": "Free", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-25", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "Full day", + "pet_friendly": True, + "wifi_available": True, + "photogenic": True, + "mood": "Romantic", + "recommended_packing_list": ["Camera", "Sunscreen", "Comfortable shoes", "Swimsuit", "Hat"] + }, + { + "id": 41, + "name": "Masai Mara", + "description": "World-renowned game reserve famous for the annual Great Migration and abundant wildlife.", + "category": "natural", + "location": {"city": "Narok", "country": "Kenya", "region": "Narok County", "continent": "Africa"}, + "rating": 4.9, + "image_url": "https://example.com/masai-mara.jpg", + "website": "https://www.maasaimara.com", + "opening_hours": "6:00 AM - 7:00 PM", + "entry_fee": "$80 per day (foreigners), KES 500 (residents)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-20", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "High", + "time_needed": "2-3 days", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Binoculars", "Camera with telephoto lens", "Safari hat", "Neutral colored clothing", "Sunscreen", "Insect repellent"] + }, + { + "id": 42, + "name": "Nairobi National Park", + "description": "Unique wildlife park with Nairobi skyline backdrop, home to lions, rhinos, and giraffes.", + "category": "natural", + "location": {"city": "Nairobi", "country": "Kenya", "region": "Nairobi County", "continent": "Africa"}, + "rating": 4.5, + "image_url": "https://example.com/nairobi-national-park.jpg", + "website": "https://www.kws.go.ke", + "opening_hours": "6:00 AM - 6:00 PM", + "entry_fee": "$43 per day (foreigners), KES 300 (residents)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-30", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "4-6 hours", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Educational", + "recommended_packing_list": ["Camera", "Binoculars", "Hat", "Sunscreen", "Water bottle", "Light jacket"] + }, + { + "id": 43, + "name": "Kruger National Park", + "description": "One of Africa's largest game reserves with incredible biodiversity and Big Five animals.", + "category": "natural", + "location": {"city": "Skukuza", "country": "South Africa", "region": "Mpumalanga", "continent": "Africa"}, + "rating": 4.8, + "image_url": "https://example.com/kruger-national-park.jpg", + "website": "https://www.sanparks.org", + "opening_hours": "5:30 AM - 6:30 PM", + "entry_fee": "R440 per day (foreigners), R110 (residents)", + "disability_accessible": True, + "outdoors": True, + "group_size": "1-25", + "age_recommendation": "All ages", + "age_restriction": None, + "budget": "Medium", + "time_needed": "2-5 days", + "pet_friendly": False, + "wifi_available": True, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Safari clothing", "Binoculars", "Camera", "Malaria prevention", "Hat", "Sunscreen"] + }, + { + "id": 44, + "name": "Ngorongoro Crater", + "description": "UNESCO World Heritage Site featuring a massive volcanic crater with dense wildlife population.", + "category": "natural", + "location": {"city": "Arusha", "country": "Tanzania", "region": "Arusha Region", "continent": "Africa"}, + "rating": 4.9, + "image_url": "https://example.com/ngorongoro-crater.jpg", + "website": "https://www.ngorongorocrater.org", + "opening_hours": "6:00 AM - 6:00 PM", + "entry_fee": "$71 per day + $295 crater fee (foreigners)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-15", + "age_recommendation": "8+", + "age_restriction": None, + "budget": "High", + "time_needed": "Full day", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Warm jacket", "Camera with zoom lens", "Binoculars", "Hat", "Sunscreen", "Dust mask"] + }, + { + "id": 45, + "name": "Okavango Delta", + "description": "Pristine wetland wilderness in the heart of the Kalahari Desert with unique water-based safaris.", + "category": "natural", + "location": {"city": "Maun", "country": "Botswana", "region": "North West District", "continent": "Africa"}, + "rating": 4.8, + "image_url": "https://example.com/okavango-delta.jpg", + "website": "https://www.botswanatourism.co.bw", + "opening_hours": "6:00 AM - 6:00 PM", + "entry_fee": "$30 per day (park fees vary by concession)", + "disability_accessible": False, + "outdoors": True, + "group_size": "1-12", + "age_recommendation": "10+", + "age_restriction": None, + "budget": "High", + "time_needed": "3-5 days", + "pet_friendly": False, + "wifi_available": False, + "photogenic": True, + "mood": "Adventurous", + "recommended_packing_list": ["Waterproof bag", "Binoculars", "Camera", "Quick-dry clothing", "Hat", "Insect repellent", "Sunscreen"] } ] diff --git a/src/mcp/attractions-mcp/main.py b/src/mcp/attractions-mcp/main.py index 5bd10d3..65c9755 100644 --- a/src/mcp/attractions-mcp/main.py +++ b/src/mcp/attractions-mcp/main.py @@ -23,7 +23,7 @@ format_search_results ) -mcp = FastMCP("Attractions", port=8008) +mcp = FastMCP("Attractions") # tools @mcp.tool() @@ -42,19 +42,95 @@ def get_attraction_details(attraction_id: int) -> Dict[str, Any]: def search_attractions( location: Optional[str] = None, category: Optional[str] = None, - limit: int = 20 + limit: int = 20, + disability_accessible: Optional[bool] = None, + outdoors: Optional[bool] = None, + group_size: Optional[str] = None, + age_recommendation: Optional[str] = None, + age_restriction: Optional[str] = None, + budget: Optional[str] = None, + time_needed: Optional[str] = None, + pet_friendly: Optional[bool] = None, + wifi_available: Optional[bool] = None, + photogenic: Optional[bool] = None, + mood: Optional[str] = None, + recommended_packing_list: Optional[str] = None ) -> Dict[str, Any]: - """Search for tourist attractions with optional filters + """Search for tourist attractions with advanced filters Args: location: Location to search in (e.g., "Paris", "India", "Italy") - category: Category filter - "historical", "natural", "cultural", "religious", "modern", "museums", "parks", "beaches", "mountains", "architecture", "entertainment", "adventure" + category: Category filter - "historical", "natural", etc. limit: Maximum number of results (1-100, default: 20) - + disability_accessible: Only show accessible attractions + outdoors: Only show outdoor/indoor attractions + group_size: Filter by group size (e.g., "1-10") + age_recommendation: Filter by recommended age (e.g., "All ages", "12+") + age_restriction: Filter by age restriction (e.g., "18+ only") + budget: Filter by budget (e.g., "Low", "Medium", "High") + time_needed: Filter by time needed (e.g., "2-3 hours") + pet_friendly: Only show pet-friendly attractions + wifi_available: Only show attractions with wifi + photogenic: Only show photogenic attractions + mood: Filter by mood (e.g., "Romantic", "Adventurous") + recommended_packing_list: Filter by required packing item (e.g., "Camera") Returns: AttractionsList object as dictionary with matching attractions """ - return search_attractions_data(location, category, limit) + # Use the existing search_attractions_data, then filter results in-memory for advanced fields + base_results = search_attractions_data(location, category, limit) + if "attractions" not in base_results: + return base_results + filtered = [] + for attr in base_results["attractions"]: + if disability_accessible is not None and attr.get("disability_accessible") != disability_accessible: + continue + if outdoors is not None and attr.get("outdoors") != outdoors: + continue + if group_size and attr.get("group_size") != group_size: + continue + if age_recommendation and attr.get("age_recommendation") != age_recommendation: + continue + if age_restriction and attr.get("age_restriction") != age_restriction: + continue + if budget and attr.get("budget") != budget: + continue + if time_needed and attr.get("time_needed") != time_needed: + continue + if pet_friendly is not None and attr.get("pet_friendly") != pet_friendly: + continue + if wifi_available is not None and attr.get("wifi_available") != wifi_available: + continue + if photogenic is not None and attr.get("photogenic") != photogenic: + continue + if mood and attr.get("mood") != mood: + continue + if recommended_packing_list: + packing = attr.get("recommended_packing_list") or [] + if recommended_packing_list not in packing: + continue + filtered.append(attr) + base_results["attractions"] = filtered + base_results["total_count"] = len(filtered) + return base_results + +# Add a generic filter tool for advanced search +@mcp.tool() +def filter_attractions( + field: str, + value: Any, + location: Optional[str] = None, + category: Optional[str] = None, + limit: int = 100 +) -> Dict[str, Any]: + """Filter attractions by any field and value (advanced search)""" + base_results = search_attractions_data(location, category, limit) + if "attractions" not in base_results: + return base_results + filtered = [a for a in base_results["attractions"] if a.get(field) == value] + base_results["attractions"] = filtered + base_results["total_count"] = len(filtered) + return base_results @mcp.tool() def get_random_attraction(region: str = "famous") -> Dict[str, Any]: @@ -189,4 +265,4 @@ def attraction_comparison_prompt(attraction_ids: str) -> str: Help decide which attractions to prioritize based on time, budget, and interests.""" if __name__ == "__main__": - mcp.run(transport="streamable-http") \ No newline at end of file + mcp.run() \ No newline at end of file diff --git a/src/mcp/attractions-mcp/models.py b/src/mcp/attractions-mcp/models.py index 920cc27..ef8e06c 100644 --- a/src/mcp/attractions-mcp/models.py +++ b/src/mcp/attractions-mcp/models.py @@ -32,6 +32,19 @@ class Attraction: website: Optional[str] = None opening_hours: Optional[str] = None entry_fee: Optional[str] = None + # Restrictions and additional info + disability_accessible: Optional[bool] = None + outdoors: Optional[bool] = None + group_size: Optional[str] = None # e.g. "1-10", "Large groups" + age_recommendation: Optional[str] = None # e.g. "All ages", "12+" + age_restriction: Optional[str] = None # e.g. "18+ only" + budget: Optional[str] = None # e.g. "Low", "Medium", "High" + time_needed: Optional[str] = None # e.g. "2-3 hours" + pet_friendly: Optional[bool] = None + wifi_available: Optional[bool] = None + photogenic: Optional[bool] = None + mood: Optional[str] = None # e.g. "Romantic", "Adventurous" + recommended_packing_list: Optional[List[str]] = None @dataclass @@ -41,6 +54,20 @@ class AttractionDetails: facilities: Optional[List[str]] = None best_time_to_visit: Optional[str] = None duration: Optional[str] = None + # Extended restrictions (for details endpoint) + disability_accessible: Optional[bool] = None + outdoors: Optional[bool] = None + group_size: Optional[str] = None + age_recommendation: Optional[str] = None + age_restriction: Optional[str] = None + budget: Optional[str] = None + time_needed: Optional[str] = None + open_hours: Optional[str] = None + pet_friendly: Optional[bool] = None + wifi_available: Optional[bool] = None + photogenic: Optional[bool] = None + mood: Optional[str] = None + recommended_packing_list: Optional[List[str]] = None @dataclass diff --git a/src/mcp/weather-mcp/main.py b/src/mcp/weather-mcp/main.py index 06b686d..ff49a3d 100644 --- a/src/mcp/weather-mcp/main.py +++ b/src/mcp/weather-mcp/main.py @@ -19,7 +19,7 @@ ) -mcp = FastMCP("Weather", port=8009) +mcp = FastMCP("Weather") # tools @mcp.tool() @@ -59,4 +59,4 @@ def weather_summary_prompt(location: str, include_forecast: bool = False) -> str return get_weather_summary_prompt(location, include_forecast) if __name__ == "__main__": - mcp.run("streamable-http") \ No newline at end of file + mcp.run() \ No newline at end of file diff --git a/weather.sh b/weather.sh new file mode 100644 index 0000000..11fdb4d --- /dev/null +++ b/weather.sh @@ -0,0 +1,2 @@ +cd ./src/mcp/weather-mcp +uv run main.py \ No newline at end of file