Skip to content

Commit 4528745

Browse files
Implement cursor-based pagination infrastructure and update repository tools
Co-authored-by: SamMorrowDrums <[email protected]>
1 parent ae7ae23 commit 4528745

File tree

2 files changed

+255
-86
lines changed

2 files changed

+255
-86
lines changed

pkg/github/repositories.go

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func GetCommit(getClient GetClientFn, t translations.TranslationHelperFunc) (too
107107
// ListCommits creates a tool to get commits of a branch in a repository.
108108
func ListCommits(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
109109
return mcp.NewTool("list_commits",
110-
mcp.WithDescription(t("TOOL_LIST_COMMITS_DESCRIPTION", "Get list of commits of a branch in a GitHub repository. Returns at least 30 results per page by default, but can return more if specified using the perPage parameter (up to 100).")),
110+
mcp.WithDescription(t("TOOL_LIST_COMMITS_DESCRIPTION", "Get list of commits of a branch in a GitHub repository. Returns 10 results per page. Use the cursor parameter for pagination.")),
111111
mcp.WithToolAnnotation(mcp.ToolAnnotation{
112112
Title: t("TOOL_LIST_COMMITS_USER_TITLE", "List commits"),
113113
ReadOnlyHint: ToBoolPtr(true),
@@ -145,21 +145,18 @@ func ListCommits(getClient GetClientFn, t translations.TranslationHelperFunc) (t
145145
if err != nil {
146146
return mcp.NewToolResultError(err.Error()), nil
147147
}
148-
pagination, err := OptionalPaginationParams(request)
148+
cursorParams, err := GetCursorBasedParams(request)
149149
if err != nil {
150150
return mcp.NewToolResultError(err.Error()), nil
151151
}
152-
// Set default perPage to 30 if not provided
153-
perPage := pagination.PerPage
154-
if perPage == 0 {
155-
perPage = 30
156-
}
152+
153+
// Request one extra item to check if there are more results
157154
opts := &github.CommitsListOptions{
158155
SHA: sha,
159156
Author: author,
160157
ListOptions: github.ListOptions{
161-
Page: pagination.Page,
162-
PerPage: perPage,
158+
Page: cursorParams.Page,
159+
PerPage: cursorParams.PerPage + 1, // Request one extra
163160
},
164161
}
165162

@@ -185,18 +182,22 @@ func ListCommits(getClient GetClientFn, t translations.TranslationHelperFunc) (t
185182
return mcp.NewToolResultError(fmt.Sprintf("failed to list commits: %s", string(body))), nil
186183
}
187184

185+
// Check if there are more results
186+
hasMore := len(commits) > cursorParams.PerPage
187+
if hasMore {
188+
// Remove the extra item
189+
commits = commits[:cursorParams.PerPage]
190+
}
191+
188192
// Convert to minimal commits
189193
minimalCommits := make([]MinimalCommit, len(commits))
190194
for i, commit := range commits {
191195
minimalCommits[i] = convertToMinimalCommit(commit, false)
192196
}
193197

194-
r, err := json.Marshal(minimalCommits)
195-
if err != nil {
196-
return nil, fmt.Errorf("failed to marshal response: %w", err)
197-
}
198-
199-
return mcp.NewToolResultText(string(r)), nil
198+
// Create paginated response
199+
paginatedResp := NewPaginatedRESTResponse(minimalCommits, cursorParams.Page, cursorParams.PerPage, hasMore)
200+
return MarshalPaginatedResponse(paginatedResp), nil
200201
}
201202
}
202203

@@ -227,15 +228,16 @@ func ListBranches(getClient GetClientFn, t translations.TranslationHelperFunc) (
227228
if err != nil {
228229
return mcp.NewToolResultError(err.Error()), nil
229230
}
230-
pagination, err := OptionalPaginationParams(request)
231+
cursorParams, err := GetCursorBasedParams(request)
231232
if err != nil {
232233
return mcp.NewToolResultError(err.Error()), nil
233234
}
234235

236+
// Request one extra item to check if there are more results
235237
opts := &github.BranchListOptions{
236238
ListOptions: github.ListOptions{
237-
Page: pagination.Page,
238-
PerPage: pagination.PerPage,
239+
Page: cursorParams.Page,
240+
PerPage: cursorParams.PerPage + 1, // Request one extra
239241
},
240242
}
241243

@@ -262,18 +264,22 @@ func ListBranches(getClient GetClientFn, t translations.TranslationHelperFunc) (
262264
return mcp.NewToolResultError(fmt.Sprintf("failed to list branches: %s", string(body))), nil
263265
}
264266

267+
// Check if there are more results
268+
hasMore := len(branches) > cursorParams.PerPage
269+
if hasMore {
270+
// Remove the extra item
271+
branches = branches[:cursorParams.PerPage]
272+
}
273+
265274
// Convert to minimal branches
266275
minimalBranches := make([]MinimalBranch, 0, len(branches))
267276
for _, branch := range branches {
268277
minimalBranches = append(minimalBranches, convertToMinimalBranch(branch))
269278
}
270279

271-
r, err := json.Marshal(minimalBranches)
272-
if err != nil {
273-
return nil, fmt.Errorf("failed to marshal response: %w", err)
274-
}
275-
276-
return mcp.NewToolResultText(string(r)), nil
280+
// Create paginated response
281+
paginatedResp := NewPaginatedRESTResponse(minimalBranches, cursorParams.Page, cursorParams.PerPage, hasMore)
282+
return MarshalPaginatedResponse(paginatedResp), nil
277283
}
278284
}
279285

@@ -1249,14 +1255,15 @@ func ListTags(getClient GetClientFn, t translations.TranslationHelperFunc) (tool
12491255
if err != nil {
12501256
return mcp.NewToolResultError(err.Error()), nil
12511257
}
1252-
pagination, err := OptionalPaginationParams(request)
1258+
cursorParams, err := GetCursorBasedParams(request)
12531259
if err != nil {
12541260
return mcp.NewToolResultError(err.Error()), nil
12551261
}
12561262

1263+
// Request one extra item to check if there are more results
12571264
opts := &github.ListOptions{
1258-
Page: pagination.Page,
1259-
PerPage: pagination.PerPage,
1265+
Page: cursorParams.Page,
1266+
PerPage: cursorParams.PerPage + 1, // Request one extra
12601267
}
12611268

12621269
client, err := getClient(ctx)
@@ -1282,12 +1289,16 @@ func ListTags(getClient GetClientFn, t translations.TranslationHelperFunc) (tool
12821289
return mcp.NewToolResultError(fmt.Sprintf("failed to list tags: %s", string(body))), nil
12831290
}
12841291

1285-
r, err := json.Marshal(tags)
1286-
if err != nil {
1287-
return nil, fmt.Errorf("failed to marshal response: %w", err)
1292+
// Check if there are more results
1293+
hasMore := len(tags) > cursorParams.PerPage
1294+
if hasMore {
1295+
// Remove the extra item
1296+
tags = tags[:cursorParams.PerPage]
12881297
}
12891298

1290-
return mcp.NewToolResultText(string(r)), nil
1299+
// Create paginated response
1300+
paginatedResp := NewPaginatedRESTResponse(tags, cursorParams.Page, cursorParams.PerPage, hasMore)
1301+
return MarshalPaginatedResponse(paginatedResp), nil
12911302
}
12921303
}
12931304

@@ -1405,14 +1416,15 @@ func ListReleases(getClient GetClientFn, t translations.TranslationHelperFunc) (
14051416
if err != nil {
14061417
return mcp.NewToolResultError(err.Error()), nil
14071418
}
1408-
pagination, err := OptionalPaginationParams(request)
1419+
cursorParams, err := GetCursorBasedParams(request)
14091420
if err != nil {
14101421
return mcp.NewToolResultError(err.Error()), nil
14111422
}
14121423

1424+
// Request one extra item to check if there are more results
14131425
opts := &github.ListOptions{
1414-
Page: pagination.Page,
1415-
PerPage: pagination.PerPage,
1426+
Page: cursorParams.Page,
1427+
PerPage: cursorParams.PerPage + 1, // Request one extra
14161428
}
14171429

14181430
client, err := getClient(ctx)
@@ -1434,12 +1446,16 @@ func ListReleases(getClient GetClientFn, t translations.TranslationHelperFunc) (
14341446
return mcp.NewToolResultError(fmt.Sprintf("failed to list releases: %s", string(body))), nil
14351447
}
14361448

1437-
r, err := json.Marshal(releases)
1438-
if err != nil {
1439-
return nil, fmt.Errorf("failed to marshal response: %w", err)
1449+
// Check if there are more results
1450+
hasMore := len(releases) > cursorParams.PerPage
1451+
if hasMore {
1452+
// Remove the extra item
1453+
releases = releases[:cursorParams.PerPage]
14401454
}
14411455

1442-
return mcp.NewToolResultText(string(r)), nil
1456+
// Create paginated response
1457+
paginatedResp := NewPaginatedRESTResponse(releases, cursorParams.Page, cursorParams.PerPage, hasMore)
1458+
return MarshalPaginatedResponse(paginatedResp), nil
14431459
}
14441460
}
14451461

@@ -1733,15 +1749,16 @@ func ListStarredRepositories(getClient GetClientFn, t translations.TranslationHe
17331749
if err != nil {
17341750
return mcp.NewToolResultError(err.Error()), nil
17351751
}
1736-
pagination, err := OptionalPaginationParams(request)
1752+
cursorParams, err := GetCursorBasedParams(request)
17371753
if err != nil {
17381754
return mcp.NewToolResultError(err.Error()), nil
17391755
}
17401756

1757+
// Request one extra item to check if there are more results
17411758
opts := &github.ActivityListStarredOptions{
17421759
ListOptions: github.ListOptions{
1743-
Page: pagination.Page,
1744-
PerPage: pagination.PerPage,
1760+
Page: cursorParams.Page,
1761+
PerPage: cursorParams.PerPage + 1, // Request one extra
17451762
},
17461763
}
17471764
if sort != "" {
@@ -1783,6 +1800,13 @@ func ListStarredRepositories(getClient GetClientFn, t translations.TranslationHe
17831800
return mcp.NewToolResultError(fmt.Sprintf("failed to list starred repositories: %s", string(body))), nil
17841801
}
17851802

1803+
// Check if there are more results
1804+
hasMore := len(repos) > cursorParams.PerPage
1805+
if hasMore {
1806+
// Remove the extra item
1807+
repos = repos[:cursorParams.PerPage]
1808+
}
1809+
17861810
// Convert to minimal format
17871811
minimalRepos := make([]MinimalRepository, 0, len(repos))
17881812
for _, starredRepo := range repos {
@@ -1810,12 +1834,9 @@ func ListStarredRepositories(getClient GetClientFn, t translations.TranslationHe
18101834
minimalRepos = append(minimalRepos, minimalRepo)
18111835
}
18121836

1813-
r, err := json.Marshal(minimalRepos)
1814-
if err != nil {
1815-
return nil, fmt.Errorf("failed to marshal starred repositories: %w", err)
1816-
}
1817-
1818-
return mcp.NewToolResultText(string(r)), nil
1837+
// Create paginated response
1838+
paginatedResp := NewPaginatedRESTResponse(minimalRepos, cursorParams.Page, cursorParams.PerPage, hasMore)
1839+
return MarshalPaginatedResponse(paginatedResp), nil
18191840
}
18201841
}
18211842

0 commit comments

Comments
 (0)