local_finder
Retrieve Google Local Finder results for any keyword and location. Filter by minimum rating and get business details including name, rating, reviews, address, phone, hours, website, and CID.
Instructions
Get Google Local Finder results for a keyword and location with optional minimum rating filter. Returns names, ratings, reviews, addresses, phone numbers, hours, websites, and CIDs. Costs 1 credit.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keyword | Yes | Search keyword (e.g. "plumber") | |
| location | Yes | City and state (e.g. "Orchard Park, NY") | |
| limit | No | Number of results. Default: 20, max: 100 | |
| min_rating | No | Minimum star rating filter (0-5) |
Implementation Reference
- src/tools/serp.ts:89-96 (handler)The handler function for the local_finder tool. It calls the API at /v1/serp/local-finder with keyword, location, optional limit, and optional min_rating parameters, then formats the result.
withErrorHandling(async ({ keyword, location, limit, min_rating }) => { const result = await callApi( "/v1/serp/local-finder", { keyword, location, ...(limit && { limit }), ...(min_rating !== undefined && { min_rating }) }, getAuth() ); return { content: [{ type: "text" as const, text: formatResult(result.data, result) }] }; }) - src/tools/serp.ts:82-87 (schema)Zod schema for local_finder tool inputs: keyword (string), location (string), optional limit (int 1-100), optional min_rating (number 0-5).
{ keyword: z.string().describe('Search keyword (e.g. "plumber")'), location: z.string().describe('City and state (e.g. "Orchard Park, NY")'), limit: z.number().int().min(1).max(100).optional().describe("Number of results. Default: 20, max: 100"), min_rating: z.number().min(0).max(5).optional().describe("Minimum star rating filter (0-5)"), }, - src/tools/serp.ts:79-97 (registration)The local_finder tool is registered via server.tool() call inside registerSerpTools(), which is invoked from the MCP server setup in src/server.ts.
server.tool( "local_finder", "Get Google Local Finder results for a keyword and location with optional minimum rating filter. Returns names, ratings, reviews, addresses, phone numbers, hours, websites, and CIDs. Costs 1 credit.", { keyword: z.string().describe('Search keyword (e.g. "plumber")'), location: z.string().describe('City and state (e.g. "Orchard Park, NY")'), limit: z.number().int().min(1).max(100).optional().describe("Number of results. Default: 20, max: 100"), min_rating: z.number().min(0).max(5).optional().describe("Minimum star rating filter (0-5)"), }, READ_ONLY, withErrorHandling(async ({ keyword, location, limit, min_rating }) => { const result = await callApi( "/v1/serp/local-finder", { keyword, location, ...(limit && { limit }), ...(min_rating !== undefined && { min_rating }) }, getAuth() ); return { content: [{ type: "text" as const, text: formatResult(result.data, result) }] }; }) ); - src/api-client.ts:143-158 (helper)The withErrorHandling wrapper that wraps the local_finder handler, catching errors and returning them as MCP error content.
export function withErrorHandling<T>( fn: (args: T) => Promise<ToolResult> ): (args: T) => Promise<ToolResult> { return async (args) => { try { return await fn(args); } catch (err) { const message = err instanceof Error ? err.message : String(err); console.error(`[mcp] Tool error: ${message}`); return { content: [{ type: "text" as const, text: `Error: ${message}` }], isError: true, }; } }; } - src/api-client.ts:132-138 (helper)The formatResult helper used by the local_finder handler to format the API response into a text result.
export function formatResult( data: unknown, meta: { credits_used: number; credits_remaining: number; cached: boolean } ): string { const metaLine = `[${meta.credits_used} credit${meta.credits_used !== 1 ? "s" : ""} used | ${meta.credits_remaining} remaining${meta.cached ? " | cached" : ""}]`; return `${metaLine}\n\n${JSON.stringify(data, null, 2)}`; }