Skip to main content
Glama

generate-frontend-client

Create TypeScript clients for frontend applications to interact with backend API endpoints, simplifying API integration and type-safe communication.

Instructions

Generate a TypeScript client for frontend apps that calls your backend API endpoints

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typesImportPathNoImport path for types file (optional, defaults to "../types")

Implementation Reference

  • src/server.ts:54-66 (registration)
    Registration of the 'generate-frontend-client' tool in the TOOLS array, including name, description, and inputSchema.
    {
      name: 'generate-frontend-client',
      description: 'Generate a TypeScript client for frontend apps that calls your backend API endpoints',
      inputSchema: {
        type: 'object',
        properties: {
          typesImportPath: {
            type: 'string',
            description: 'Import path for types file (optional, defaults to "../types")',
          },
        },
      },
    },
  • Dispatch handler in the CallToolRequestSchema switch statement that invokes generateFrontendClient and returns the generated code.
    case 'generate-frontend-client': {
      const code = generateFrontendClient({
        typesImportPath: args?.typesImportPath as string | undefined,
      });
    
      return {
        content: [
          {
            type: 'text',
            text: code,
          },
        ],
      };
    }
  • Core handler function that generates the complete TypeScript frontend API client code as a large template string literal, including all endpoint functions with fetch calls to backend routes.
    export function generateFrontendClient(options?: { typesImportPath?: string }): string {
      const typesPath = options?.typesImportPath || '../types';
    
      return `import * as Types from '${typesPath}';
    import { convertToLocalTime } from '@kalendis/utils';
    
    export const api = {
      getUsers: async (): Promise<Types.User[]> => {
        const response = await fetch('/api/users');
        if (!response.ok) throw new Error('Failed to fetch users');
        return response.json();
      },
    
      createUser: async (data: { id: string; name: string; email?: string; timezone?: string }): Promise<Types.User> => {
        const response = await fetch('/api/users', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to create user');
        return response.json();
      },
    
      updateUser: async (data: { id: string; name?: string; timezone?: string }): Promise<Types.User> => {
        const response = await fetch(\`/api/users/\${data.id}\`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to update user');
        return response.json();
      },
    
      deleteUser: async (id: string): Promise<Types.User> => {
        const response = await fetch(\`/api/users/\${id}\`, {
          method: 'DELETE'
        });
        if (!response.ok) throw new Error('Failed to delete user');
        return response.json();
      },
    
      getAvailability: async (params?: { userId?: string; start?: string; end?: string }): Promise<Types.Availability[]> => {
        const query = new URLSearchParams(params as any).toString();
        const response = await fetch('/api/availability' + (query ? '?' + query : ''));
        if (!response.ok) throw new Error('Failed to fetch availability');
        const data = await response.json();
        return convertToLocalTime(data);
      },
    
      getAllAvailability: async (params: { start: string; end?: string; timezone?: string }): Promise<Array<{userId: string; start: string; end: string}>> => {
        const query = new URLSearchParams(params as any).toString();
        const response = await fetch('/api/availability/all?' + query);
        if (!response.ok) throw new Error('Failed to fetch all availability');
        const data = await response.json();
        return convertToLocalTime(data);
      },
    
      getMultiUserCalculatedAvailability: async (data: {
        userIds: string[];
        start: string;
        end?: string;
        timezone?: string;
      }): Promise<Array<{userId: string; availability: Array<{start: string; end: string; offset: number}>}>> => {
        const response = await fetch('/api/availability/calculated', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to fetch calculated availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      getRecurringAvailabilityByDate: async (data: {
        userId: string;
        start: string;
        cadence: string;
        frequency: number;
        numberOfOccurrences: number;
        timezone?: string;
      }): Promise<Array<Array<{start: string; end: string; offset: number}>>> => {
        const response = await fetch('/api/availability/recurring', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to fetch recurring availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      getMatchingAvailabilityByDate: async (data: {
        userIds: string[];
        start: string;
        end?: string;
        timezone?: string;
      }): Promise<Array<{start: string; end: string}>> => {
        const response = await fetch('/api/availability/matching', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to fetch matching availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      addAvailability: async (data: { userId: string; start: string; end: string; timezone?: string }): Promise<Types.Availability> => {
        const response = await fetch('/api/availability', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to add availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      updateAvailability: async (data: { id: string; start?: string; end?: string; timezone?: string }): Promise<Types.Availability> => {
        const response = await fetch(\`/api/availability/\${data.id}\`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to update availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      deleteAvailability: async (id: string, userId: string): Promise<{message: string}> => {
        const response = await fetch(\`/api/availability/\${id}?userId=\${userId}\`, {
          method: 'DELETE'
        });
        if (!response.ok) throw new Error('Failed to delete availability');
        return response.json();
      },
    
      getRecurringAvailability: async (userId: string): Promise<Types.RecurringAvailability[]> => {
        const response = await fetch(\`/api/recurring-availability?userId=\${userId}\`);
        if (!response.ok) throw new Error('Failed to fetch recurring availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      addRecurringAvailability: async (data: {
        userId: string;
        daysOfWeek: Types.DaysOfWeek[];
        start: string;
        end: string;
        expiration?: string;
        timezone?: string;
      }): Promise<Types.RecurringAvailability> => {
        const response = await fetch('/api/recurring-availability', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to add recurring availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      updateRecurringAvailability: async (data: {
        id: string;
        userId: string;
        daysOfWeek?: Types.DaysOfWeek[];
        start?: string;
        end?: string;
        expiration?: string;
        makeInfinite?: boolean;
        timezone?: string;
      }): Promise<Types.RecurringAvailability> => {
        const response = await fetch(\`/api/recurring-availability/\${data.id}\`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to update recurring availability');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      deleteRecurringAvailability: async (id: string, userId: string): Promise<{message: string}> => {
        const response = await fetch(\`/api/recurring-availability/\${id}?userId=\${userId}\`, {
          method: 'DELETE'
        });
        if (!response.ok) throw new Error('Failed to delete recurring availability');
        return response.json();
      },
    
      getAvailabilityException: async (userId: string): Promise<Types.AvailabilityException[]> => {
        const response = await fetch(\`/api/availability-exceptions?userId=\${userId}\`);
        if (!response.ok) throw new Error('Failed to fetch availability exceptions');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      addAvailabilityException: async (data: {
        userId: string;
        start: string;
        end: string;
        timezone?: string;
      }): Promise<Types.AvailabilityException> => {
        const response = await fetch('/api/availability-exceptions', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to add availability exception');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      addRecurringAvailabilityException: async (data: {
        userId: string;
        daysOfWeek: Types.DaysOfWeek[];
        start: string;
        end: string;
        expiration?: string;
        timezone?: string;
      }): Promise<Types.AvailabilityException[]> => {
        const response = await fetch('/api/availability-exceptions/recurring', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to add recurring availability exception');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      updateAvailabilityException: async (data: {
        id: string;
        start?: string;
        end?: string;
        timezone?: string;
      }): Promise<Types.AvailabilityException> => {
        const response = await fetch(\`/api/availability-exceptions/\${data.id}\`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to update availability exception');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      deleteAvailabilityException: async (id: string, userId: string): Promise<{message: string}> => {
        const response = await fetch(\`/api/availability-exceptions/\${id}?userId=\${userId}\`, {
          method: 'DELETE'
        });
        if (!response.ok) throw new Error('Failed to delete availability exception');
        return response.json();
      },
    
      getBookings: async (params: { userId: string; start: string; end?: string }): Promise<Types.Booking[]> => {
        const query = new URLSearchParams(params as any).toString();
        const response = await fetch('/api/bookings?' + query);
        if (!response.ok) throw new Error('Failed to fetch bookings');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      getBookingsByIds: async (bookingIds: string[]): Promise<Types.Booking[]> => {
        const response = await fetch('/api/bookings/bulk', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ bookingIds })
        });
        if (!response.ok) throw new Error('Failed to fetch bookings');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      createBooking: async (data: { userIds: string[]; start: string; end: string; timezone?: string }): Promise<Types.Booking> => {
        const response = await fetch('/api/bookings', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to create booking');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      updateBooking: async (data: { id: string; userIds?: string[]; start?: string; end?: string; timezone?: string }): Promise<Types.Booking> => {
        const response = await fetch(\`/api/bookings/\${data.id}\`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to update booking');
        const responseData = await response.json();
        return convertToLocalTime(responseData);
      },
    
      deleteBooking: async (id: string): Promise<{message: string}> => {
        const response = await fetch(\`/api/bookings/\${id}\`, {
          method: 'DELETE'
        });
        if (!response.ok) throw new Error('Failed to delete booking');
        return response.json();
      },
    
      getAccount: async (): Promise<Types.Account> => {
        const response = await fetch('/api/account');
        if (!response.ok) throw new Error('Failed to fetch account');
        return response.json();
      },
    
      updateAccount: async (data: { name?: string; active?: boolean }): Promise<Types.Account> => {
        const response = await fetch('/api/account', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
        if (!response.ok) throw new Error('Failed to update account');
        return response.json();
      }
    };
    
    export default api;
    `;
    }

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/kalendis-dev/kalendis-mcp'

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