get_ai_visibility_dashboard
Retrieve AI Visibility scores for all competitors, measuring how ChatGPT, Claude, and Gemini rank your brand. Returns composite score, mention rate, per-provider breakdowns, and competitor rankings.
Instructions
Get the latest AI Visibility scores for all competitors. This is CompetLab's unique dimension — no other CI platform tracks how LLMs rank brands. Returns AI Visibility Score (weighted 0-100 composite), Mention Rate (fraction of queries where brand is mentioned), per-provider breakdowns (OpenAI, Claude, Gemini), competitor rankings, and aggregated AI analysis. Each check queries 3 prompts across 3 LLMs = 9 total AI queries. Use this for the current snapshot; use get_ai_visibility_history for past checks or get_ai_visibility_trend for time-series data. Read-only. Returns JSON object.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID (from list_projects) |
Implementation Reference
- src/index.ts:16-25 (handler)Generic handler that registers all tools. For 'get_ai_visibility_dashboard', it calls tool.path(args) which resolves to /v1/projects/{projectId}/ai-visibility, then calls apiGet to fetch the data from the CompetLab API.
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/tools.ts:252-261 (schema)Schema definition for the get_ai_visibility_dashboard tool. Accepts projectId (24-char hex string). Returns AI Visibility Score (0-100), Mention Rate, per-provider breakdowns (OpenAI, Claude, Gemini), competitor rankings. Maps to GET /v1/projects/{projectId}/ai-visibility.
// ── AI Visibility ───────────────────────────────────────── { name: "get_ai_visibility_dashboard", description: "Get the latest AI Visibility scores for all competitors. This is CompetLab's unique dimension — no other CI platform tracks how LLMs rank brands. Returns AI Visibility Score (weighted 0-100 composite), Mention Rate (fraction of queries where brand is mentioned), per-provider breakdowns (OpenAI, Claude, Gemini), competitor rankings, and aggregated AI analysis. Each check queries 3 prompts across 3 LLMs = 9 total AI queries. Use this for the current snapshot; use get_ai_visibility_history for past checks or get_ai_visibility_trend for time-series data. Read-only. Returns JSON object.", parameters: z.object({ projectId: objectId("Project ID (from list_projects)"), }), path: (a) => `/v1/projects/${a.projectId}/ai-visibility`, }, - src/index.ts:16-25 (registration)Tools are registered dynamically by iterating the tools array. server.tool() registers each with name, description, params schema, and a handler that calls apiGet.
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:1-58 (helper)apiGet helper that makes authenticated GET requests to api.competlab.com using the COMPETLAB_API_KEY env var. Returns JSON text wrapped in MCP content format.
const API_BASE = "https://api.competlab.com"; 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, }; } }