@@ -266,6 +266,104 @@ func AddSubIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (t
266266 }
267267}
268268
269+ // ListSubIssues creates a tool to list sub-issues for a GitHub issue.
270+ func ListSubIssues (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
271+ return mcp .NewTool ("list_sub_issues" ,
272+ mcp .WithDescription (t ("TOOL_LIST_SUB_ISSUES_DESCRIPTION" , "List sub-issues for a specific issue in a GitHub repository." )),
273+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
274+ Title : t ("TOOL_LIST_SUB_ISSUES_USER_TITLE" , "List sub-issues" ),
275+ ReadOnlyHint : toBoolPtr (true ),
276+ }),
277+ mcp .WithString ("owner" ,
278+ mcp .Required (),
279+ mcp .Description ("Repository owner" ),
280+ ),
281+ mcp .WithString ("repo" ,
282+ mcp .Required (),
283+ mcp .Description ("Repository name" ),
284+ ),
285+ mcp .WithNumber ("issue_number" ,
286+ mcp .Required (),
287+ mcp .Description ("Issue number" ),
288+ ),
289+ mcp .WithNumber ("page" ,
290+ mcp .Description ("Page number for pagination (default: 1)" ),
291+ ),
292+ mcp .WithNumber ("per_page" ,
293+ mcp .Description ("Number of results per page (max 100, default: 30)" ),
294+ ),
295+ ),
296+ func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
297+ owner , err := requiredParam [string ](request , "owner" )
298+ if err != nil {
299+ return mcp .NewToolResultError (err .Error ()), nil
300+ }
301+ repo , err := requiredParam [string ](request , "repo" )
302+ if err != nil {
303+ return mcp .NewToolResultError (err .Error ()), nil
304+ }
305+ issueNumber , err := RequiredInt (request , "issue_number" )
306+ if err != nil {
307+ return mcp .NewToolResultError (err .Error ()), nil
308+ }
309+ page , err := OptionalIntParamWithDefault (request , "page" , 1 )
310+ if err != nil {
311+ return mcp .NewToolResultError (err .Error ()), nil
312+ }
313+ perPage , err := OptionalIntParamWithDefault (request , "per_page" , 30 )
314+ if err != nil {
315+ return mcp .NewToolResultError (err .Error ()), nil
316+ }
317+
318+ client , err := getClient (ctx )
319+ if err != nil {
320+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
321+ }
322+
323+ // Since the go-github library might not have sub-issues support yet,
324+ // we'll make a direct HTTP request using the client's HTTP client
325+ url := fmt .Sprintf ("%srepos/%s/%s/issues/%d/sub_issues?page=%d&per_page=%d" ,
326+ client .BaseURL .String (), owner , repo , issueNumber , page , perPage )
327+ req , err := http .NewRequestWithContext (ctx , "GET" , url , nil )
328+ if err != nil {
329+ return nil , fmt .Errorf ("failed to create request: %w" , err )
330+ }
331+
332+ req .Header .Set ("Accept" , "application/vnd.github+json" )
333+ req .Header .Set ("X-GitHub-Api-Version" , "2022-11-28" )
334+
335+ // Use the same authentication as the GitHub client
336+ httpClient := client .Client ()
337+ resp , err := httpClient .Do (req )
338+ if err != nil {
339+ return nil , fmt .Errorf ("failed to list sub-issues: %w" , err )
340+ }
341+ defer func () { _ = resp .Body .Close () }()
342+
343+ body , err := io .ReadAll (resp .Body )
344+ if err != nil {
345+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
346+ }
347+
348+ if resp .StatusCode != http .StatusOK {
349+ return mcp .NewToolResultError (fmt .Sprintf ("failed to list sub-issues: %s" , string (body ))), nil
350+ }
351+
352+ // Parse and re-marshal to ensure consistent formatting
353+ var result interface {}
354+ if err := json .Unmarshal (body , & result ); err != nil {
355+ return nil , fmt .Errorf ("failed to unmarshal response: %w" , err )
356+ }
357+
358+ r , err := json .Marshal (result )
359+ if err != nil {
360+ return nil , fmt .Errorf ("failed to marshal response: %w" , err )
361+ }
362+
363+ return mcp .NewToolResultText (string (r )), nil
364+ }
365+ }
366+
269367// SearchIssues creates a tool to search for issues and pull requests.
270368func SearchIssues (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
271369 return mcp .NewTool ("search_issues" ,
0 commit comments