Skip to main content
Glama
client-list.ts5.11 kB
/** * client_list Tool * * List clients from FreshBooks with filtering and pagination. */ import { z } from 'zod'; import { ClientListInputSchema, ClientListOutputSchema } from './schemas.js'; import { FreshBooksClientWrapper } from '../../client/index.js'; import { ErrorHandler } from '../../errors/error-handler.js'; import { ToolContext } from '../../errors/types.js'; import { logger } from '../../utils/logger.js'; /** * Tool definition for client_list */ export const clientListTool = { name: 'client_list', description: `List clients from FreshBooks with optional filtering and pagination. WHEN TO USE: - User asks to "see clients", "list clients", "show all customers" - User wants to find a client by name, email, or organization - User needs to select a client for invoicing or project setup - Getting client information for time tracking context REQUIRED: - accountId: FreshBooks account ID (get from auth_status if not specified) OPTIONAL FILTERS: - email: Find client by exact email address - organization: Search by company name (partial match) - fName: Search by first name (partial match) - lName: Search by last name (partial match) - visState: Filter by status (0=active, 1=deleted, 2=archived) PAGINATION: - page: Page number (default: 1) - perPage: Results per page (default: 30, max: 100) RETURNS: Array of clients with: - id: Client ID - fName, lName: Contact name - organization: Company name - email: Email address - Phone numbers, addresses - currencyCode: Billing currency - visState: Status Plus pagination metadata (page, pages, total) EXAMPLES: - "Show me all active clients" - "List clients with 'Acme' in their organization name" - "Find the client with email john@example.com" - "Show all archived clients"`, inputSchema: ClientListInputSchema, outputSchema: ClientListOutputSchema, /** * Execute the tool */ async execute( input: z.infer<typeof ClientListInputSchema>, client: FreshBooksClientWrapper ): Promise<z.infer<typeof ClientListOutputSchema>> { const handler = ErrorHandler.wrapHandler( 'client_list', async ( input: z.infer<typeof ClientListInputSchema>, _context: ToolContext ) => { logger.debug('Listing clients', { accountId: input.accountId, filters: { email: input.email, organization: input.organization, visState: input.visState, }, }); const result = await client.executeWithRetry( 'client_list', async (fbClient) => { // Import query builders from SDK const { SearchQueryBuilder, PaginationQueryBuilder } = await import( '@freshbooks/api/dist/models/builders/index.js' ); // Build query builders const queryBuilders: any[] = []; // Add pagination if (input.page || input.perPage) { const pagination = new PaginationQueryBuilder() .page(input.page || 1) .perPage(input.perPage || 30); queryBuilders.push(pagination); } // Add search filters const hasFilters = input.email || input.organization || input.fName || input.lName || input.visState !== undefined; if (hasFilters) { const search = new SearchQueryBuilder(); if (input.email) { search.equals('email', input.email); } if (input.organization) { search.like('organization', input.organization); } if (input.fName) { search.like('fname', input.fName); } if (input.lName) { search.like('lname', input.lName); } if (input.visState !== undefined) { search.equals('vis_state', input.visState); } queryBuilders.push(search); } // Call FreshBooks API const response = await fbClient.clients.list( input.accountId, queryBuilders ); if (!response.ok) { throw response.error; } const clients = response.data?.clients || []; const pagesData = response.data?.pages as any; const pagination = { total: pagesData?.total || 0, page: pagesData?.page || 1, perPage: pagesData?.perPage || pagesData?.per_page || pagesData?.size || 30, pages: pagesData?.pages || 1, }; return { pagination, clients, } as z.infer<typeof ClientListOutputSchema>; } ); logger.info('Clients listed successfully', { count: result.clients.length, total: result.pagination.total, }); return result; } ); return handler(input, { accountId: input.accountId }); }, };

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/Good-Samaritan-Software-LLC/freshbooks-mcp'

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