Skip to main content
Glama

generate-frontend-client

Generate TypeScript clients for frontend applications to call backend API endpoints, enabling integration with scheduling systems for managing users, availability, and bookings.

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

  • Main handler function that generates and returns the complete TypeScript code for the frontend API client as a hardcoded template string with fetch calls to backend endpoints.
    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; `; }
  • MCP server tool call handler case that invokes generateFrontendClient and formats the response.
    case 'generate-frontend-client': { const code = generateFrontendClient({ typesImportPath: args?.typesImportPath as string | undefined, }); return { content: [ { type: 'text', text: code, }, ], }; }
  • Tool schema definition including name, description, and input schema for typesImportPath.
    { 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")', }, }, }, },
  • src/server.ts:96-98 (registration)
    Registers the listTools handler that exposes the generate-frontend-client tool among others.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS, }));

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