Skip to content

Commit 0302728

Browse files
authored
Allow filtering of datasources by type (#73)
To reduce the amount of context passed back to the agent it is now possible to do client-side filtering of all datasources to just the type desired. This is implemented using case insensitive Contains so that the type does not have to be perfect.
1 parent a3bf6a6 commit 0302728

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

tools/datasources.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ package tools
33
import (
44
"context"
55
"fmt"
6+
"strings"
67

78
"github.com/mark3labs/mcp-go/server"
89

910
"github.com/grafana/grafana-openapi-client-go/models"
1011
mcpgrafana "github.com/grafana/mcp-grafana"
1112
)
1213

13-
type ListDatasourcesParams struct{}
14+
type ListDatasourcesParams struct {
15+
Type string `json:"type,omitempty" jsonschema:"descripton=The type of datasources to search for. For example, 'prometheus', 'loki', 'tempo', etc..."`
16+
}
1417

1518
type dataSourceSummary struct {
1619
ID int64 `json:"id"`
@@ -22,11 +25,28 @@ type dataSourceSummary struct {
2225

2326
func listDatasources(ctx context.Context, args ListDatasourcesParams) ([]dataSourceSummary, error) {
2427
c := mcpgrafana.GrafanaClientFromContext(ctx)
25-
datasources, err := c.Datasources.GetDataSources()
28+
resp, err := c.Datasources.GetDataSources()
2629
if err != nil {
2730
return nil, fmt.Errorf("list datasources: %w", err)
2831
}
29-
return summarizeDatasources(datasources.Payload), nil
32+
datasources := filterDatasources(resp.Payload, args.Type)
33+
return summarizeDatasources(datasources), nil
34+
}
35+
36+
// filterDatasources returns only datasources of the specified type `t`. If `t`
37+
// is an empty string no filtering is done.
38+
func filterDatasources(datasources models.DataSourceList, t string) models.DataSourceList {
39+
if t == "" {
40+
return datasources
41+
}
42+
filtered := models.DataSourceList{}
43+
t = strings.ToLower(t)
44+
for _, ds := range datasources {
45+
if strings.Contains(strings.ToLower(ds.Type), t) {
46+
filtered = append(filtered, ds)
47+
}
48+
}
49+
return filtered
3050
}
3151

3252
func summarizeDatasources(dataSources models.DataSourceList) []dataSourceSummary {

tools/datasources_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ func TestDatasourcesTools(t *testing.T) {
5757
assert.Len(t, result, 3)
5858
})
5959

60+
t.Run("list datasources for type", func(t *testing.T) {
61+
ctx := newTestContext()
62+
result, err := listDatasources(ctx, ListDatasourcesParams{Type: "Prometheus"})
63+
require.NoError(t, err)
64+
// Only two Prometheus datasources are provisioned in the test environment.
65+
assert.Len(t, result, 2)
66+
})
67+
6068
t.Run("get datasource by uid", func(t *testing.T) {
6169
ctx := newTestContext()
6270
result, err := getDatasourceByUID(ctx, GetDatasourceByUIDParams{

0 commit comments

Comments
 (0)