Skip to main content
Glama
0xteamhq

Grafana MCP Server

by 0xteamhq

fetch_pyroscope_profile

Retrieve performance profiling data from Pyroscope for specified time ranges and criteria to analyze application performance and identify bottlenecks.

Instructions

Fetches a profile from a Pyroscope data source for a given time range

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
data_source_uidYesThe UID of the datasource to query
end_rfc_3339NoEnd time in RFC3339 format
matchersNoPrometheus-style matchers
max_node_depthNoMaximum depth of nodes in the profile
profile_typeYesProfile type to fetch
start_rfc_3339NoStart time in RFC3339 format

Implementation Reference

  • Main execution handler for the fetch_pyroscope_profile tool that queries the Pyroscope datasource via Grafana proxy and returns profile in DOT format.
    export const fetchPyroscopeProfile: ToolDefinition = {
      name: 'fetch_pyroscope_profile',
      description: 'Fetches a profile from a Pyroscope data source for a given time range',
      inputSchema: FetchPyroscopeProfileSchema,
      handler: async (params, context: ToolContext) => {
        try {
          const client = createPyroscopeClient(context.config.grafanaConfig, params.data_source_uid);
          const timeRange = params.start_rfc_3339 || params.end_rfc_3339 
            ? { start: '', end: '' } 
            : getDefaultTimeRange();
          
          const queryParams: any = {
            query: params.profile_type,
            from: params.start_rfc_3339 || timeRange.start,
            until: params.end_rfc_3339 || timeRange.end,
            format: 'dot', // Return in DOT format
          };
          
          if (params.matchers) {
            queryParams.query = `${params.profile_type}${params.matchers}`;
          }
          
          if (params.max_node_depth !== undefined && params.max_node_depth !== -1) {
            queryParams.max_nodes = params.max_node_depth;
          }
          
          const response = await client.get('/pyroscope/render', { params: queryParams });
          
          // Clean up DOT format output
          let dotContent = response.data;
          if (typeof dotContent === 'object') {
            dotContent = JSON.stringify(dotContent, null, 2);
          }
          
          return createToolResult({
            profile_type: params.profile_type,
            format: 'dot',
            content: dotContent,
          });
        } catch (error: any) {
          return createErrorResult(error.response?.data?.message || error.message);
        }
      },
    };
  • Zod input schema validation for the fetch_pyroscope_profile tool parameters.
    const FetchPyroscopeProfileSchema = z.object({
      data_source_uid: z.string().describe('The UID of the datasource to query'),
      profile_type: z.string().describe('Profile type to fetch'),
      start_rfc_3339: z.string().optional().describe('Start time in RFC3339 format'),
      end_rfc_3339: z.string().optional().describe('End time in RFC3339 format'),
      matchers: z.string().optional().describe('Prometheus-style matchers'),
      max_node_depth: z.number().optional().describe('Maximum depth of nodes in the profile'),
    });
  • Local registration function that registers the fetch_pyroscope_profile tool (and other Pyroscope tools) with the MCP server.
    export function registerPyroscopeTools(server: any) {
      server.registerTool(listPyroscopeLabelNames);
      server.registerTool(listPyroscopeLabelValues);
      server.registerTool(listPyroscopeProfileTypes);
      server.registerTool(fetchPyroscopeProfile);
    }
  • src/cli.ts:128-130 (registration)
    Top-level conditional registration of Pyroscope tools (including fetch_pyroscope_profile) in the CLI entrypoint when 'pyroscope' category is enabled.
    if (enabledTools.has('pyroscope')) {
      registerPyroscopeTools(server);
    }
  • Helper function to create Axios client for Pyroscope datasource proxy, used by the handler.
    function createPyroscopeClient(config: any, datasourceUid: string) {
      const headers: any = {
        'User-Agent': 'mcp-grafana/1.0.0',
      };
      
      if (config.serviceAccountToken) {
        headers['Authorization'] = `Bearer ${config.serviceAccountToken}`;
      } else if (config.apiKey) {
        headers['Authorization'] = `Bearer ${config.apiKey}`;
      }
      
      return axios.create({
        baseURL: `${config.url}/api/datasources/proxy/uid/${datasourceUid}`,
        headers,
        timeout: 30000,
      });
    }

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/0xteamhq/mcp-grafana'

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