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; } }