Skip to main content
Glama
localseodata

Local SEO Data

Official

local_finder

Read-only

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

TableJSON Schema
NameRequiredDescriptionDefault
keywordYesSearch keyword (e.g. "plumber")
locationYesCity and state (e.g. "Orchard Park, NY")
limitNoNumber of results. Default: 20, max: 100
min_ratingNoMinimum star rating filter (0-5)

Implementation Reference

  • 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) }] };
    })
  • 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)"),
    },
  • 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) }] };
      })
    );
  • 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,
          };
        }
      };
    }
  • 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)}`;
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate read-only and non-destructive behavior; the description adds that it costs 1 credit and lists returned fields. This is sufficient disclosure beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. First sentence states core purpose, second adds details (outputs, cost). Front-loaded and concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, inputs, outputs, and cost. Lacks handling of edge cases (e.g., empty results, pagination) but is adequate for a simple search tool with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers all parameters (100%), but the description adds context by summarizing the rating filter and specifying return fields beyond schema definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool gets Google Local Finder results for a keyword and location, listing specific outputs. It differentiates from siblings like local_pack and organic_serp by targeting Local Finder.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context (keyword/location search with optional rating filter) but no explicit when-not-to-use or alternatives. However, the purpose is specific enough for agents to infer appropriate use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/localseodata/mcp-server'

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