mcp_powerdrill_list_data_sources
List and filter data sources within Powerdrill datasets to manage and analyze data connections for AI-powered insights.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| datasetId | Yes | The ID of the dataset to list data sources from | |
| pageNumber | No | The page number to start listing (default: 1) | |
| pageSize | No | The number of items on a single page (default: 10) | |
| status | No | Filter data sources by status: synching, invalid, synched (comma-separated for multiple) |
Implementation Reference
- src/index.ts:346-442 (registration)Registers the MCP tool 'mcp_powerdrill_list_data_sources' with input schema and inline async handler function that initializes PowerdrillClient and calls listDataSources.server.tool( 'mcp_powerdrill_list_data_sources', { datasetId: z.string().describe('The ID of the dataset to list data sources from'), pageNumber: z.number().optional().describe('The page number to start listing (default: 1)'), pageSize: z.number().optional().describe('The number of items on a single page (default: 10)'), status: z.string().optional().describe('Filter data sources by status: synching, invalid, synched (comma-separated for multiple)') }, async (args, extra) => { try { const { datasetId, pageNumber, pageSize, status } = args; // Initialize Powerdrill client const client = new (await import('./utils/powerdrillClient.js')).PowerdrillClient(); // Fetch data sources const response = await client.listDataSources(datasetId, { pageNumber, pageSize, status }); // Check if response is valid if (!response) { throw new Error(`Empty response received from API`); } if (response.code !== 0) { throw new Error(`API returned error code: ${response.code}, message: ${response.message || 'No message'}`); } if (!response.data || !response.data.records) { throw new Error(`Invalid API response format: missing data.records property`); } const dataSources = response.data.records || []; if (dataSources.length === 0) { return { content: [ { type: "text", text: JSON.stringify({ message: "No data sources found in the dataset", data_sources: [] }, null, 2) } ] }; } // Format the response as MCP content const result = { count: dataSources.length, total: response.data.total_items || dataSources.length, page: response.data.page_number || 1, page_size: response.data.page_size || 10, data_sources: dataSources.map((dataSource: any) => ({ id: dataSource.id, name: dataSource.name, type: dataSource.type, status: dataSource.status, size: dataSource.size, dataset_id: dataSource.dataset_id })) }; // Return the formatted response return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error: any) { console.error(`Error listing data sources: ${error.message}`); console.error(error.stack); // Return error response return { content: [ { type: "text", text: JSON.stringify({ error: `Error listing data sources: ${error.message}`, errorType: error.name, errorStack: process.env.NODE_ENV === 'development' ? error.stack : undefined }, null, 2) } ], isError: true }; } } );
- src/index.ts:354-441 (handler)The main handler function for the tool that destructures args, creates PowerdrillClient instance, calls listDataSources on it, processes the response, and returns formatted JSON content or error.async (args, extra) => { try { const { datasetId, pageNumber, pageSize, status } = args; // Initialize Powerdrill client const client = new (await import('./utils/powerdrillClient.js')).PowerdrillClient(); // Fetch data sources const response = await client.listDataSources(datasetId, { pageNumber, pageSize, status }); // Check if response is valid if (!response) { throw new Error(`Empty response received from API`); } if (response.code !== 0) { throw new Error(`API returned error code: ${response.code}, message: ${response.message || 'No message'}`); } if (!response.data || !response.data.records) { throw new Error(`Invalid API response format: missing data.records property`); } const dataSources = response.data.records || []; if (dataSources.length === 0) { return { content: [ { type: "text", text: JSON.stringify({ message: "No data sources found in the dataset", data_sources: [] }, null, 2) } ] }; } // Format the response as MCP content const result = { count: dataSources.length, total: response.data.total_items || dataSources.length, page: response.data.page_number || 1, page_size: response.data.page_size || 10, data_sources: dataSources.map((dataSource: any) => ({ id: dataSource.id, name: dataSource.name, type: dataSource.type, status: dataSource.status, size: dataSource.size, dataset_id: dataSource.dataset_id })) }; // Return the formatted response return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error: any) { console.error(`Error listing data sources: ${error.message}`); console.error(error.stack); // Return error response return { content: [ { type: "text", text: JSON.stringify({ error: `Error listing data sources: ${error.message}`, errorType: error.name, errorStack: process.env.NODE_ENV === 'development' ? error.stack : undefined }, null, 2) } ], isError: true }; } }
- src/index.ts:348-353 (schema)Zod schema defining the input parameters for the tool: datasetId (required), optional pagination and status filter.{ datasetId: z.string().describe('The ID of the dataset to list data sources from'), pageNumber: z.number().optional().describe('The page number to start listing (default: 1)'), pageSize: z.number().optional().describe('The number of items on a single page (default: 10)'), status: z.string().optional().describe('Filter data sources by status: synching, invalid, synched (comma-separated for multiple)') },
- Helper method in PowerdrillClient class that performs the actual API call to list data sources for a dataset, handling query parameters, HTTP request with axios, error handling, and returning the raw API response.async listDataSources(datasetId: string, options: { pageNumber?: number; pageSize?: number; status?: string | string[]; timeout?: number; } = {}) { const timeout = options.timeout || 30000; // Default 30 second timeout try { // Build query parameters let queryParams = `user_id=${this.config.userId}`; if (options.pageNumber) { queryParams += `&page_number=${options.pageNumber}`; } if (options.pageSize) { queryParams += `&page_size=${options.pageSize}`; } if (options.status) { // Handle array of statuses or single status const statusValue = Array.isArray(options.status) ? options.status.join(',') : options.status; queryParams += `&status=${statusValue}`; } const response = await this.client.get(`/datasets/${datasetId}/datasources?${queryParams}`, { timeout: timeout, validateStatus: (status) => status >= 200 && status < 500 // Don't throw on 4xx errors }); // Handle HTTP errors manually if (response.status >= 400) { throw new Error(`HTTP error ${response.status}: ${response.statusText || 'Unknown error'}`); } // Validate response structure if (!response.data) { throw new Error('Invalid API response: missing data'); } return response.data; } catch (error: any) { if (error.code === 'ECONNABORTED') { console.error(`PowerdrillClient: Request timed out after ${timeout}ms`); throw new Error(`Request timed out after ${timeout}ms`); } if (error.response) { // The request was made and the server responded with a status code console.error(`PowerdrillClient: HTTP error ${error.response.status}`, error.response.data); throw new Error(`API error: ${error.response.status} ${error.response.statusText}`); } else if (error.request) { // The request was made but no response was received console.error('PowerdrillClient: No response received', error.request); throw new Error('No response received from API'); } console.error('PowerdrillClient: Error listing data sources:', error.message); throw error; } }