Files
gitea-mcp/operation/issue/issue.go
hiifong 5270d2eb08 Adding more logs (#6)
Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/6
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: hiifong <i@hiif.ong>
Co-committed-by: hiifong <i@hiif.ong>
2025-03-25 17:22:39 +00:00

182 lines
5.9 KiB
Go

package issue
import (
"context"
"fmt"
"gitea.com/gitea/gitea-mcp/pkg/gitea"
"gitea.com/gitea/gitea-mcp/pkg/log"
"gitea.com/gitea/gitea-mcp/pkg/to"
gitea_sdk "code.gitea.io/sdk/gitea"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
const (
GetIssueByIndexToolName = "get_issue_by_index"
ListRepoIssuesToolName = "list_repo_issues"
CreateIssueToolName = "create_issue"
CreateIssueCommentToolName = "create_issue_comment"
)
var (
GetIssueByIndexTool = mcp.NewTool(
GetIssueByIndexToolName,
mcp.WithDescription("get issue by index"),
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("repository issue index")),
)
ListRepoIssuesTool = mcp.NewTool(
ListRepoIssuesToolName,
mcp.WithDescription("List repository issues"),
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
mcp.WithString("state", mcp.Description("issue state"), mcp.DefaultString("all")),
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
)
CreateIssueTool = mcp.NewTool(
CreateIssueToolName,
mcp.WithDescription("create issue"),
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
mcp.WithString("title", mcp.Required(), mcp.Description("issue title")),
mcp.WithString("body", mcp.Required(), mcp.Description("issue body")),
)
CreateIssueCommentTool = mcp.NewTool(
CreateIssueCommentToolName,
mcp.WithDescription("create issue comment"),
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("repository issue index")),
mcp.WithString("body", mcp.Required(), mcp.Description("issue comment body")),
)
)
func RegisterTool(s *server.MCPServer) {
s.AddTool(GetIssueByIndexTool, GetIssueByIndexFn)
s.AddTool(ListRepoIssuesTool, ListRepoIssuesFn)
s.AddTool(CreateIssueTool, CreateIssueFn)
s.AddTool(CreateIssueCommentTool, CreateIssueCommentFn)
}
func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("Called GetIssueByIndexFn")
owner, ok := req.Params.Arguments["owner"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("owner is required"))
}
repo, ok := req.Params.Arguments["repo"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("repo is required"))
}
index, ok := req.Params.Arguments["index"].(float64)
if !ok {
return to.ErrorResult(fmt.Errorf("index is required"))
}
issue, _, err := gitea.Client().GetIssue(owner, repo, int64(index))
if err != nil {
return to.ErrorResult(fmt.Errorf("get %v/%v/issue/%v err: %v", owner, repo, int64(index), err))
}
return to.TextResult(issue)
}
func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("Called ListIssuesFn")
owner, ok := req.Params.Arguments["owner"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("owner is required"))
}
repo, ok := req.Params.Arguments["repo"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("repo is required"))
}
state, ok := req.Params.Arguments["state"].(string)
if !ok {
state = "all"
}
page, ok := req.Params.Arguments["page"].(float64)
if !ok {
page = 1
}
pageSize, ok := req.Params.Arguments["pageSize"].(float64)
if !ok {
pageSize = 100
}
opt := gitea_sdk.ListIssueOption{
State: gitea_sdk.StateType(state),
ListOptions: gitea_sdk.ListOptions{
Page: int(page),
PageSize: int(pageSize),
},
}
issues, _, err := gitea.Client().ListRepoIssues(owner, repo, opt)
if err != nil {
return to.ErrorResult(fmt.Errorf("get %v/%v/issues err: %v", owner, repo, err))
}
return to.TextResult(issues)
}
func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("Called CreateIssueFn")
owner, ok := req.Params.Arguments["owner"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("owner is required"))
}
repo, ok := req.Params.Arguments["repo"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("repo is required"))
}
title, ok := req.Params.Arguments["title"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("title is required"))
}
body, ok := req.Params.Arguments["body"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("body is required"))
}
issue, _, err := gitea.Client().CreateIssue(owner, repo, gitea_sdk.CreateIssueOption{
Title: title,
Body: body,
})
if err != nil {
return to.ErrorResult(fmt.Errorf("create %v/%v/issue err", owner, repo))
}
return to.TextResult(issue)
}
func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("Called CreateIssueCommentFn")
owner, ok := req.Params.Arguments["owner"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("owner is required"))
}
repo, ok := req.Params.Arguments["repo"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("repo is required"))
}
index, ok := req.Params.Arguments["index"].(float64)
if !ok {
return to.ErrorResult(fmt.Errorf("index is required"))
}
body, ok := req.Params.Arguments["body"].(string)
if !ok {
return to.ErrorResult(fmt.Errorf("body is required"))
}
opt := gitea_sdk.CreateIssueCommentOption{
Body: body,
}
issueComment, _, err := gitea.Client().CreateIssueComment(owner, repo, int64(index), opt)
if err != nil {
return to.ErrorResult(fmt.Errorf("create %v/%v/issue/%v/comment err", owner, repo, int64(index)))
}
return to.TextResult(issueComment)
}