Skip to content

Commit ae5f1b2

Browse files
committed
Implement pagination for ListDiscussionCategories
1 parent bc5abbd commit ae5f1b2

3 files changed

Lines changed: 58 additions & 11 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,10 @@ export GITHUB_MCP_TOOL_ADD_ISSUE_COMMENT_DESCRIPTION="an alternative description
643643
- **list_discussion_categories** - List discussion categories for a repository, with their IDs and names
644644
- `owner`: Repository owner (string, required)
645645
- `repo`: Repository name (string, required)
646+
- `first`: Pagination - Number of categories to return per page (number, optional, min 1, max 100)
647+
- `last`: Pagination - Number of categories to return from the end (number, optional, min 1, max 100)
648+
- `after`: Pagination - Cursor to start with (string, optional)
649+
- `before`: Pagination - Cursor to end with (string, optional)
646650

647651
## Resources
648652

pkg/github/discussions.go

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,51 @@ func ListDiscussionCategories(getGQLClient GetGQLClientFn, t translations.Transl
315315
mcp.Required(),
316316
mcp.Description("Repository name"),
317317
),
318+
mcp.WithNumber("first",
319+
mcp.Description("Number of categories to return per page (min 1, max 100)"),
320+
mcp.Min(1),
321+
mcp.Max(100),
322+
),
323+
mcp.WithNumber("last",
324+
mcp.Description("Number of categories to return from the end (min 1, max 100)"),
325+
mcp.Min(1),
326+
mcp.Max(100),
327+
),
328+
mcp.WithString("after",
329+
mcp.Description("Cursor for pagination, use the 'after' field from the previous response"),
330+
),
331+
mcp.WithString("before",
332+
mcp.Description("Cursor for pagination, use the 'before' field from the previous response"),
333+
),
318334
),
319335
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
320-
owner, err := requiredParam[string](request, "owner")
321-
if err != nil {
322-
return mcp.NewToolResultError(err.Error()), nil
336+
// Decode params
337+
var params struct {
338+
Owner string
339+
Repo string
340+
First int32
341+
Last int32
342+
After string
343+
Before string
323344
}
324-
repo, err := requiredParam[string](request, "repo")
325-
if err != nil {
345+
if err := mapstructure.Decode(request.Params.Arguments, &params); err != nil {
326346
return mcp.NewToolResultError(err.Error()), nil
327347
}
348+
349+
// Validate pagination parameters
350+
if params.First != 0 && params.Last != 0 {
351+
return mcp.NewToolResultError("only one of 'first' or 'last' may be specified"), nil
352+
}
353+
if params.After != "" && params.Before != "" {
354+
return mcp.NewToolResultError("only one of 'after' or 'before' may be specified"), nil
355+
}
356+
if params.After != "" && params.Last != 0 {
357+
return mcp.NewToolResultError("'after' cannot be used with 'last'. Did you mean to use 'before' instead?"), nil
358+
}
359+
if params.Before != "" && params.First != 0 {
360+
return mcp.NewToolResultError("'before' cannot be used with 'first'. Did you mean to use 'after' instead?"), nil
361+
}
362+
328363
client, err := getGQLClient(ctx)
329364
if err != nil {
330365
return mcp.NewToolResultError(fmt.Sprintf("failed to get GitHub GQL client: %v", err)), nil
@@ -336,12 +371,16 @@ func ListDiscussionCategories(getGQLClient GetGQLClientFn, t translations.Transl
336371
ID githubv4.ID
337372
Name githubv4.String
338373
}
339-
} `graphql:"discussionCategories(first: 30)"`
374+
} `graphql:"discussionCategories(first: $first, last: $last, after: $after, before: $before)"`
340375
} `graphql:"repository(owner: $owner, name: $repo)"`
341376
}
342377
vars := map[string]interface{}{
343-
"owner": githubv4.String(owner),
344-
"repo": githubv4.String(repo),
378+
"owner": githubv4.String(params.Owner),
379+
"repo": githubv4.String(params.Repo),
380+
"first": githubv4.Int(params.First),
381+
"last": githubv4.Int(params.Last),
382+
"after": githubv4.String(params.After),
383+
"before": githubv4.String(params.Before),
345384
}
346385
if err := client.Query(ctx, &q, vars); err != nil {
347386
return mcp.NewToolResultError(err.Error()), nil

pkg/github/discussions_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,12 +410,16 @@ func Test_ListDiscussionCategories(t *testing.T) {
410410
ID githubv4.ID
411411
Name githubv4.String
412412
}
413-
} `graphql:"discussionCategories(first: 30)"`
413+
} `graphql:"discussionCategories(first: $first, last: $last, after: $after, before: $before)"`
414414
} `graphql:"repository(owner: $owner, name: $repo)"`
415415
}
416416
vars := map[string]interface{}{
417-
"owner": githubv4.String("owner"),
418-
"repo": githubv4.String("repo"),
417+
"owner": githubv4.String("owner"),
418+
"repo": githubv4.String("repo"),
419+
"first": githubv4.Int(0),
420+
"last": githubv4.Int(0),
421+
"after": githubv4.String(""),
422+
"before": githubv4.String(""),
419423
}
420424
mockResp := githubv4mock.DataResponse(map[string]any{
421425
"repository": map[string]any{

0 commit comments

Comments
 (0)