{
 "openapi": "3.1.0",
 "info": {
  "title": "RoundTrips",
  "version": "1.1.0",
  "description": "Plan and coordinate a group trip from your AI assistant: start a trip, invite friends with one link, add and vote on ideas, build the days, RSVP and split costs. Also plans a few free hours or a few days in a city, in walking order.",
  "contact": {
   "email": "partnership@thehowtonetwork.com",
   "url": "https://roundtrips.org/connect/"
  }
 },
 "servers": [
  {
   "url": "https://mcp.roundtrips.org"
  }
 ],
 "paths": {
  "/api/free_time_plan": {
   "get": {
    "operationId": "free_time_plan",
    "summary": "Plan a few free hours",
    "description": "Answers: \"We're in this city with a few free hours, what do we do?\" Returns 2–3 options, each a short route of stops in walking order with the walking minutes between them and a total that fits the hours. Inputs: city (required), hours (1–12, required), group (couple | friends | kids), vibe (e.g. \"music\", \"food, views\", \"relaxed\"), start_location (address, landmark or \"lat,lng\"; when given, the route starts there), when (morning | afternoon | evening | night or a time; evenings favour music and bars, daytime favours museums and parks). Stops from a published RoundTrips trip carry Zoe's own note; other stops come from open data (Wikidata, Wikipedia, OpenStreetMap) and are labelled that way. If coverage is thin the response says so. Example: {\"city\":\"Nashville\",\"hours\":4,\"group\":\"friends\"}",
    "parameters": [
     {
      "name": "city",
      "in": "query",
      "required": true,
      "description": "City name, e.g. \"Nashville\" or \"Lisbon, Portugal\"",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "hours",
      "in": "query",
      "required": true,
      "description": "Free time in hours",
      "schema": {
       "type": "number"
      }
     },
     {
      "name": "group",
      "in": "query",
      "required": false,
      "description": "Who is going",
      "schema": {
       "type": "string",
       "enum": [
        "couple",
        "friends",
        "kids"
       ]
      }
     },
     {
      "name": "vibe",
      "in": "query",
      "required": false,
      "description": "One or more of: culture, history, food, nightlife, music, outdoors, views, relaxed, iconic, family, shopping",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "start_location",
      "in": "query",
      "required": false,
      "description": "Where you are now: address, landmark or \"lat,lng\"",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "when",
      "in": "query",
      "required": false,
      "description": "morning | afternoon | evening | night, or a clock time like \"18:30\". Default: daytime.",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Result with a `summary` string plus structured fields",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "summary": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error with `message` and `suggestion`",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/day_itinerary": {
   "get": {
    "operationId": "day_itinerary",
    "summary": "Day-by-day city plan",
    "description": "Answers: \"We have N days in this city, what should each day look like?\" Where RoundTrips has a published trip for the city (Lisbon, Tokyo, Amalfi Coast), returns Zoe's real day-by-day plan and the link to fork it. Elsewhere, groups the city's best-documented places into one walkable area per day; for cities it doesn't cover it may return an AI suggestion, clearly labelled, with every stop checked on OpenStreetMap. Every answer includes save_plan, ready to become a RoundTrips trip. Inputs: city (required), days (1–14, required), group (couple | friends | kids), pace (relaxed | moderate | packed), vibe (interests). Example: {\"city\":\"Lisbon\",\"days\":3}",
    "parameters": [
     {
      "name": "city",
      "in": "query",
      "required": true,
      "description": "",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "days",
      "in": "query",
      "required": true,
      "description": "",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "group",
      "in": "query",
      "required": false,
      "description": "",
      "schema": {
       "type": "string",
       "enum": [
        "couple",
        "friends",
        "kids"
       ]
      }
     },
     {
      "name": "pace",
      "in": "query",
      "required": false,
      "description": "",
      "schema": {
       "type": "string",
       "enum": [
        "relaxed",
        "moderate",
        "packed"
       ]
      }
     },
     {
      "name": "vibe",
      "in": "query",
      "required": false,
      "description": "Interests, one or more of: culture, history, food, nightlife, music, outdoors, views, relaxed, iconic, family, shopping",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Result with a `summary` string plus structured fields",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "summary": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error with `message` and `suggestion`",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/whats_near": {
   "get": {
    "operationId": "whats_near",
    "summary": "What's near here",
    "description": "Answers: \"What's worth walking to from right here?\" Returns up to 10 places within the walking time, nearest first, each with walking minutes, a one-line reason or description, opening hours when known, and a directions link. Inputs: location (required: address, landmark or \"lat,lng\"), minutes_walk (1–45, default 15), type (e.g. food, coffee, bars, music, museum, park, views, kids, market, history). Example: {\"location\":\"Ryman Auditorium, Nashville\",\"minutes_walk\":10,\"type\":\"music\"}",
    "parameters": [
     {
      "name": "location",
      "in": "query",
      "required": true,
      "description": "",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "minutes_walk",
      "in": "query",
      "required": false,
      "description": "",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "description": "",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Result with a `summary` string plus structured fields",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "summary": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error with `message` and `suggestion`",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/api/list_cities": {
   "get": {
    "operationId": "list_cities",
    "summary": "Which cities are covered",
    "description": "Answers: \"Which cities can RoundTrips plan for, and how deep is the coverage?\" Returns every covered city with its coverage level (curated = a published RoundTrips trip exists; open-map = OpenStreetMap places only; thin = few places) and place counts. No inputs. Example: {}",
    "parameters": [],
    "responses": {
     "200": {
      "description": "Result with a `summary` string plus structured fields",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "summary": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Error with `message` and `suggestion`",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "message": {
      "type": "string"
     },
     "suggestion": {
      "type": "string"
     },
     "retry_after": {
      "type": "integer"
     }
    }
   }
  }
 }
}