Initial commit: Gitea MCP Server
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
package collaborator
|
||||
|
||||
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 (
|
||||
ListCollaboratorsToolName = "list_collaborators"
|
||||
GetCollaboratorToolName = "get_collaborator"
|
||||
AddCollaboratorToolName = "add_collaborator"
|
||||
DeleteCollaboratorToolName = "delete_collaborator"
|
||||
CollaboratorPermissionToolName = "collaborator_permission"
|
||||
)
|
||||
|
||||
var Tool = tool.New()
|
||||
|
||||
var (
|
||||
ListCollaboratorsTool = mcp.NewTool(
|
||||
ListCollaboratorsToolName,
|
||||
mcp.WithDescription("List collaborators for a repository"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("role", mcp.Description("Filter by role (admin, write, read, none)")),
|
||||
)
|
||||
|
||||
GetCollaboratorTool = mcp.NewTool(
|
||||
GetCollaboratorToolName,
|
||||
mcp.WithDescription("Check if a user is a collaborator"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("collaborator", mcp.Required(), mcp.Description("username to check")),
|
||||
)
|
||||
|
||||
AddCollaboratorTool = mcp.NewTool(
|
||||
AddCollaboratorToolName,
|
||||
mcp.WithDescription("Add a collaborator to a repository"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("collaborator", mcp.Required(), mcp.Description("username to add")),
|
||||
mcp.WithString("permission", mcp.Description("Permission level"), mcp.Enum("read", "write", "admin")),
|
||||
)
|
||||
|
||||
DeleteCollaboratorTool = mcp.NewTool(
|
||||
DeleteCollaboratorToolName,
|
||||
mcp.WithDescription("Remove a collaborator from a repository"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("collaborator", mcp.Required(), mcp.Description("username to remove")),
|
||||
)
|
||||
|
||||
CollaboratorPermissionTool = mcp.NewTool(
|
||||
CollaboratorPermissionToolName,
|
||||
mcp.WithDescription("Get collaborator permission details"),
|
||||
mcp.WithString("owner", mcp.Required(), mcp.Description("repository owner")),
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithString("collaborator", mcp.Required(), mcp.Description("username")),
|
||||
)
|
||||
)
|
||||
|
||||
func init() {
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: ListCollaboratorsTool,
|
||||
Handler: listCollaboratorsFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: GetCollaboratorTool,
|
||||
Handler: getCollaboratorFn,
|
||||
})
|
||||
Tool.RegisterRead(server.ServerTool{
|
||||
Tool: CollaboratorPermissionTool,
|
||||
Handler: collaboratorPermissionFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: AddCollaboratorTool,
|
||||
Handler: addCollaboratorFn,
|
||||
})
|
||||
Tool.RegisterWrite(server.ServerTool{
|
||||
Tool: DeleteCollaboratorTool,
|
||||
Handler: deleteCollaboratorFn,
|
||||
})
|
||||
}
|
||||
|
||||
func listCollaboratorsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Collaborator] Called listCollaboratorsFn")
|
||||
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))
|
||||
}
|
||||
|
||||
opt := gitea_sdk.ListCollaboratorsOptions{}
|
||||
|
||||
collabs, _, err := client.ListCollaborators(owner, repo, opt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list collaborators err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult(slimUsers(collabs))
|
||||
}
|
||||
|
||||
func getCollaboratorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Collaborator] Called getCollaboratorFn")
|
||||
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)
|
||||
}
|
||||
collaborator, err := params.GetString(args, "collaborator")
|
||||
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))
|
||||
}
|
||||
|
||||
isCollab, _, err := client.IsCollaborator(owner, repo, collaborator)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("check collaborator err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult(map[string]interface{}{
|
||||
"is_collaborator": isCollab,
|
||||
})
|
||||
}
|
||||
|
||||
func addCollaboratorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Collaborator] Called addCollaboratorFn")
|
||||
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)
|
||||
}
|
||||
collaborator, err := params.GetString(args, "collaborator")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
permission := params.GetOptionalString(args, "permission", "read")
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
|
||||
}
|
||||
|
||||
mode := gitea_sdk.AccessMode(permission)
|
||||
opt := gitea_sdk.AddCollaboratorOption{
|
||||
Permission: &mode,
|
||||
}
|
||||
|
||||
_, err = client.AddCollaborator(owner, repo, collaborator, opt)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("add collaborator err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult("Collaborator added successfully")
|
||||
}
|
||||
|
||||
func deleteCollaboratorFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Collaborator] Called deleteCollaboratorFn")
|
||||
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)
|
||||
}
|
||||
collaborator, err := params.GetString(args, "collaborator")
|
||||
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.DeleteCollaborator(owner, repo, collaborator)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("delete collaborator err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult("Collaborator removed successfully")
|
||||
}
|
||||
|
||||
func collaboratorPermissionFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("[Collaborator] Called collaboratorPermissionFn")
|
||||
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)
|
||||
}
|
||||
collaborator, err := params.GetString(args, "collaborator")
|
||||
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))
|
||||
}
|
||||
|
||||
result, _, err := client.CollaboratorPermission(owner, repo, collaborator)
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("get collaborator permission err: %v", err))
|
||||
}
|
||||
|
||||
return to.TextResult(map[string]interface{}{
|
||||
"permission": result.Permission,
|
||||
"role": result.Role,
|
||||
"user": result.User.UserName,
|
||||
})
|
||||
}
|
||||
|
||||
func slimUsers(users []*gitea_sdk.User) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, len(users))
|
||||
for i, u := range users {
|
||||
result[i] = map[string]interface{}{
|
||||
"id": u.ID,
|
||||
"username": u.UserName,
|
||||
"name": u.FullName,
|
||||
"email": u.Email,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user