Skip to main content
Glama
krzko

Google Cloud MCP Server

by krzko

gcp-error-reporting-get-group-details

Retrieve detailed information about error groups in Google Cloud Error Reporting to analyze and troubleshoot application issues.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The core handler function for the 'gcp-error-reporting-get-group-details' tool. It authenticates with Google Cloud, fetches detailed error group information and recent error events using the Error Reporting REST API, parses and formats the data into a comprehensive Markdown report including group metadata, event details (timestamps, service context, messages, HTTP requests, source locations), and suggested investigation steps.
    async ({ groupId, timeRange, pageSize }) => { try { const projectId = await getProjectId(); // Initialize Google Auth client (same pattern as trace service) const auth = await initGoogleAuth(true); if (!auth) { throw new GcpMcpError( "Google Cloud authentication not available. Please configure authentication to access error reporting data.", "UNAUTHENTICATED", 401, ); } const client = await auth.getClient(); const token = await client.getAccessToken(); // Parse time range - ensure we have a valid timeRange value const actualTimeRange = timeRange || "24h"; const actualPageSize = pageSize || 10; // Map time range to Google Cloud Error Reporting periods let period: string; switch (actualTimeRange) { case "1h": period = "PERIOD_1_HOUR"; break; case "6h": period = "PERIOD_6_HOURS"; break; case "24h": case "1d": period = "PERIOD_1_DAY"; break; case "7d": period = "PERIOD_1_WEEK"; break; case "30d": period = "PERIOD_30_DAYS"; break; default: // Default to 1 day for event details period = "PERIOD_1_DAY"; break; } // First, get the error group details using projects.groups/get // The group name format should be: projects/{projectId}/groups/{groupId} const groupName = `projects/${projectId}/groups/${groupId}`; const groupApiUrl = `https://clouderrorreporting.googleapis.com/v1beta1/${groupName}`; // Get group details const groupResponse = await fetch(groupApiUrl, { method: "GET", headers: { Authorization: `Bearer ${token.token}`, Accept: "application/json", }, }); if (!groupResponse.ok) { const errorText = await groupResponse.text(); throw new GcpMcpError( `Failed to fetch error group details: ${errorText}`, "FAILED_PRECONDITION", groupResponse.status, ); } const groupData = await groupResponse.json(); // Build query parameters for events API // groupId should be the raw group identifier for the events API const params = new URLSearchParams({ groupId: groupId, "timeRange.period": period, pageSize: actualPageSize.toString(), }); // Make REST API call to list events const apiUrl = `https://clouderrorreporting.googleapis.com/v1beta1/projects/${projectId}/events?${params}`; const response = await fetch(apiUrl, { method: "GET", headers: { Authorization: `Bearer ${token.token}`, Accept: "application/json", }, }); if (!response.ok) { const errorText = await response.text(); throw new GcpMcpError( `Failed to fetch error events: ${errorText}`, "FAILED_PRECONDITION", response.status, ); } const data = await response.json(); const errorEvents = data.errorEvents || []; // Start building content with group details let content = `# Error Group Details\n\n`; // Add group information content += `**Group ID:** ${groupId}\n`; content += `**Project:** ${projectId}\n`; content += `**Group Name:** ${groupData.name || "Unknown"}\n`; if (groupData.resolutionStatus) { content += `**Resolution Status:** ${groupData.resolutionStatus}\n`; } if (groupData.trackingIssues && groupData.trackingIssues.length > 0) { content += `**Tracking Issues:** ${groupData.trackingIssues.length} linked\n`; } content += `**Time Range:** ${actualTimeRange}\n\n`; if (!errorEvents || errorEvents.length === 0) { content += `## Recent Error Events\n\nNo error events found for this group in the specified time range.`; return { content: [ { type: "text", text: content, }, ], }; } content += `## Recent Error Events (${errorEvents.length})\n\n`; errorEvents.forEach((event: any, index: number) => { content += `### Event ${index + 1}\n\n`; content += `**Time:** ${new Date(event.eventTime).toLocaleString()}\n`; content += `**Service:** ${event.serviceContext?.service || "Unknown"}`; if (event.serviceContext?.version) { content += ` (v${event.serviceContext.version})`; } content += `\n\n`; content += `**Message:** ${event.message}\n\n`; if (event.context?.httpRequest) { const req = event.context.httpRequest; content += `**HTTP Request:**\n`; if (req.method && req.url) { content += `- ${req.method} ${req.url}\n`; } if (req.responseStatusCode) { content += `- Status: ${req.responseStatusCode}\n`; } if (req.userAgent) { content += `- User Agent: ${req.userAgent}\n`; } if (req.remoteIp) { content += `- Remote IP: ${req.remoteIp}\n`; } content += `\n`; } if (event.context?.reportLocation) { const loc = event.context.reportLocation; content += `**Source Location:**\n`; if (loc.filePath) { content += `- File: ${loc.filePath}`; if (loc.lineNumber) { content += `:${loc.lineNumber}`; } content += `\n`; } if (loc.functionName) { content += `- Function: ${loc.functionName}\n`; } content += `\n`; } if (event.context?.user) { content += `**User:** ${event.context.user}\n\n`; } content += `---\n\n`; }); // Add investigation suggestions content += `## Investigation Steps\n\n`; content += `1. **Check Logs:** Use Cloud Logging to find related log entries around the error times\n`; content += `2. **Monitor Metrics:** Review monitoring dashboards for correlated performance metrics\n`; content += `3. **Recent Changes:** Check recent deployments and configuration changes\n`; content += `4. **Pattern Analysis:** Look for patterns in user agents, IP addresses, or request parameters\n`; content += `5. **Trace Analysis:** If available, examine distributed traces for request flow\n\n`; return { content: [ { type: "text", text: content, }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; throw new GcpMcpError( `Failed to get error group details: ${errorMessage}`, "INTERNAL_ERROR", 500, ); } },
  • Zod-based input schema validation for the tool, defining parameters: groupId (required string), timeRange (optional string, default '24h'), pageSize (optional number 1-100, default 10).
    inputSchema: { groupId: z.string().describe("Error group ID to get details for"), timeRange: z .string() .optional() .default("24h") .describe('Time range to query events (e.g., "1h", "24h", "7d")'), pageSize: z .number() .min(1) .max(100) .default(10) .describe("Maximum number of error events to return"), },
  • Registration of the tool on the MCP server within the registerErrorReportingTools function, specifying name, metadata (title, description), input schema, and handler implementation.
    "gcp-error-reporting-get-group-details", { title: "Get Error Group Details", description: "Get detailed information about a specific error group including recent events", inputSchema: { groupId: z.string().describe("Error group ID to get details for"), timeRange: z .string() .optional() .default("24h") .describe('Time range to query events (e.g., "1h", "24h", "7d")'), pageSize: z .number() .min(1) .max(100) .default(10) .describe("Maximum number of error events to return"), }, }, async ({ groupId, timeRange, pageSize }) => { try { const projectId = await getProjectId(); // Initialize Google Auth client (same pattern as trace service) const auth = await initGoogleAuth(true); if (!auth) { throw new GcpMcpError( "Google Cloud authentication not available. Please configure authentication to access error reporting data.", "UNAUTHENTICATED", 401, ); } const client = await auth.getClient(); const token = await client.getAccessToken(); // Parse time range - ensure we have a valid timeRange value const actualTimeRange = timeRange || "24h"; const actualPageSize = pageSize || 10; // Map time range to Google Cloud Error Reporting periods let period: string; switch (actualTimeRange) { case "1h": period = "PERIOD_1_HOUR"; break; case "6h": period = "PERIOD_6_HOURS"; break; case "24h": case "1d": period = "PERIOD_1_DAY"; break; case "7d": period = "PERIOD_1_WEEK"; break; case "30d": period = "PERIOD_30_DAYS"; break; default: // Default to 1 day for event details period = "PERIOD_1_DAY"; break; } // First, get the error group details using projects.groups/get // The group name format should be: projects/{projectId}/groups/{groupId} const groupName = `projects/${projectId}/groups/${groupId}`; const groupApiUrl = `https://clouderrorreporting.googleapis.com/v1beta1/${groupName}`; // Get group details const groupResponse = await fetch(groupApiUrl, { method: "GET", headers: { Authorization: `Bearer ${token.token}`, Accept: "application/json", }, }); if (!groupResponse.ok) { const errorText = await groupResponse.text(); throw new GcpMcpError( `Failed to fetch error group details: ${errorText}`, "FAILED_PRECONDITION", groupResponse.status, ); } const groupData = await groupResponse.json(); // Build query parameters for events API // groupId should be the raw group identifier for the events API const params = new URLSearchParams({ groupId: groupId, "timeRange.period": period, pageSize: actualPageSize.toString(), }); // Make REST API call to list events const apiUrl = `https://clouderrorreporting.googleapis.com/v1beta1/projects/${projectId}/events?${params}`; const response = await fetch(apiUrl, { method: "GET", headers: { Authorization: `Bearer ${token.token}`, Accept: "application/json", }, }); if (!response.ok) { const errorText = await response.text(); throw new GcpMcpError( `Failed to fetch error events: ${errorText}`, "FAILED_PRECONDITION", response.status, ); } const data = await response.json(); const errorEvents = data.errorEvents || []; // Start building content with group details let content = `# Error Group Details\n\n`; // Add group information content += `**Group ID:** ${groupId}\n`; content += `**Project:** ${projectId}\n`; content += `**Group Name:** ${groupData.name || "Unknown"}\n`; if (groupData.resolutionStatus) { content += `**Resolution Status:** ${groupData.resolutionStatus}\n`; } if (groupData.trackingIssues && groupData.trackingIssues.length > 0) { content += `**Tracking Issues:** ${groupData.trackingIssues.length} linked\n`; } content += `**Time Range:** ${actualTimeRange}\n\n`; if (!errorEvents || errorEvents.length === 0) { content += `## Recent Error Events\n\nNo error events found for this group in the specified time range.`; return { content: [ { type: "text", text: content, }, ], }; } content += `## Recent Error Events (${errorEvents.length})\n\n`; errorEvents.forEach((event: any, index: number) => { content += `### Event ${index + 1}\n\n`; content += `**Time:** ${new Date(event.eventTime).toLocaleString()}\n`; content += `**Service:** ${event.serviceContext?.service || "Unknown"}`; if (event.serviceContext?.version) { content += ` (v${event.serviceContext.version})`; } content += `\n\n`; content += `**Message:** ${event.message}\n\n`; if (event.context?.httpRequest) { const req = event.context.httpRequest; content += `**HTTP Request:**\n`; if (req.method && req.url) { content += `- ${req.method} ${req.url}\n`; } if (req.responseStatusCode) { content += `- Status: ${req.responseStatusCode}\n`; } if (req.userAgent) { content += `- User Agent: ${req.userAgent}\n`; } if (req.remoteIp) { content += `- Remote IP: ${req.remoteIp}\n`; } content += `\n`; } if (event.context?.reportLocation) { const loc = event.context.reportLocation; content += `**Source Location:**\n`; if (loc.filePath) { content += `- File: ${loc.filePath}`; if (loc.lineNumber) { content += `:${loc.lineNumber}`; } content += `\n`; } if (loc.functionName) { content += `- Function: ${loc.functionName}\n`; } content += `\n`; } if (event.context?.user) { content += `**User:** ${event.context.user}\n\n`; } content += `---\n\n`; }); // Add investigation suggestions content += `## Investigation Steps\n\n`; content += `1. **Check Logs:** Use Cloud Logging to find related log entries around the error times\n`; content += `2. **Monitor Metrics:** Review monitoring dashboards for correlated performance metrics\n`; content += `3. **Recent Changes:** Check recent deployments and configuration changes\n`; content += `4. **Pattern Analysis:** Look for patterns in user agents, IP addresses, or request parameters\n`; content += `5. **Trace Analysis:** If available, examine distributed traces for request flow\n\n`; return { content: [ { type: "text", text: content, }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; throw new GcpMcpError( `Failed to get error group details: ${errorMessage}`, "INTERNAL_ERROR", 500, ); } }, );

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/krzko/google-cloud-mcp'

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