get_tech_trust_history
Get paginated history of Tech & Trust monitoring runs with completion timestamps. Compare changes over time, each run captures a full snapshot of all competitors. Use runId to retrieve run details.
Instructions
Get paginated history of Tech & Trust monitoring runs with completion timestamps. Use this to compare changes over time — each run captures a full snapshot of all competitors. Retrieve specific run data with get_tech_trust_run_detail using the runId from this response. Read-only. Returns paginated JSON array with pagination.hasMore flag.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID (from list_projects) | |
| page | No | Page number (1-indexed, default: 1) | |
| limit | No | Items per page (default: 20, max: 100) |
Implementation Reference
- src/tools.ts:93-113 (registration)The tool 'get_tech_trust_history' is registered as a ToolDef entry in the tools array with its name, description, Zod schema parameters, and API path mapping.
// ── Tech & Trust ────────────────────────────────────────── { name: "get_tech_trust_dashboard", description: "Get the latest Tech & Trust Profile for all competitors. Returns security headers (grade A-F, HSTS, CSP, X-Frame-Options), trust signals (compliance, reviews, social proof, certifications — 24 signals in 4 categories), technology stack (47 tech, 43 growth, 27 engagement tools), robots.txt AI bot blocking status, DNS infrastructure, and AI analysis with insights and actions. Use this for the current snapshot; use get_tech_trust_history for past runs. Read-only. Returns JSON object.", parameters: z.object({ projectId: objectId("Project ID (from list_projects)"), }), path: (a) => `/v1/projects/${a.projectId}/tech-trust`, }, { name: "get_tech_trust_history", description: "Get paginated history of Tech & Trust monitoring runs with completion timestamps. Use this to compare changes over time — each run captures a full snapshot of all competitors. Retrieve specific run data with get_tech_trust_run_detail using the runId from this response. Read-only. Returns paginated JSON array with pagination.hasMore flag.", parameters: z.object({ projectId: objectId("Project ID (from list_projects)"), ...pagination, }), path: (a) => `/v1/projects/${a.projectId}/tech-trust/history`, queryParams: ["page", "limit"], }, - src/tools.ts:107-110 (schema)Input schema for get_tech_trust_history: requires projectId (24-char hex string) and optional pagination params (page, limit).
parameters: z.object({ projectId: objectId("Project ID (from list_projects)"), ...pagination, }), - src/index.ts:16-25 (handler)Generic handler that executes all tools (including get_tech_trust_history) by calling the API via apiGet with the path and query params defined in the ToolDef.
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)The apiGet helper that performs the actual HTTP GET request to the CompetLab API, using the COMPETLAB_API_KEY env var for authentication.
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, }; } } - src/index.ts:16-25 (registration)The generic registration loop that iterates over all ToolDef entries (including get_tech_trust_history) and registers them with the MCP server via server.tool().
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); }); }