Skip to main content
Glama

Grafana MCP Server

by levalhq
prometheus-client.tsโ€ข3.92 kB
import { BaseClient } from './base-client'; import { GrafanaConfig } from '../types/config'; export interface PrometheusQueryResult { metric: Record<string, string>; value?: [number, string]; // [timestamp, value] for instant queries values?: [number, string][]; // Array of [timestamp, value] for range queries } export class PrometheusClient extends BaseClient { constructor(config: GrafanaConfig, datasourceUid: string) { // Use Grafana proxy endpoint for Prometheus queries super(config, `${config.url}/api/datasources/proxy/uid/${datasourceUid}`); } async query(expr: string, time?: string): Promise<PrometheusQueryResult[]> { try { const params: any = { query: expr }; if (time) { params.time = time; } const response = await this.client.get('/api/v1/query', { params }); if (response.data.status !== 'success') { throw new Error(`Prometheus query failed: ${response.data.error}`); } return response.data.data.result; } catch (error) { this.handleError(error); } } async queryRange( expr: string, start: string, end: string, step: string ): Promise<PrometheusQueryResult[]> { try { const response = await this.client.get('/api/v1/query_range', { params: { query: expr, start, end, step, }, }); if (response.data.status !== 'success') { throw new Error(`Prometheus query failed: ${response.data.error}`); } return response.data.data.result; } catch (error) { this.handleError(error); } } async getLabelNames(match?: string[], start?: string, end?: string): Promise<string[]> { try { const params: any = {}; if (match && match.length > 0) { params['match[]'] = match; } if (start) params.start = start; if (end) params.end = end; const response = await this.client.get('/api/v1/labels', { params }); if (response.data.status !== 'success') { throw new Error(`Failed to get label names: ${response.data.error}`); } return response.data.data; } catch (error) { this.handleError(error); } } async getLabelValues( label: string, match?: string[], start?: string, end?: string ): Promise<string[]> { try { const params: any = {}; if (match && match.length > 0) { params['match[]'] = match; } if (start) params.start = start; if (end) params.end = end; const response = await this.client.get(`/api/v1/label/${label}/values`, { params }); if (response.data.status !== 'success') { throw new Error(`Failed to get label values: ${response.data.error}`); } return response.data.data; } catch (error) { this.handleError(error); } } async getMetricMetadata(metric?: string, limit?: number): Promise<any[]> { try { const params: any = {}; if (metric) params.metric = metric; if (limit) params.limit = limit; const response = await this.client.get('/api/v1/metadata', { params }); if (response.data.status !== 'success') { throw new Error(`Failed to get metric metadata: ${response.data.error}`); } return response.data.data; } catch (error) { this.handleError(error); } } async getSeries(match: string[], start?: string, end?: string): Promise<any[]> { try { const params: any = { 'match[]': match }; if (start) params.start = start; if (end) params.end = end; const response = await this.client.get('/api/v1/series', { params }); if (response.data.status !== 'success') { throw new Error(`Failed to get series: ${response.data.error}`); } return response.data.data; } catch (error) { this.handleError(error); } } }

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

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