Expand Up @@ -32,9 +32,18 @@ func getIssue(client *github.Client, t translations.TranslationHelperFunc) (tool ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner := request.Params.Arguments["owner"].(string) repo := request.Params.Arguments["repo"].(string) issueNumber := int(request.Params.Arguments["issue_number"].(float64)) owner, err := requiredParam[string](request, "owner") if err != nil { return mcp.NewToolResultError(err.Error()), nil } repo, err := requiredParam[string](request, "repo") if err != nil { return mcp.NewToolResultError(err.Error()), nil } issueNumber, err := requiredInt(request, "issue_number") if err != nil { return mcp.NewToolResultError(err.Error()), nil } issue, resp, err := client.Issues.Get(ctx, owner, repo, issueNumber) if err != nil { Expand Down Expand Up @@ -81,10 +90,22 @@ func addIssueComment(client *github.Client, t translations.TranslationHelperFunc ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner := request.Params.Arguments["owner"].(string) repo := request.Params.Arguments["repo"].(string) issueNumber := int(request.Params.Arguments["issue_number"].(float64)) body := request.Params.Arguments["body"].(string) owner, err := requiredParam[string](request, "owner") if err != nil { return mcp.NewToolResultError(err.Error()), nil } repo, err := requiredParam[string](request, "repo") if err != nil { return mcp.NewToolResultError(err.Error()), nil } issueNumber, err := requiredInt(request, "issue_number") if err != nil { return mcp.NewToolResultError(err.Error()), nil } body, err := requiredParam[string](request, "body") if err != nil { return mcp.NewToolResultError(err.Error()), nil } comment := &github.IssueComment{ Body: github.Ptr(body), Expand Down Expand Up @@ -135,22 +156,25 @@ func searchIssues(client *github.Client, t translations.TranslationHelperFunc) ( ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { query := request.Params.Arguments["q"].(string) sort := "" if s, ok := request.Params.Arguments["sort"].(string); ok { sort = s query, err := requiredParam[string](request, "q") if err != nil { return mcp.NewToolResultError(err.Error()), nil } order :="" ifo, ok := request.Params.Arguments["order"].(string); ok { order = o sort, err :=optionalParam[string](request, "sort") iferr != nil { return mcp.NewToolResultError(err.Error()), nil } perPage :=30 ifpp, ok := request.Params.Arguments["per_page"].(float64); ok { perPage = int(pp) order, err :=optionalParam[string](request, "order") iferr != nil { return mcp.NewToolResultError(err.Error()), nil } page := 1 if p, ok := request.Params.Arguments["page"].(float64); ok { page = int(p) perPage, err := optionalIntParamWithDefault(request, "per_page", 30) if err != nil { return mcp.NewToolResultError(err.Error()), nil } page, err := optionalIntParamWithDefault(request, "page", 1) if err != nil { return mcp.NewToolResultError(err.Error()), nil } opts := &github.SearchOptions{ Expand Down Expand Up @@ -212,26 +236,34 @@ func createIssue(client *github.Client, t translations.TranslationHelperFunc) (t ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner := request.Params.Arguments["owner"].(string) repo := request.Params.Arguments["repo"].(string) title := request.Params.Arguments["title"].(string) owner, err := requiredParam[string](request, "owner") if err != nil { return mcp.NewToolResultError(err.Error()), nil } repo, err := requiredParam[string](request, "repo") if err != nil { return mcp.NewToolResultError(err.Error()), nil } title, err := requiredParam[string](request, "title") if err != nil { return mcp.NewToolResultError(err.Error()), nil } // Optional parameters var body stringifb, ok := request.Params.Arguments["body"].(string); ok { body = b body, err := optionalParam[ string](request, "body") iferr != nil { return mcp.NewToolResultError(err.Error()), nil } //Parse assignees if present assignees :=[]string{} // default to empty slice, can't be nil ifa, ok := request.Params.Arguments["assignees"].(string); ok && a !="" { assignees = parseCommaSeparatedList(a) //Get assignees assignees, err :=optionalCommaSeparatedListParam(request, "assignees") iferr !=nil { return mcp.NewToolResultError(err.Error()), nil } // Parse labels if present labels := []string{} // default to empty slice, can't be nil if l, ok := request.Params.Arguments["labels"].(string); ok && l != "" { labels = parseCommaSeparatedList(l) // Get labels labels, err := optionalCommaSeparatedListParam(request, "labels") if err != nil { return mcp.NewToolResultError(err.Error()), nil } // Create the issue request Expand Down Expand Up @@ -300,29 +332,43 @@ func listIssues(client *github.Client, t translations.TranslationHelperFunc) (to ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner := request.Params.Arguments["owner"].(string) repo := request.Params.Arguments["repo"].(string) owner, err := requiredParam[string](request, "owner") if err != nil { return mcp.NewToolResultError(err.Error()), nil } repo, err := requiredParam[string](request, "repo") if err != nil { return mcp.NewToolResultError(err.Error()), nil } opts := &github.IssueListByRepoOptions{} // Set optional parameters if provided if state, ok := request.Params.Arguments["state"].(string); ok && state != "" { opts.State = state opts.State, err = optionalParam[string](request, "state") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if labels, ok := request.Params.Arguments["labels"].(string); ok && labels != "" { opts.Labels = parseCommaSeparatedList(labels) opts.Labels, err = optionalCommaSeparatedListParam(request, "labels") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if sort, ok := request.Params.Arguments["sort"].(string); ok && sort != "" { opts.Sort = sort opts.Sort, err = optionalParam[string](request, "sort") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if direction, ok := request.Params.Arguments["direction"].(string); ok && direction != "" { opts.Direction = direction opts.Direction, err = optionalParam[string](request, "direction") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if since, ok := request.Params.Arguments["since"].(string); ok && since != "" { since, err := optionalParam[string](request, "since") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if since != "" { timestamp, err := parseISOTimestamp(since) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("failed to list issues: %s", err.Error())), nil Expand Down Expand Up @@ -397,38 +443,69 @@ func updateIssue(client *github.Client, t translations.TranslationHelperFunc) (t ), ), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { owner := request.Params.Arguments["owner"].(string) repo := request.Params.Arguments["repo"].(string) issueNumber := int(request.Params.Arguments["issue_number"].(float64)) owner, err := requiredParam[string](request, "owner") if err != nil { return mcp.NewToolResultError(err.Error()), nil } repo, err := requiredParam[string](request, "repo") if err != nil { return mcp.NewToolResultError(err.Error()), nil } issueNumber, err := requiredInt(request, "issue_number") if err != nil { return mcp.NewToolResultError(err.Error()), nil } // Create the issue request with only provided fields issueRequest := &github.IssueRequest{} // Set optional parameters if provided if title, ok := request.Params.Arguments["title"].(string); ok && title != "" { title, err := optionalParam[string](request, "title") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if title != "" { issueRequest.Title = github.Ptr(title) } if body, ok := request.Params.Arguments["body"].(string); ok && body != "" { body, err := optionalParam[string](request, "body") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if body != "" { issueRequest.Body = github.Ptr(body) } if state, ok := request.Params.Arguments["state"].(string); ok && state != "" { state, err := optionalParam[string](request, "state") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if state != "" { issueRequest.State = github.Ptr(state) } if labels, ok := request.Params.Arguments["labels"].(string); ok && labels != "" { labelsList := parseCommaSeparatedList(labels) issueRequest.Labels = &labelsList labels, err := optionalCommaSeparatedListParam(request, "labels") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if len(labels) > 0 { issueRequest.Labels = &labels } if assignees, ok := request.Params.Arguments["assignees"].(string); ok && assignees != "" { assigneesList := parseCommaSeparatedList(assignees) issueRequest.Assignees = &assigneesList assignees, err := optionalCommaSeparatedListParam(request, "assignees") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if len(assignees) > 0 { issueRequest.Assignees = &assignees } if milestone, ok := request.Params.Arguments["milestone"].(float64); ok { milestoneNum := int(milestone) milestone, err := optionalIntParam(request, "milestone") if err != nil { return mcp.NewToolResultError(err.Error()), nil } if milestone != 0 { milestoneNum := milestone issueRequest.Milestone = &milestoneNum } Expand Down