UNPKG

@makingchatbots/genesys-cloud-mcp-server

Version:

A Model Context Protocol (MCP) server exposing Genesys Cloud tools for LLMs, including sentiment analysis, conversation search, topic detection and more.

111 lines (110 loc) 4.75 kB
import { z } from "zod"; import { createTool } from "../utils/createTool.js"; import { errorResult } from "../utils/errorResult.js"; import { isUnauthorisedError } from "../utils/genesys/isUnauthorisedError.js"; import { waitFor } from "../utils/waitFor.js"; const MAX_ATTEMPTS = 10; const TOOL_CACHE_KEY = "oauth-client-usage"; const paramsSchema = z.object({ oauthClientId: z .string() .uuid() .describe("The UUID of the OAuth Client to retrieve the usage for (e.g., 00000000-0000-0000-0000-000000000000)"), startDate: z .string() .describe("The start date/time in ISO-8601 format (e.g., '2024-01-01T00:00:00Z')"), endDate: z .string() .describe("The end date/time in ISO-8601 format (e.g., '2024-01-07T23:59:59Z')"), }); export const oauthClientUsage = ({ oauthApi, cache }) => createTool({ schema: { name: "oauth_client_usage", annotations: { title: "OAuth Client Usage" }, description: "Retrieves the usage of an OAuth Client for a given period. It returns the total number of requests and a breakdown of Platform API endpoints used by the client.", paramsSchema, }, call: async ({ oauthClientId, startDate, endDate }) => { const from = new Date(startDate); const to = new Date(endDate); if (Number.isNaN(from.getTime())) return errorResult("startDate is not a valid ISO-8601 date"); if (Number.isNaN(to.getTime())) return errorResult("endDate is not a valid ISO-8601 date"); if (from >= to) return errorResult("Start date must be before end date"); const now = new Date(); if (to > now) { to.setTime(now.getTime()); } const cacheName = `${TOOL_CACHE_KEY}.${oauthClientId}-${from.getTime()}-${to.getTime()}`; const cachedResult = cache?.get(cacheName); if (cachedResult) { return { content: [ { type: "text", text: JSON.stringify(cachedResult), }, ], }; } let result; try { result = await oauthApi.postOauthClientUsageQuery(oauthClientId, { interval: `${from.toISOString()}/${to.toISOString()}`, metrics: ["Requests"], groupBy: ["TemplateUri", "HttpMethod"], }); } catch (error) { const errorMessage = isUnauthorisedError(error) ? "Failed to retrieve usage of OAuth client: Unauthorised access. Please check API credentials or permissions" : `Failed to retrieve usage of OAuth client: ${error instanceof Error ? error.message : JSON.stringify(error)}`; return errorResult(errorMessage); } if (!result.executionId) { return errorResult("Failed to get an Execution ID from Genesys Cloud's Platform API"); } let apiUsageQueryResult; let state; let attempts = 0; while (attempts < MAX_ATTEMPTS) { const executionResult = await oauthApi.getOauthClientUsageQueryResult(result.executionId, oauthClientId); state = executionResult?.queryStatus?.toUpperCase() ?? "UNKNOWN"; if (state === "COMPLETE") { apiUsageQueryResult = executionResult; break; } switch (executionResult.queryStatus) { case "FAILED": return errorResult(`Failed to get usage data for OAuth Client ${oauthClientId}.`); case "UNKNOWN": return errorResult("Execution returned an unknown or undefined state."); } await waitFor(3000); attempts++; } if (state !== "COMPLETE") { return errorResult(`Timed out waiting for OAuth Client usage to complete for client ${oauthClientId}.`); } const toolResult = { startDate, endDate, totalRequests: (apiUsageQueryResult?.results ?? []).reduce((acc, curr) => acc + (curr.requests ?? 0), 0), requestsPerEndpoint: (apiUsageQueryResult?.results ?? []).map((result) => ({ endpoint: [result.httpMethod, result.templateUri].join(" ") || undefined, requests: result.requests, })), }; cache?.set(`${TOOL_CACHE_KEY}.${oauthClientId}-${from.getTime()}-${to.getTime()}`, toolResult); return { content: [ { type: "text", text: JSON.stringify(toolResult), }, ], }; }, });