get_ai_visibility_trend
Track how LLM brand perception changes over time. Analyze up to 200 data points per query, with optional provider filter for OpenAI, Claude, or Gemini. Ideal for time-series analysis of AI visibility.
Instructions
Get AI Visibility trend data over time — track how LLM brand perception changes. Returns up to 200 data points. Without provider filter: returns pre-computed aggregate summaries across all LLMs. With provider filter (openai, claude, gemini): computes from raw per-provider results. Use this for time-series analysis; use get_ai_visibility_dashboard for the latest snapshot or get_ai_visibility_check_detail for a specific check. Read-only. Returns JSON array. Dates are ISO-8601 format.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID (from list_projects) | |
| dateFrom | No | Start date in ISO-8601 format (e.g., 2026-01-01) | |
| dateTo | No | End date in ISO-8601 format (e.g., 2026-03-15) | |
| provider | No | Filter by LLM provider. Omit for aggregate view across all providers |
Implementation Reference
- src/tools.ts:283-304 (schema)Schema definition for get_ai_visibility_trend tool. Defines input parameters (projectId required, dateFrom/dateTo/provider optional) and API endpoint path.
{ name: "get_ai_visibility_trend", description: "Get AI Visibility trend data over time — track how LLM brand perception changes. Returns up to 200 data points. Without provider filter: returns pre-computed aggregate summaries across all LLMs. With provider filter (openai, claude, gemini): computes from raw per-provider results. Use this for time-series analysis; use get_ai_visibility_dashboard for the latest snapshot or get_ai_visibility_check_detail for a specific check. Read-only. Returns JSON array. Dates are ISO-8601 format.", parameters: z.object({ projectId: objectId("Project ID (from list_projects)"), dateFrom: z .string() .optional() .describe("Start date in ISO-8601 format (e.g., 2026-01-01)"), dateTo: z .string() .optional() .describe("End date in ISO-8601 format (e.g., 2026-03-15)"), provider: z .enum(["openai", "claude", "gemini"]) .optional() .describe("Filter by LLM provider. Omit for aggregate view across all providers"), }), path: (a) => `/v1/projects/${a.projectId}/ai-visibility/trend`, queryParams: ["dateFrom", "dateTo", "provider"], }, - src/index.ts:16-25 (registration)Generic registration loop that registers all tools (including get_ai_visibility_trend) from the tools array via server.tool(). The handler delegates to apiGet with the endpoint path and query params.
for (const tool of tools) { server.tool(tool.name, tool.description, tool.parameters.shape, async (args: Record<string, any>) => { const path = tool.path(args); const query: Record<string, any> = {}; for (const key of tool.queryParams ?? []) { if (args[key] !== undefined) query[key] = args[key]; } return apiGet(path, Object.keys(query).length ? query : undefined); }); } - src/api-client.ts:3-58 (helper)Generic HTTP GET helper used by all tools. Makes fetch request to CompetLab API with CL-API-Key header, returns JSON text response or error.
export async function apiGet( path: string, query?: Record<string, string | number>, ): Promise<{ content: Array<{ type: "text"; text: string }>; isError?: true }> { const apiKey = process.env.COMPETLAB_API_KEY; if (!apiKey) { return { content: [ { type: "text", text: JSON.stringify({ error: "api_key_missing", message: "COMPETLAB_API_KEY environment variable is not set", }), }, ], isError: true, }; } const url = new URL(`${API_BASE}${path}`); if (query) { for (const [k, v] of Object.entries(query)) { if (v !== undefined) url.searchParams.set(k, String(v)); } } try { const res = await fetch(url, { headers: { "CL-API-Key": apiKey }, }); const body = await res.text(); if (!res.ok) { return { content: [{ type: "text", text: body }], isError: true }; } return { content: [{ type: "text", text: body }] }; } catch (err) { return { content: [ { type: "text", text: JSON.stringify({ error: "api_unreachable", message: err instanceof Error ? err.message : "Failed to reach CompetLab API", status: 503, }), }, ], isError: true, }; } } - src/index.ts:16-25 (handler)Handler for get_ai_visibility_trend - implemented by the generic tool loop. Calls the API at /v1/projects/{projectId}/ai-visibility/trend with optional query params (dateFrom, dateTo, provider). Returns JSON array of trend data points.
for (const tool of tools) { server.tool(tool.name, tool.description, tool.parameters.shape, async (args: Record<string, any>) => { const path = tool.path(args); const query: Record<string, any> = {}; for (const key of tool.queryParams ?? []) { if (args[key] !== undefined) query[key] = args[key]; } return apiGet(path, Object.keys(query).length ? query : undefined); }); }