Skip to main content
Glama
powerdrillai

Powerdrill MCP Server

Official
by powerdrillai

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
NameRequiredDescriptionDefault
datasetIdYesThe ID of the dataset to list data sources from
pageNumberNoThe page number to start listing (default: 1)
pageSizeNoThe number of items on a single page (default: 10)
statusNoFilter 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
          };
        }
      }
    );
  • 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
        };
      }
    }
  • 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;
      }
    }

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/powerdrillai/powerdrill-mcp'

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