search_nearby
Find nearby places like restaurants or coffee shops by entering a location, search radius, and optional filters for current hours or minimum ratings.
Instructions
Search for places near a specific location
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| center | Yes | ||
| keyword | No | Search keyword (e.g., restaurant, coffee) | |
| radius | No | Search radius in meters | |
| openNow | No | Only show places that are currently open | |
| minRating | No | Minimum rating requirement (0-5) |
Implementation Reference
- src/mcp/create-server.ts:35-58 (handler)MCP tool handler function for 'search_nearby' that executes the places search and returns structured content response or error.async (args) => { try { const result = await placesSearcher.searchNearby(args); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) }, ], isError: !result.success, }; } catch (error) { const errorResponse = handleError(error); return { content: [ { type: "text", text: errorResponse.error || "An unknown error occurred", }, ], isError: true, }; } }
- src/schemas/tool-schemas.ts:10-16 (schema)Input schema defining parameters for the search_nearby tool: center location, keyword, radius, openNow, minRating.export const SearchNearbySchema = { center: LocationInputSchema, keyword: z.string().optional().describe("Search keyword (e.g., restaurant, coffee)"), radius: z.number().optional().default(1000).describe("Search radius in meters"), openNow: z.boolean().optional().default(false).describe("Only show places that are currently open"), minRating: z.number().min(0).max(5).optional().describe("Minimum rating requirement (0-5)") };
- src/mcp/create-server.ts:28-59 (registration)Registration of the 'search_nearby' tool in the MCP server, specifying name, metadata, input schema, and handler.server.registerTool( "search_nearby", { title: "Search Nearby Places", description: "Search for places near a specific location", inputSchema: SearchNearbySchema, }, async (args) => { try { const result = await placesSearcher.searchNearby(args); return { content: [ { type: "text", text: JSON.stringify(result, null, 2) }, ], isError: !result.success, }; } catch (error) { const errorResponse = handleError(error); return { content: [ { type: "text", text: errorResponse.error || "An unknown error occurred", }, ], isError: true, }; } } );
- src/services/places.ts:31-92 (helper)Supporting class method in PlacesSearcher that performs the actual nearby places search using Google Maps client, handles geocoding if needed, filters by rating, etc.async searchNearby(params: { center: LocationInput; keyword?: string; radius?: number; openNow?: boolean; minRating?: number; }): Promise<ServiceResponse<PlaceDetails[]>> { try { let location: Location; if (params.center.isCoordinates) { const [lat, lng] = params.center.value.split(",").map(Number); validateCoordinates(lat, lng); location = { lat, lng }; } else { const geocodeResult = await this.geocode(params.center.value); if (!geocodeResult.success || !geocodeResult.data) { throw new Error("Failed to geocode center location"); } location = geocodeResult.data; } const response = await this.client.placesNearby({ params: { key: config.googleMapsApiKey, location: location, radius: params.radius || 1000, keyword: params.keyword, opennow: params.openNow, language: config.defaultLanguage, }, }); let places = response.data.results.map((place) => { if (!place.geometry || !place.place_id || !place.name) { throw new Error("Required place data is missing"); } return { placeId: place.place_id, name: place.name, location: place.geometry.location, rating: place.rating, userRatingsTotal: place.user_ratings_total, types: place.types, vicinity: place.vicinity, }; }); if (params.minRating) { places = places.filter( (place) => (place.rating || 0) >= (params.minRating || 0) ); } return { success: true, data: places, }; } catch (error) { return handleError(error); } }