Initial commit: Gitea MCP Server

This commit is contained in:
2026-04-10 21:57:19 -07:00
commit 1f27844dce
119 changed files with 25001 additions and 0 deletions
+160
View File
@@ -0,0 +1,160 @@
package orgmember
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 (
CheckOrgMembershipToolName = "check_org_membership"
SetPublicOrgMembershipToolName = "set_public_org_membership"
ListUserOrgsToolName = "list_user_orgs_public"
)
var Tool = tool.New()
var (
CheckOrgMembershipTool = mcp.NewTool(
CheckOrgMembershipToolName,
mcp.WithDescription("Check if a user is a member of an organization"),
mcp.WithString("org", mcp.Required(), mcp.Description("Organization name")),
mcp.WithString("user", mcp.Required(), mcp.Description("Username to check")),
)
SetPublicOrgMembershipTool = mcp.NewTool(
SetPublicOrgMembershipToolName,
mcp.WithDescription("Set public organization membership visibility"),
mcp.WithString("org", mcp.Required(), mcp.Description("Organization name")),
mcp.WithString("user", mcp.Required(), mcp.Description("Username")),
mcp.WithBoolean("visible", mcp.Required(), mcp.Description("Make membership public (true) or private (false)")),
)
ListUserOrgsTool = mcp.NewTool(
ListUserOrgsToolName,
mcp.WithDescription("List organizations a user belongs to"),
mcp.WithString("user", mcp.Required(), mcp.Description("Username")),
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
mcp.WithNumber("perPage", mcp.Description("results per page"), mcp.DefaultNumber(30)),
)
)
func init() {
Tool.RegisterRead(server.ServerTool{
Tool: CheckOrgMembershipTool,
Handler: checkOrgMembershipFn,
})
Tool.RegisterRead(server.ServerTool{
Tool: ListUserOrgsTool,
Handler: listUserOrgsFn,
})
Tool.RegisterWrite(server.ServerTool{
Tool: SetPublicOrgMembershipTool,
Handler: setPublicOrgMembershipFn,
})
}
func checkOrgMembershipFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[OrgMember] Called checkOrgMembershipFn")
args := req.GetArguments()
org, err := params.GetString(args, "org")
if err != nil {
return to.ErrorResult(err)
}
user, err := params.GetString(args, "user")
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))
}
isMember, _, err := client.CheckOrgMembership(org, user)
if err != nil {
return to.ErrorResult(fmt.Errorf("check org membership err: %v", err))
}
return to.TextResult(map[string]interface{}{
"is_member": isMember,
})
}
func setPublicOrgMembershipFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[OrgMember] Called setPublicOrgMembershipFn")
args := req.GetArguments()
org, err := params.GetString(args, "org")
if err != nil {
return to.ErrorResult(err)
}
user, err := params.GetString(args, "user")
if err != nil {
return to.ErrorResult(err)
}
visible, _ := args["visible"].(bool)
client, err := gitea.ClientFromContext(ctx)
if err != nil {
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
}
_, err = client.SetPublicOrgMembership(org, user, visible)
if err != nil {
return to.ErrorResult(fmt.Errorf("set public org membership err: %v", err))
}
return to.TextResult(fmt.Sprintf("Public org membership %s for %s", map[bool]string{true: "enabled", false: "disabled"}[visible], user))
}
func listUserOrgsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
log.Debugf("[OrgMember] Called listUserOrgsFn")
args := req.GetArguments()
user, err := params.GetString(args, "user")
if err != nil {
return to.ErrorResult(err)
}
page, pageSize := params.GetPagination(args, 30)
client, err := gitea.ClientFromContext(ctx)
if err != nil {
return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err))
}
opt := gitea_sdk.ListOrgsOptions{
ListOptions: gitea_sdk.ListOptions{
Page: page,
PageSize: pageSize,
},
}
orgs, _, err := client.ListUserOrgs(user, opt)
if err != nil {
return to.ErrorResult(fmt.Errorf("list user orgs err: %v", err))
}
return to.TextResult(slimOrgs(orgs))
}
func slimOrgs(orgs []*gitea_sdk.Organization) []map[string]interface{} {
result := make([]map[string]interface{}, len(orgs))
for i, o := range orgs {
result[i] = map[string]interface{}{
"id": o.ID,
"username": o.UserName,
"full_name": o.FullName,
"description": o.Description,
"website": o.Website,
}
}
return result
}