Skip to main content
Glama
by ricleedo

places-search

Find nearby businesses, landmarks, and points of interest using text search queries with location-based filtering.

Instructions

Search for places using text query

Input Schema

NameRequiredDescriptionDefault
locationNoBias results around this location (e.g., 'lat,lng')
queryYesThe search query
radiusNoSearch radius in meters

Input Schema (JSON Schema)

{ "properties": { "location": { "description": "Bias results around this location (e.g., 'lat,lng')", "type": "string" }, "query": { "description": "The search query", "type": "string" }, "radius": { "description": "Search radius in meters", "type": "number" } }, "required": [ "query" ], "type": "object" }

Implementation Reference

  • The handler function that performs the places search using Google Maps Text Search API, processes up to 5 results, formats them with formatPlacesToMarkdown, and returns markdown content or error.
    export async function placesSearch( params: z.infer<typeof placesSearchSchema>, extra?: any ) { const apiKey = process.env.GOOGLE_MAPS_API_KEY; if (!apiKey) { throw new Error("GOOGLE_MAPS_API_KEY is required"); } try { const requestParams: any = { query: params.query, key: apiKey, }; if (params.location) { requestParams.location = params.location; } if (params.radius) { requestParams.radius = params.radius; } const response = await googleMapsClient.textSearch({ params: requestParams, }); const results = response.data.results; if (results.length === 0) { return { content: [ { type: "text" as const, text: "No places found for the given query.", }, ], }; } const places = results.slice(0, 5).map((place) => ({ name: place.name, formatted_address: place.formatted_address, latitude: place.geometry?.location.lat, longitude: place.geometry?.location.lng, place_id: place.place_id, rating: place.rating, types: place.types, })); return { content: [ { type: "text" as const, text: formatPlacesToMarkdown(places), }, ], }; } catch (error) { return { content: [ { type: "text" as const, text: `Error searching places: ${ error instanceof Error ? error.message : String(error) }`, }, ], }; } }
  • Zod schema defining input parameters for the places-search tool: query (required), optional location bias and radius.
    export const placesSearchSchema = z.object({ query: z.string().describe("The search query"), location: z .string() .optional() .describe("Bias results around this location (e.g., 'lat,lng')"), radius: z.number().optional().describe("Search radius in meters"), });
  • src/index.ts:80-87 (registration)
    Registration of the 'places-search' tool on the MCP server, linking to the handler and schema from maps.ts.
    server.tool( "places-search", "Search for places using text query", placesSearchSchema.shape, async (params) => { return await placesSearch(params); } );
  • Helper function to format the list of places into a structured markdown output used by the handler.
    function formatPlacesToMarkdown(places: any[]): string { if (!places.length) return "No places found."; let markdown = `# Places Search Results (${places.length})\n\n`; places.forEach((place, index) => { markdown += `## ${index + 1}. ${place.name}\n`; markdown += `Address: ${place.formatted_address} \n`; if (place.rating) { markdown += `Rating: ${place.rating}⭐ \n`; } if (place.latitude && place.longitude) { markdown += `Location: ${place.latitude}, ${place.longitude} \n`; markdown += `Maps: [View](https://maps.google.com/?q=${place.latitude},${place.longitude}) \n`; } if (place.place_id) { markdown += `Place ID: \`${place.place_id}\` \n`; } markdown += `\n`; }); return markdown; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ricleedo/Google-Service-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server