Skip to main content
Glama
nrwl

Nx MCP Server

Official
by nrwl
get-tasks-details-search.ts7.18 kB
import { Logger, httpRequest, HttpError } from '@nx-console/shared-utils'; import { isNxCloudUsed } from './is-nx-cloud-used'; import { getNxCloudUrl } from './cloud-ids'; import { nxCloudAuthHeaders } from './nx-cloud-auth-headers'; export interface DateValue { date: string; value: number; } export interface TaskStatisticDetails { projectName: string; target: string; avgRemoteCacheHitDurationMs: number; avgLocalCacheHitDurationMs: number; avgCacheMissDurationMs: number; avgRemoteCacheHitRate: number; avgLocalCacheHitRate: number; avgCacheMissRate: number; totalCount: number; avgSuccessRate: number; avgFailureRate: number; isCI: boolean; rawRemoteCacheHitDurations: DateValue[]; rawLocalCacheHitDurations: DateValue[]; rawCacheMissDurations: DateValue[]; rawRemoteCacheHitRates: DateValue[]; rawLocalCacheHitRates: DateValue[]; rawCacheMissRates: DateValue[]; rawSuccessRates: DateValue[]; rawFailureRates: DateValue[]; rawTotalCounts: DateValue[]; } export interface TaskDetailsSearchRequest { taskIds?: string[]; projectNames?: string[]; targets?: string[]; configurations?: string[]; minStartTime?: string; maxStartTime?: string; limit?: number; pageToken?: string; includeLocal?: boolean; } export interface TaskDetailsSearchResponse { items: TaskStatisticDetails[]; nextPageToken?: string; } export interface TaskDetailsSearchError { type: 'authentication' | 'network' | 'other'; message: string; } export async function getTasksDetailsSearch( workspacePath: string, logger: Logger, request: TaskDetailsSearchRequest, ): Promise<{ data?: TaskDetailsSearchResponse; error?: TaskDetailsSearchError; }> { if (!(await isNxCloudUsed(workspacePath, logger))) { return { error: { type: 'other', message: 'Nx Cloud is not used in this workspace', }, }; } const nxCloudUrl = await getNxCloudUrl(workspacePath); const url = `${nxCloudUrl}/nx-cloud/mcp-context/tasks/details`; const headers: any = { 'Content-Type': 'application/json', ...(await nxCloudAuthHeaders(workspacePath)), }; const data = JSON.stringify(request); logger.log(`Making tasks details search request`); try { const response = await httpRequest({ type: 'POST', url, headers, data, timeout: 10000, }); const responseData = JSON.parse( response.responseText, ) as TaskDetailsSearchResponse; return { data: responseData, }; } catch (e) { if (e instanceof HttpError && e.status === 401) { logger.log(`Authentication error: ${e.responseText}`); return { error: { type: 'authentication', message: e.responseText, }, }; } logger.log(`Error: ${JSON.stringify(e)}`); return { error: { type: 'other', message: e instanceof HttpError ? e.responseText : (e as Error).message, }, }; } } export function formatTasksDetailsSearchContent( data: TaskDetailsSearchResponse, ): string[] { const content: string[] = []; if (data.items && data.items.length > 0) { content.push(`Found ${data.items.length} detailed task statistics:`); for (const task of data.items) { let taskText = `=== ${task.projectName}:${task.target} ===\n`; taskText += `Environment: ${task.isCI ? 'CI' : 'Local'}\n`; taskText += `Total Executions: ${task.totalCount}\n\n`; // Summary statistics taskText += `SUMMARY STATISTICS:\n`; taskText += `- Average Success Rate: ${(task.avgSuccessRate * 100).toFixed(3)}%\n`; taskText += `- Average Failure Rate: ${(task.avgFailureRate * 100).toFixed(3)}%\n`; taskText += `- Average Remote Cache Hit Rate: ${(task.avgRemoteCacheHitRate * 100).toFixed(3)}%\n`; taskText += `- Average Local Cache Hit Rate: ${(task.avgLocalCacheHitRate * 100).toFixed(3)}%\n`; taskText += `- Average Cache Miss Rate: ${(task.avgCacheMissRate * 100).toFixed(3)}%\n`; taskText += `- Average Remote Cache Hit Duration: ${task.avgRemoteCacheHitDurationMs.toFixed(2)}ms\n`; taskText += `- Average Local Cache Hit Duration: ${task.avgLocalCacheHitDurationMs.toFixed(2)}ms\n`; taskText += `- Average Cache Miss Duration: ${task.avgCacheMissDurationMs.toFixed(2)}ms\n\n`; // Raw time series data taskText += `RAW TIME SERIES DATA:\n\n`; if (task.rawSuccessRates.length > 0) { taskText += `Success Rates by Date:\n`; task.rawSuccessRates.forEach((entry) => { taskText += ` ${entry.date}: ${(entry.value * 100).toFixed(3)}%\n`; }); taskText += `\n`; } if (task.rawFailureRates.length > 0) { taskText += `Failure Rates by Date:\n`; task.rawFailureRates.forEach((entry) => { taskText += ` ${entry.date}: ${(entry.value * 100).toFixed(3)}%\n`; }); taskText += `\n`; } if (task.rawRemoteCacheHitRates.length > 0) { taskText += `Remote Cache Hit Rates by Date:\n`; task.rawRemoteCacheHitRates.forEach((entry) => { taskText += ` ${entry.date}: ${(entry.value * 100).toFixed(3)}%\n`; }); taskText += `\n`; } if (task.rawLocalCacheHitRates.length > 0) { taskText += `Local Cache Hit Rates by Date:\n`; task.rawLocalCacheHitRates.forEach((entry) => { taskText += ` ${entry.date}: ${(entry.value * 100).toFixed(3)}%\n`; }); taskText += `\n`; } if (task.rawCacheMissRates.length > 0) { taskText += `Cache Miss Rates by Date:\n`; task.rawCacheMissRates.forEach((entry) => { taskText += ` ${entry.date}: ${(entry.value * 100).toFixed(3)}%\n`; }); taskText += `\n`; } if (task.rawRemoteCacheHitDurations.length > 0) { taskText += `Remote Cache Hit Durations by Date (ms):\n`; task.rawRemoteCacheHitDurations.forEach((entry) => { taskText += ` ${entry.date}: ${entry.value.toFixed(2)}ms\n`; }); taskText += `\n`; } if (task.rawLocalCacheHitDurations.length > 0) { taskText += `Local Cache Hit Durations by Date (ms):\n`; task.rawLocalCacheHitDurations.forEach((entry) => { taskText += ` ${entry.date}: ${entry.value.toFixed(2)}ms\n`; }); taskText += `\n`; } if (task.rawCacheMissDurations.length > 0) { taskText += `Cache Miss Durations by Date (ms):\n`; task.rawCacheMissDurations.forEach((entry) => { taskText += ` ${entry.date}: ${entry.value.toFixed(2)}ms\n`; }); taskText += `\n`; } if (task.rawTotalCounts.length > 0) { taskText += `Total Execution Counts by Date:\n`; task.rawTotalCounts.forEach((entry) => { taskText += ` ${entry.date}: ${entry.value} executions\n`; }); } content.push(taskText); } if (data.nextPageToken) { content.push(`Next page token: ${data.nextPageToken}`); } } else { content.push('No detailed task statistics found matching the criteria.'); } return content; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nrwl/nx-console'

If you have feedback or need assistance with the MCP directory API, please join our Discord server