diff --git a/operation/issue/issue.go b/operation/issue/issue.go index 7393887..415b9aa 100644 --- a/operation/issue/issue.go +++ b/operation/issue/issue.go @@ -7,45 +7,68 @@ import ( "gitea.com/gitea/gitea-mcp/pkg/gitea" "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" + GetIssueByIndexToolName = "get_issue_by_index" + GetPullRequestByIndexToolName = "get_pull_request_by_index" + CreateIssueToolName = "create_issue" + CreateIssueCommentToolName = "create_issue_comment" + CreatePullRequestToolName = "create_pull_request" ) var ( GetIssueByIndexTool = mcp.NewTool( GetIssueByIndexToolName, - GetIssueByIndexOpt..., - ) - - GetIssueByIndexOpt = []mcp.ToolOption{ mcp.WithDescription("get issue by index"), - mcp.WithString( - "owner", - mcp.Required(), - mcp.Description("repository owner"), - mcp.DefaultString(""), - ), - mcp.WithString( - "repo", - mcp.Required(), - mcp.Description("repository name"), - mcp.DefaultString(""), - ), - mcp.WithNumber( - "index", - mcp.Required(), - mcp.Description("repository issue index"), - mcp.DefaultNumber(0), - ), - } + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithNumber("index", mcp.Required(), mcp.Description("repository issue index"), mcp.DefaultNumber(0)), + ) + GetPullRequestByIndexTool = mcp.NewTool( + GetPullRequestByIndexToolName, + mcp.WithDescription("get pull request by index"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithNumber("index", mcp.Required(), mcp.Description("repository pull request index"), mcp.DefaultNumber(0)), + ) + CreateIssueTool = mcp.NewTool( + CreateIssueToolName, + mcp.WithDescription("create issue"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("title", mcp.Required(), mcp.Description("issue title"), mcp.DefaultString("")), + mcp.WithString("body", mcp.Required(), mcp.Description("issue body"), mcp.DefaultString("")), + ) + CreateIssueCommentTool = mcp.NewTool( + CreateIssueCommentToolName, + mcp.WithDescription("create issue comment"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithNumber("index", mcp.Required(), mcp.Description("repository issue index"), mcp.DefaultNumber(0)), + mcp.WithString("body", mcp.Required(), mcp.Description("issue comment body"), mcp.DefaultString("")), + ) + CreatePullRequestTool = mcp.NewTool( + CreatePullRequestToolName, + mcp.WithDescription("create pull request"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("title", mcp.Required(), mcp.Description("pull request title"), mcp.DefaultString("")), + mcp.WithString("body", mcp.Required(), mcp.Description("pull request body"), mcp.DefaultString("")), + mcp.WithString("head", mcp.Required(), mcp.Description("pull request head"), mcp.DefaultString("")), + mcp.WithString("base", mcp.Required(), mcp.Description("pull request base"), mcp.DefaultString("")), + ) ) func RegisterTool(s *server.MCPServer) { s.AddTool(GetIssueByIndexTool, GetIssueByIndexFn) + s.AddTool(GetPullRequestByIndexTool, GetPullRequestByIndexFn) + s.AddTool(CreateIssueTool, CreateIssueFn) + s.AddTool(CreateIssueCommentTool, CreateIssueCommentFn) + s.AddTool(CreatePullRequestTool, CreatePullRequestFn) } func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -59,3 +82,66 @@ func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT return to.TextResult(issue) } + +func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + index := req.Params.Arguments["index"].(float64) + pr, _, err := gitea.Client().GetPullRequest(owner, repo, int64(index)) + if err != nil { + return mcp.NewToolResultError(fmt.Sprintf("get %v/%v/pr/%v err", owner, repo, int64(index))), err + } + + return to.TextResult(pr) +} + +func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + title := req.Params.Arguments["title"].(string) + body := req.Params.Arguments["body"].(string) + issue, _, err := gitea.Client().CreateIssue(owner, repo, gitea_sdk.CreateIssueOption{ + Title: title, + Body: body, + }) + if err != nil { + return mcp.NewToolResultError(fmt.Sprintf("create %v/%v/issue err", owner, repo)), err + } + + return to.TextResult(issue) +} + +func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + index := req.Params.Arguments["index"].(float64) + body := req.Params.Arguments["body"].(string) + issueComment, _, err := gitea.Client().CreateIssueComment(owner, repo, int64(index), gitea_sdk.CreateIssueCommentOption{ + Body: body, + }) + if err != nil { + return mcp.NewToolResultError(fmt.Sprintf("create %v/%v/issue/%v/comment err", owner, repo, int64(index))), err + } + + return to.TextResult(issueComment) +} + +func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + title := req.Params.Arguments["title"].(string) + body := req.Params.Arguments["body"].(string) + head := req.Params.Arguments["head"].(string) + base := req.Params.Arguments["base"].(string) + pr, _, err := gitea.Client().CreatePullRequest(owner, repo, gitea_sdk.CreatePullRequestOption{ + Title: title, + Body: body, + Head: head, + Base: base, + }) + if err != nil { + return mcp.NewToolResultError(fmt.Sprintf("create %v/%v/pull_request err", owner, repo)), err + } + + return to.TextResult(pr) +} diff --git a/operation/repo/branch.go b/operation/repo/branch.go new file mode 100644 index 0000000..aa75661 --- /dev/null +++ b/operation/repo/branch.go @@ -0,0 +1,42 @@ +package repo + +import ( + "context" + + "gitea.com/gitea/gitea-mcp/pkg/gitea" + "github.com/mark3labs/mcp-go/mcp" + + gitea_sdk "code.gitea.io/sdk/gitea" +) + +const ( + CreateBranchToolName = "create_branch" +) + +var ( + CreateBranchTool = mcp.NewTool( + CreateBranchToolName, + mcp.WithDescription("Create branch"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("branch", mcp.Required(), mcp.Description("Name of the branch to create"), mcp.DefaultString("")), + mcp.WithString("old_branch", mcp.Description("Name of the old branch to create from"), mcp.DefaultString("")), + ) +) + +func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + branch := req.Params.Arguments["branch"].(string) + oldBranch := req.Params.Arguments["old_branch"].(string) + + _, _, err := gitea.Client().CreateBranch(owner, repo, gitea_sdk.CreateBranchOption{ + BranchName: branch, + OldBranchName: oldBranch, + }) + if err != nil { + return mcp.NewToolResultError("Create Branch Error"), err + } + + return mcp.NewToolResultText("Branch Created"), nil +} diff --git a/operation/repo/repo.go b/operation/repo/repo.go index 9861df5..7cd4ecc 100644 --- a/operation/repo/repo.go +++ b/operation/repo/repo.go @@ -19,48 +19,33 @@ const ( var ( CreateRepoTool = mcp.NewTool( CreateRepoToolName, - CreateRepoOpt..., - ) - - CreateRepoOpt = []mcp.ToolOption{ mcp.WithDescription("Create repository"), - mcp.WithString("name", mcp.Required(), mcp.DefaultString("test"), mcp.Description("Name of the repository to create")), - mcp.WithString("description", mcp.DefaultString(""), mcp.Description("Description of the repository to create")), - mcp.WithBoolean("private", mcp.DefaultBool(true), mcp.Description("Whether the repository is private")), - mcp.WithString("issue_labels", mcp.DefaultString(""), mcp.Description("Issue Label set to use")), - mcp.WithBoolean("auto_init", mcp.DefaultBool(false), mcp.Description("Whether the repository should be auto-intialized?")), - mcp.WithBoolean("template", mcp.DefaultBool(false), mcp.Description("Whether the repository is template")), - mcp.WithString("gitignores", mcp.DefaultString(""), mcp.Description("Gitignores to use")), - mcp.WithString("license", mcp.DefaultString("MIT"), mcp.Description("License to use")), - mcp.WithString("readme", mcp.DefaultString(""), mcp.Description("Readme of the repository to create")), - mcp.WithString("default_branch", mcp.DefaultString("main"), mcp.Description("DefaultBranch of the repository (used when initializes and in template)")), - } + mcp.WithString("name", mcp.Required(), mcp.Description("Name of the repository to create"), mcp.DefaultString("test")), + mcp.WithString("description", mcp.Description("Description of the repository to create"), mcp.DefaultString("")), + mcp.WithBoolean("private", mcp.Description("Whether the repository is private"), mcp.DefaultBool(true)), + mcp.WithString("issue_labels", mcp.Description("Issue Label set to use"), mcp.DefaultString("")), + mcp.WithBoolean("auto_init", mcp.Description("Whether the repository should be auto-intialized?"), mcp.DefaultBool(false)), + mcp.WithBoolean("template", mcp.Description("Whether the repository is template"), mcp.DefaultBool(false)), + mcp.WithString("gitignores", mcp.Description("Gitignores to use"), mcp.DefaultString("")), + mcp.WithString("license", mcp.Description("License to use"), mcp.DefaultString("MIT")), + mcp.WithString("readme", mcp.Description("Readme of the repository to create"), mcp.DefaultString("")), + mcp.WithString("default_branch", mcp.Description("DefaultBranch of the repository (used when initializes and in template)"), mcp.DefaultString("main")), + ) ListMyReposTool = mcp.NewTool( ListMyReposToolName, - ListMyReposOpt..., - ) - - ListMyReposOpt = []mcp.ToolOption{ mcp.WithDescription("List my repositories"), - mcp.WithNumber( - "page", - mcp.Description("Page number"), - mcp.DefaultNumber(1), - mcp.Min(1), - ), - mcp.WithNumber( - "pageSize", - mcp.Description("Page size number"), - mcp.DefaultNumber(10), - mcp.Min(1), - ), - } + mcp.WithNumber("page", mcp.Required(), mcp.Description("Page number"), mcp.DefaultNumber(1), mcp.Min(1)), + mcp.WithNumber("pageSize", mcp.Required(), mcp.Description("Page size number"), mcp.DefaultNumber(10), mcp.Min(1)), + ) ) func RegisterTool(s *server.MCPServer) { s.AddTool(CreateRepoTool, CreateRepoFn) s.AddTool(ListMyReposTool, ListMyReposFn) + + // Branch + s.AddTool(CreateBranchTool, CreateBranchFn) } func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {