Skip to main content
Glama
local-falcon

Local Falcon MCP Server

by local-falcon

listLocalFalconCampaignReports

Retrieve a list of Location Reports from your Local Falcon account, filter by date range, Google Place ID, or limit results for precise local SEO campaign analysis.

Instructions

Retrieves a list of all Location Reports within your Local Falcon account.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
endDateNoUpper limit date of a Campaign run or schedule you wish to retrieve. Expects date formatted as MM/DD/YYYY.
limitNoThe number of results you wish to retrieve. Expects 10 to 100.10
nextTokenNoThis parameter is used to get the next 'page' of results. The value used with the parameter is provided from a previous response by this endpoint if more 'pages' of results exist.
placeIdNoFilter only results for specific Google Place ID. Supports multiple Google Place IDs, seperated by commas.
startDateNoA lower limit date of a Campaign run you wish to retrieve. Expects date formatted as MM/DD/YYYY.

Implementation Reference

  • MCP tool handler: validates API key, sets user-specific limit, calls helper function with processed parameters, returns JSON-formatted response.
    async ({ startDate, endDate, placeId, nextToken }, ctx) => {
      const apiKey = getApiKey(ctx);
      if (!apiKey) {
        return { content: [{ type: "text", text: "Missing LOCAL_FALCON_API_KEY in environment variables or request headers" }] };
      }
      const limit = isProUser(ctx) ? HIGH_LIMIT : LOW_LIMIT;
      const resp = await fetchLocalFalconCampaignReports(apiKey, limit, handleNullOrUndefined(startDate), handleNullOrUndefined(endDate), handleNullOrUndefined(placeId), handleNullOrUndefined(nextToken));
      return { content: [{ type: "text", text: JSON.stringify(resp, null, 2) }] };
    }
  • Input schema using Zod for validating parameters: startDate, endDate, placeId, nextToken.
    {
      startDate: z.string().date().nullish().describe("A lower limit date of a Campaign run you wish to retrieve. Expects date formatted as MM/DD/YYYY."),
      endDate: z.string().date().nullish().describe("Upper limit date of a Campaign run or schedule you wish to retrieve. Expects date formatted as MM/DD/YYYY."),
      placeId: z.string().nullish().describe("Filter only results for specific Google Place ID. Supports multiple Google Place IDs, seperated by commas."),
      nextToken: z.string().nullish().describe("This parameter is used to get the next 'page' of results. The value used with the parameter is provided from a previous response by this endpoint if more 'pages' of results exist."),
    },
  • server.ts:147-165 (registration)
    Tool registration call using server.tool() including name, description, schema, and handler.
    server.tool(
      "listLocalFalconCampaignReports",
      "Lists all campaign reports in your account. Campaigns are the primary way to organize and track rankings at scale. Can include: single location + single keyword, multiple locations + single keyword, single location + multiple keywords, or multiple locations + multiple keywords. Most campaigns run on automated schedules (daily, weekly, monthly) making them the preferred method for ongoing tracking, but can also be run manually. Campaign reports consolidate all data in one place - no separate location/keyword reports are generated for campaign scans. Check here to see scheduled scan activity and multi-location/keyword performance data.",
      {
        startDate: z.string().date().nullish().describe("A lower limit date of a Campaign run you wish to retrieve. Expects date formatted as MM/DD/YYYY."),
        endDate: z.string().date().nullish().describe("Upper limit date of a Campaign run or schedule you wish to retrieve. Expects date formatted as MM/DD/YYYY."),
        placeId: z.string().nullish().describe("Filter only results for specific Google Place ID. Supports multiple Google Place IDs, seperated by commas."),
        nextToken: z.string().nullish().describe("This parameter is used to get the next 'page' of results. The value used with the parameter is provided from a previous response by this endpoint if more 'pages' of results exist."),
      },
      async ({ startDate, endDate, placeId, nextToken }, ctx) => {
        const apiKey = getApiKey(ctx);
        if (!apiKey) {
          return { content: [{ type: "text", text: "Missing LOCAL_FALCON_API_KEY in environment variables or request headers" }] };
        }
        const limit = isProUser(ctx) ? HIGH_LIMIT : LOW_LIMIT;
        const resp = await fetchLocalFalconCampaignReports(apiKey, limit, handleNullOrUndefined(startDate), handleNullOrUndefined(endDate), handleNullOrUndefined(placeId), handleNullOrUndefined(nextToken));
        return { content: [{ type: "text", text: JSON.stringify(resp, null, 2) }] };
      }
    );
  • Core API client function: constructs URL with query params, applies rate limiting and retries, performs POST request to /campaigns, validates and cleans response data.
    export async function fetchLocalFalconCampaignReports(apiKey: string, limit: string, startDate?: string, endDate?: string, placeId?: string, nextToken?: string) {
      const url = new URL(`${API_BASE}/campaigns`);
      url.searchParams.set("api_key", apiKey);
      url.searchParams.set("limit", limit);
    
      if (startDate) url.searchParams.set("start_date", startDate);
      if (endDate) url.searchParams.set("end_date", endDate);
      if (placeId) url.searchParams.set("place_id", placeId);
      if (nextToken) url.searchParams.set("next_token", nextToken);
    
      await rateLimiter.waitForAvailableSlot();
    
      return withRetry(async () => {
        const res = await fetchWithTimeout(url.toString(), {
          method: "POST",
          headers: HEADERS,
        });
    
        if (!res.ok) {
          const errorText = await res.text();
          throw new Error(`Local Falcon API error: ${res.status} ${res.statusText} - ${errorText}`);
        }
    
        const data = await safeParseJson(res);
    
        // Validate the response
        if (!data || !data.data || !data.data.reports) {
          throw new Error('Invalid response format from Local Falcon API');
        }
    
        const limitNum = parseInt(limit) || data.data.reports.length;
    
        return {
          ...data.data,
          reports: data.data.reports.slice(0, limitNum).map((report: any) => {
            // Remove unnecessary fields to save bandwidth
            const {
              data_points,
              locations,
              keywords,
              scans,
              frequency,
              last_run,
              status,
              ...cleanReport
            } = report;
            return cleanReport;
          })
        };
      });
    }

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/local-falcon/mcp'

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