You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat: add title annotations to all tools
This commit adds the ability to customise tools using `mcp.ToolOption`s,
then updates all calls to `MustTool` to include a title annotation,
which can be displayed in any UIs instead of the non-human-friendly
name.
Co-authored-by: Luccas Quadros <[email protected]>
* feat: add more annotations to tools
Add the read-only, idempotent, and destructive hint annotations to tools
where appropriate.
Co-authored-by: Luccas Quadros <[email protected]>
---------
Co-authored-by: Luccas Quadros <[email protected]>
Copy file name to clipboardExpand all lines: tools/alerting.go
+6Lines changed: 6 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -150,6 +150,8 @@ var ListAlertRules = mcpgrafana.MustTool(
150
150
"Lists Grafana alert rules, returning a summary including UID, title, current state (e.g., 'pending', 'firing', 'inactive'), and labels. Supports filtering by labels using selectors and pagination. Example label selector: `[{'name': 'severity', 'type': '=', 'value': 'critical'}]`. Inactive state means the alert state is normal, not firing",
151
151
listAlertRules,
152
152
mcp.WithTitleAnnotation("List alert rules"),
153
+
mcp.WithIdempotentHintAnnotation(true),
154
+
mcp.WithReadOnlyHintAnnotation(true),
153
155
)
154
156
155
157
typeGetAlertRuleByUIDParamsstruct {
@@ -182,6 +184,8 @@ var GetAlertRuleByUID = mcpgrafana.MustTool(
182
184
"Retrieves the full configuration and detailed status of a specific Grafana alert rule identified by its unique ID (UID). The response includes fields like title, condition, query data, folder UID, rule group, state settings (no data, error), evaluation interval, annotations, and labels.",
@@ -256,6 +260,8 @@ var ListContactPoints = mcpgrafana.MustTool(
256
260
"Lists Grafana notification contact points, returning a summary including UID, name, and type for each. Supports filtering by name - exact match - and limiting the number of results.",
Copy file name to clipboardExpand all lines: tools/dashboard.go
+5Lines changed: 5 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -56,13 +56,16 @@ var GetDashboardByUID = mcpgrafana.MustTool(
56
56
"Retrieves the complete dashboard, including panels, variables, and settings, for a specific dashboard identified by its UID.",
57
57
getDashboardByUID,
58
58
mcp.WithTitleAnnotation("Get dashboard details"),
59
+
mcp.WithIdempotentHintAnnotation(true),
60
+
mcp.WithReadOnlyHintAnnotation(true),
59
61
)
60
62
61
63
varUpdateDashboard=mcpgrafana.MustTool(
62
64
"update_dashboard",
63
65
"Create or update a dashboard",
64
66
updateDashboard,
65
67
mcp.WithTitleAnnotation("Create or update dashboard"),
68
+
mcp.WithDestructiveHintAnnotation(true),
66
69
)
67
70
68
71
typeDashboardPanelQueriesParamsstruct {
@@ -144,6 +147,8 @@ var GetDashboardPanelQueries = mcpgrafana.MustTool(
144
147
"Get the title, query string, and datasource information for each panel in a dashboard. The datasource is an object with fields `uid` (which may be a concrete UID or a template variable like \"$datasource\") and `type`. If the datasource UID is a template variable, it won't be usable directly for queries. Returns an array of objects, each representing a panel, with fields: title, query, and datasource (an object with uid and type).",
Copy file name to clipboardExpand all lines: tools/datasources.go
+6Lines changed: 6 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -69,6 +69,8 @@ var ListDatasources = mcpgrafana.MustTool(
69
69
"List available Grafana datasources. Optionally filter by datasource type (e.g., 'prometheus', 'loki'). Returns a summary list including ID, UID, name, type, and default status.",
70
70
listDatasources,
71
71
mcp.WithTitleAnnotation("List datasources"),
72
+
mcp.WithIdempotentHintAnnotation(true),
73
+
mcp.WithReadOnlyHintAnnotation(true),
72
74
)
73
75
74
76
typeGetDatasourceByUIDParamsstruct {
@@ -93,6 +95,8 @@ var GetDatasourceByUID = mcpgrafana.MustTool(
93
95
"Retrieves detailed information about a specific datasource using its UID. Returns the full datasource model, including name, type, URL, access settings, JSON data, and secure JSON field status.",
94
96
getDatasourceByUID,
95
97
mcp.WithTitleAnnotation("Get datasource by UID"),
98
+
mcp.WithIdempotentHintAnnotation(true),
99
+
mcp.WithReadOnlyHintAnnotation(true),
96
100
)
97
101
98
102
typeGetDatasourceByNameParamsstruct {
@@ -113,6 +117,8 @@ var GetDatasourceByName = mcpgrafana.MustTool(
113
117
"Retrieves detailed information about a specific datasource using its name. Returns the full datasource model, including UID, type, URL, access settings, JSON data, and secure JSON field status.",
114
118
getDatasourceByName,
115
119
mcp.WithTitleAnnotation("Get datasource by name"),
Copy file name to clipboardExpand all lines: tools/incident.go
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -51,6 +51,8 @@ var ListIncidents = mcpgrafana.MustTool(
51
51
"List Grafana incidents. Allows filtering by status ('active', 'resolved') and optionally including drill incidents. Returns a preview list with basic details.",
52
52
listIncidents,
53
53
mcp.WithTitleAnnotation("List incidents"),
54
+
mcp.WithIdempotentHintAnnotation(true),
55
+
mcp.WithReadOnlyHintAnnotation(true),
54
56
)
55
57
56
58
typeCreateIncidentParamsstruct {
@@ -148,4 +150,6 @@ var GetIncident = mcpgrafana.MustTool(
148
150
"Get a single incident by ID. Returns the full incident details including title, status, severity, labels, timestamps, and other metadata.",
Copy file name to clipboardExpand all lines: tools/loki.go
+8Lines changed: 8 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -224,6 +224,8 @@ var ListLokiLabelNames = mcpgrafana.MustTool(
224
224
"Lists all available label names (keys) found in logs within a specified Loki datasource and time range. Returns a list of unique label strings (e.g., `[\"app\", \"env\", \"pod\"]`). If the time range is not provided, it defaults to the last hour.",
225
225
listLokiLabelNames,
226
226
mcp.WithTitleAnnotation("List Loki label names"),
227
+
mcp.WithIdempotentHintAnnotation(true),
228
+
mcp.WithReadOnlyHintAnnotation(true),
227
229
)
228
230
229
231
// ListLokiLabelValuesParams defines the parameters for listing Loki label values
@@ -263,6 +265,8 @@ var ListLokiLabelValues = mcpgrafana.MustTool(
263
265
"Retrieves all unique values associated with a specific `labelName` within a Loki datasource and time range. Returns a list of string values (e.g., for `labelName=\"env\"`, might return `[\"prod\", \"staging\", \"dev\"]`). Useful for discovering filter options. Defaults to the last hour if the time range is omitted.",
// LogStream represents a stream of log entries from Loki
@@ -471,6 +475,8 @@ var QueryLokiLogs = mcpgrafana.MustTool(
471
475
"Executes a LogQL query against a Loki datasource to retrieve log entries or metric values. Returns a list of results, each containing a timestamp, labels, and either a log line (`line`) or a numeric metric value (`value`). Defaults to the last hour, a limit of 10 entries, and 'backward' direction (newest first). Supports full LogQL syntax for log and metric queries (e.g., `{app=\"foo\"} |= \"error\"`, `rate({app=\"bar\"}[1m])`). Prefer using `query_loki_stats` first to check stream size and `list_loki_label_names` and `list_loki_label_values` to verify labels exist.",
472
476
queryLokiLogs,
473
477
mcp.WithTitleAnnotation("Query Loki logs"),
478
+
mcp.WithIdempotentHintAnnotation(true),
479
+
mcp.WithReadOnlyHintAnnotation(true),
474
480
)
475
481
476
482
// fetchStats is a method to fetch stats data from Loki API
@@ -529,6 +535,8 @@ var QueryLokiStats = mcpgrafana.MustTool(
529
535
"Retrieves statistics about log streams matching a given LogQL *selector* within a Loki datasource and time range. Returns an object containing the count of streams, chunks, entries, and total bytes (e.g., `{\"streams\": 5, \"chunks\": 50, \"entries\": 10000, \"bytes\": 512000}`). The `logql` parameter **must** be a simple label selector (e.g., `{app=\"nginx\", env=\"prod\"}`) and does not support line filters, parsers, or aggregations. Defaults to the last hour if the time range is omitted.",
Copy file name to clipboardExpand all lines: tools/oncall.go
+10Lines changed: 10 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -194,6 +194,8 @@ var ListOnCallSchedules = mcpgrafana.MustTool(
194
194
"List Grafana OnCall schedules, optionally filtering by team ID. If a specific schedule ID is provided, retrieves details for only that schedule. Returns a list of schedule summaries including ID, name, team ID, timezone, and shift IDs. Supports pagination.",
195
195
listOnCallSchedules,
196
196
mcp.WithTitleAnnotation("List OnCall schedules"),
197
+
mcp.WithIdempotentHintAnnotation(true),
198
+
mcp.WithReadOnlyHintAnnotation(true),
197
199
)
198
200
199
201
typeGetOnCallShiftParamsstruct {
@@ -219,6 +221,8 @@ var GetOnCallShift = mcpgrafana.MustTool(
219
221
"Get detailed information for a specific Grafana OnCall shift using its ID. A shift represents a designated time period within a schedule when users are actively on-call. Returns the full shift details.",
220
222
getOnCallShift,
221
223
mcp.WithTitleAnnotation("Get OnCall shift"),
224
+
mcp.WithIdempotentHintAnnotation(true),
225
+
mcp.WithReadOnlyHintAnnotation(true),
222
226
)
223
227
224
228
// CurrentOnCallUsers represents the currently on-call users for a schedule
@@ -280,6 +284,8 @@ var GetCurrentOnCallUsers = mcpgrafana.MustTool(
280
284
"Get the list of users currently on-call for a specific Grafana OnCall schedule ID. Returns the schedule ID, name, and a list of detailed user objects for those currently on call.",
281
285
getCurrentOnCallUsers,
282
286
mcp.WithTitleAnnotation("Get current on-call users"),
287
+
mcp.WithIdempotentHintAnnotation(true),
288
+
mcp.WithReadOnlyHintAnnotation(true),
283
289
)
284
290
285
291
typeListOnCallTeamsParamsstruct {
@@ -310,6 +316,8 @@ var ListOnCallTeams = mcpgrafana.MustTool(
310
316
"List teams configured in Grafana OnCall. Returns a list of team objects with their details. Supports pagination.",
311
317
listOnCallTeams,
312
318
mcp.WithTitleAnnotation("List OnCall teams"),
319
+
mcp.WithIdempotentHintAnnotation(true),
320
+
mcp.WithReadOnlyHintAnnotation(true),
313
321
)
314
322
315
323
typeListOnCallUsersParamsstruct {
@@ -354,6 +362,8 @@ var ListOnCallUsers = mcpgrafana.MustTool(
354
362
"List users from Grafana OnCall. Can retrieve all users, a specific user by ID, or filter by username. Returns a list of user objects with their details. Supports pagination.",
@@ -229,6 +233,8 @@ var ListPrometheusMetricNames = mcpgrafana.MustTool(
229
233
"List metric names in a Prometheus datasource. Retrieves all metric names and then filters them locally using the provided regex. Supports pagination.",
Copy file name to clipboardExpand all lines: tools/sift.go
+8Lines changed: 8 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -178,6 +178,8 @@ var GetSiftInvestigation = mcpgrafana.MustTool(
178
178
"Retrieves an existing Sift investigation by its UUID. The ID should be provided as a string in UUID format (e.g. '02adab7c-bf5b-45f2-9459-d71a2c29e11b').",
// FindErrorPatternLogsParams defines the parameters for running an ErrorPatternLogs check
@@ -336,6 +342,7 @@ var FindErrorPatternLogs = mcpgrafana.MustTool(
336
342
"Searches Loki logs for elevated error patterns compared to the last day's average, waits for the analysis to complete, and returns the results including any patterns found.",
337
343
findErrorPatternLogs,
338
344
mcp.WithTitleAnnotation("Find error patterns in logs"),
345
+
mcp.WithReadOnlyHintAnnotation(true),
339
346
)
340
347
341
348
// FindSlowRequestsParams defines the parameters for running an SlowRequests check
@@ -401,6 +408,7 @@ var FindSlowRequests = mcpgrafana.MustTool(
401
408
"Searches relevant Tempo datasources for slow requests, waits for the analysis to complete, and returns the results.",
402
409
findSlowRequests,
403
410
mcp.WithTitleAnnotation("Find slow requests"),
411
+
mcp.WithReadOnlyHintAnnotation(true),
404
412
)
405
413
406
414
// AddSiftTools registers all Sift tools with the MCP server
0 commit comments