UNPKG

@chargetrip/mcp

Version:

Chargetrip MCP server

240 lines (225 loc) 7.53 kB
import { CallToolResult } from '@modelcontextprotocol/sdk/types'; import { GraphQLError } from 'graphql'; import { GraphQLClient } from './graphql-client'; export class FetchAndProcessUtil { /** * @description Unified method to fetch a list of items from the Chargetrip GraphQL API and process the results. * Please make sure that the query return the elements of the list in a field named `list`. * * @param {string} query The GraphQL query string to execute. * @param {Record<string, any>} variables The variables to be used in the GraphQL query. * @param {Function} mapFunction A function that maps each item in the list to a string representation. * @returns {Promise<CallToolResult>} A promise that resolves to a CallToolResult containing the processed list. */ static async getList<T>({ query, variables, mapFunction, }: { query: string; variables: Record<string, any>; mapFunction: (item: T) => string; }): Promise<CallToolResult> { try { const { data, error } = await GraphQLClient.getInstance().query<{ list: T[]; }>(query, variables); if (error) { throw new GraphQLError(error.message); } if (!data?.list || data.list.length === 0) { throw new Error('No data found or an error occurred while fetching the list.'); } return { content: [ { type: 'text', text: 'Here is the response of the API for the list:', }, { type: 'text', text: data.list.map(mapFunction).join('\n'), }, { type: 'text', text: 'Here is the query that was used to fetch the list:', }, { type: 'text', text: `Query: "${query}"\nVariables: "${JSON.stringify(variables, null, 2)}"`, }, ], }; } catch (error) { if (error instanceof GraphQLError) { return { content: [ { type: 'text', text: `GraphQL error occurred while fetching the list: ${error.message}`, }, ], }; } return { content: [ { type: 'text', text: `Unexpected error occurred while fetching the list: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } /** * @description Unified method to fetch a single item from the Chargetrip GraphQL API and process the result. * Please make sure that the query return the item in a field named `item`. * * @param {string} itemName The name of the item being fetched, used for error messages. * @param {string} query The GraphQL query string to execute. * @param {Record<string, any>} variables The variables to be used in the GraphQL query. * @param {Function} mapFunction A function that maps the item to a string representation. * @param {string} operationType The type of operation to perform, either 'query' or 'mutation'. * @returns {Promise<CallToolResult>} A promise that resolves to a CallToolResult containing the processed item. */ static async getItem<T>({ itemName, query, variables, operationType = 'query', mapFunction, }: { itemName: string; query: string; variables: Record<string, any>; operationType?: 'query' | 'mutation'; mapFunction: (item: T) => string; }): Promise<CallToolResult> { try { const { data, error } = operationType === 'mutation' ? await GraphQLClient.getInstance().mutate<{ item: T }>(query, variables) : await GraphQLClient.getInstance().query<{ item: T }>(query, variables); if (error) { throw new GraphQLError(error.message); } if (!data?.item) { throw new Error('No data found or an error occurred while fetching the data.'); } return { content: [ { type: 'text', text: `Here is the response of the API for the ${itemName}:`, }, { type: 'text', text: mapFunction(data.item), }, { type: 'text', text: `Here is the query that was used to fetch the ${itemName}:`, }, { type: 'text', text: `Query: "${query}"\nVariables: "${JSON.stringify(variables, null, 2)}"`, }, ], }; } catch (error) { if (error instanceof GraphQLError) { return { content: [ { type: 'text', text: `GraphQL error occurred while fetching the ${itemName}: ${error.message}`, }, ], }; } return { content: [ { type: 'text', text: `Unexpected error occurred while fetching the ${itemName}: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } /** * @description Unified method to fetch a single item from the Chargetrip GraphQL API using a subscription and process the result. * * @param {string} itemName The name of the item being fetched, used for error messages. * @param {string} query The GraphQL query string to execute. * @param {Record<string, any>} variables The variables to be used in the GraphQL query. * @param {Function} subscribeFunction A function that determines whether to continue subscribing based on the item received. * @param {Function} mapFunction A function that maps the item to a string representation. * @returns {Promise<CallToolResult>} A promise that resolves to a CallToolResult containing the processed item. */ static async getItemFromSubscription<T>({ itemName, query, variables, subscribeFunction, mapFunction, }: { itemName: string; query: string; variables: Record<string, any>; subscribeFunction: (item: T) => boolean; mapFunction: (item: T) => string; }): Promise<CallToolResult> { try { const data: T = await new Promise(resolve => { const { unsubscribe } = GraphQLClient.getInstance() .subscription<T>(query, variables) .subscribe(data => { if (subscribeFunction(data.data as T)) { unsubscribe(); return resolve(data.data as T); } }); }); return { content: [ { type: 'text', text: `Here is the response of the API for the ${itemName}:`, }, { type: 'text', text: mapFunction(data), }, { type: 'text', text: `Here is the query that was used to fetch the ${itemName}:`, }, { type: 'text', text: `Query: "${query}"\nVariables: "${JSON.stringify(variables, null, 2)}"`, }, ], }; } catch (error) { if (error instanceof GraphQLError) { return { content: [ { type: 'text', text: `GraphQL error occurred while waiting for the ${itemName}: ${error.message}`, }, ], }; } return { content: [ { type: 'text', text: `Unexpected error occurred while waiting for the ${itemName}: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } }