Skip to content

Commit 592d905

Browse files
committed
Fix some tools
1 parent 6cda0e7 commit 592d905

File tree

4 files changed

+72
-25
lines changed

4 files changed

+72
-25
lines changed

client.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,16 @@ func GrafanaClientFromContext(ctx context.Context) *client.GrafanaHTTPAPI {
137137
type incidentClientKey struct{}
138138

139139
var ExtractIncidentClientFromEnv server.StdioContextFunc = func(ctx context.Context) context.Context {
140-
grafanaUrl, apiKey := urlAndAPIKeyFromEnv()
141-
incidentUrl := fmt.Sprintf("%s/api/plugins/grafana-incident-app/resources/api", grafanaUrl)
142-
client := incident.NewClient(incidentUrl, apiKey)
140+
grafanaURL, apiKey := urlAndAPIKeyFromEnv()
141+
incidentURL := fmt.Sprintf("%s/api/plugins/grafana-incident-app/resources/api", grafanaURL)
142+
client := incident.NewClient(incidentURL, apiKey)
143143
return context.WithValue(ctx, incidentClientKey{}, client)
144144
}
145145

146146
var ExtractIncidentClientFromHeaders server.SSEContextFunc = func(ctx context.Context, req *http.Request) context.Context {
147-
grafanaUrl, apiKey := urlAndAPIKeyFromHeaders(req)
148-
incidentUrl := fmt.Sprintf("%s/api/plugins/grafana-incident-app/resources/api", grafanaUrl)
149-
client := incident.NewClient(incidentUrl, apiKey)
147+
grafanaURL, apiKey := urlAndAPIKeyFromHeaders(req)
148+
incidentURL := fmt.Sprintf("%s/api/plugins/grafana-incident-app/resources/api", grafanaURL)
149+
client := incident.NewClient(incidentURL, apiKey)
150150
return context.WithValue(ctx, incidentClientKey{}, client)
151151
}
152152

tools/datasources.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var ListDatasourcesTool, ListDatasourcesHandler = mcpgrafana.MustTool(
3333
)
3434

3535
type GetDatasourceByUIDParams struct {
36-
UID string `json:"uid" jsonschema:"description=The uid of the datasource"`
36+
UID string `json:"uid" jsonschema:"required,description=The uid of the datasource"`
3737
}
3838

3939
func getDatasourceByUID(ctx context.Context, args GetDatasourceByUIDParams) (*mcp.CallToolResult, error) {
@@ -56,7 +56,7 @@ var GetDatasourceByUIDTool, GetDatasourceByUIDHandler = mcpgrafana.MustTool(
5656
)
5757

5858
type GetDatasourceByNameParams struct {
59-
Name string `json:"name" jsonschema:"description=The name of the datasource"`
59+
Name string `json:"name" jsonschema:"required,description=The name of the datasource"`
6060
}
6161

6262
func getDatasourceByName(ctx context.Context, args GetDatasourceByNameParams) (*mcp.CallToolResult, error) {

tools/prometheus.go

+22-17
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func promClientFromContext(ctx context.Context, uid string) (promv1.API, error)
3636
}
3737

3838
type ListPrometheusMetricMetadataParams struct {
39-
DatasourceUID string `json:"datasourceUid" jsonschema:"description=The UID of the datasource to query"`
39+
DatasourceUID string `json:"datasourceUid" jsonschema:"required,description=The UID of the datasource to query"`
4040
Limit int `json:"limit" jsonschema:"description=The maximum number of metrics to return"`
4141
LimitPerMetric int `json:"limitPerMetric" jsonschema:"description=The maximum number of metrics to return per metric"`
4242
Metric string `json:"metric" jsonschema:"description=The metric to query"`
@@ -71,9 +71,9 @@ var ListPrometheusMetricMetadataTool, ListPrometheusMetricMetadataHandler = mcpg
7171
)
7272

7373
type QueryPrometheusParams struct {
74-
DatasourceUID string `json:"datasourceUid" jsonschema:"description=The UID of the datasource to query"`
75-
Expr string `json:"expr" jsonschema:"description=The PromQL expression to query"`
76-
StartRFC3339 string `json:"startRfc3339" jsonschema:"description=The start time in RFC3339 format"`
74+
DatasourceUID string `json:"datasourceUid" jsonschema:"required,description=The UID of the datasource to query"`
75+
Expr string `json:"expr" jsonschema:"required,description=The PromQL expression to query"`
76+
StartRFC3339 string `json:"startRfc3339" jsonschema:"required,description=The start time in RFC3339 format"`
7777
EndRFC3339 string `json:"endRfc3339,omitempty" jsonschema:"description=The end time in RFC3339 format. Ignored if queryType is 'instant'"`
7878
StepSeconds int `json:"stepSeconds,omitempty" jsonschema:"description=The time series step size in seconds. Ignored if queryType is 'instant'"`
7979
QueryType string `json:"queryType,omitempty" jsonschema:"description=The type of query to use. Either 'range' or 'instant'"`
@@ -143,7 +143,7 @@ var QueryPrometheusTool, QueryPrometheusHandler = mcpgrafana.MustTool(
143143
)
144144

145145
type ListPrometheusMetricNamesParams struct {
146-
DatasourceUID string `json:"datasourceUid" jsonschema:"description=The UID of the datasource to query"`
146+
DatasourceUID string `json:"datasourceUid" jsonschema:"required,description=The UID of the datasource to query"`
147147
Regex string `json:"regex" jsonschema:"description=The regex to match against the metric names"`
148148
Limit int `json:"limit,omitempty" jsonschema:"description=The maximum number of results to return"`
149149
Page int `json:"page,omitempty" jsonschema:"description=The page number to return"`
@@ -171,15 +171,20 @@ func ListPrometheusMetricNames(ctx context.Context, args ListPrometheusMetricNam
171171
return nil, fmt.Errorf("listing Prometheus metric names: %w", err)
172172
}
173173

174-
// Filter by regex
175-
re, err := regexp.Compile(args.Regex)
176-
if err != nil {
177-
return nil, fmt.Errorf("compiling regex: %w", err)
178-
}
179-
180-
var matches []string
181-
for _, val := range labelValues {
182-
if re.MatchString(string(val)) {
174+
// Filter by regex if provided
175+
matches := []string{}
176+
if args.Regex != "" {
177+
re, err := regexp.Compile(args.Regex)
178+
if err != nil {
179+
return nil, fmt.Errorf("compiling regex: %w", err)
180+
}
181+
for _, val := range labelValues {
182+
if re.MatchString(string(val)) {
183+
matches = append(matches, string(val))
184+
}
185+
}
186+
} else {
187+
for _, val := range labelValues {
183188
matches = append(matches, string(val))
184189
}
185190
}
@@ -232,7 +237,7 @@ func (s Selector) String() string {
232237
}
233238

234239
type ListPrometheusLabelNamesParams struct {
235-
DatasourceUID string `json:"datasourceUid" jsonschema:"description=The UID of the datasource to query"`
240+
DatasourceUID string `json:"datasourceUid" jsonschema:"required,description=The UID of the datasource to query"`
236241
Matches []Selector `json:"matches,omitempty" jsonschema:"description=Optionally, a list of label matchers to filter the results by"`
237242
StartRFC3339 string `json:"startRfc3339,omitempty" jsonschema:"description=Optionally, the start time of the time range to filter the results by"`
238243
EndRFC3339 string `json:"endRfc3339,omitempty" jsonschema:"description=Optionally, the end time of the time range to filter the results by"`
@@ -291,8 +296,8 @@ var ListPrometheusLabelNamesTool, ListPrometheusLabelNamesHandler = mcpgrafana.M
291296
)
292297

293298
type ListPrometheusLabelValuesParams struct {
294-
DatasourceUID string `json:"datasourceUid" jsonschema:"description=The UID of the datasource to query"`
295-
LabelName string `json:"labelName" jsonschema:"description=The name of the label to query"`
299+
DatasourceUID string `json:"datasourceUid" jsonschema:"required,description=The UID of the datasource to query"`
300+
LabelName string `json:"labelName" jsonschema:"required,description=The name of the label to query"`
296301
Matches []Selector `json:"matches,omitempty" jsonschema:"description=Optionally, a list of selectors to filter the results by"`
297302
StartRFC3339 string `json:"startRfc3339,omitempty" jsonschema:"description=Optionally, the start time of the query"`
298303
EndRFC3339 string `json:"endRfc3339,omitempty" jsonschema:"description=Optionally, the end time of the query"`

tools_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ func testToolHandler(ctx context.Context, params testToolParams) (*mcp.CallToolR
2323
return mcp.NewToolResultText(params.Name + ": " + string(rune(params.Value))), nil
2424
}
2525

26+
type emptyToolParams struct{}
27+
28+
func emptyToolHandler(ctx context.Context, params emptyToolParams) (*mcp.CallToolResult, error) {
29+
return mcp.NewToolResultText("empty"), nil
30+
}
31+
2632
func TestConvertTool(t *testing.T) {
2733
t.Run("valid handler conversion", func(t *testing.T) {
2834
tool, handler, err := ConvertTool("test_tool", "A test tool", testToolHandler)
@@ -88,6 +94,42 @@ func TestConvertTool(t *testing.T) {
8894
assert.Equal(t, "test error", err.Error())
8995
})
9096

97+
t.Run("empty handler params", func(t *testing.T) {
98+
tool, handler, err := ConvertTool("empty", "description", emptyToolHandler)
99+
100+
require.NoError(t, err)
101+
require.NotNil(t, tool)
102+
require.NotNil(t, handler)
103+
104+
// Check tool properties
105+
assert.Equal(t, "empty", tool.Name)
106+
assert.Equal(t, "description", tool.Description)
107+
108+
// Check schema properties
109+
assert.Equal(t, "object", tool.InputSchema.Type)
110+
assert.Len(t, tool.InputSchema.Properties, 0)
111+
112+
// Test handler execution
113+
ctx := context.Background()
114+
request := mcp.CallToolRequest{
115+
Params: struct {
116+
Name string "json:\"name\""
117+
Arguments map[string]any "json:\"arguments,omitempty\""
118+
Meta *struct {
119+
ProgressToken mcp.ProgressToken "json:\"progressToken,omitempty\""
120+
} "json:\"_meta,omitempty\""
121+
}{
122+
Name: "empty",
123+
},
124+
}
125+
result, err := handler(ctx, request)
126+
require.NoError(t, err)
127+
require.Len(t, result.Content, 1)
128+
resultString, ok := result.Content[0].(mcp.TextContent)
129+
require.True(t, ok)
130+
assert.Equal(t, "empty", resultString.Text)
131+
})
132+
91133
t.Run("invalid handler types", func(t *testing.T) {
92134
// Test non-function handler
93135
_, _, err := ConvertTool("invalid", "description", "not a function")

0 commit comments

Comments
 (0)