[{"name":"find_city","description":"Resolve a city name (in any language script) to TMAIV2's canonical city UUID. Use this FIRST when the user mentions a city by name. Returns the canonical megacity ID if the user named a neighborhood (e.g. 'Brooklyn' resolves to NYC's UUID). Match strategy: exact name then case-insensitive then trigram-fuzzy. If no good match, returns alternatives so you can choose or ask for clarification. Always pass the iso_alpha2 country code when known to disambiguate (e.g. 'Paris, FR' vs 'Paris, US').","input_schema":{"type":"object","properties":{"name":{"type":"string","description":"City name in any script (Japanese, Hindi, Romanized, etc.)"},"iso_alpha2":{"type":"string","description":"Optional 2-letter country code for disambiguation (e.g. 'IN', 'JP', 'FR')"}},"required":["name"]}},{"name":"get_city_context","description":"Get rich grounded context for a city: master_score, top POIs, top hotels, top restaurants (Michelin tier first, then quality), nearest airport with IATA, transit stop count, India enrichments where applicable (ASI heritage, tourism circuit memberships, railway stations). Call this for EACH city in the planned itinerary. Returns more detail than find_city and is the primary source for the itinerary content.","input_schema":{"type":"object","properties":{"city_id":{"type":"string","description":"Canonical city UUID from find_city"}},"required":["city_id"]}},{"name":"get_circuit","description":"Get a named tourism circuit (India OR global): name, description, member cities in order with coordinates, duration days, best season, cross-border flag, scope. India slugs: 'buddhist-circuit', 'golden-triangle', 'kerala-backwaters', 'coastal-karnataka', 'desert-circuit', 'royal-rajasthan', and others. Global slugs: 'silk-road', 'camino-de-santiago', 'buddhist-asia', 'grand-tour-europe', 'southeast-asia-loop', 'safari-trail', 'world-wine-trail', 'culinary-capitals', 'alpine-ski', 'great-dive-sites', 'surf-coast', 'northern-lights', 'andean-trail', 'route-66', 'trans-siberian', 'scandinavia-fjords', 'cradles-of-civilization'. Use this when the user mentions a named circuit OR hints at a multi-city themed route (pilgrimage, heritage, safari, wine, ski, diving, surfing, road trip, northern lights). Returns NULL if the slug doesn't exist.","input_schema":{"type":"object","properties":{"slug":{"type":"string","description":"Circuit slug, kebab-case"}},"required":["slug"]}},{"name":"list_heritage_in_state","description":"List ASI Centrally Protected Monuments in an Indian state (max 100). state_code is ISO-3166-2 (e.g. 'IN-BR' for Bihar, 'IN-UP' for Uttar Pradesh, 'IN-DL' for Delhi). Use only when the user wants heritage-rich planning in a specific Indian state. Each row includes name, category, protected_since year, latitude/longitude, nearest_city_km.","input_schema":{"type":"object","properties":{"state_code":{"type":"string","description":"ISO-3166-2 state code (e.g. 'IN-BR')"}},"required":["state_code"]}},{"name":"list_unesco_in_country","description":"List UNESCO World Heritage Sites in a country (max 100). Optionally filter to in-danger sites only. Use for cross-border UNESCO context (e.g. Lumbini in Nepal for the Buddhist Circuit) or when the user asks specifically about UNESCO heritage. iso_alpha2 is the 2-letter country code.","input_schema":{"type":"object","properties":{"iso_alpha2":{"type":"string","description":"2-letter country code (e.g. 'IN', 'NP')"},"in_danger_only":{"type":"boolean","description":"If true, return only sites listed as in_danger"}},"required":["iso_alpha2"]}},{"name":"find_restaurants_in_city","description":"Get restaurants in a city, sorted Michelin tier first then by quality. Use sparingly: get_city_context already returns top restaurants. Only call this if the user has dietary or cuisine constraints needing a longer list.","input_schema":{"type":"object","properties":{"city_id":{"type":"string"},"limit":{"type":"integer","description":"Max rows (1-50, default 20)"}},"required":["city_id"]}},{"name":"find_hotels_in_city","description":"Get hotels in a city, sorted by quality_class (premium then mid then budget). Same caveat as restaurants: get_city_context already returns the top set; only use when the user wants more options or a specific category.","input_schema":{"type":"object","properties":{"city_id":{"type":"string"},"limit":{"type":"integer","description":"Max rows (1-50, default 20)"}},"required":["city_id"]}},{"name":"get_sentiment","description":"Get sentiment summary for a city: safety, crowdedness, friendliness signals where available. Use ONLY when the user is risk-sensitive (solo female traveler, seniors, families with very young children, post-conflict zones). India coverage is currently sparse; expect NULL/empty for many Indian cities.","input_schema":{"type":"object","properties":{"city_id":{"type":"string"}},"required":["city_id"]}},{"name":"visa_requirement","description":"Look up the visa requirement for a country pair (passport country -> destination country). Backed by 79K country-pair edges (W109). Use when the user is from one country and traveling to another, especially when planning multi-country itineraries (e.g. Buddhist Circuit crossing IN->NP->BT). Returns 'no_pair_in_db' if the pair is not covered; surface that as a coverage gap.","input_schema":{"type":"object","properties":{"from_country":{"type":"string","description":"Passport country (ISO-2 or full name)"},"to_country":{"type":"string","description":"Destination country (ISO-2 or full name)"}},"required":["from_country","to_country"]}},{"name":"find_pairs","description":"Find POIs that pair well with a given POI or are clustered nearby in a given city. Backed by 1.5M PAIRS_WELL_WITH edges from the legacy graph (W110). Use when the user wants 'and what else is nearby' / 'what to combine with X'. Returns rows with distance_km and pairing_type (e.g. meal_activity).","input_schema":{"type":"object","properties":{"poi_name":{"type":"string","description":"Anchor POI name (optional if city given)"},"city":{"type":"string","description":"City name (optional if poi_name given)"},"max_distance_km":{"type":"number","description":"Default 5 km"},"limit":{"type":"integer","description":"Default 8, max 25"}}}},{"name":"when_to_visit","description":"Per-month seasonality scores (0..1) for a place by name+city. Backed by 9.7M BEST_SEASON edges from the legacy graph (W115). Use when the user asks 'what's the best time to visit X?' or is planning around a constraint (monsoon avoidance, festival season, school holidays). Returns by_month array + best_month.","input_schema":{"type":"object","properties":{"target_name":{"type":"string","description":"POI / place / city name"},"city":{"type":"string","description":"City context to disambiguate (optional)"}}}},{"name":"find_prior_itineraries","description":"Retrieve gov-published tourism itineraries promoted from official state-tourism PDFs (license grade A). These are real, ground-truth itineraries published by state DMOs and the national portal — use them as priority anchors for the first draft rather than inventing structure. Filter by state_iso (ISO-3166-2 like 'IN-BR'), normalised theme ('buddhist', 'heritage', 'eco', 'spiritual', 'trekking', 'cycling', 'wellness', 'cultural', 'cruise', 'tea', etc.), duration band, and/or required POI names. Sorted by stop_count DESC (richer itineraries first). Each row has duration_days, theme, the original days[] array (with locations[] and activities[] per day), source_pdf_url, and license.","input_schema":{"type":"object","properties":{"state_iso":{"type":"string","description":"ISO-3166-2 state code, e.g. 'IN-BR' for Bihar."},"theme":{"type":"string","description":"Normalised theme ('buddhist', 'heritage', 'eco', 'spiritual', 'trekking', 'cycling', 'wellness', 'cultural', 'cruise', 'tea', etc.). Matched against theme_normalized."},"min_days":{"type":"integer","description":"Minimum trip length, inclusive."},"max_days":{"type":"integer","description":"Maximum trip length, inclusive."},"must_include_pois":{"type":"array","items":{"type":"string"},"description":"Required stop names (case-insensitive substring); only itineraries containing all of these will be returned."},"limit":{"type":"integer","description":"Max rows to return (1-25, default 10)."}}}},{"name":"find_state_tourism_content","description":"Hybrid full-text search over authoritative state-tourism gov sources. Two corpora are searched in parallel and score-merged: (A) ~19K HTML pages from 37 official Indian state-tourism portals (plus the national incredibleindia.gov.in), and (B) ~17.6K per-page extracts from gov-published tourism PDF brochures (vision-LLM extraction pass) carrying POI descriptions, multi-day itineraries, festival/timing/fee details that rarely make it into the HTML pages. Both corpora are license grade A (gov_in_tourism_published). Use this when the user asks about places, things to do, multi-day plans, festivals, or itinerary ideas for a specific Indian state — strictly higher signal than general LLM knowledge. Multi-day itinerary questions are especially well served by the PDF half. Optionally filter by state_iso (ISO-3166-2 like 'IN-BR'). Each result row carries `source` ('html' | 'pdf_page'), `score`, a snippet excerpt, and provenance: HTML rows have `source_url` + `source_domain`; PDF rows have `pdf_url` + `page_num` (cite as e.g. 'tourist_attractions_of_bihar.pdf p.7'). Prefer this over find_prior_itineraries when the user wants free-form context; use both when the user wants both narrative + a structured day-by-day plan.","input_schema":{"type":"object","properties":{"query":{"type":"string","description":"Free-text query (English). Pass the user's intent verbatim or a paraphrase."},"state_iso":{"type":"string","description":"Optional ISO-3166-2 state filter, e.g. 'IN-BR' for Bihar, 'IN-KL' for Kerala. Omit for cross-state search."},"must_include_pois":{"type":"array","items":{"type":"string"},"description":"Optional - boost rows mentioning these POIs (case-insensitive substring match against body_text)."},"limit":{"type":"integer","description":"Max rows to return (1-20, default 5)."}},"required":["query"]}},{"name":"find_similar_cities","description":"Find K cities most similar to a given city by travel-intent profile (not geographic distance). Backed by graph embeddings trained on POI/connectivity edges. Use when the user asks 'cities like X', 'alternatives to X', or you need comparable destinations. Score 1.0 = identical profile, 0.0 = unrelated. Always call find_city first to get the canonical city_id. Coverage is partial (~6,700 cities); the tool returns 'not_in_index' for uncovered cities so you can fall back to find_city + get_city_context manually.","input_schema":{"type":"object","properties":{"city_id":{"type":"string","description":"Canonical UUID from find_city."},"k":{"type":"integer","description":"How many similar cities to return (1-20).","default":5}},"required":["city_id"]}},{"name":"qa_lookup","description":"Look up Q&A pairs about travel from the StackExchange/CC-BY-SA knowledge base (tmai-qa-bysa-v1, 2.31M docs). PLAN-GATED: only available to enterprise customers with the cc_by_sa_content opt-in tier. Returns each match with a CC BY-SA attribution line in citations.attribution_lines. Default-tier customers see an explicit gate-error and should be told to upgrade or use the other (commercial-OK) tools instead.","input_schema":{"type":"object","properties":{"query":{"type":"string","description":"Free-text travel question."},"k":{"type":"integer","description":"Max rows to return (1-10).","default":5}},"required":["query"]},"plan_gate":"cc_by_sa_content"},{"name":"get_airport_weather","description":"Fetch current observed weather (METAR), forecast (TAF), and static airport metadata for a given airport by ICAO code. Use when the user asks about flight delays, visibility, wind, turbulence forecast, or runway/airport conditions. Returns a single object with `metar` (current obs), `taf` (forecast change periods), and `airport_info` (runways, elevation, ICAO/IATA/FAA mapping). Source: NOAA Aviation Weather Center, public domain (PD-US). 10-minute cache. Examples: 'KJFK' (New York JFK), 'VIDP' (Delhi), 'EGLL' (London Heathrow), 'RJTT' (Tokyo Haneda).","input_schema":{"type":"object","properties":{"icao":{"type":"string","description":"ICAO airport code, exactly 4 uppercase letters (e.g. 'KJFK', 'VIDP', 'EGLL'). IATA codes (3 letters) are NOT accepted by this tool; use the nearest_airport tool first if you only have a city or IATA code."},"mode":{"type":"string","enum":["current","forecast","both"],"description":"'current' = METAR only (latest observation); 'forecast' = TAF only (next ~24h forecast); 'both' = METAR + TAF + airport_info (default). Use 'current' for 'is the weather OK right now?' questions, 'forecast' for next-day planning."}},"required":["icao"]}},{"name":"convert_currency","description":"Convert a monetary amount between currencies using European Central Bank reference rates. Returns converted amount + the exchange rate used + the rate's effective date. Use whenever the user asks 'how much is X EUR in INR?' or when an itinerary step needs costs in the traveler's home currency. Optionally pass `date` (YYYY-MM-DD) for historical rates (rates published back to 1999). Source: European Central Bank — public-domain reference data, no API key. The USD-pegged Gulf/Levant currencies (AED, SAR, QAR, OMR, BHD, JOD) are also supported via their central-bank pegs. Examples: convert_currency(amount=100, from='USD', to='INR') → ~9,564 INR; convert_currency(amount=500, from='AED', to='THB') → Dubai dirhams to Thai baht.","input_schema":{"type":"object","properties":{"amount":{"type":"number","description":"Amount in `from_` currency to convert. Must be > 0."},"from_":{"type":"string","description":"Source currency, ISO-4217 alpha-3 code uppercase (e.g. 'USD', 'EUR', 'INR', 'JPY'). ~30 ECB currencies plus the USD-pegged Gulf/Levant currencies AED, SAR, QAR, OMR, BHD, JOD (bridged through USD)."},"to":{"type":"string","description":"Target currency, ISO-4217 alpha-3 code uppercase."},"date":{"type":"string","description":"Optional historical date (YYYY-MM-DD). Omit for latest rate. Rates available from 1999-01-04."}},"required":["amount","from_","to"]}},{"name":"get_public_holidays","description":"Return the list of public holidays for a country and year, with optional sub-national (state/province) breakdown. Use when the user asks 'is X day a holiday in Germany?' or when planning whether a museum / government office / consulate will be open on a specific date. Coverage: 200+ countries including India with state-level subdivisions (e.g. subdivision='KA' for Karnataka, 'MH' for Maharashtra). Source: the BSD-3-licensed `holidays` Python library (vacanza/holidays), running in-process — no network call. If subdivision is omitted, returns country-level/observed holidays; pass subdivision='<code>' to include state-specific additions (Gudi Padwa in MH, Ugadi in KA, etc.).","input_schema":{"type":"object","properties":{"country_iso2":{"type":"string","description":"Country code, ISO-3166-1 alpha-2 uppercase (e.g. 'IN', 'US', 'JP')."},"year":{"type":"integer","description":"4-digit year (e.g. 2026). Library supports ~1900 to ~2100 depending on country."},"subdivision":{"type":"string","description":"Optional state/province code (e.g. 'KA' for Karnataka in IN, 'CA' for California in US, 'BY' for Bavaria in DE). Omit for country-wide holidays only. Pass an unsupported subdivision and the tool returns a list of valid options in the error."}},"required":["country_iso2","year"]}},{"name":"get_point_forecast","description":"Fetch a weather forecast for ANY point on Earth (any lat/lon, not restricted to airports). Returns the next ~36 hours of hourly forecast: temperature, humidity, wind, precipitation, cloud cover, plus a 1/6/12-hour 'symbol code' summary (clear/cloudy/rain/snow/fog/...). Use whenever the user asks about weather AT a city, attraction, or specific coordinate (not an airport). For airport-specific aviation weather use get_airport_weather instead. Source: Norwegian Meteorological Institute (met.no), CC-BY-4.0. Coverage: global, including remote areas with no airport nearby.","input_schema":{"type":"object","properties":{"lat":{"type":"number","description":"Latitude in decimal degrees (-90 to 90)."},"lon":{"type":"number","description":"Longitude in decimal degrees (-180 to 180)."},"hours":{"type":"integer","description":"How many hours of forecast to return (1-36, default 24). met.no publishes up to 240h but the first 36h are hourly; beyond that is 6-hourly."}},"required":["lat","lon"]}},{"name":"get_local_time","description":"Resolve the IANA timezone name for any point on Earth and return current local clock time (or the local time at a specified UTC instant). Use when the user asks 'what time is it in <city>?', 'when does my flight arrive local time?', or to convert between timezones. Returns the IANA tz name (e.g. 'Asia/Tokyo'), UTC offset in seconds, whether DST is active, and the local clock time. Source: timezonefinder (MIT) + IANA tz database. Fully offline, no network call.","input_schema":{"type":"object","properties":{"lat":{"type":"number","description":"Latitude in decimal degrees (-90 to 90)."},"lon":{"type":"number","description":"Longitude in decimal degrees (-180 to 180)."},"at":{"type":"string","description":"Optional ISO-8601 UTC timestamp to convert (e.g. '2026-12-25T18:00:00Z'). Omit for current time. If you pass a naive datetime without 'Z' or offset, it's treated as UTC."}},"required":["lat","lon"]}},{"name":"get_country_info","description":"Resolve canonical metadata for an ISO-3166-1 alpha-2 country code: name, ISO-3 code, numeric code, official name, official currency (ISO-4217, via Babel/CLDR), official languages (ISO-639), and a human-readable display name in the locale you ask for. Use when the user asks 'what currency does X use?', 'what's the official name of Y?', or needs the ISO-3 code for a country. Fully offline — pycountry (LGPL) ships the ISO data and Babel (BSD-3) ships CLDR data.","input_schema":{"type":"object","properties":{"country_iso2":{"type":"string","description":"Country code, ISO-3166-1 alpha-2 uppercase (e.g. 'IN', 'US', 'JP')."},"locale":{"type":"string","description":"Optional Babel locale code for the localized display name (e.g. 'en' for English, 'fr' for French, 'hi' for Hindi). Defaults to 'en'."}},"required":["country_iso2"]}},{"name":"convert_calendar","description":"Convert a date between civil calendars: Gregorian, Julian, Islamic (tabular Hijri), Hebrew, Indian Civil (Saka), Persian (Jalali), Bahá'í. Use when the user asks 'what Hijri date is X?' or 'when is Y Hebrew date in the Gregorian calendar?'. Note: the Islamic conversion is arithmetic (tabular) and may differ ±1 day from observed Hijri in some countries — the response flags this. Source: convertdate (MIT) — fully offline, no network call.","input_schema":{"type":"object","properties":{"date":{"type":"string","description":"Source date as 'YYYY-MM-DD' in the calendar named by `from_calendar` (e.g. '1447-06-15' for an Islamic source date, '2026-12-25' for Gregorian)."},"from_calendar":{"type":"string","description":"Source calendar (gregorian, julian, islamic, hebrew, indian_civil, persian, bahai).","enum":["gregorian","julian","islamic","hebrew","indian_civil","persian","bahai"]},"to_calendar":{"type":"string","description":"Target calendar (same enum as from_calendar).","enum":["gregorian","julian","islamic","hebrew","indian_civil","persian","bahai"]}},"required":["date","from_calendar","to_calendar"]}}]