From 065f65ad2a2856b9a182a5a3e5b2220e2d10737e Mon Sep 17 00:00:00 2001 From: hiifong Date: Sun, 23 Mar 2025 15:24:49 +0800 Subject: [PATCH] Update --- README.md | 31 +++++++++++ operation/issue/issue.go | 67 ++++++----------------- operation/operation.go | 4 ++ operation/pull/pull.go | 112 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 51 deletions(-) create mode 100644 operation/pull/pull.go diff --git a/README.md b/README.md index c45969a..e38147d 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,37 @@ Once everything is set up, try typing the following in your MCP-compatible chatb list all my repositories ``` +## ✅Available Tools + +The Gitea MCP Server supports the following tools: + +| Tool | Scope | Description | +|:------:|:-------:|:------------:| +|get_my_user_info|User|Get the information of the authenticated user| +|create_repo|Repository|Create a new repository| +|fork_repo|Repository|Fork a repository| +|list_my_repos|Repository|List all repositories owned by the authenticated user| +|create_branch|Branch|Create a new branch| +|delete_branch|Branch|Delete a branch| +|list_branches|Branch|List all branches in a repository| +|list_repo_commits|Commit|List all commits in a repository| +|get_file|File|Get the content of a file| +|create_file|File|Create a new file| +|update_file|File|Update an existing file| +|delete_file|File|Delete a file| +|get_issue_by_index|Issue|Get an issue by its index| +|list_repo_issues|Issue|List all issues in a repository| +|create_issue|Issue|Create a new issue| +|create_issue_comment|Issue|Create a comment on an issue| +|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| +|search_users|User|Search for users| +|search_org_teams|Organization|Search for teams in an organization| +|search_repos|Repository|Search for repositories| +|get_gitea_mcp_server_version|Server|Get the version of the Gitea MCP Server| + + ## 🐛 Debugging To enable debug mode, add the `-d` flag when running the Gitea MCP Server with sse mode: diff --git a/operation/issue/issue.go b/operation/issue/issue.go index e6371a7..a8b96c9 100644 --- a/operation/issue/issue.go +++ b/operation/issue/issue.go @@ -14,11 +14,10 @@ import ( ) const ( - GetIssueByIndexToolName = "get_issue_by_index" - GetPullRequestByIndexToolName = "get_pull_request_by_index" - CreateIssueToolName = "create_issue" - CreateIssueCommentToolName = "create_issue_comment" - CreatePullRequestToolName = "create_pull_request" + GetIssueByIndexToolName = "get_issue_by_index" + ListRepoIssuesToolName = "list_repo_issues" + CreateIssueToolName = "create_issue" + CreateIssueCommentToolName = "create_issue_comment" ) var ( @@ -29,13 +28,12 @@ var ( 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)), + + ListRepoIssuesTool = mcp.NewTool( + ListRepoIssuesToolName, + mcp.WithDescription("List repository issues"), ) + CreateIssueTool = mcp.NewTool( CreateIssueToolName, mcp.WithDescription("create issue"), @@ -52,24 +50,13 @@ var ( 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(ListRepoIssuesTool, ListRepoIssuesFn) s.AddTool(CreateIssueTool, CreateIssueFn) s.AddTool(CreateIssueCommentTool, CreateIssueCommentFn) - s.AddTool(CreatePullRequestTool, CreatePullRequestFn) } func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -85,17 +72,16 @@ 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) { - log.Debugf("Called GetPullRequestByIndexFn") +func ListRepoIssuesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called ListIssuesFn") 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)) + opt := gitea_sdk.ListIssueOption{} + issues, _, err := gitea.Client().ListRepoIssues(owner, repo, opt) if err != nil { - return nil, fmt.Errorf("get %v/%v/pr/%v err", owner, repo, int64(index)) + return nil, fmt.Errorf("get %v/%v/issues err", owner, repo) } - - return to.TextResult(pr) + return to.TextResult(issues) } func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -130,24 +116,3 @@ func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca return to.TextResult(issueComment) } - -func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { - log.Debugf("Called CreatePullRequestFn") - 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 nil, fmt.Errorf("create %v/%v/pull_request err", owner, repo) - } - - return to.TextResult(pr) -} diff --git a/operation/operation.go b/operation/operation.go index 956f0d3..8318ef1 100644 --- a/operation/operation.go +++ b/operation/operation.go @@ -4,6 +4,7 @@ import ( "fmt" "gitea.com/gitea/gitea-mcp/operation/issue" + "gitea.com/gitea/gitea-mcp/operation/pull" "gitea.com/gitea/gitea-mcp/operation/repo" "gitea.com/gitea/gitea-mcp/operation/search" "gitea.com/gitea/gitea-mcp/operation/user" @@ -28,6 +29,9 @@ func RegisterTool(s *server.MCPServer) { // Issue Tool issue.RegisterTool(s) + // Pull Tool + pull.RegisterTool(s) + // Search Tool search.RegisterTool(s) diff --git a/operation/pull/pull.go b/operation/pull/pull.go new file mode 100644 index 0000000..763721e --- /dev/null +++ b/operation/pull/pull.go @@ -0,0 +1,112 @@ +package pull + +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 ( + GetPullRequestByIndexToolName = "get_pull_request_by_index" + ListRepoPullRequestsToolName = "list_repo_pull_requests" + CreatePullRequestToolName = "create_pull_request" +) + +var ( + 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)), + ) + + ListRepoPullRequestsTool = mcp.NewTool( + ListRepoPullRequestsToolName, + mcp.WithDescription("List repository pull requests"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("state", mcp.Description("state"), mcp.DefaultString("")), + mcp.WithString("sort", mcp.Description("sort"), mcp.DefaultString("")), + mcp.WithNumber("milestone", mcp.Description("milestone"), mcp.DefaultNumber(0)), + ) + + 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(GetPullRequestByIndexTool, GetPullRequestByIndexFn) + s.AddTool(ListRepoPullRequestsTool, ListRepoPullRequestsFn) + s.AddTool(CreatePullRequestTool, CreatePullRequestFn) +} + +func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called GetPullRequestByIndexFn") + 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 nil, fmt.Errorf("get %v/%v/pr/%v err", owner, repo, int64(index)) + } + + return to.TextResult(pr) +} + +func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called ListRepoPullRequests") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + opt := gitea_sdk.ListPullRequestsOptions{ + State: gitea_sdk.StateType(req.Params.Arguments["state"].(string)), + Sort: req.Params.Arguments["sort"].(string), + Milestone: req.Params.Arguments["milestone"].(int64), + ListOptions: gitea_sdk.ListOptions{ + Page: 1, + PageSize: 1000, + }, + } + pullRequests, _, err := gitea.Client().ListRepoPullRequests("", "", opt) + if err != nil { + return nil, fmt.Errorf("list %v/%v/pull_requests err", owner, repo) + } + + return to.TextResult(pullRequests) +} + +func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called CreatePullRequestFn") + 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 nil, fmt.Errorf("create %v/%v/pull_request err", owner, repo) + } + + return to.TextResult(pr) +}