Skip to content

Commit c23ac4a

Browse files
authored
Merge pull request #45 from buildkite/feat_link_header
feat: add the link header to list results
2 parents 5b29e47 + 73b151f commit c23ac4a

12 files changed

Lines changed: 54 additions & 14 deletions

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/buildkite/buildkite-mcp-server
33
go 1.24.2
44

55
require (
6-
github.com/alecthomas/kong v1.10.0
6+
github.com/alecthomas/kong v1.11.0
77
github.com/buildkite/go-buildkite/v4 v4.1.0
88
github.com/buildkite/terminal-to-html/v3 v3.16.8
99
github.com/huantt/plaintext-extractor v1.1.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
22
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
3-
github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw=
4-
github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
3+
github.com/alecthomas/kong v1.11.0 h1:y++1gI7jf8O7G7l4LZo5ASFhrhJvzc+WgF/arranEmM=
4+
github.com/alecthomas/kong v1.11.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
55
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
66
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
77
github.com/buildkite/go-buildkite/v4 v4.1.0 h1:n1f3EAe8/64ju9QjSWJYMjD8++mn1pOLK/tZscD5DKo=

internal/buildkite/artifacts.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,14 @@ func ListArtifacts(ctx context.Context, client ArtifactsClient) (tool mcp.Tool,
107107
return mcp.NewToolResultError(fmt.Sprintf("failed to get issue: %s", string(body))), nil
108108
}
109109

110-
r, err := json.Marshal(artifacts)
110+
result := PaginatedResult[buildkite.Artifact]{
111+
Items: artifacts,
112+
Headers: map[string]string{
113+
"Link": resp.Header.Get("Link"),
114+
},
115+
}
116+
117+
r, err := json.Marshal(result)
111118
if err != nil {
112119
return nil, fmt.Errorf("failed to marshal artifacts: %w", err)
113120
}

internal/buildkite/buildkite.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import (
55
"github.com/mark3labs/mcp-go/mcp"
66
)
77

8+
type PaginatedResult[T any] struct {
9+
Headers map[string]string `json:"headers"`
10+
Items []T `json:"items"`
11+
}
12+
813
func optionalPaginationParams(r mcp.CallToolRequest) (buildkite.ListOptions, error) {
914
page := r.GetInt("page", 1)
1015
perPage := r.GetInt("perPage", 1)

internal/buildkite/builds.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,14 @@ func ListBuilds(ctx context.Context, client BuildsClient) (tool mcp.Tool, handle
7777
return mcp.NewToolResultError(fmt.Sprintf("failed to get issue: %s", string(body))), nil
7878
}
7979

80-
r, err := json.Marshal(&builds)
80+
result := PaginatedResult[buildkite.Build]{
81+
Items: builds,
82+
Headers: map[string]string{
83+
"Link": resp.Header.Get("Link"),
84+
},
85+
}
86+
87+
r, err := json.Marshal(&result)
8188
if err != nil {
8289
return nil, fmt.Errorf("failed to marshal builds: %w", err)
8390
}

internal/buildkite/builds_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ func TestListBuilds(t *testing.T) {
102102

103103
textContent := getTextResult(t, result)
104104

105-
assert.Equal(`[{"id":"123","number":1,"state":"running","author":{},"created_at":"0001-01-01T00:00:00Z","creator":{"avatar_url":"","created_at":null,"email":"","id":"","name":""}}]`, textContent.Text)
106-
105+
assert.Equal(`{"headers":{"Link":""},"items":[{"id":"123","number":1,"state":"running","author":{},"created_at":"0001-01-01T00:00:00Z","creator":{"avatar_url":"","created_at":null,"email":"","id":"","name":""}}]}`, textContent.Text)
106+
107107
// Verify default pagination parameters - ensure they are set to 1 per page
108108
assert.NotNil(capturedOptions)
109109
assert.Equal(1, capturedOptions.Page)
@@ -151,4 +151,4 @@ func TestListBuildsWithCustomPagination(t *testing.T) {
151151
assert.NotNil(capturedOptions)
152152
assert.Equal(3, capturedOptions.Page)
153153
assert.Equal(50, capturedOptions.PerPage)
154-
}
154+
}

internal/buildkite/cluster_queue.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,14 @@ func ListClusterQueues(ctx context.Context, client ClusterQueuesClient) (tool mc
7272
return mcp.NewToolResultText("No clusters found"), nil
7373
}
7474

75-
r, err := json.Marshal(queues)
75+
result := PaginatedResult[buildkite.ClusterQueue]{
76+
Items: queues,
77+
Headers: map[string]string{
78+
"Link": resp.Header.Get("Link"),
79+
},
80+
}
81+
82+
r, err := json.Marshal(&result)
7683
if err != nil {
7784
return nil, fmt.Errorf("failed to marshal cluster queues response: %w", err)
7885
}

internal/buildkite/cluster_queue_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestListClusterQueues(t *testing.T) {
5959
assert.NoError(err)
6060

6161
textContent := getTextResult(t, result)
62-
assert.Equal("[{\"id\":\"queue-id\",\"created_by\":{}}]", textContent.Text)
62+
assert.Equal(`{"headers":{"Link":""},"items":[{"id":"queue-id","created_by":{}}]}`, textContent.Text)
6363
}
6464

6565
func TestGetClusterQueue(t *testing.T) {

internal/buildkite/clusters.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,14 @@ func ListClusters(ctx context.Context, client ClustersClient) (tool mcp.Tool, ha
6262
return mcp.NewToolResultText("No clusters found"), nil
6363
}
6464

65-
r, err := json.Marshal(clusters)
65+
result := PaginatedResult[buildkite.Cluster]{
66+
Items: clusters,
67+
Headers: map[string]string{
68+
"Link": resp.Header.Get("Link"),
69+
},
70+
}
71+
72+
r, err := json.Marshal(&result)
6673
if err != nil {
6774
return nil, fmt.Errorf("failed to marshal clusters response: %w", err)
6875
}

internal/buildkite/clusters_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestListClusters(t *testing.T) {
5959
assert.NoError(err)
6060

6161
textContent := getTextResult(t, result)
62-
assert.Equal("[{\"id\":\"cluster-id\",\"name\":\"cluster-name\",\"created_by\":{}}]", textContent.Text)
62+
assert.Equal(`{"headers":{"Link":""},"items":[{"id":"cluster-id","name":"cluster-name","created_by":{}}]}`, textContent.Text)
6363
}
6464

6565
func TestGetCluster(t *testing.T) {

0 commit comments

Comments
 (0)