get_project
Retrieve project details including monitoring freshness per dimension (techTrust, content, positioning, pricing, AI visibility), AI prompts, and overall status. Use to check dimension update times before fetching data.
Instructions
Get project details including per-dimension monitoring freshness (techTrust, content, positioning, pricing, aiVisibility), AI monitoring prompts, and overall status. Use this after list_projects to check when each dimension was last updated before fetching dimension data. Read-only. Returns JSON object.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID (from list_projects) |
Implementation Reference
- src/tools.ts:38-44 (schema)The ToolDef object for 'get_project' — defines the schema (projectId parameter with Zod validation) and API path (`/v1/projects/${projectId}`). This is where the tool's name, description, parameter schema, and URL path are configured.
name: "get_project", description: "Get project details including per-dimension monitoring freshness (techTrust, content, positioning, pricing, aiVisibility), AI monitoring prompts, and overall status. Use this after list_projects to check when each dimension was last updated before fetching dimension data. Read-only. Returns JSON object.", parameters: z.object({ projectId: objectId("Project ID (from list_projects)"), }), path: (a) => `/v1/projects/${a.projectId}`, - src/index.ts:16-25 (registration)Dynamic registration loop that iterates over all tools (including 'get_project') and calls `server.tool()` to register each one with the MCP server. The `tool.path(args)` is resolved and an API call is made via `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:3-58 (helper)The `apiGet` helper function used by the tool handler. For 'get_project', it makes a GET request to `/v1/projects/{projectId}` using the COMPETLAB_API_KEY.
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, }; } }