Files
gitea-mcp-server/mcp/operation/settings/settings.go
T

233 lines
7.3 KiB
Go

package settings
import (
"context"
"fmt"
"gitea.com/gitea/gitea-mcp/pkg/gitea"
"gitea.com/gitea/gitea-mcp/pkg/log"
"gitea.com/gitea/gitea-mcp/pkg/params"
"gitea.com/gitea/gitea-mcp/pkg/to"
"gitea.com/gitea/gitea-mcp/pkg/tool"
gitea_sdk "code.gitea.io/sdk/gitea"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
const (
GetUserSettingsToolName = "get_user_settings"
UpdateUserSettingsToolName = "update_user_settings"
GetRepoSettingsToolName = "get_repo_settings"
UpdateRepoSettingsToolName = "update_repo_settings"
)
var Tool = tool.New()
var (
GetUserSettingsTool = mcp.NewTool(
GetUserSettingsToolName,
mcp.WithDescription("Get current user's settings"),
)
UpdateUserSettingsTool = mcp.NewTool(
UpdateUserSettingsToolName,
mcp.WithDescription("Update current user's settings"),
mcp.WithString("description", mcp.Description("User description")),
mcp.WithString("website", mcp.Description("Website URL")),
mcp.WithString("location", mcp.Description("Location")),
mcp.WithString("theme", mcp.Description("Theme preference")),
)
GetRepoSettingsTool = mcp.NewTool(
GetRepoSettingsToolName,
mcp.WithDescription("Get repository settings"),
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
)
UpdateRepoSettingsTool = mcp.NewTool(
UpdateRepoSettingsToolName,
mcp.WithDescription("Update repository settings"),
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
mcp.WithString("description", mcp.Description("Repository description")),
mcp.WithString("website", mcp.Description("Website URL")),
mcp.WithString("default_branch", mcp.Description("Default branch name")),
mcp.WithBoolean("private", mcp.Description("Whether repo is private")),
mcp.WithBoolean("protected", mcp.Description("Whether repo is protected")),
mcp.WithBoolean("enable_wiki", mcp.Description("Enable wiki")),
mcp.WithBoolean("enable_issues", mcp.Description("Enable issues")),
mcp.WithBoolean("enable_pull_requests", mcp.Description("Enable pull requests")),
mcp.WithString("default_merge_style", mcp.Description("Default merge style"), mcp.Enum("merge", "rebase", "squash")),
)
)
func init() {
Tool.RegisterRead(server.ServerTool{
Tool: GetUserSettingsTool,
Handler: getUserSettingsFn,
})
Tool.RegisterRead(server.ServerTool{
Tool: GetRepoSettingsTool,
Handler: getRepoSettingsFn,
})
Tool.RegisterWrite(server.ServerTool{
Tool: UpdateUserSettingsTool,
Handler: updateUserSettingsFn,
})
Tool.RegisterWrite(server.ServerTool{
Tool: UpdateRepoSettingsTool,
Handler: updateRepoSettingsFn,
})
}
func getUserSettingsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[Settings] Called getUserSettingsFn")
client, err := gitea.ClientFromContext(ctx)
if err != nil {
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
}
settings, _, err := client.GetUserSettings()
if err != nil {
return to.ErrorResult(fmt.Errorf("get user settings err: %v", err))
}
return to.TextResult(slimUserSettings(settings))
}
func updateUserSettingsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[Settings] Called updateUserSettingsFn")
args := req.GetArguments()
opt := gitea_sdk.UserSettingsOptions{}
if v, ok := args["description"].(string); ok && v != "" {
opt.Description = &v
}
if v, ok := args["website"].(string); ok && v != "" {
opt.Website = &v
}
if v, ok := args["location"].(string); ok && v != "" {
opt.Location = &v
}
if v, ok := args["theme"].(string); ok && v != "" {
opt.Theme = &v
}
client, err := gitea.ClientFromContext(ctx)
if err != nil {
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
}
settings, _, err := client.UpdateUserSettings(opt)
if err != nil {
return to.ErrorResult(fmt.Errorf("update user settings err: %v", err))
}
return to.TextResult(slimUserSettings(settings))
}
func getRepoSettingsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[Settings] Called getRepoSettingsFn")
args := req.GetArguments()
owner, err := params.GetString(args, "owner")
if err != nil {
return to.ErrorResult(err)
}
repo, err := params.GetString(args, "repo")
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))
}
r, _, err := client.GetRepo(owner, repo)
if err != nil {
return to.ErrorResult(fmt.Errorf("get repo err: %v", err))
}
return to.TextResult(slimRepoSettings(r))
}
func updateRepoSettingsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[Settings] Called updateRepoSettingsFn")
args := req.GetArguments()
owner, err := params.GetString(args, "owner")
if err != nil {
return to.ErrorResult(err)
}
repo, err := params.GetString(args, "repo")
if err != nil {
return to.ErrorResult(err)
}
opt := gitea_sdk.EditRepoOption{}
if v, ok := args["description"].(string); ok && v != "" {
opt.Description = &v
}
if v, ok := args["website"].(string); ok && v != "" {
opt.Website = &v
}
if v, ok := args["default_branch"].(string); ok && v != "" {
opt.DefaultBranch = &v
}
if v, ok := args["private"].(bool); ok {
opt.Private = &v
}
if v, ok := args["protected"].(bool); ok {
opt.Archived = &v
}
if v, ok := args["enable_wiki"].(bool); ok {
opt.HasWiki = &v
}
if v, ok := args["enable_issues"].(bool); ok {
opt.HasIssues = &v
}
if v, ok := args["enable_pull_requests"].(bool); ok {
opt.HasPullRequests = &v
}
if v, ok := args["default_merge_style"].(string); ok && v != "" {
style := gitea_sdk.MergeStyle(v)
opt.DefaultMergeStyle = &style
}
client, err := gitea.ClientFromContext(ctx)
if err != nil {
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
}
r, _, err := client.EditRepo(owner, repo, opt)
if err != nil {
return to.ErrorResult(fmt.Errorf("update repo settings err: %v", err))
}
return to.TextResult(slimRepoSettings(r))
}
func slimUserSettings(s *gitea_sdk.UserSettings) map[string]interface{} {
return map[string]interface{}{
"full_name": s.FullName,
"description": s.Description,
"website": s.Website,
"location": s.Location,
"theme": s.Theme,
"language": s.Language,
"diff_view_style": s.DiffViewStyle,
"hide_email": s.HideEmail,
"hide_activity": s.HideActivity,
}
}
func slimRepoSettings(r *gitea_sdk.Repository) map[string]interface{} {
return map[string]interface{}{
"id": r.ID,
"name": r.Name,
"full_name": r.FullName,
"description": r.Description,
"website": r.Website,
"default_branch": r.DefaultBranch,
"private": r.Private,
"has_wiki": r.HasWiki,
"has_issues": r.HasIssues,
"has_projects": r.HasProjects,
"default_merge_style": r.DefaultMergeStyle,
"default_delete_branch_after_merge": r.DefaultDeleteBranchAfterMerge,
}
}