diff --git a/operation/user/user.go b/operation/user/user.go index d3f5142..5466f8e 100644 --- a/operation/user/user.go +++ b/operation/user/user.go @@ -15,68 +15,94 @@ import ( ) const ( + // GetMyUserInfoToolName is the unique tool name used for MCP registration and lookup of the get_my_user_info command. GetMyUserInfoToolName = "get_my_user_info" - GetUserOrgsToolName = "get_user_orgs" + // 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 = 100 ) +// 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 "pageSize" 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(1)), - mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)), + mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(defaultPage)), + mcp.WithNumber("pageSize", mcp.Description("page size"), 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() { - Tool.RegisterRead(server.ServerTool{ - Tool: GetMyUserInfoTool, - Handler: GetUserInfoFn, - }) - - Tool.RegisterRead(server.ServerTool{ - Tool: GetUserOrgsTool, - Handler: GetUserOrgsFn, - }) + 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) + } +} + +// getIntArg parses an integer argument from the MCP request arguments map. +// Returns def if missing, not a number, or less than 1. Used for pagination arguments. +func getIntArg(req mcp.CallToolRequest, name string, def int) int { + val, ok := req.GetArguments()[name].(float64) + if !ok || val < 1 { + return def + } + return int(val) +} + +// GetUserInfoFn is the handler for "get_my_user_info" 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("Called GetUserInfoFn") + log.Debugf("[User] Called GetUserInfoFn") user, _, err := gitea.Client().GetMyUserInfo() if err != nil { return to.ErrorResult(fmt.Errorf("get user info err: %v", err)) } - return to.TextResult(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("Called GetUserOrgsFn") - page, ok := req.GetArguments()["page"].(float64) - if !ok || page < 1 { - page = 1 - } - pageSize, ok := req.GetArguments()["pageSize"].(float64) - if !ok || pageSize < 1 { - pageSize = 100 - } + log.Debugf("[User] Called GetUserOrgsFn") + page := getIntArg(req, "page", defaultPage) + pageSize := getIntArg(req, "pageSize", defaultPageSize) + opt := gitea_sdk.ListOrgsOptions{ ListOptions: gitea_sdk.ListOptions{ - Page: int(page), - PageSize: int(pageSize), + Page: page, + PageSize: pageSize, }, } orgs, _, err := gitea.Client().ListMyOrgs(opt) if err != nil { return to.ErrorResult(fmt.Errorf("get user orgs err: %v", err)) } - return to.TextResult(orgs) }