package user 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 ( // GetMyUserInfoToolName is the unique tool name used for MCP registration and lookup of the get_me command. GetMyUserInfoToolName = "get_me" // GetUserOrgsToolName is the unique tool name used for MCP registration and lookup of the get_user_orgs command. GetUserOrgsToolName = "get_user_orgs" // defaultPage is the default starting page number used for paginated organization listings. defaultPage = 1 // defaultPageSize is the default number of organizations per page for paginated queries. defaultPageSize = 30 ) // Tool is the MCP tool manager instance for registering all MCP tools in this package. var Tool = tool.New() var ( // GetMyUserInfoTool is the MCP tool for retrieving the current user's info. // It is registered with a specific name and a description string. GetMyUserInfoTool = mcp.NewTool( GetMyUserInfoToolName, mcp.WithDescription("Get my user info"), ) // GetUserOrgsTool is the MCP tool for listing organizations for the authenticated user. // It supports pagination via "page" and "perPage" arguments with default values specified above. GetUserOrgsTool = mcp.NewTool( GetUserOrgsToolName, mcp.WithDescription("Get organizations associated with the authenticated user"), mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(defaultPage)), mcp.WithNumber("perPage", mcp.Description("results per page"), mcp.DefaultNumber(defaultPageSize)), ) ) // init registers all MCP tools in Tool at package initialization. // This function ensures the handler functions are registered before server usage. func init() { registerTools() } // registerTools registers all local MCP tool definitions and their handler functions. // To add new functionality, append your tool/handler pair to the tools slice below. func registerTools() { tools := []server.ServerTool{ {Tool: GetMyUserInfoTool, Handler: GetUserInfoFn}, {Tool: GetUserOrgsTool, Handler: GetUserOrgsFn}, } for _, t := range tools { Tool.RegisterRead(t) } } // GetUserInfoFn is the handler for "get_me" MCP tool requests. // Logs invocation, fetches current user info from gitea, wraps result for MCP. func GetUserInfoFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("[User] Called GetUserInfoFn") client, err := gitea.ClientFromContext(ctx) if err != nil { return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) } user, _, err := client.GetMyUserInfo() if err != nil { return to.ErrorResult(fmt.Errorf("get user info err: %v", err)) } return to.TextResult(slimUserDetail(user)) } // GetUserOrgsFn is the handler for "get_user_orgs" MCP tool requests. // Logs invocation, pulls validated pagination arguments from request, // performs Gitea organization listing, and wraps the result for MCP. func GetUserOrgsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { log.Debugf("[User] Called GetUserOrgsFn") page, pageSize := params.GetPagination(req.GetArguments(), defaultPageSize) opt := gitea_sdk.ListOrgsOptions{ ListOptions: gitea_sdk.ListOptions{ Page: page, PageSize: pageSize, }, } client, err := gitea.ClientFromContext(ctx) if err != nil { return to.ErrorResult(fmt.Errorf("get gitea client err: %v", err)) } orgs, _, err := client.ListMyOrgs(opt) if err != nil { return to.ErrorResult(fmt.Errorf("get user orgs err: %v", err)) } return to.TextResult(slimOrgs(orgs)) }