Initial commit: Gitea MCP Server
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
package mirror
|
||||
|
||||
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 (
|
||||
ListPushMirrorsToolName = "list_push_mirrors"
|
||||
GetPushMirrorToolName = "get_push_mirror"
|
||||
CreatePushMirrorToolName = "create_push_mirror"
|
||||
DeletePushMirrorToolName = "delete_push_mirror"
|
||||
SyncMirrorToolName = "sync_mirror"
|
||||
)
|
||||
|
||||
var Tool = tool.New()
|
||||
|
||||
var (
|
||||
ListPushMirrorsTool = mcp.NewTool(
|
||||
ListPushMirrorsToolName,
|
||||
mcp.WithDescription("List push mirrors for a repository"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
)
|
||||
|
||||
GetPushMirrorTool = mcp.NewTool(
|
||||
GetPushMirrorToolName,
|
||||
mcp.WithDescription("Get a specific push mirror by remote name"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("remote_name", mcp.Required(), mcp.Description("Remote name")),
|
||||
)
|
||||
|
||||
CreatePushMirrorTool = mcp.NewTool(
|
||||
CreatePushMirrorToolName,
|
||||
mcp.WithDescription("Create a push mirror for a repository"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("remote_name", mcp.Required(), mcp.Description("Remote name")),
|
||||
mcp.WithString("remote_addr", mcp.Required(), mcp.Description("Remote address (git URL)")),
|
||||
mcp.WithString("sync_interval", mcp.Description("Sync interval (e.g. 8h30m0s)")),
|
||||
mcp.WithBoolean("sync_on_commit", mcp.Description("Sync on commit"), mcp.DefaultBool(false)),
|
||||
)
|
||||
|
||||
DeletePushMirrorTool = mcp.NewTool(
|
||||
DeletePushMirrorToolName,
|
||||
mcp.WithDescription("Delete a push mirror"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("remote_name", mcp.Required(), mcp.Description("Remote name")),
|
||||
)
|
||||
|
||||
SyncMirrorTool = mcp.NewTool(
|
||||
SyncMirrorToolName,
|
||||
mcp.WithDescription("Trigger immediate sync for a mirror repository"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
)
|
||||
)
|
||||
|
||||
func init() {
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: ListPushMirrorsTool,
|
||||
Handler: listPushMirrorsFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: GetPushMirrorTool,
|
||||
Handler: getPushMirrorFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: CreatePushMirrorTool,
|
||||
Handler: createPushMirrorFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: DeletePushMirrorTool,
|
||||
Handler: deletePushMirrorFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: SyncMirrorTool,
|
||||
Handler: syncMirrorFn,
|
||||
})
|
||||
}
|
||||
|
||||
func listPushMirrorsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Mirror] Called listPushMirrorsFn")
|
||||
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))
|
||||
}
|
||||
|
||||
mirrors, _, err := client.ListPushMirrors(owner, repo, gitea_sdk.ListOptions{})
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list push mirrors err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult(slimMirrors(mirrors))
|
||||
}
|
||||
|
||||
func getPushMirrorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Mirror] Called getPushMirrorFn")
|
||||
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)
|
||||
}
|
||||
remoteName, err := params.GetString(args, "remote_name")
|
||||
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))
|
||||
}
|
||||
|
||||
mirror, _, err := client.GetPushMirrorByRemoteName(owner, repo, remoteName)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get push mirror err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult(slimMirror(mirror))
|
||||
}
|
||||
|
||||
func createPushMirrorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Mirror] Called createPushMirrorFn")
|
||||
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)
|
||||
}
|
||||
remoteAddr, err := params.GetString(args, "remote_addr")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
syncInterval, _ := args["sync_interval"].(string)
|
||||
syncOnCommit, _ := args["sync_on_commit"].(bool)
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
opt := gitea_sdk.CreatePushMirrorOption{
|
||||
RemoteAddress: remoteAddr,
|
||||
Interval: syncInterval,
|
||||
SyncONCommit: syncOnCommit,
|
||||
}
|
||||
|
||||
mirror, _, err := client.PushMirrors(owner, repo, opt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("create push mirror err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult(slimMirror(mirror))
|
||||
}
|
||||
|
||||
func deletePushMirrorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Mirror] Called deletePushMirrorFn")
|
||||
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)
|
||||
}
|
||||
remoteName, err := params.GetString(args, "remote_name")
|
||||
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.DeletePushMirror(owner, repo, remoteName)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("delete push mirror err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult("Push mirror deleted successfully")
|
||||
}
|
||||
|
||||
func syncMirrorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Mirror] Called syncMirrorFn")
|
||||
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))
|
||||
}
|
||||
|
||||
_, err = client.MirrorSync(owner, repo)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("sync mirror err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult("Mirror sync triggered successfully")
|
||||
}
|
||||
|
||||
func slimMirrors(mirrors []*gitea_sdk.PushMirrorResponse) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, len(mirrors))
|
||||
for i, m := range mirrors {
|
||||
result[i] = slimMirror(m)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func slimMirror(m *gitea_sdk.PushMirrorResponse) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"remote_name": m.RemoteName,
|
||||
"remote_addr": m.RemoteAddress,
|
||||
"interval": m.Interval,
|
||||
"sync_on_commit": m.SyncONCommit,
|
||||
"last_update": m.LastUpdate,
|
||||
"last_error": m.LastError,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user