diff --git a/operation/issue/issue.go b/operation/issue/issue.go index f255c07..a13ade4 100644 --- a/operation/issue/issue.go +++ b/operation/issue/issue.go @@ -2,10 +2,10 @@ package issue import ( "context" - "encoding/json" "fmt" "gitea.com/gitea/gitea-mcp/pkg/gitea" + "gitea.com/gitea/gitea-mcp/pkg/to" "github.com/mark3labs/mcp-go/mcp" ) @@ -16,6 +16,10 @@ const ( var ( GetIssueByIndexTool = mcp.NewTool( GetIssueByIndexToolName, + GetIssueByIndexOpt..., + ) + + GetIssueByIndexOpt = []mcp.ToolOption{ mcp.WithDescription("get issue by index"), mcp.WithString( "owner", @@ -32,21 +36,17 @@ var ( mcp.Required(), mcp.Description("repository issue index"), ), - ) + } ) -func GetIssueByIndexFn(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - owner := request.Params.Arguments["owner"].(string) - repo := request.Params.Arguments["repo"].(string) - index := request.Params.Arguments["index"].(float64) +func GetIssueByIndexFn(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) 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 } - result, err := json.Marshal(issue) - if err != nil { - return mcp.NewToolResultError("marshal issue err"), err - } - return mcp.NewToolResultText(string(result)), nil + return to.TextResult(issue) } diff --git a/operation/operation.go b/operation/operation.go index d4885f0..4ae8d51 100644 --- a/operation/operation.go +++ b/operation/operation.go @@ -21,6 +21,7 @@ func RegisterTool(s *server.MCPServer) { s.AddTool(user.GetMyUserInfoTool, user.GetUserInfoFn) // Repo Tool + s.AddTool(repo.CreateRepoTool, repo.CreateRepoFn) s.AddTool(repo.ListMyReposTool, repo.ListMyReposFn) // Issue Tool diff --git a/operation/repo/repo.go b/operation/repo/repo.go index 3d106cf..0c56676 100644 --- a/operation/repo/repo.go +++ b/operation/repo/repo.go @@ -2,20 +2,44 @@ package repo import ( "context" - "encoding/json" "code.gitea.io/sdk/gitea" giteaPkg "gitea.com/gitea/gitea-mcp/pkg/gitea" + "gitea.com/gitea/gitea-mcp/pkg/to" "github.com/mark3labs/mcp-go/mcp" ) const ( + CreateRepoToolName = "create_repo" ListMyReposToolName = "list_my_repos" ) var ( + CreateRepoTool = mcp.NewTool( + CreateRepoToolName, + CreateRepoOpt..., + ) + + CreateRepoOpt = []mcp.ToolOption{ + mcp.WithDescription("Create repository"), + mcp.WithString("name", mcp.Required(), mcp.Description("Name of the repository to create")), + mcp.WithString("description", mcp.Description("Description of the repository to create")), + mcp.WithBoolean("private", mcp.Description("Whether the repository is private")), + mcp.WithString("issue_labels", mcp.Description("Issue Label set to use")), + mcp.WithBoolean("auto_init", mcp.Description("Whether the repository should be auto-intialized?")), + mcp.WithBoolean("template", mcp.Description("Whether the repository is template")), + mcp.WithString("gitignores", mcp.Description("Gitignores to use")), + mcp.WithString("license", mcp.Description("License to use")), + mcp.WithString("readme", mcp.Description("Readme of the repository to create")), + mcp.WithString("default_branch", mcp.Description("DefaultBranch of the repository (used when initializes and in template)")), + } + ListMyReposTool = mcp.NewTool( ListMyReposToolName, + ListMyReposOpt..., + ) + + ListMyReposOpt = []mcp.ToolOption{ mcp.WithDescription("List my repositories"), mcp.WithNumber( "page", @@ -29,15 +53,46 @@ var ( mcp.DefaultNumber(10), mcp.Min(1), ), - ) + } ) -func ListMyReposFn(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - page, ok := request.Params.Arguments["page"].(float64) +func CreateRepoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + name := req.Params.Arguments["name"].(string) + description := req.Params.Arguments["description"].(string) + private := req.Params.Arguments["private"].(bool) + issueLabels := req.Params.Arguments["issue_labels"].(string) + autoInit := req.Params.Arguments["auto_init"].(bool) + template := req.Params.Arguments["template"].(bool) + gitignores := req.Params.Arguments["gitignores"].(string) + license := req.Params.Arguments["license"].(string) + readme := req.Params.Arguments["readme"].(string) + defaultBranch := req.Params.Arguments["default_branch"].(string) + + opt := gitea.CreateRepoOption{ + Name: name, + Description: description, + Private: private, + IssueLabels: issueLabels, + AutoInit: autoInit, + Template: template, + Gitignores: gitignores, + License: license, + Readme: readme, + DefaultBranch: defaultBranch, + } + repo, _, err := giteaPkg.Client().CreateRepo(opt) + if err != nil { + return nil, err + } + return to.TextResult(repo) +} + +func ListMyReposFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { + page, ok := req.Params.Arguments["page"].(float64) if !ok { return mcp.NewToolResultError("get page number error"), nil } - size, ok := request.Params.Arguments["pageSize"].(float64) + size, ok := req.Params.Arguments["pageSize"].(float64) if !ok { return mcp.NewToolResultError("get page size number error"), nil } @@ -52,9 +107,5 @@ func ListMyReposFn(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallT return mcp.NewToolResultError("List my repositories error"), err } - result, err := json.Marshal(repos) - if err != nil { - return mcp.NewToolResultError("marshal repository list error"), err - } - return mcp.NewToolResultText(string(result)), nil + return to.TextResult(repos) } diff --git a/operation/user/user.go b/operation/user/user.go index 1ec87dd..57ae367 100644 --- a/operation/user/user.go +++ b/operation/user/user.go @@ -2,9 +2,9 @@ package user import ( "context" - "encoding/json" "gitea.com/gitea/gitea-mcp/pkg/gitea" + "gitea.com/gitea/gitea-mcp/pkg/to" "github.com/mark3labs/mcp-go/mcp" ) @@ -20,15 +20,11 @@ var ( ) ) -func GetUserInfoFn(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { +func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { user, _, err := gitea.Client().GetMyUserInfo() if err != nil { return mcp.NewToolResultError("Get My User Info Error"), err } - result, err := json.Marshal(user) - if err != nil { - return mcp.NewToolResultError("marshal my user info error"), err - } - return mcp.NewToolResultText(string(result)), nil + return to.TextResult(user) } diff --git a/operation/version/version.go b/operation/version/version.go index 263949b..69dbb96 100644 --- a/operation/version/version.go +++ b/operation/version/version.go @@ -5,6 +5,7 @@ import ( "fmt" "gitea.com/gitea/gitea-mcp/pkg/flag" + "gitea.com/gitea/gitea-mcp/pkg/to" "github.com/mark3labs/mcp-go/mcp" ) @@ -19,10 +20,10 @@ var ( ) ) -func GetGiteaMCPServerVersionFn(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { +func GetGiteaMCPServerVersionFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { version := flag.Version if version == "" { version = "dev" } - return mcp.NewToolResultText(fmt.Sprintf("Gitea MCP Server version: %v", version)), nil + return to.TextResult(fmt.Sprintf("Gitea MCP Server version: %v", version)) } diff --git a/pkg/to/to.go b/pkg/to/to.go new file mode 100644 index 0000000..40ed892 --- /dev/null +++ b/pkg/to/to.go @@ -0,0 +1,15 @@ +package to + +import ( + "encoding/json" + + "github.com/mark3labs/mcp-go/mcp" +) + +func TextResult(v any) (*mcp.CallToolResult, error) { + result, err := json.Marshal(v) + if err != nil { + return mcp.NewToolResultError("marshal result error"), err + } + return mcp.NewToolResultText(string(result)), nil +}