Skip to main content
Glama
nrwl

Nx MCP Server

Official
by nrwl
get-tasks-search.ts3.75 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 TaskSearchRequest { taskIds?: string[]; projectNames?: string[]; targets?: string[]; configurations?: string[]; minStartTime?: string; maxStartTime?: string; limit?: number; pageToken?: string; includeLocal?: boolean; } export interface TaskStatisticSummary { projectName: string; target: string; avgRemoteCacheHitDurationMs: number; avgLocalCacheHitDurationMs: number; avgCacheMissDurationMs: number; avgRemoteCacheHitRate: number; avgLocalCacheHitRate: number; avgCacheMissRate: number; totalCount: number; avgSuccessRate: number; avgFailureRate: number; isCI: boolean; } export interface TaskSearchResponse { items: TaskStatisticSummary[]; nextPageToken?: string; } export interface TaskSearchError { type: 'authentication' | 'network' | 'other'; message: string; } export async function getTasksSearch( workspacePath: string, logger: Logger, request: TaskSearchRequest, ): Promise<{ data?: TaskSearchResponse; error?: TaskSearchError; }> { 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/search`; const headers: any = { 'Content-Type': 'application/json', ...(await nxCloudAuthHeaders(workspacePath)), }; const data = JSON.stringify(request); logger.log(`Making tasks search request`); try { const response = await httpRequest({ type: 'POST', url, headers, data, timeout: 10000, }); const responseData = JSON.parse( response.responseText, ) as TaskSearchResponse; 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 formatTasksSearchContent(data: TaskSearchResponse): string[] { const content: string[] = []; if (data.items && data.items.length > 0) { content.push(`Found ${data.items.length} task statistics:`); for (const task of data.items) { let taskText = `- ${task.projectName}:${task.target}\n`; taskText += ` Total Runs: ${task.totalCount} (${task.isCI ? 'CI' : 'Local'})\n`; taskText += ` Success Rate: ${(task.avgSuccessRate * 100).toFixed(1)}%, Failure Rate: ${(task.avgFailureRate * 100).toFixed(1)}%\n`; taskText += ` Cache Hit Rates - Remote: ${(task.avgRemoteCacheHitRate * 100).toFixed(1)}%, Local: ${(task.avgLocalCacheHitRate * 100).toFixed(1)}%, Miss: ${(task.avgCacheMissRate * 100).toFixed(1)}%\n`; taskText += ` Avg Durations - Remote Hit: ${Math.round(task.avgRemoteCacheHitDurationMs / 1000)}s, Local Hit: ${Math.round(task.avgLocalCacheHitDurationMs / 1000)}s, Cache Miss: ${Math.round(task.avgCacheMissDurationMs / 1000)}s`; content.push(taskText); } if (data.nextPageToken) { content.push(`Next page token: ${data.nextPageToken}`); } } else { content.push('No 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