lb_projects_get_stats
Retrieve daily statistics for a project including service execution, SERP rankings, ARA analytics, brand referral, and search query data. Supports up to 365 days of history.
Instructions
Get daily stats for a Listing Bureau project: service execution (SFB, ATC, PGV), SERP rankings, ARA analytics, Brand Referral, and Search Query data. Note: this call may be slow (~1-2s) due to 14+ backend DB queries.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ui_id | Yes | Project unique identifier | |
| days | No | Number of days of history (default 30, max 365) |
Implementation Reference
- src/tools/projects.tools.ts:160-191 (handler)Handler for lb_projects_get_stats tool. Registers an MCP tool that accepts ui_id (required) and days (optional, 1-365). Calls GET /api/v1/projects/{ui_id}/stats with optional days query param, returns ProjectStatsResponse.
server.tool( "lb_projects_get_stats", "Get daily stats for a Listing Bureau project: service execution (SFB, ATC, PGV), SERP rankings, ARA analytics, Brand Referral, and Search Query data. Note: this call may be slow (~1-2s) due to 14+ backend DB queries.", { ui_id: z.string().describe("Project unique identifier"), days: z .number() .int() .min(1) .max(365) .optional() .describe("Number of days of history (default 30, max 365)"), }, { readOnlyHint: true }, async (params) => { try { const query: Record<string, string> = {}; if (params.days !== undefined) query.days = String(params.days); const res = await client.request<ProjectStatsResponse>( "GET", `/api/v1/projects/${encodeURIComponent(params.ui_id)}/stats`, undefined, query, "lb_projects_get_stats", ); return formatResult(res.data); } catch (e) { return formatErrorResult(e); } }, ); - src/index.ts:58-58 (registration)Registration entry point. Called from index.ts to register all project tools including lb_projects_get_stats on the MCP server.
registerProjectsTools(server, client); - src/client/types.ts:175-179 (schema)Type definition for the response of lb_projects_get_stats. Contains days (number), total (number), and stats (array of ProjectStatsDay).
export interface ProjectStatsResponse { days: number; total: number; stats: ProjectStatsDay[]; } - src/client/types.ts:181-199 (schema)Type definition for a single day's stats. Contains date, services (sfb/atc/pgv), serp, ara, br, sqr, and ranks fields.
export interface ProjectStatsDay { date: string; // YYYYMMDD dt: string | null; // ISO datetime with timezone services: { sfb: ServiceDayStats; atc: ServiceDayStats; pgv: ServiceDayStats; }; serp: Record<string, unknown> | null; ara: Record<string, unknown> | null; br: Record<string, unknown> | null; sqr: Record<string, unknown> | null; ranks: unknown[] | null; } export interface ServiceDayStats { assignments: number | null; executed: number; } - src/client/lb-client.ts:188-222 (helper)Generic authenticated request method used by the handler. Handles token refresh, retries on 401, and sends X-LB-Tool header for tracking.
async request<T>( method: string, path: string, body?: Record<string, unknown>, query?: Record<string, string>, toolName?: string, ): Promise<ApiSuccessResponse<T>> { await this.ensureAuth(); const response = await this.doRequest<T>(method, path, body, query, toolName); // Single retry on 401 if (response.status === "error" && response._statusCode === 401) { this.jwt = null; await this.ensureAuth(); const retry = await this.doRequest<T>(method, path, body, query, toolName); if (retry.status === "error") { throw new LBApiError( retry._statusCode ?? 500, retry.error.code, retry.error.message, ); } return retry as ApiSuccessResponse<T>; } if (response.status === "error") { throw new LBApiError( response._statusCode ?? 500, response.error.code, response.error.message, ); } return response as ApiSuccessResponse<T>; }