Skip to content

Commit 9287a51

Browse files
Alerting: Add support for getting alert rule information (#58)
* Alerting: Add support for getting alert rule information * Alerting tool: add tool-level pagination * Add filtering by labels * Use prometheus labels Matcher for comparison
1 parent 6ea6df6 commit 9287a51

File tree

9 files changed

+994
-24
lines changed

9 files changed

+994
-24
lines changed

Diff for: README.md

+28-20
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,40 @@ This provides access to your Grafana instance and the surrounding ecosystem.
2727
- [x] Stats
2828
- [x] Search, create, update and close incidents
2929
- [ ] Start Sift investigations and view the results
30+
- [ ] Alerting
31+
- [x] List and fetch alert rule information
32+
- [ ] Get alert rule statuses (firing/normal/error/etc.)
33+
- [ ] Create and change alert rules
34+
- [ ] List contact points
35+
- [ ] Create and change contact points
3036

3137
The list of tools is configurable, so you can choose which tools you want to make available to the MCP client.
3238
This is useful if you don't use certain functionality or if you don't want to take up too much of the context window.
3339

3440
### Tools
3541

36-
| Tool | Category | Description |
37-
| --- | --- | --- |
38-
| `search_dashboards` | Search | Search for dashboards |
39-
| `get_dashboard_by_uid` | Dashboard | Get a dashboard by uid |
40-
| `list_datasources` | Datasources | List datasources |
41-
| `get_datasource_by_uid` | Datasources | Get a datasource by uid |
42-
| `get_datasource_by_name` | Datasources | Get a datasource by name |
43-
| `query_prometheus` | Prometheus | Execute a query against a Prometheus datasource |
44-
| `list_prometheus_metric_metadata` | Prometheus | List metric metadata |
45-
| `list_prometheus_metric_names` | Prometheus | List available metric names |
46-
| `list_prometheus_label_names` | Prometheus | List label names matching a selector |
47-
| `list_prometheus_label_values` | Prometheus | List values for a specific label |
48-
| `list_incidents` | Incident | List incidents in Grafana Incident |
49-
| `create_incident` | Incident | Create an incident in Grafana Incident |
50-
| `add_activity_to_incident` | Incident | Add an activity item to an incident in Grafana Incident |
51-
| `resolve_incident` | Incident | Resolve an incident in Grafana Incident |
52-
| `query_loki_logs` | Loki | Query and retrieve logs using LogQL (either log or metric queries) |
53-
| `list_loki_label_names` | Loki | List all available label names in logs |
54-
| `list_loki_label_values` | Loki | List values for a specific log label |
55-
| `query_loki_stats` | Loki | Get statistics about log streams |
42+
| Tool | Category | Description |
43+
|-----------------------------------|-------------|--------------------------------------------------------------------|
44+
| `search_dashboards` | Search | Search for dashboards |
45+
| `get_dashboard_by_uid` | Dashboard | Get a dashboard by uid |
46+
| `list_datasources` | Datasources | List datasources |
47+
| `get_datasource_by_uid` | Datasources | Get a datasource by uid |
48+
| `get_datasource_by_name` | Datasources | Get a datasource by name |
49+
| `query_prometheus` | Prometheus | Execute a query against a Prometheus datasource |
50+
| `list_prometheus_metric_metadata` | Prometheus | List metric metadata |
51+
| `list_prometheus_metric_names` | Prometheus | List available metric names |
52+
| `list_prometheus_label_names` | Prometheus | List label names matching a selector |
53+
| `list_prometheus_label_values` | Prometheus | List values for a specific label |
54+
| `list_incidents` | Incident | List incidents in Grafana Incident |
55+
| `create_incident` | Incident | Create an incident in Grafana Incident |
56+
| `add_activity_to_incident` | Incident | Add an activity item to an incident in Grafana Incident |
57+
| `resolve_incident` | Incident | Resolve an incident in Grafana Incident |
58+
| `query_loki_logs` | Loki | Query and retrieve logs using LogQL (either log or metric queries) |
59+
| `list_loki_label_names` | Loki | List all available label names in logs |
60+
| `list_loki_label_values` | Loki | List values for a specific log label |
61+
| `query_loki_stats` | Loki | Get statistics about log streams |
62+
| `list_alert_rules` | Alerting | List alert rules |
63+
| `get_alert_rule_by_uid` | Alerting | Get alert rule by UID |
5664

5765
## Usage
5866

Diff for: cmd/mcp-grafana/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func newServer() *server.MCPServer {
2323
tools.AddIncidentTools(s)
2424
tools.AddPrometheusTools(s)
2525
tools.AddLokiTools(s)
26+
tools.AddAlertingTools(s)
2627
tools.AddDashboardTools(s)
2728
return s
2829
}

Diff for: go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/mark3labs/mcp-go v0.15.0
1111
github.com/prometheus/client_golang v1.21.0
1212
github.com/prometheus/common v0.62.0
13+
github.com/prometheus/prometheus v0.302.1
1314
github.com/stretchr/testify v1.10.0
1415
)
1516

@@ -32,6 +33,7 @@ require (
3233
github.com/go-openapi/swag v0.23.0 // indirect
3334
github.com/go-openapi/validate v0.24.0 // indirect
3435
github.com/google/uuid v1.6.0 // indirect
36+
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
3537
github.com/josharian/intern v1.0.0 // indirect
3638
github.com/jpillora/backoff v1.0.0 // indirect
3739
github.com/json-iterator/go v1.1.12 // indirect
@@ -52,7 +54,6 @@ require (
5254
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
5355
go.opentelemetry.io/otel v1.34.0 // indirect
5456
go.opentelemetry.io/otel/metric v1.34.0 // indirect
55-
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
5657
go.opentelemetry.io/otel/trace v1.34.0 // indirect
5758
golang.org/x/net v0.34.0 // indirect
5859
golang.org/x/oauth2 v0.25.0 // indirect

Diff for: go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ github.com/grafana/grafana-openapi-client-go v0.0.0-20250108132429-8d7e1f158f65
4646
github.com/grafana/grafana-openapi-client-go v0.0.0-20250108132429-8d7e1f158f65/go.mod h1:hiZnMmXc9KXNUlvkV2BKFsiWuIFF/fF4wGgYWEjBitI=
4747
github.com/grafana/incident-go v0.0.0-20250211094540-dc6a98fdae43 h1:+MCsOKi5BJ1wO3PRj3eDNxCScYwE2IcKNW1t8OcTarE=
4848
github.com/grafana/incident-go v0.0.0-20250211094540-dc6a98fdae43/go.mod h1:3QDfdZOWKRxNhMJFL+0C/+12+jLNHDlt0VKNr/i9Daw=
49+
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248=
50+
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
4951
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
5052
github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
5153
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -92,6 +94,8 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
9294
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
9395
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
9496
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
97+
github.com/prometheus/prometheus v0.302.1 h1:xqVdrwrB4WNpdgJqxsz5loqFWNUZitsK8myqLuSZ6Ag=
98+
github.com/prometheus/prometheus v0.302.1/go.mod h1:YcyCoTbUR/TM8rY3Aoeqr0AWTu/pu1Ehh+trpX3eRzg=
9599
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
96100
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
97101
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

Diff for: testdata/provisioning/alerting/alert_rules.yaml

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
apiVersion: 1
2+
3+
groups:
4+
- orgId: 1
5+
name: Test Alert Rules
6+
folder: Test Alerts
7+
interval: 1m
8+
rules:
9+
- uid: test_alert_rule_1
10+
title: Test Alert Rule 1
11+
condition: B
12+
data:
13+
- refId: A
14+
relativeTimeRange:
15+
from: 600
16+
to: 0
17+
datasourceUid: prometheus
18+
model:
19+
datasource:
20+
type: prometheus
21+
uid: prometheus
22+
editorMode: code
23+
expr: vector(1)
24+
hide: false
25+
instant: true
26+
legendFormat: __auto
27+
range: false
28+
refId: A
29+
- refId: B
30+
datasourceUid: __expr__
31+
model:
32+
conditions:
33+
- evaluator:
34+
params:
35+
- 0
36+
- 0
37+
type: gt
38+
operator:
39+
type: and
40+
query:
41+
params: []
42+
reducer:
43+
params: []
44+
type: avg
45+
type: query
46+
datasource:
47+
name: Expression
48+
type: __expr__
49+
uid: __expr__
50+
expression: A
51+
hide: false
52+
refId: B
53+
type: threshold
54+
noDataState: NoData
55+
execErrState: Error
56+
for: 1m
57+
keepFiringFor: 0s
58+
annotations:
59+
description: This is a test alert rule that is always firing
60+
labels:
61+
severity: info
62+
type: test
63+
rule: first
64+
isPaused: false
65+
66+
- uid: test_alert_rule_2
67+
title: Test Alert Rule 2
68+
condition: B
69+
data:
70+
- refId: A
71+
relativeTimeRange:
72+
from: 600
73+
to: 0
74+
datasourceUid: prometheus
75+
model:
76+
datasource:
77+
type: prometheus
78+
uid: prometheus
79+
editorMode: code
80+
expr: vector(0)
81+
hide: false
82+
instant: true
83+
legendFormat: __auto
84+
range: false
85+
refId: A
86+
- refId: B
87+
datasourceUid: __expr__
88+
model:
89+
conditions:
90+
- evaluator:
91+
params:
92+
- 0
93+
- 0
94+
type: gt
95+
operator:
96+
type: and
97+
query:
98+
params: []
99+
reducer:
100+
params: []
101+
type: avg
102+
type: query
103+
datasource:
104+
name: Expression
105+
type: __expr__
106+
uid: __expr__
107+
expression: A
108+
hide: false
109+
refId: B
110+
type: threshold
111+
noDataState: NoData
112+
execErrState: Error
113+
for: 1m
114+
keepFiringFor: 0s
115+
annotations:
116+
description: This is a test alert rule that is always normal
117+
labels:
118+
severity: info
119+
type: test
120+
rule: second
121+
isPaused: false
122+
123+
- uid: test_alert_rule_paused
124+
title: Test Alert Rule (Paused)
125+
condition: B
126+
data:
127+
- refId: A
128+
relativeTimeRange:
129+
from: 600
130+
to: 0
131+
datasourceUid: prometheus
132+
model:
133+
datasource:
134+
type: prometheus
135+
uid: prometheus
136+
editorMode: code
137+
expr: vector(1)
138+
hide: false
139+
instant: true
140+
legendFormat: __auto
141+
range: false
142+
refId: A
143+
- refId: B
144+
datasourceUid: __expr__
145+
model:
146+
conditions:
147+
- evaluator:
148+
params:
149+
- 0
150+
- 0
151+
type: gt
152+
operator:
153+
type: and
154+
query:
155+
params: []
156+
reducer:
157+
params: []
158+
type: avg
159+
type: query
160+
datasource:
161+
name: Expression
162+
type: __expr__
163+
uid: __expr__
164+
expression: A
165+
hide: false
166+
refId: B
167+
type: threshold
168+
noDataState: NoData
169+
execErrState: Error
170+
for: 1m
171+
keepFiringFor: 0s
172+
annotations:
173+
description: This is a paused alert rule
174+
labels:
175+
severity: info
176+
type: test
177+
rule: third
178+
isPaused: true

0 commit comments

Comments
 (0)