package issue import ( "context" "errors" "fmt" "git.lethalbits.com/lethalbits/gitea-mcp-extended/pkg/gitea" "git.lethalbits.com/lethalbits/gitea-mcp-extended/pkg/log" "git.lethalbits.com/lethalbits/gitea-mcp-extended/pkg/params" "git.lethalbits.com/lethalbits/gitea-mcp-extended/pkg/to" gitea_sdk "code.gitea.io/sdk/gitea" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" ) const ( ListIssueSubscribersToolName = "list_issue_subscribers" CheckIssueSubscriptionToolName = "check_issue_subscription" IssueSubscribeToolName = "issue_subscribe" IssueUnSubscribeToolName = "issue_unsubscribe" ) var ( ListIssueSubscribersTool = mcp.NewTool( ListIssueSubscribersToolName, mcp.WithDescription("List users subscribed to an issue"), 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("issue index")), ) CheckIssueSubscriptionTool = mcp.NewTool( CheckIssueSubscriptionToolName, mcp.WithDescription("Check if the authenticated user is subscribed to an issue"), 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("issue index")), ) IssueSubscribeTool = mcp.NewTool( IssueSubscribeToolName, mcp.WithDescription("Subscribe to an issue"), 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("issue index")), ) IssueUnSubscribeTool = mcp.NewTool( IssueUnSubscribeToolName, mcp.WithDescription("Unsubscribe from an issue"), 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("issue index")), ) ) func init() { Tool.RegisterRead(server.ServerTool{Tool: ListIssueSubscribersTool, Handler: ListIssueSubscribersFn}) Tool.RegisterRead(server.ServerTool{Tool: CheckIssueSubscriptionTool, Handler: CheckIssueSubscriptionFn}) Tool.RegisterWrite(server.ServerTool{Tool: IssueSubscribeTool, Handler: IssueSubscribeFn}) Tool.RegisterWrite(server.ServerTool{Tool: IssueUnSubscribeTool, Handler: IssueUnSubscribeFn}) } func ListIssueSubscribersFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("Called ListIssueSubscribersFn") owner, _ := req.GetArguments()["owner"].(string) repo, _ := req.GetArguments()["repo"].(string) if owner == "" || repo == "" { return to.ErrorResult(errors.New("owner and repo are required")) } index, err := params.GetIndex(req.GetArguments(), "index") if err != nil { return to.ErrorResult(err) } client, err := gitea.ClientFromContext(ctx) if err != nil { return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) } users, _, err := client.ListIssueSubscribers(owner, repo, index, gitea_sdk.ListIssueSubscribersOptions{}) if err != nil { return to.ErrorResult(fmt.Errorf("list issue subscribers err: %v", err)) } return to.TextResult(users) } func CheckIssueSubscriptionFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("Called CheckIssueSubscriptionFn") owner, _ := req.GetArguments()["owner"].(string) repo, _ := req.GetArguments()["repo"].(string) if owner == "" || repo == "" { return to.ErrorResult(errors.New("owner and repo are required")) } index, err := params.GetIndex(req.GetArguments(), "index") if err != nil { return to.ErrorResult(err) } client, err := gitea.ClientFromContext(ctx) if err != nil { return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) } info, _, err := client.CheckIssueSubscription(owner, repo, index) if err != nil { return to.ErrorResult(fmt.Errorf("check issue subscription err: %v", err)) } return to.TextResult(info) } func IssueSubscribeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("Called IssueSubscribeFn") owner, _ := req.GetArguments()["owner"].(string) repo, _ := req.GetArguments()["repo"].(string) if owner == "" || repo == "" { return to.ErrorResult(errors.New("owner and repo are required")) } index, err := params.GetIndex(req.GetArguments(), "index") if err != nil { return to.ErrorResult(err) } client, err := gitea.ClientFromContext(ctx) if err != nil { return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) } _, err = client.IssueSubscribe(owner, repo, index) if err != nil { return to.ErrorResult(fmt.Errorf("issue subscribe err: %v", err)) } return to.TextResult(map[string]string{"status": "subscribed"}) } func IssueUnSubscribeFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("Called IssueUnSubscribeFn") owner, _ := req.GetArguments()["owner"].(string) repo, _ := req.GetArguments()["repo"].(string) if owner == "" || repo == "" { return to.ErrorResult(errors.New("owner and repo are required")) } index, err := params.GetIndex(req.GetArguments(), "index") if err != nil { return to.ErrorResult(err) } client, err := gitea.ClientFromContext(ctx) if err != nil { return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) } _, err = client.IssueUnSubscribe(owner, repo, index) if err != nil { return to.ErrorResult(fmt.Errorf("issue unsubscribe err: %v", err)) } return to.TextResult(map[string]string{"status": "unsubscribed"}) }