thunderclient_get_licenses
Retrieve Thunder Client licenses from the API, with an option to fetch specific pages or automatically gather all available data for comprehensive management.
Instructions
Get Thunder Client licenses. If pageNumber is not provided, fetches all pages automatically.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pageNumber | No | Specific page number to fetch (optional, fetches all pages if omitted) |
Input Schema (JSON Schema)
{
"properties": {
"pageNumber": {
"description": "Specific page number to fetch (optional, fetches all pages if omitted)",
"minimum": 1,
"type": "number"
}
},
"required": [],
"type": "object"
}
Implementation Reference
- src/api-client.ts:116-182 (handler)Core handler implementation for thunderclient_get_licenses tool. Handles optional pagination: fetches specific page or all pages by looping through API responses.async getLicenses(request: GetLicensesRequest): Promise<ApiResponse<GetLicensesResponse | PaginatedLicensesResponse>> { const accountNumber = this.getAccountNumber(); try { // If pageNumber is specified, fetch only that page if (request.pageNumber !== undefined) { const result = await this.getLicensesPage(accountNumber, request.pageNumber); if (!result) { return { success: false, error: `Failed to fetch page ${request.pageNumber}` }; } return { success: true, data: result, message: `Retrieved page ${request.pageNumber} of licenses` }; } // If no pageNumber specified, fetch all pages const allLicenses: LicenseInfo[] = []; let currentPage = 1; let totalPages = 1; let totalCount = 0; const maxPages = 100; // Safety limit to prevent infinite loops while (currentPage <= totalPages && currentPage <= maxPages) { const result = await this.getLicensesPage(accountNumber, currentPage); if (!result) { break; } allLicenses.push(...result.licenses); totalPages = result.totalPages; totalCount = result.totalCount; if (!result.hasMore || currentPage >= totalPages) { break; } currentPage++; } const paginatedResponse: PaginatedLicensesResponse = { licenses: allLicenses, totalPages: totalPages, totalCount: totalCount, pagesFetched: currentPage }; return { success: true, data: paginatedResponse, message: `Retrieved ${allLicenses.length} licenses across ${currentPage} page(s)` }; } catch (error) { return { success: false, error: `Request failed: ${error instanceof Error ? error.message : String(error)}` }; } }
- src/index.ts:156-167 (handler)MCP CallToolRequestSchema dispatch handler for thunderclient_get_licenses, delegates to API client and formats response as text content.case 'thunderclient_get_licenses': { const getRequest = (args || {}) as unknown as GetLicensesRequest; const result = await this.apiClient.getLicenses(getRequest); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; }
- src/index.ts:92-106 (registration)Tool registration in ListToolsRequestSchema handler, defining name, description, and input schema.{ name: 'thunderclient_get_licenses', description: 'Get Thunder Client licenses. If pageNumber is not provided, fetches all pages automatically.', inputSchema: { type: 'object', properties: { pageNumber: { type: 'number', description: 'Specific page number to fetch (optional, fetches all pages if omitted)', minimum: 1, }, }, required: [], }, },
- src/api-client.ts:78-111 (helper)Helper function to fetch and transform a single page of licenses from the Thunder Client API endpoint.private async getLicensesPage(accountNumber: string, pageNumber: number): Promise<GetLicensesResponse | null> { const url = new URL(`${this.config.baseUrl}/api/license/query`); url.searchParams.set('accountNumber', accountNumber); url.searchParams.set('pageNumber', pageNumber.toString()); try { const response = await fetch(url.toString(), { method: 'GET', headers: this.getHeaders() }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP ${response.status}: ${response.statusText} - ${errorText}`); } const data = await response.json(); // Thunder Client API uses 'teamMembers' for license data const licenseArray = data.teamMembers || []; // Transform the response to match our expected structure return { licenses: licenseArray, currentPage: pageNumber, totalPages: data.totalPages || 1, totalCount: data.usedSeats || licenseArray.length, hasMore: data.hasMore !== undefined ? data.hasMore : (pageNumber < (data.totalPages || 1)) }; } catch (error) { console.error(`Failed to fetch page ${pageNumber}:`, error); return null; } }
- src/types.ts:10-12 (schema)TypeScript interface defining the input schema for the getLicenses tool (matches MCP inputSchema).export interface GetLicensesRequest { pageNumber?: number; }