mirror of
https://gitea.com/gitea/gitea-mcp.git
synced 2026-01-16 20:52:43 +00:00
feat(pull): add PR review tools (#111)
Add 8 new MCP tools for managing pull request reviews: Read operations: - list_pull_request_reviews: list all reviews for a PR - get_pull_request_review: get a specific review by ID - list_pull_request_review_comments: list inline comments for a review Write operations: - create_pull_request_review: create a review with optional inline comments - submit_pull_request_review: submit a pending review - delete_pull_request_review: delete a review - dismiss_pull_request_review: dismiss a review with optional message - delete_pull_request_reviewer: remove reviewer requests from a PR Fixes #107 Co-authored-by: hiifong <i@hiif.ong> Co-authored-by: hiifong <f@f.style> Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/111 Co-authored-by: Thomas Foubert <thomas.foubert@mistral.ai> Co-committed-by: Thomas Foubert <thomas.foubert@mistral.ai>
This commit is contained in:
10
README.md
10
README.md
@@ -165,7 +165,7 @@ list all my repositories
|
||||
The Gitea MCP Server supports the following tools:
|
||||
|
||||
| Tool | Scope | Description |
|
||||
| :-----------------------------: | :----------: | :------------------------------------------------------: |
|
||||
| :-------------------------------: | :----------: | :------------------------------------------------------: |
|
||||
| get_my_user_info | User | Get the information of the authenticated user |
|
||||
| get_user_orgs | User | Get organizations associated with the authenticated user |
|
||||
| create_repo | Repository | Create a new repository |
|
||||
@@ -200,6 +200,14 @@ The Gitea MCP Server supports the following tools:
|
||||
| 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 |
|
||||
| delete_pull_request_reviewer | Pull Request | Remove reviewers from a pull request |
|
||||
| list_pull_request_reviews | Pull Request | List all reviews for a pull request |
|
||||
| get_pull_request_review | Pull Request | Get a specific review by ID |
|
||||
| list_pull_request_review_comments | Pull Request | List inline comments for a review |
|
||||
| create_pull_request_review | Pull Request | Create a review with optional inline comments |
|
||||
| submit_pull_request_review | Pull Request | Submit a pending review |
|
||||
| delete_pull_request_review | Pull Request | Delete a review |
|
||||
| dismiss_pull_request_review | Pull Request | Dismiss a review with optional message |
|
||||
| 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 |
|
||||
|
||||
@@ -165,7 +165,7 @@ cp gitea-mcp /usr/local/bin/
|
||||
Gitea MCP 服务器支持以下工具:
|
||||
|
||||
| 工具 | 范围 | 描述 |
|
||||
| :--------------------------: | :------: | :------------------------: |
|
||||
| :-------------------------------: | :------: | :------------------------: |
|
||||
| get_my_user_info | 用户 | 获取已认证用户信息 |
|
||||
| get_user_orgs | 用户 | 获取已认证用户关联组织 |
|
||||
| create_repo | 仓库 | 创建新仓库 |
|
||||
@@ -200,6 +200,14 @@ Gitea MCP 服务器支持以下工具:
|
||||
| list_repo_pull_requests | 拉取请求 | 列出所有拉取请求 |
|
||||
| create_pull_request | 拉取请求 | 创建新拉取请求 |
|
||||
| create_pull_request_reviewer | 拉取请求 | 为拉取请求添加审查者 |
|
||||
| delete_pull_request_reviewer | 拉取请求 | 移除拉取请求的审查者 |
|
||||
| list_pull_request_reviews | 拉取请求 | 列出拉取请求的所有审查 |
|
||||
| get_pull_request_review | 拉取请求 | 按 ID 获取特定审查 |
|
||||
| list_pull_request_review_comments | 拉取请求 | 列出审查的行内评论 |
|
||||
| create_pull_request_review | 拉取请求 | 创建审查(可含行内评论) |
|
||||
| submit_pull_request_review | 拉取请求 | 提交待处理的审查 |
|
||||
| delete_pull_request_review | 拉取请求 | 删除审查 |
|
||||
| dismiss_pull_request_review | 拉取请求 | 驳回审查(可附消息) |
|
||||
| search_users | 用户 | 搜索用户 |
|
||||
| search_org_teams | 组织 | 搜索组织团队 |
|
||||
| list_org_labels | 组织 | 列出组织标签 |
|
||||
|
||||
@@ -165,7 +165,7 @@ cp gitea-mcp /usr/local/bin/
|
||||
Gitea MCP 伺服器支援以下工具:
|
||||
|
||||
| 工具 | 範圍 | 描述 |
|
||||
| :--------------------------: | :------: | :--------------------------: |
|
||||
| :-------------------------------: | :------: | :--------------------------: |
|
||||
| get_my_user_info | 用戶 | 取得已認證用戶資訊 |
|
||||
| get_user_orgs | 用戶 | 取得已認證用戶所屬組織 |
|
||||
| create_repo | 倉庫 | 創建新倉庫 |
|
||||
@@ -200,6 +200,14 @@ Gitea MCP 伺服器支援以下工具:
|
||||
| list_repo_pull_requests | 拉取請求 | 列出所有拉取請求 |
|
||||
| create_pull_request | 拉取請求 | 創建新拉取請求 |
|
||||
| create_pull_request_reviewer | 拉取請求 | 為拉取請求添加審查者 |
|
||||
| delete_pull_request_reviewer | 拉取請求 | 移除拉取請求的審查者 |
|
||||
| list_pull_request_reviews | 拉取請求 | 列出拉取請求的所有審查 |
|
||||
| get_pull_request_review | 拉取請求 | 依 ID 取得特定審查 |
|
||||
| list_pull_request_review_comments | 拉取請求 | 列出審查的行內評論 |
|
||||
| create_pull_request_review | 拉取請求 | 創建審查(可含行內評論) |
|
||||
| submit_pull_request_review | 拉取請求 | 提交待處理的審查 |
|
||||
| delete_pull_request_review | 拉取請求 | 刪除審查 |
|
||||
| dismiss_pull_request_review | 拉取請求 | 駁回審查(可附訊息) |
|
||||
| search_users | 用戶 | 搜尋用戶 |
|
||||
| search_org_teams | 組織 | 搜尋組織團隊 |
|
||||
| list_org_labels | 組織 | 列出組織標籤 |
|
||||
|
||||
@@ -21,6 +21,14 @@ const (
|
||||
ListRepoPullRequestsToolName = "list_repo_pull_requests"
|
||||
CreatePullRequestToolName = "create_pull_request"
|
||||
CreatePullRequestReviewerToolName = "create_pull_request_reviewer"
|
||||
DeletePullRequestReviewerToolName = "delete_pull_request_reviewer"
|
||||
ListPullRequestReviewsToolName = "list_pull_request_reviews"
|
||||
GetPullRequestReviewToolName = "get_pull_request_review"
|
||||
ListPullRequestReviewCommentsToolName = "list_pull_request_review_comments"
|
||||
CreatePullRequestReviewToolName = "create_pull_request_review"
|
||||
SubmitPullRequestReviewToolName = "submit_pull_request_review"
|
||||
DeletePullRequestReviewToolName = "delete_pull_request_review"
|
||||
DismissPullRequestReviewToolName = "dismiss_pull_request_review"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -64,6 +72,94 @@ var (
|
||||
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"})),
|
||||
)
|
||||
|
||||
DeletePullRequestReviewerTool = mcp.NewTool(
|
||||
DeletePullRequestReviewerToolName,
|
||||
mcp.WithDescription("remove reviewer requests from a pull request"),
|
||||
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 to remove"), mcp.Items(map[string]interface{}{"type": "string"})),
|
||||
mcp.WithArray("team_reviewers", mcp.Description("list of team reviewer names to remove"), mcp.Items(map[string]interface{}{"type": "string"})),
|
||||
)
|
||||
|
||||
ListPullRequestReviewsTool = mcp.NewTool(
|
||||
ListPullRequestReviewsToolName,
|
||||
mcp.WithDescription("list all reviews for a pull request"),
|
||||
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.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
||||
)
|
||||
|
||||
GetPullRequestReviewTool = mcp.NewTool(
|
||||
GetPullRequestReviewToolName,
|
||||
mcp.WithDescription("get a specific review for a pull request"),
|
||||
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.WithNumber("review_id", mcp.Required(), mcp.Description("review ID")),
|
||||
)
|
||||
|
||||
ListPullRequestReviewCommentsTool = mcp.NewTool(
|
||||
ListPullRequestReviewCommentsToolName,
|
||||
mcp.WithDescription("list all comments for a specific pull request review"),
|
||||
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.WithNumber("review_id", mcp.Required(), mcp.Description("review ID")),
|
||||
)
|
||||
|
||||
CreatePullRequestReviewTool = mcp.NewTool(
|
||||
CreatePullRequestReviewToolName,
|
||||
mcp.WithDescription("create a review for a pull request"),
|
||||
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.WithString("state", mcp.Description("review state"), mcp.Enum("APPROVED", "REQUEST_CHANGES", "COMMENT", "PENDING")),
|
||||
mcp.WithString("body", mcp.Description("review body/comment")),
|
||||
mcp.WithString("commit_id", mcp.Description("commit SHA to review")),
|
||||
mcp.WithArray("comments", mcp.Description("inline review comments (objects with path, body, old_line_num, new_line_num)"), mcp.Items(map[string]interface{}{
|
||||
"type": "object",
|
||||
"properties": map[string]interface{}{
|
||||
"path": map[string]interface{}{"type": "string", "description": "file path to comment on"},
|
||||
"body": map[string]interface{}{"type": "string", "description": "comment body"},
|
||||
"old_line_num": map[string]interface{}{"type": "number", "description": "line number in the old file (for deletions/changes)"},
|
||||
"new_line_num": map[string]interface{}{"type": "number", "description": "line number in the new file (for additions/changes)"},
|
||||
},
|
||||
})),
|
||||
)
|
||||
|
||||
SubmitPullRequestReviewTool = mcp.NewTool(
|
||||
SubmitPullRequestReviewToolName,
|
||||
mcp.WithDescription("submit a pending pull request review"),
|
||||
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.WithNumber("review_id", mcp.Required(), mcp.Description("review ID")),
|
||||
mcp.WithString("state", mcp.Required(), mcp.Description("final review state"), mcp.Enum("APPROVED", "REQUEST_CHANGES", "COMMENT")),
|
||||
mcp.WithString("body", mcp.Description("submission message")),
|
||||
)
|
||||
|
||||
DeletePullRequestReviewTool = mcp.NewTool(
|
||||
DeletePullRequestReviewToolName,
|
||||
mcp.WithDescription("delete a pull request review"),
|
||||
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.WithNumber("review_id", mcp.Required(), mcp.Description("review ID")),
|
||||
)
|
||||
|
||||
DismissPullRequestReviewTool = mcp.NewTool(
|
||||
DismissPullRequestReviewToolName,
|
||||
mcp.WithDescription("dismiss a pull request review"),
|
||||
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.WithNumber("review_id", mcp.Required(), mcp.Description("review ID")),
|
||||
mcp.WithString("message", mcp.Description("dismissal reason")),
|
||||
)
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -75,6 +171,18 @@ func init() {
|
||||
Tool: ListRepoPullRequestsTool,
|
||||
Handler: ListRepoPullRequestsFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: ListPullRequestReviewsTool,
|
||||
Handler: ListPullRequestReviewsFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: GetPullRequestReviewTool,
|
||||
Handler: GetPullRequestReviewFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: ListPullRequestReviewCommentsTool,
|
||||
Handler: ListPullRequestReviewCommentsFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: CreatePullRequestTool,
|
||||
Handler: CreatePullRequestFn,
|
||||
@@ -83,6 +191,26 @@ func init() {
|
||||
Tool: CreatePullRequestReviewerTool,
|
||||
Handler: CreatePullRequestReviewerFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: DeletePullRequestReviewerTool,
|
||||
Handler: DeletePullRequestReviewerFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: CreatePullRequestReviewTool,
|
||||
Handler: CreatePullRequestReviewFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: SubmitPullRequestReviewTool,
|
||||
Handler: SubmitPullRequestReviewFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: DeletePullRequestReviewTool,
|
||||
Handler: DeletePullRequestReviewFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: DismissPullRequestReviewTool,
|
||||
Handler: DismissPullRequestReviewFn,
|
||||
})
|
||||
}
|
||||
|
||||
func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
@@ -260,3 +388,359 @@ func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
||||
|
||||
return to.TextResult(successMsg)
|
||||
}
|
||||
|
||||
func DeletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called DeletePullRequestReviewerFn")
|
||||
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.DeleteReviewRequests(owner, repo, int64(index), gitea_sdk.PullReviewRequestOptions{
|
||||
Reviewers: reviewers,
|
||||
TeamReviewers: teamReviewers,
|
||||
})
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("delete review requests for %v/%v/pr/%v err: %v", owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
successMsg := map[string]interface{}{
|
||||
"message": "Successfully deleted review requests",
|
||||
"reviewers": reviewers,
|
||||
"team_reviewers": teamReviewers,
|
||||
"pr_index": int64(index),
|
||||
"repository": fmt.Sprintf("%s/%s", owner, repo),
|
||||
}
|
||||
|
||||
return to.TextResult(successMsg)
|
||||
}
|
||||
|
||||
func ListPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called ListPullRequestReviewsFn")
|
||||
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"))
|
||||
}
|
||||
page, ok := req.GetArguments()["page"].(float64)
|
||||
if !ok {
|
||||
page = 1
|
||||
}
|
||||
pageSize, ok := req.GetArguments()["pageSize"].(float64)
|
||||
if !ok {
|
||||
pageSize = 100
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
reviews, _, err := client.ListPullReviews(owner, repo, int64(index), gitea_sdk.ListPullReviewsOptions{
|
||||
ListOptions: gitea_sdk.ListOptions{
|
||||
Page: int(page),
|
||||
PageSize: int(pageSize),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list reviews for %v/%v/pr/%v err: %v", owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
return to.TextResult(reviews)
|
||||
}
|
||||
|
||||
func GetPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called GetPullRequestReviewFn")
|
||||
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"))
|
||||
}
|
||||
reviewID, ok := req.GetArguments()["review_id"].(float64)
|
||||
if !ok {
|
||||
return to.ErrorResult(fmt.Errorf("review_id is required"))
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
review, _, err := client.GetPullReview(owner, repo, int64(index), int64(reviewID))
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get review %v for %v/%v/pr/%v err: %v", int64(reviewID), owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
return to.TextResult(review)
|
||||
}
|
||||
|
||||
func ListPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called ListPullRequestReviewCommentsFn")
|
||||
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"))
|
||||
}
|
||||
reviewID, ok := req.GetArguments()["review_id"].(float64)
|
||||
if !ok {
|
||||
return to.ErrorResult(fmt.Errorf("review_id is required"))
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
comments, _, err := client.ListPullReviewComments(owner, repo, int64(index), int64(reviewID))
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list review comments for review %v on %v/%v/pr/%v err: %v", int64(reviewID), owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
return to.TextResult(comments)
|
||||
}
|
||||
|
||||
func CreatePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called CreatePullRequestReviewFn")
|
||||
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"))
|
||||
}
|
||||
|
||||
opt := gitea_sdk.CreatePullReviewOptions{}
|
||||
|
||||
if state, ok := req.GetArguments()["state"].(string); ok {
|
||||
opt.State = gitea_sdk.ReviewStateType(state)
|
||||
}
|
||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
||||
opt.Body = body
|
||||
}
|
||||
if commitID, ok := req.GetArguments()["commit_id"].(string); ok {
|
||||
opt.CommitID = commitID
|
||||
}
|
||||
|
||||
// Parse inline comments
|
||||
if commentsArg, exists := req.GetArguments()["comments"]; exists {
|
||||
if commentsSlice, ok := commentsArg.([]interface{}); ok {
|
||||
for _, comment := range commentsSlice {
|
||||
if commentMap, ok := comment.(map[string]interface{}); ok {
|
||||
reviewComment := gitea_sdk.CreatePullReviewComment{}
|
||||
if path, ok := commentMap["path"].(string); ok {
|
||||
reviewComment.Path = path
|
||||
}
|
||||
if body, ok := commentMap["body"].(string); ok {
|
||||
reviewComment.Body = body
|
||||
}
|
||||
if oldLineNum, ok := commentMap["old_line_num"].(float64); ok {
|
||||
reviewComment.OldLineNum = int64(oldLineNum)
|
||||
}
|
||||
if newLineNum, ok := commentMap["new_line_num"].(float64); ok {
|
||||
reviewComment.NewLineNum = int64(newLineNum)
|
||||
}
|
||||
opt.Comments = append(opt.Comments, reviewComment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
review, _, err := client.CreatePullReview(owner, repo, int64(index), opt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("create review for %v/%v/pr/%v err: %v", owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
return to.TextResult(review)
|
||||
}
|
||||
|
||||
func SubmitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called SubmitPullRequestReviewFn")
|
||||
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"))
|
||||
}
|
||||
reviewID, ok := req.GetArguments()["review_id"].(float64)
|
||||
if !ok {
|
||||
return to.ErrorResult(fmt.Errorf("review_id is required"))
|
||||
}
|
||||
state, ok := req.GetArguments()["state"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(fmt.Errorf("state is required"))
|
||||
}
|
||||
|
||||
opt := gitea_sdk.SubmitPullReviewOptions{
|
||||
State: gitea_sdk.ReviewStateType(state),
|
||||
}
|
||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
||||
opt.Body = body
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
review, _, err := client.SubmitPullReview(owner, repo, int64(index), int64(reviewID), opt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("submit review %v for %v/%v/pr/%v err: %v", int64(reviewID), owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
return to.TextResult(review)
|
||||
}
|
||||
|
||||
func DeletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called DeletePullRequestReviewFn")
|
||||
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"))
|
||||
}
|
||||
reviewID, ok := req.GetArguments()["review_id"].(float64)
|
||||
if !ok {
|
||||
return to.ErrorResult(fmt.Errorf("review_id is required"))
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
_, err = client.DeletePullReview(owner, repo, int64(index), int64(reviewID))
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("delete review %v for %v/%v/pr/%v err: %v", int64(reviewID), owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
successMsg := map[string]interface{}{
|
||||
"message": "Successfully deleted review",
|
||||
"review_id": int64(reviewID),
|
||||
"pr_index": int64(index),
|
||||
"repository": fmt.Sprintf("%s/%s", owner, repo),
|
||||
}
|
||||
|
||||
return to.TextResult(successMsg)
|
||||
}
|
||||
|
||||
func DismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called DismissPullRequestReviewFn")
|
||||
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"))
|
||||
}
|
||||
reviewID, ok := req.GetArguments()["review_id"].(float64)
|
||||
if !ok {
|
||||
return to.ErrorResult(fmt.Errorf("review_id is required"))
|
||||
}
|
||||
|
||||
opt := gitea_sdk.DismissPullReviewOptions{}
|
||||
if message, ok := req.GetArguments()["message"].(string); ok {
|
||||
opt.Message = message
|
||||
}
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
_, err = client.DismissPullReview(owner, repo, int64(index), int64(reviewID), opt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("dismiss review %v for %v/%v/pr/%v err: %v", int64(reviewID), owner, repo, int64(index), err))
|
||||
}
|
||||
|
||||
successMsg := map[string]interface{}{
|
||||
"message": "Successfully dismissed review",
|
||||
"review_id": int64(reviewID),
|
||||
"pr_index": int64(index),
|
||||
"repository": fmt.Sprintf("%s/%s", owner, repo),
|
||||
}
|
||||
|
||||
return to.TextResult(successMsg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user