Skip to main content
Glama
krzko

Google Cloud MCP Server

by krzko

gcp-error-reporting-get-group-details

Retrieve detailed error group information from Google Cloud Error Reporting to analyze and troubleshoot specific issues, enabling targeted resolution and improved system reliability.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Handler function that authenticates with GCP using initGoogleAuth, fetches specific error group details via GET /projects/{projectId}/groups/{groupId}, lists recent error events via GET /projects/{projectId}/events?groupId={groupId}, formats comprehensive Markdown report with group info, event details (time, service, message, HTTP request, source location, user), and investigation recommendations.
    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, ); } },
  • Input schema using Zod: 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"), },
  • Tool registration via server.tool('gcp-error-reporting-get-group-details') with title 'Get Error Group Details', description, and inline inputSchema and handler.
    server.tool( "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