Skip to content

Commit 9b8ebc0

Browse files
committed
Create 'list sub-issues' tool
1 parent 080e498 commit 9b8ebc0

File tree

3 files changed

+385
-0
lines changed

3 files changed

+385
-0
lines changed

pkg/github/issues.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
270368
func SearchIssues(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
271369
return mcp.NewTool("search_issues",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy