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,
      });
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states the basic action without behavioral details. It doesn't disclose whether this is a read-only operation, potential side effects (e.g., rate limits, authentication needs), response format, or error handling. For a tool with 6 parameters and no output schema, this leaves significant gaps in understanding how the tool behaves beyond its inputs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste—it directly states the tool's purpose without fluff. It's appropriately sized for a straightforward fetch operation and front-loaded with the core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (6 parameters, no annotations, no output schema), the description is incomplete. It doesn't address what the tool returns (e.g., profile data structure), error conditions, or behavioral constraints. For a data-fetching tool with multiple inputs, more context is needed to guide effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 6 parameters (e.g., data_source_uid, profile_type). The description adds minimal value beyond the schema by implying time-range usage but doesn't explain parameter interactions or provide examples (e.g., format for matchers). Baseline 3 is appropriate as the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('fetches') and resource ('a profile from a Pyroscope data source') with specific context ('for a given time range'). It distinguishes from siblings like list_pyroscope_profile_types or query_prometheus by focusing on profile retrieval rather than listing or querying metrics. However, it doesn't explicitly differentiate from tools like get_sift_analysis that might involve similar data retrieval patterns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing a valid data source UID), when-not scenarios (e.g., for real-time vs. historical data), or direct alternatives among siblings like list_pyroscope_profile_types for discovery. Usage is implied by the action but not explicitly framed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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