search_hackathons_by_location
Find offline Unstop hackathons near a specific city, address, or campus by setting a search radius and applying filters for payment, team size, and user type.
Instructions
Find offline Unstop hackathons within a radius of a city, address, or campus.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | ||
| radius_km | No | ||
| region | No | ||
| payment | No | ||
| teamsize | No | ||
| usertype | No | ||
| search | No | ||
| sort | No | ||
| direction | No | ||
| page | No | ||
| per_page | No |
Implementation Reference
- src/unstop_mcp/service.py:199-237 (handler)The business logic implementation of the search_hackathons_by_location tool in the service layer.
def search_hackathons_by_location(self, query: SearchByLocationInput) -> LocationSearchResponse: if not self.geocoder: raise UnstopValidationError( "Location search requires geopy. Install optional geocoding support before using this tool." ) coordinates = self.geocode_input(query.location) if coordinates is None: raise UnstopValidationError( f"Could not geocode location '{query.location}'. Try a more specific city or address." ) self.ensure_cache() filtered = self.filter_cached( region=query.region, payment=query.payment, teamsize=query.teamsize, usertype=query.usertype, search=query.search, ) results: list[dict[str, Any]] = [] for hackathon in filtered: if hackathon.get("region") == "online" and query.region != "online": continue lat = hackathon.get("_lat") lng = hackathon.get("_lng") if lat is None or lng is None: continue distance = haversine(coordinates[0], coordinates[1], lat, lng) if distance <= query.radius_km: enriched = dict(hackathon) enriched["distance_km"] = round(distance, 1) results.append(enriched) if query.sort in (None, "distance"): reverse = query.direction == "desc" - src/unstop_mcp/server.py:74-106 (registration)The MCP tool registration and request handler in server.py which calls the service.
name="search_hackathons_by_location", description="Find offline Unstop hackathons within a radius of a city, address, or campus.", ) def search_hackathons_by_location( location: str, radius_km: float = 300.0, region: str | None = None, payment: str | None = None, teamsize: int | None = None, usertype: str | None = None, search: str | None = None, sort: str | None = None, direction: str | None = None, page: int = 1, per_page: int = 18, ) -> dict: try: query = SearchByLocationInput( location=location, radius_km=radius_km, region=region, payment=payment, teamsize=teamsize, usertype=usertype, search=search, sort=sort, direction=direction, page=page, per_page=per_page, ) return service.search_hackathons_by_location(query).model_dump(mode="json") except (UnstopValidationError, UnstopAPIError, ValueError) as exc: raise ValueError(str(exc)) from exc - src/unstop_mcp/schemas.py:36-47 (schema)Input validation schema for the search_hackathons_by_location tool.
class SearchByLocationInput(BaseModel): location: str = Field(min_length=1) radius_km: float = Field(default=300.0, gt=0) region: Literal["online", "offline"] | None = None payment: Literal["paid", "unpaid"] | None = None teamsize: Literal[1, 2, 3] | None = None usertype: Literal["college_students", "fresher", "professionals", "school_students"] | None = None search: str | None = None sort: Literal["prize", "days_left", "distance"] | None = None direction: Literal["asc", "desc"] | None = None page: int = Field(default=1, ge=1) per_page: int = Field(default=DEFAULT_PER_PAGE, ge=1, le=MAX_PER_PAGE)