feat(PR): add tooling and docs for managing pull request reviewers (#103)
- Add support for creating pull request reviewers through a new tool and handler - Document the new tool for adding reviewers to a pull request in English, Simplified Chinese, and Traditional Chinese READMEs Signed-off-by: appleboy <appleboy.tw@gmail.com> Reviewed-on: #103 Co-authored-by: appleboy <appleboy.tw@gmail.com> Co-committed-by: appleboy <appleboy.tw@gmail.com>
This commit was merged in pull request #103.
This commit is contained in:
@@ -199,6 +199,7 @@ The Gitea MCP Server supports the following tools: | ||||
| get_pull_request_by_index | Pull Request | Get a pull request by its index | | ||||
| list_repo_pull_requests | Pull Request | List all pull requests in a repository | | ||||
| create_pull_request | Pull Request | Create a new pull request | | ||||
| create_pull_request_reviewer | Pull Request | Add reviewers to a pull request | | ||||
| search_users | User | Search for users | | ||||
| search_org_teams | Organization | Search for teams in an organization | | ||||
| list_org_labels | Organization | List labels defined at organization level | | ||||
| ||||
@@ -199,6 +199,7 @@ Gitea MCP 服务器支持以下工具: | ||||
| get_pull_request_by_index | 拉取请求 | 按索引获取拉取请求 | | ||||
| list_repo_pull_requests | 拉取请求 | 列出所有拉取请求 | | ||||
| create_pull_request | 拉取请求 | 创建新拉取请求 | | ||||
| create_pull_request_reviewer | 拉取请求 | 为拉取请求添加审查者 | | ||||
| search_users | 用户 | 搜索用户 | | ||||
| search_org_teams | 组织 | 搜索组织团队 | | ||||
| list_org_labels | 组织 | 列出组织标签 | | ||||
| ||||
@@ -199,6 +199,7 @@ Gitea MCP 伺服器支援以下工具: | ||||
| get_pull_request_by_index | 拉取請求 | 依索引取得拉取請求 | | ||||
| list_repo_pull_requests | 拉取請求 | 列出所有拉取請求 | | ||||
| create_pull_request | 拉取請求 | 創建新拉取請求 | | ||||
| create_pull_request_reviewer | 拉取請求 | 為拉取請求添加審查者 | | ||||
| search_users | 用戶 | 搜尋用戶 | | ||||
| search_org_teams | 組織 | 搜尋組織團隊 | | ||||
| list_org_labels | 組織 | 列出組織標籤 | | ||||
| ||||
@@ -17,9 +17,10 @@ import ( | ||||
var Tool = tool.New() | ||||
| ||||
const ( | ||||
GetPullRequestByIndexToolName = "get_pull_request_by_index" | ||||
ListRepoPullRequestsToolName = "list_repo_pull_requests" | ||||
CreatePullRequestToolName = "create_pull_request" | ||||
GetPullRequestByIndexToolName = "get_pull_request_by_index" | ||||
ListRepoPullRequestsToolName = "list_repo_pull_requests" | ||||
CreatePullRequestToolName = "create_pull_request" | ||||
CreatePullRequestReviewerToolName = "create_pull_request_reviewer" | ||||
) | ||||
| ||||
var ( | ||||
@@ -53,6 +54,16 @@ var ( | ||||
mcp.WithString("head", mcp.Required(), mcp.Description("pull request head")), | ||||
mcp.WithString("base", mcp.Required(), mcp.Description("pull request base")), | ||||
) | ||||
| ||||
CreatePullRequestReviewerTool = mcp.NewTool( | ||||
CreatePullRequestReviewerToolName, | ||||
mcp.WithDescription("create pull request reviewer"), | ||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")), | ||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")), | ||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("pull request index")), | ||||
mcp.WithArray("reviewers", mcp.Description("list of reviewer usernames"), mcp.Items(map[string]interface{}{"type": "string"})), | ||||
mcp.WithArray("team_reviewers", mcp.Description("list of team reviewer names"), mcp.Items(map[string]interface{}{"type": "string"})), | ||||
) | ||||
) | ||||
| ||||
func init() { | ||||
@@ -68,6 +79,10 @@ func init() { | ||||
Tool: CreatePullRequestTool, | ||||
Handler: CreatePullRequestFn, | ||||
}) | ||||
Tool.RegisterWrite(server.ServerTool{ | ||||
Tool: CreatePullRequestReviewerTool, | ||||
Handler: CreatePullRequestReviewerFn, | ||||
}) | ||||
} | ||||
| ||||
func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
@@ -183,3 +198,65 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal | ||||
| ||||
return to.TextResult(pr) | ||||
} | ||||
| ||||
func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { | ||||
log.Debugf("Called CreatePullRequestReviewerFn") | ||||
owner, ok := req.GetArguments()["owner"].(string) | ||||
if !ok { | ||||
return to.ErrorResult(fmt.Errorf("owner is required")) | ||||
} | ||||
repo, ok := req.GetArguments()["repo"].(string) | ||||
if !ok { | ||||
return to.ErrorResult(fmt.Errorf("repo is required")) | ||||
} | ||||
index, ok := req.GetArguments()["index"].(float64) | ||||
if !ok { | ||||
return to.ErrorResult(fmt.Errorf("index is required")) | ||||
} | ||||
| ||||
var reviewers []string | ||||
if reviewersArg, exists := req.GetArguments()["reviewers"]; exists { | ||||
if reviewersSlice, ok := reviewersArg.([]interface{}); ok { | ||||
for _, reviewer := range reviewersSlice { | ||||
if reviewerStr, ok := reviewer.(string); ok { | ||||
reviewers = append(reviewers, reviewerStr) | ||||
} | ||||
} | ||||
} | ||||
} | ||||
| ||||
var teamReviewers []string | ||||
if teamReviewersArg, exists := req.GetArguments()["team_reviewers"]; exists { | ||||
if teamReviewersSlice, ok := teamReviewersArg.([]interface{}); ok { | ||||
for _, teamReviewer := range teamReviewersSlice { | ||||
if teamReviewerStr, ok := teamReviewer.(string); ok { | ||||
teamReviewers = append(teamReviewers, teamReviewerStr) | ||||
} | ||||
} | ||||
} | ||||
} | ||||
| ||||
client, err := gitea.ClientFromContext(ctx) | ||||
if err != nil { | ||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) | ||||
} | ||||
| ||||
_, err = client.CreateReviewRequests(owner, repo, int64(index), gitea_sdk.PullReviewRequestOptions{ | ||||
Reviewers: reviewers, | ||||
TeamReviewers: teamReviewers, | ||||
}) | ||||
if err != nil { | ||||
return to.ErrorResult(fmt.Errorf("create review requests for %v/%v/pr/%v err: %v", owner, repo, int64(index), err)) | ||||
} | ||||
| ||||
// Return a success message instead of the Response object which contains non-serializable functions | ||||
successMsg := map[string]interface{}{ | ||||
"message": "Successfully created review requests", | ||||
"reviewers": reviewers, | ||||
"team_reviewers": teamReviewers, | ||||
"pr_index": int64(index), | ||||
"repository": fmt.Sprintf("%s/%s", owner, repo), | ||||
} | ||||
| ||||
return to.TextResult(successMsg) | ||||
} | ||||
| ||||
Reference in New Issue
Block a user