From 24310675bad7b4a8d4b9608be6b3bbd66c44e8d7 Mon Sep 17 00:00:00 2001 From: hiifong Date: Sun, 23 Mar 2025 14:53:15 +0800 Subject: [PATCH] Update --- operation/issue/issue.go | 10 +-- operation/operation.go | 4 ++ operation/repo/branch.go | 54 +++++++++++++- operation/repo/commit.go | 46 ++++++++++++ operation/repo/file.go | 143 +++++++++++++++++++++++++++++++++++++ operation/repo/repo.go | 48 +++++++++++-- operation/search/search.go | 119 ++++++++++++++++++++++++++++++ operation/user/user.go | 3 +- pkg/to/to.go | 3 +- 9 files changed, 417 insertions(+), 13 deletions(-) create mode 100644 operation/repo/commit.go create mode 100644 operation/repo/file.go create mode 100644 operation/search/search.go diff --git a/operation/issue/issue.go b/operation/issue/issue.go index 617b3a3..e6371a7 100644 --- a/operation/issue/issue.go +++ b/operation/issue/issue.go @@ -79,7 +79,7 @@ func GetIssueByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT index := req.Params.Arguments["index"].(float64) issue, _, err := gitea.Client().GetIssue(owner, repo, int64(index)) if err != nil { - return mcp.NewToolResultError(fmt.Sprintf("get %v/%v/issue/%v err", owner, repo, int64(index))), err + return nil, fmt.Errorf("get %v/%v/issue/%v err", owner, repo, int64(index)) } return to.TextResult(issue) @@ -92,7 +92,7 @@ func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp 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 nil, fmt.Errorf("get %v/%v/pr/%v err", owner, repo, int64(index)) } return to.TextResult(pr) @@ -109,7 +109,7 @@ func CreateIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR Body: body, }) if err != nil { - return mcp.NewToolResultError(fmt.Sprintf("create %v/%v/issue err", owner, repo)), err + return nil, fmt.Errorf("create %v/%v/issue err", owner, repo) } return to.TextResult(issue) @@ -125,7 +125,7 @@ func CreateIssueCommentFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca Body: body, }) if err != nil { - return mcp.NewToolResultError(fmt.Sprintf("create %v/%v/issue/%v/comment err", owner, repo, int64(index))), err + return nil, fmt.Errorf("create %v/%v/issue/%v/comment err", owner, repo, int64(index)) } return to.TextResult(issueComment) @@ -146,7 +146,7 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal Base: base, }) if err != nil { - return mcp.NewToolResultError(fmt.Sprintf("create %v/%v/pull_request err", owner, repo)), err + 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 b76b7dd..956f0d3 100644 --- a/operation/operation.go +++ b/operation/operation.go @@ -5,6 +5,7 @@ import ( "gitea.com/gitea/gitea-mcp/operation/issue" "gitea.com/gitea/gitea-mcp/operation/repo" + "gitea.com/gitea/gitea-mcp/operation/search" "gitea.com/gitea/gitea-mcp/operation/user" "gitea.com/gitea/gitea-mcp/operation/version" "gitea.com/gitea/gitea-mcp/pkg/flag" @@ -27,6 +28,9 @@ func RegisterTool(s *server.MCPServer) { // Issue Tool issue.RegisterTool(s) + // Search Tool + search.RegisterTool(s) + // Version Tool version.RegisterTool(s) } diff --git a/operation/repo/branch.go b/operation/repo/branch.go index b287e96..703b139 100644 --- a/operation/repo/branch.go +++ b/operation/repo/branch.go @@ -2,16 +2,20 @@ package repo import ( "context" + "fmt" "gitea.com/gitea/gitea-mcp/pkg/gitea" "gitea.com/gitea/gitea-mcp/pkg/log" - "github.com/mark3labs/mcp-go/mcp" + "gitea.com/gitea/gitea-mcp/pkg/to" gitea_sdk "code.gitea.io/sdk/gitea" + "github.com/mark3labs/mcp-go/mcp" ) const ( CreateBranchToolName = "create_branch" + DeleteBranchToolName = "delete_branch" + ListBranchesToolName = "list_branches" ) var ( @@ -23,6 +27,21 @@ var ( 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("")), ) + + DeleteBranchTool = mcp.NewTool( + DeleteBranchToolName, + mcp.WithDescription("Delete 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 delete"), mcp.DefaultString("")), + ) + + ListBranchesTool = mcp.NewTool( + ListBranchesToolName, + mcp.WithDescription("List branches"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + ) ) func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -37,8 +56,39 @@ func CreateBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallTool OldBranchName: oldBranch, }) if err != nil { - return mcp.NewToolResultError("Create Branch Error"), err + return nil, fmt.Errorf("Create Branch Error: %v", err) } return mcp.NewToolResultText("Branch Created"), nil } + +func DeleteBranchFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called DeleteBranchFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + branch := req.Params.Arguments["branch"].(string) + _, _, err := gitea.Client().DeleteRepoBranch(owner, repo, branch) + if err != nil { + return nil, fmt.Errorf("Delete Branch Error: %v", err) + } + + return to.TextResult("Branch Deleted") +} + +func ListBranchesFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called ListBranchesFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + opt := gitea_sdk.ListRepoBranchesOptions{ + ListOptions: gitea_sdk.ListOptions{ + Page: 1, + PageSize: 100, + }, + } + branches, _, err := gitea.Client().ListRepoBranches(owner, repo, opt) + if err != nil { + return nil, fmt.Errorf("List Branches Error: %v", err) + } + + return to.TextResult(branches) +} diff --git a/operation/repo/commit.go b/operation/repo/commit.go new file mode 100644 index 0000000..f233bbf --- /dev/null +++ b/operation/repo/commit.go @@ -0,0 +1,46 @@ +package repo + +import ( + "context" + "fmt" + + gitea_sdk "code.gitea.io/sdk/gitea" + "gitea.com/gitea/gitea-mcp/pkg/gitea" + "gitea.com/gitea/gitea-mcp/pkg/log" + "gitea.com/gitea/gitea-mcp/pkg/to" + "github.com/mark3labs/mcp-go/mcp" +) + +const ( + ListRepoCommitsToolName = "list_repo_commits" +) + +var ( + ListRepoCommitsTool = mcp.NewTool( + ListRepoCommitsToolName, + mcp.WithDescription("List repository commits"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("sha", mcp.Description("sha"), mcp.DefaultString("")), + mcp.WithString("path", mcp.Description("path"), mcp.DefaultString("")), + ) +) + +func ListRepoCommitsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called ListRepoCommitsFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + opt := gitea_sdk.ListCommitOptions{ + ListOptions: gitea_sdk.ListOptions{ + Page: 1, + PageSize: 1000, + }, + SHA: req.Params.Arguments["sha"].(string), + Path: req.Params.Arguments["path"].(string), + } + commits, _, err := gitea.Client().ListRepoCommits(owner, repo, opt) + if err != nil { + return nil, fmt.Errorf("list repo commits err: %v", err) + } + return to.TextResult(commits) +} diff --git a/operation/repo/file.go b/operation/repo/file.go new file mode 100644 index 0000000..f8dd4ed --- /dev/null +++ b/operation/repo/file.go @@ -0,0 +1,143 @@ +package repo + +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" +) + +const ( + GetFileToolName = "get_file" + CreateFileToolName = "create_file" + UpdateFileToolName = "update_file" + DeleteFileToolName = "delete_file" +) + +var ( + GetFileTool = mcp.NewTool( + GetFileToolName, + mcp.WithDescription("Get file"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("ref", mcp.Required(), mcp.Description("ref"), mcp.DefaultString("")), + mcp.WithString("filePath", mcp.Required(), mcp.Description("file path"), mcp.DefaultString("")), + ) + + CreateFileTool = mcp.NewTool( + CreateFileToolName, + mcp.WithDescription("Create file"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("filePath", mcp.Required(), mcp.Description("file path"), mcp.DefaultString("")), + mcp.WithString("content", mcp.Required(), mcp.Description("file content"), mcp.DefaultString("")), + mcp.WithString("message", mcp.Required(), mcp.Description("commit message"), mcp.DefaultString("")), + mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name"), mcp.DefaultString("")), + mcp.WithString("new_branch_name", mcp.Description("new branch name"), mcp.DefaultString("")), + ) + + UpdateFileTool = mcp.NewTool( + UpdateFileToolName, + mcp.WithDescription("Update file"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("filePath", mcp.Required(), mcp.Description("file path"), mcp.DefaultString("")), + mcp.WithString("content", mcp.Required(), mcp.Description("file content"), mcp.DefaultString("")), + mcp.WithString("message", mcp.Required(), mcp.Description("commit message"), mcp.DefaultString("")), + mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name"), mcp.DefaultString("")), + mcp.WithString("new_branch_name", mcp.Description("new branch name"), mcp.DefaultString("")), + mcp.WithString("from_path", mcp.Description("from path"), mcp.DefaultString("")), + mcp.WithString("sha", mcp.Description("sha"), mcp.DefaultString("")), + ) + + DeleteFileTool = mcp.NewTool( + DeleteFileToolName, + mcp.WithDescription("Delete file"), + mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner"), mcp.DefaultString("")), + mcp.WithString("repo", mcp.Required(), mcp.Description("repository name"), mcp.DefaultString("")), + mcp.WithString("filePath", mcp.Required(), mcp.Description("file path"), mcp.DefaultString("")), + mcp.WithString("message", mcp.Required(), mcp.Description("commit message"), mcp.DefaultString("")), + mcp.WithString("branch_name", mcp.Required(), mcp.Description("branch name"), mcp.DefaultString("")), + mcp.WithString("sha", mcp.Description("sha"), mcp.DefaultString("")), + ) +) + +func GetFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called GetFileFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + ref := req.Params.Arguments["ref"].(string) + filePath := req.Params.Arguments["filePath"].(string) + file, _, err := gitea.Client().GetFile(owner, repo, ref, filePath) + if err != nil { + return nil, fmt.Errorf("get file err: %v", err) + } + return to.TextResult(file) +} + +func CreateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called CreateFileFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + filePath := req.Params.Arguments["filePath"].(string) + opt := gitea_sdk.CreateFileOptions{ + Content: req.Params.Arguments["content"].(string), + FileOptions: gitea_sdk.FileOptions{ + Message: req.Params.Arguments["message"].(string), + BranchName: req.Params.Arguments["branch_name"].(string), + NewBranchName: req.Params.Arguments["new_branch_name"].(string), + }, + } + + _, _, err := gitea.Client().CreateFile(owner, repo, filePath, opt) + if err != nil { + return nil, fmt.Errorf("create file err: %v", err) + } + return to.TextResult("Create file success") +} + +func UpdateFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called UpdateFileFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + filePath := req.Params.Arguments["filePath"].(string) + opt := gitea_sdk.UpdateFileOptions{ + Content: req.Params.Arguments["content"].(string), + FromPath: req.Params.Arguments["from_path"].(string), + SHA: req.Params.Arguments["sha"].(string), + FileOptions: gitea_sdk.FileOptions{ + Message: req.Params.Arguments["message"].(string), + BranchName: req.Params.Arguments["branch_name"].(string), + NewBranchName: req.Params.Arguments["new_branch_name"].(string), + }, + } + _, _, err := gitea.Client().UpdateFile(owner, repo, filePath, opt) + if err != nil { + return nil, fmt.Errorf("update file err: %v", err) + } + return to.TextResult("Update file success") +} + +func DeleteFileFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called DeleteFileFn") + owner := req.Params.Arguments["owner"].(string) + repo := req.Params.Arguments["repo"].(string) + filePath := req.Params.Arguments["filePath"].(string) + opt := gitea_sdk.DeleteFileOptions{ + FileOptions: gitea_sdk.FileOptions{ + Message: req.Params.Arguments["message"].(string), + BranchName: req.Params.Arguments["branch_name"].(string), + }, + SHA: req.Params.Arguments["sha"].(string), + } + _, err := gitea.Client().DeleteFile(owner, repo, filePath, opt) + if err != nil { + return nil, fmt.Errorf("delete file err: %v", err) + } + return to.TextResult("Delete file success") +} diff --git a/operation/repo/repo.go b/operation/repo/repo.go index 8c85807..6b4e72e 100644 --- a/operation/repo/repo.go +++ b/operation/repo/repo.go @@ -2,18 +2,22 @@ package repo import ( "context" + "errors" + "fmt" - gitea_sdk "code.gitea.io/sdk/gitea" "gitea.com/gitea/gitea-mcp/pkg/gitea" "gitea.com/gitea/gitea-mcp/pkg/log" + "gitea.com/gitea/gitea-mcp/pkg/ptr" "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 ( CreateRepoToolName = "create_repo" + ForkRepoToolName = "fork_repo" ListMyReposToolName = "list_my_repos" ) @@ -33,6 +37,15 @@ var ( mcp.WithString("default_branch", mcp.Description("DefaultBranch of the repository (used when initializes and in template)"), mcp.DefaultString("main")), ) + ForkRepoTool = mcp.NewTool( + ForkRepoToolName, + mcp.WithDescription("Fork repository"), + mcp.WithString("user", mcp.Required(), mcp.Description("User name of the repository to fork")), + mcp.WithString("repo", mcp.Required(), mcp.Description("Repository name to fork")), + mcp.WithString("organization", mcp.Description("Organization name to fork")), + mcp.WithString("name", mcp.Description("Name of the forked repository")), + ) + ListMyReposTool = mcp.NewTool( ListMyReposToolName, mcp.WithDescription("List my repositories"), @@ -43,10 +56,22 @@ var ( func RegisterTool(s *server.MCPServer) { s.AddTool(CreateRepoTool, CreateRepoFn) + s.AddTool(ForkRepoTool, ForkRepoFn) s.AddTool(ListMyReposTool, ListMyReposFn) + // File + s.AddTool(GetFileTool, GetFileFn) + s.AddTool(CreateFileTool, CreateFileFn) + s.AddTool(UpdateFileTool, UpdateFileFn) + s.AddTool(DeleteFileTool, DeleteFileFn) + // Branch s.AddTool(CreateBranchTool, CreateBranchFn) + s.AddTool(DeleteBranchTool, DeleteBranchFn) + s.AddTool(ListBranchesTool, ListBranchesFn) + + // Commit + s.AddTool(ListRepoCommitsTool, ListRepoCommitsFn) } func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -81,15 +106,30 @@ func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRe return to.TextResult(repo) } +func ForkRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called ForkRepoFn") + user := req.Params.Arguments["user"].(string) + repo := req.Params.Arguments["repo"].(string) + opt := gitea_sdk.CreateForkOption{ + Organization: ptr.To(req.Params.Arguments["organization"].(string)), + Name: ptr.To(req.Params.Arguments["name"].(string)), + } + _, _, err := gitea.Client().CreateFork(user, repo, opt) + if err != nil { + return nil, fmt.Errorf("fork repository error %v", err) + } + return to.TextResult("Fork success") +} + func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("Called ListMyReposFn") page, ok := req.Params.Arguments["page"].(float64) if !ok { - return mcp.NewToolResultError("get page number error"), nil + return nil, errors.New("get page number error") } size, ok := req.Params.Arguments["pageSize"].(float64) if !ok { - return mcp.NewToolResultError("get page size number error"), nil + return nil, errors.New("get page size number error") } opt := gitea_sdk.ListReposOptions{ ListOptions: gitea_sdk.ListOptions{ @@ -99,7 +139,7 @@ func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR } repos, _, err := gitea.Client().ListMyRepos(opt) if err != nil { - return mcp.NewToolResultError("List my repositories error"), err + return nil, fmt.Errorf("list my repositories error %v", err) } return to.TextResult(repos) diff --git a/operation/search/search.go b/operation/search/search.go new file mode 100644 index 0000000..af33c44 --- /dev/null +++ b/operation/search/search.go @@ -0,0 +1,119 @@ +package search + +import ( + "context" + "fmt" + + "gitea.com/gitea/gitea-mcp/pkg/gitea" + "gitea.com/gitea/gitea-mcp/pkg/log" + "gitea.com/gitea/gitea-mcp/pkg/ptr" + "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 ( + SearchUsersToolName = "search_users" + SearchOrgTeamsToolName = "search_org_teams" + SearchReposToolName = "search_repos" +) + +var ( + SearchUsersTool = mcp.NewTool( + SearchUsersToolName, + mcp.WithDescription("search users"), + mcp.WithString("keyword", mcp.Description("Keyword"), mcp.DefaultString("")), + mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)), + mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(100)), + ) + + SearOrgTeamsTool = mcp.NewTool( + SearchOrgTeamsToolName, + mcp.WithDescription("search organization teams"), + mcp.WithString("org", mcp.Description("organization name"), mcp.DefaultString("")), + mcp.WithString("query", mcp.Description("search organization teams"), mcp.DefaultString("")), + mcp.WithBoolean("includeDescription", mcp.Description("include description?"), mcp.DefaultBool(true)), + mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)), + mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(100)), + ) + + SearchReposTool = mcp.NewTool( + SearchReposToolName, + mcp.WithDescription("search repos"), + mcp.WithString("keyword", mcp.Description("Keyword"), mcp.DefaultString("")), + mcp.WithBoolean("keywordIsTopic", mcp.Description("KeywordIsTopic"), mcp.DefaultBool(false)), + mcp.WithBoolean("keywordInDescription", mcp.Description("KeywordInDescription"), mcp.DefaultBool(false)), + mcp.WithNumber("ownerID", mcp.Description("OwnerID"), mcp.DefaultNumber(0)), + mcp.WithBoolean("isPrivate", mcp.Description("IsPrivate"), mcp.DefaultBool(false)), + mcp.WithBoolean("isArchived", mcp.Description("IsArchived"), mcp.DefaultBool(false)), + mcp.WithString("sort", mcp.Description("Sort"), mcp.DefaultString(""), mcp.Enum("")), + mcp.WithString("order", mcp.Description("Order"), mcp.DefaultString(""), mcp.Enum("")), + mcp.WithNumber("page", mcp.Description("Page"), mcp.DefaultNumber(1)), + mcp.WithNumber("pageSize", mcp.Description("PageSize"), mcp.DefaultNumber(100)), + ) +) + +func RegisterTool(s *server.MCPServer) { + s.AddTool(SearchUsersTool, SearchUsersFn) + s.AddTool(SearOrgTeamsTool, SearchOrgTeamsFn) + s.AddTool(SearchReposTool, SearchReposFn) +} + +func SearchUsersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called SearchUsersFn") + opt := gitea_sdk.SearchUsersOption{ + KeyWord: req.Params.Arguments["keyword"].(string), + ListOptions: gitea_sdk.ListOptions{ + Page: req.Params.Arguments["page"].(int), + PageSize: req.Params.Arguments["pageSize"].(int), + }, + } + users, _, err := gitea.Client().SearchUsers(opt) + if err != nil { + return nil, err + } + return to.TextResult(users) +} + +func SearchOrgTeamsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called SearchOrgTeamsFn") + org := req.Params.Arguments["org"].(string) + opt := gitea_sdk.SearchTeamsOptions{ + Query: req.Params.Arguments["query"].(string), + IncludeDescription: req.Params.Arguments["includeDescription"].(bool), + ListOptions: gitea_sdk.ListOptions{ + Page: req.Params.Arguments["page"].(int), + PageSize: req.Params.Arguments["pageSize"].(int), + }, + } + teams, _, err := gitea.Client().SearchOrgTeams(org, &opt) + if err != nil { + return nil, fmt.Errorf("search organization teams error: %v", err) + } + return to.TextResult(teams) +} + +func SearchReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + log.Debugf("Called SearchReposFn") + opt := gitea_sdk.SearchRepoOptions{ + Keyword: req.Params.Arguments["keyword"].(string), + KeywordIsTopic: req.Params.Arguments["keywordIsTopic"].(bool), + KeywordInDescription: req.Params.Arguments["keywordInDescription"].(bool), + OwnerID: req.Params.Arguments["ownerID"].(int64), + IsPrivate: ptr.To(req.Params.Arguments["isPrivate"].(bool)), + IsArchived: ptr.To(req.Params.Arguments["isArchived"].(bool)), + Sort: req.Params.Arguments["sort"].(string), + Order: req.Params.Arguments["order"].(string), + ListOptions: gitea_sdk.ListOptions{ + Page: req.Params.Arguments["page"].(int), + PageSize: req.Params.Arguments["pageSize"].(int), + }, + } + repos, _, err := gitea.Client().SearchRepos(opt) + if err != nil { + return nil, fmt.Errorf("search repos error: %v", err) + } + return to.TextResult(repos) +} diff --git a/operation/user/user.go b/operation/user/user.go index 2462b7a..87ba391 100644 --- a/operation/user/user.go +++ b/operation/user/user.go @@ -2,6 +2,7 @@ package user import ( "context" + "fmt" "gitea.com/gitea/gitea-mcp/pkg/gitea" "gitea.com/gitea/gitea-mcp/pkg/log" @@ -30,7 +31,7 @@ func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR log.Debugf("Called GetUserInfoFn") user, _, err := gitea.Client().GetMyUserInfo() if err != nil { - return mcp.NewToolResultError("Get My User Info Error"), err + return nil, fmt.Errorf("get user info err: %v", err) } return to.TextResult(user) diff --git a/pkg/to/to.go b/pkg/to/to.go index a150415..8dd406b 100644 --- a/pkg/to/to.go +++ b/pkg/to/to.go @@ -2,6 +2,7 @@ package to import ( "encoding/json" + "fmt" "gitea.com/gitea/gitea-mcp/pkg/log" "github.com/mark3labs/mcp-go/mcp" @@ -10,7 +11,7 @@ import ( func TextResult(v any) (*mcp.CallToolResult, error) { result, err := json.Marshal(v) if err != nil { - return mcp.NewToolResultError("marshal result error"), err + return nil, fmt.Errorf("marshal result err: %v", err) } log.Debugf("Text Result: %s", string(result)) return mcp.NewToolResultText(string(result)), nil