Skip to content

Commit a03bf12

Browse files
authored
Merge pull request #8 from grafana/rename-prometheus-tools
2 parents da04f80 + 5dfce67 commit a03bf12

File tree

4 files changed

+56
-48
lines changed

4 files changed

+56
-48
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ This is useful if you don't use certain functionality or if you don't want to ta
3333
| `get_datasource_by_uid` | Datasources | Get a datasource by uid |
3434
| `get_datasource_by_name` | Datasources | Get a datasource by name |
3535
| `query_prometheus` | Prometheus | Execute a query against a Prometheus datasource |
36-
| `get_prometheus_metric_metadata` | Prometheus | Get metadata for a metric |
37-
| `get_prometheus_metric_names` | Prometheus | Get list of available metric names |
38-
| `get_prometheus_label_names` | Prometheus | Get list of label names for a metric |
39-
| `get_prometheus_label_values` | Prometheus | Get values for a specific label |
36+
| `list_prometheus_metric_metadata` | Prometheus | List metric metadata |
37+
| `list_prometheus_metric_names` | Prometheus | List available metric names |
38+
| `list_prometheus_label_names` | Prometheus | List label names matching a selector |
39+
| `list_prometheus_label_values` | Prometheus | List values for a specific label |
4040
| `list_incidents` | Incident | List incidents in Grafana Incident |
4141
| `create_incident` | Incident | Create an incident in Grafana Incident |
4242
| `add_activity_to_incident` | Incident | Add an activity item to an incident in Grafana Incident |

src/mcp_grafana/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ async def query(self, _from: datetime, to: datetime, queries: list[Query]) -> by
151151
}
152152
return await self.post("/api/ds/query", json=body)
153153

154-
async def get_prometheus_metric_metadata(
154+
async def list_prometheus_metric_metadata(
155155
self,
156156
datasource_uid: str,
157157
limit: int | None = None,
@@ -169,7 +169,7 @@ async def get_prometheus_metric_metadata(
169169
f"/api/datasources/proxy/uid/{datasource_uid}/api/v1/metadata", params
170170
)
171171

172-
async def get_prometheus_label_names(
172+
async def list_prometheus_label_names(
173173
self,
174174
datasource_uid: str,
175175
matches: list[Selector] | None = None,
@@ -192,7 +192,7 @@ async def get_prometheus_label_names(
192192
params,
193193
)
194194

195-
async def get_prometheus_label_values(
195+
async def list_prometheus_label_values(
196196
self,
197197
datasource_uid: str,
198198
label_name: str,

src/mcp_grafana/tools/prometheus.py

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import itertools
12
import re
23
from datetime import datetime
34
from typing import Literal
@@ -59,27 +60,28 @@ async def query_prometheus(
5960
return DSQueryResponse.model_validate_json(response)
6061

6162

62-
async def get_prometheus_metric_metadata(
63+
async def list_prometheus_metric_metadata(
6364
datasource_uid: str,
64-
limit: int | None = None,
65-
limit_per_metric: int | None = None,
65+
limit: int = 10,
66+
limit_per_metric: int = 10,
6667
metric: str | None = None,
6768
) -> dict[str, list[PrometheusMetricMetadata]]:
6869
"""
69-
Get metadata for all metrics in Prometheus.
70+
List metadata for all metrics in Prometheus.
7071
7172
# Parameters.
7273
7374
datasource_uid: The uid of the Grafana datasource to query.
74-
limit: Optionally, the maximum number of results to return.
75-
limit_per_metric: Optionally, the maximum number of results to return per metric.
75+
limit: The maximum number of results to return. Defaults to 10.
76+
limit_per_metric: The maximum number of results to return per metric.
77+
Defaults to 10.
7678
metric: Optionally, a metric name to filter the results by.
7779
7880
# Returns.
7981
8082
A mapping from metric name to all available metadata for that metric.
8183
"""
82-
response = await grafana_client.get_prometheus_metric_metadata(
84+
response = await grafana_client.list_prometheus_metric_metadata(
8385
datasource_uid,
8486
limit=limit,
8587
limit_per_metric=limit_per_metric,
@@ -92,39 +94,46 @@ async def get_prometheus_metric_metadata(
9294
)
9395

9496

95-
async def get_prometheus_metric_names(
97+
async def list_prometheus_metric_names(
9698
datasource_uid: str,
9799
regex: str,
100+
limit: int = 10,
101+
page: int = 1,
98102
) -> list[str]:
99103
"""
100-
Get metric names in a Prometheus datasource that match the given regex.
104+
List metric names in a Prometheus datasource that match the given regex.
101105
102106
# Parameters.
103107
104108
datasource_uid: The uid of the Grafana datasource to query.
105109
regex: The regex to match against the metric names. Uses Python's re.match.
110+
limit: The maximum number of results to return. Defaults to 10.
111+
page: The page number to return. Defaults to 1.
106112
107113
# Returns.
108114
109115
A list of metric names that match the given regex.
110116
"""
111-
name_label_values = await get_prometheus_label_values(datasource_uid, "__name__")
117+
name_label_values = await list_prometheus_label_values(datasource_uid, "__name__")
112118
compiled = re.compile(regex)
113-
return [name for name in name_label_values if compiled.match(name)]
119+
matches = (name for name in name_label_values if compiled.match(name))
120+
start = (page - 1) * limit
121+
stop = start + limit
122+
return list(itertools.islice(matches, start, stop))
114123

115124

116-
async def get_prometheus_label_names(
125+
async def list_prometheus_label_names(
117126
datasource_uid: str,
118127
matches: list[Selector] | None = None,
119128
start: datetime | None = None,
120129
end: datetime | None = None,
121-
limit: int | None = None,
130+
limit: int = 100,
122131
) -> list[str]:
123132
"""
124-
Get the label names in a Prometheus datasource, optionally filtered to those
133+
List the label names in a Prometheus datasource, optionally filtered to those
125134
matching the given selectors and within the given time range.
126135
127-
If you want to get the label names for a specific metric, pass a matcher
136+
If you want to list the label names for a specific metric, pass a matcher
128137
like `{__name__="metric_name"}` to the `matches` parameter.
129138
130139
# Parameters.
@@ -133,9 +142,9 @@ async def get_prometheus_label_names(
133142
matches: Optionally, a list of label matchers to filter the results by.
134143
start: Optionally, the start time of the time range to filter the results by.
135144
end: Optionally, the end time of the time range to filter the results by.
136-
limit: Optionally, the maximum number of results to return.
145+
limit: Optionally, the maximum number of results to return. Defaults to 100.
137146
"""
138-
response = await grafana_client.get_prometheus_label_names(
147+
response = await grafana_client.list_prometheus_label_names(
139148
datasource_uid,
140149
matches=matches,
141150
start=start,
@@ -145,13 +154,13 @@ async def get_prometheus_label_names(
145154
return ResponseWrapper[list[str]].model_validate_json(response).data
146155

147156

148-
async def get_prometheus_label_values(
157+
async def list_prometheus_label_values(
149158
datasource_uid: str,
150159
label_name: str,
151160
matches: list[Selector] | None = None,
152161
start: datetime | None = None,
153162
end: datetime | None = None,
154-
limit: int | None = None,
163+
limit: int = 100,
155164
):
156165
"""
157166
Get the values of a label in Prometheus.
@@ -163,9 +172,9 @@ async def get_prometheus_label_values(
163172
matches: Optionally, a list of selectors to filter the results by.
164173
start: Optionally, the start time of the query.
165174
end: Optionally, the end time of the query.
166-
limit: Optionally, the maximum number of results to return.
175+
limit: Optionally, the maximum number of results to return. Defaults to 100.
167176
"""
168-
response = await grafana_client.get_prometheus_label_values(
177+
response = await grafana_client.list_prometheus_label_values(
169178
datasource_uid,
170179
label_name,
171180
matches=matches,
@@ -178,7 +187,7 @@ async def get_prometheus_label_values(
178187

179188
def add_tools(mcp: FastMCP):
180189
mcp.add_tool(query_prometheus)
181-
mcp.add_tool(get_prometheus_metric_metadata)
182-
mcp.add_tool(get_prometheus_metric_names)
183-
mcp.add_tool(get_prometheus_label_names)
184-
mcp.add_tool(get_prometheus_label_values)
190+
mcp.add_tool(list_prometheus_metric_metadata)
191+
mcp.add_tool(list_prometheus_metric_names)
192+
mcp.add_tool(list_prometheus_label_names)
193+
mcp.add_tool(list_prometheus_label_values)

tests/tools/prometheus_test.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
from mcp_grafana.grafana_types import DSQueryResponse, LabelMatcher, Selector
77
from mcp_grafana.tools.prometheus import (
88
query_prometheus,
9-
get_prometheus_metric_metadata,
10-
get_prometheus_metric_names,
11-
get_prometheus_label_names,
12-
get_prometheus_label_values,
9+
list_prometheus_metric_metadata,
10+
list_prometheus_metric_names,
11+
list_prometheus_label_names,
12+
list_prometheus_label_values,
1313
)
1414

1515
from . import mark_integration
@@ -117,23 +117,22 @@ async def test_query_prometheus_empty_result(self):
117117
assert len(query_result.frames[0].data.values) == 0
118118

119119

120-
async def test_get_prometheus_metric_metadata():
120+
async def test_list_prometheus_metric_metadata():
121121
# Test fetching metric metadata
122-
metadata = await get_prometheus_metric_metadata("robustperception", 10)
122+
metadata = await list_prometheus_metric_metadata("robustperception", 10)
123123
assert 0 < len(metadata) <= 10
124124

125125

126-
async def test_get_prometheus_metric_names():
127-
# Test getting list of available metric names
128-
metric_names = await get_prometheus_metric_names("robustperception", ".*")
126+
async def test_list_prometheus_metric_names():
127+
# Test listing available metric names
128+
metric_names = await list_prometheus_metric_names("robustperception", ".*")
129129
assert isinstance(metric_names, list)
130130
assert len(metric_names) > 0
131-
assert "up" in metric_names # 'up' metric should always be present
132131

133132

134-
async def test_get_prometheus_label_names():
135-
# Test getting list of label names for a metric
136-
label_names = await get_prometheus_label_names(
133+
async def test_list_prometheus_label_names():
134+
# Test listing label names for a metric
135+
label_names = await list_prometheus_label_names(
137136
"robustperception",
138137
[Selector(filters=[LabelMatcher(name="job", value="node")])],
139138
)
@@ -142,8 +141,8 @@ async def test_get_prometheus_label_names():
142141
assert "instance" in label_names # 'instance' is a common label
143142

144143

145-
async def test_get_prometheus_label_values():
146-
# Test getting values for a specific label
147-
label_values = await get_prometheus_label_values("robustperception", "job")
144+
async def test_list_prometheus_label_values():
145+
# Test listing values for a specific label
146+
label_values = await list_prometheus_label_values("robustperception", "job")
148147
assert isinstance(label_values, list)
149148
assert len(label_values) > 0

0 commit comments

Comments
 (0)