@@ -286,6 +286,7 @@ func GetDiscussionComments(getGQLClient GetGQLClientFn, t translations.Translati
286
286
mcp .WithString ("owner" , mcp .Required (), mcp .Description ("Repository owner" )),
287
287
mcp .WithString ("repo" , mcp .Required (), mcp .Description ("Repository name" )),
288
288
mcp .WithNumber ("discussionNumber" , mcp .Required (), mcp .Description ("Discussion Number" )),
289
+ WithGraphQLPagination (),
289
290
),
290
291
func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
291
292
// Decode params
@@ -298,6 +299,17 @@ func GetDiscussionComments(getGQLClient GetGQLClientFn, t translations.Translati
298
299
return mcp .NewToolResultError (err .Error ()), nil
299
300
}
300
301
302
+ paginationParams , err := OptionalGraphQLPaginationParams (request )
303
+ if err != nil {
304
+ return mcp .NewToolResultError (err .Error ()), nil
305
+ }
306
+
307
+ // Use default of 100 if neither first nor last is specified
308
+ if paginationParams .First == nil && paginationParams .Last == nil {
309
+ defaultFirst := int32 (100 )
310
+ paginationParams .First = & defaultFirst
311
+ }
312
+
301
313
client , err := getGQLClient (ctx )
302
314
if err != nil {
303
315
return mcp .NewToolResultError (fmt .Sprintf ("failed to get GitHub GQL client: %v" , err )), nil
@@ -310,24 +322,39 @@ func GetDiscussionComments(getGQLClient GetGQLClientFn, t translations.Translati
310
322
Nodes []struct {
311
323
Body githubv4.String
312
324
}
313
- } `graphql:"comments(first:100)"`
325
+ PageInfo struct {
326
+ HasNextPage githubv4.Boolean
327
+ EndCursor githubv4.String
328
+ }
329
+ } `graphql:"comments(first: $first, after: $after)"`
314
330
} `graphql:"discussion(number: $discussionNumber)"`
315
331
} `graphql:"repository(owner: $owner, name: $repo)"`
316
332
}
317
333
vars := map [string ]interface {}{
318
334
"owner" : githubv4 .String (params .Owner ),
319
335
"repo" : githubv4 .String (params .Repo ),
320
336
"discussionNumber" : githubv4 .Int (params .DiscussionNumber ),
337
+ "first" : (* githubv4 .Int )(paginationParams .First ),
338
+ "after" : (* githubv4 .String )(paginationParams .After ),
321
339
}
322
340
if err := client .Query (ctx , & q , vars ); err != nil {
323
341
return mcp .NewToolResultError (err .Error ()), nil
324
342
}
343
+
325
344
var comments []* github.IssueComment
326
345
for _ , c := range q .Repository .Discussion .Comments .Nodes {
327
346
comments = append (comments , & github.IssueComment {Body : github .Ptr (string (c .Body ))})
328
347
}
329
348
330
- out , err := json .Marshal (comments )
349
+ result := map [string ]interface {}{
350
+ "comments" : comments ,
351
+ "pageInfo" : map [string ]interface {}{
352
+ "hasNextPage" : bool (q .Repository .Discussion .Comments .PageInfo .HasNextPage ),
353
+ "endCursor" : string (q .Repository .Discussion .Comments .PageInfo .EndCursor ),
354
+ },
355
+ }
356
+
357
+ out , err := json .Marshal (result )
331
358
if err != nil {
332
359
return nil , fmt .Errorf ("failed to marshal comments: %w" , err )
333
360
}
@@ -351,80 +378,75 @@ func ListDiscussionCategories(getGQLClient GetGQLClientFn, t translations.Transl
351
378
mcp .Required (),
352
379
mcp .Description ("Repository name" ),
353
380
),
354
- mcp .WithNumber ("first" ,
355
- mcp .Description ("Number of categories to return per page (min 1, max 100)" ),
356
- mcp .Min (1 ),
357
- mcp .Max (100 ),
358
- ),
359
- mcp .WithNumber ("last" ,
360
- mcp .Description ("Number of categories to return from the end (min 1, max 100)" ),
361
- mcp .Min (1 ),
362
- mcp .Max (100 ),
363
- ),
364
- mcp .WithString ("after" ,
365
- mcp .Description ("Cursor for pagination, use the 'after' field from the previous response" ),
366
- ),
367
- mcp .WithString ("before" ,
368
- mcp .Description ("Cursor for pagination, use the 'before' field from the previous response" ),
369
- ),
381
+ WithGraphQLPagination (),
370
382
),
371
383
func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
372
384
// Decode params
373
385
var params struct {
374
- Owner string
375
- Repo string
376
- First int32
377
- Last int32
378
- After string
379
- Before string
386
+ Owner string
387
+ Repo string
380
388
}
381
389
if err := mapstructure .Decode (request .Params .Arguments , & params ); err != nil {
382
390
return mcp .NewToolResultError (err .Error ()), nil
383
391
}
384
392
385
- // Validate pagination parameters
386
- if params .First != 0 && params .Last != 0 {
387
- return mcp .NewToolResultError ("only one of 'first' or 'last' may be specified" ), nil
388
- }
389
- if params .After != "" && params .Before != "" {
390
- return mcp .NewToolResultError ("only one of 'after' or 'before' may be specified" ), nil
391
- }
392
- if params .After != "" && params .Last != 0 {
393
- return mcp .NewToolResultError ("'after' cannot be used with 'last'. Did you mean to use 'before' instead?" ), nil
393
+ pagination , err := OptionalGraphQLPaginationParams (request )
394
+ if err != nil {
395
+ return mcp .NewToolResultError (err .Error ()), nil
394
396
}
395
- if params .Before != "" && params .First != 0 {
396
- return mcp .NewToolResultError ("'before' cannot be used with 'first'. Did you mean to use 'after' instead?" ), nil
397
+
398
+ // Use default of 100 if neither first nor last is specified
399
+ if pagination .First == nil && pagination .Last == nil {
400
+ defaultFirst := int32 (100 )
401
+ pagination .First = & defaultFirst
397
402
}
398
403
399
404
client , err := getGQLClient (ctx )
400
405
if err != nil {
401
406
return mcp .NewToolResultError (fmt .Sprintf ("failed to get GitHub GQL client: %v" , err )), nil
402
407
}
408
+
403
409
var q struct {
404
410
Repository struct {
405
411
DiscussionCategories struct {
406
412
Nodes []struct {
407
413
ID githubv4.ID
408
414
Name githubv4.String
409
415
}
410
- } `graphql:"discussionCategories(first: 100)"`
416
+ PageInfo struct {
417
+ HasNextPage githubv4.Boolean
418
+ EndCursor githubv4.String
419
+ }
420
+ } `graphql:"discussionCategories(first: $first, after: $after)"`
411
421
} `graphql:"repository(owner: $owner, name: $repo)"`
412
422
}
413
423
vars := map [string ]interface {}{
414
424
"owner" : githubv4 .String (params .Owner ),
415
425
"repo" : githubv4 .String (params .Repo ),
426
+ "first" : (* githubv4 .Int )(pagination .First ),
427
+ "after" : (* githubv4 .String )(pagination .After ),
416
428
}
417
429
if err := client .Query (ctx , & q , vars ); err != nil {
418
430
return mcp .NewToolResultError (err .Error ()), nil
419
431
}
432
+
420
433
var categories []map [string ]string
421
434
for _ , c := range q .Repository .DiscussionCategories .Nodes {
422
435
categories = append (categories , map [string ]string {
423
436
"id" : fmt .Sprint (c .ID ),
424
437
"name" : string (c .Name ),
425
438
})
426
439
}
427
- out , err := json .Marshal (categories )
440
+
441
+ result := map [string ]interface {}{
442
+ "categories" : categories ,
443
+ "pageInfo" : map [string ]interface {}{
444
+ "hasNextPage" : bool (q .Repository .DiscussionCategories .PageInfo .HasNextPage ),
445
+ "endCursor" : string (q .Repository .DiscussionCategories .PageInfo .EndCursor ),
446
+ },
447
+ }
448
+
449
+ out , err := json .Marshal (result )
428
450
if err != nil {
429
451
return nil , fmt .Errorf ("failed to marshal discussion categories: %w" , err )
430
452
}
0 commit comments