refactor: refactor MCP tool registration and pagination handling (#86) All checks were successful release-nightly / release-image (push) Successful in 1m8s
All checks were successful
release-nightly / release-image (push) Successful in 1m8s
- Add documentation for MCP tool constants and tool registration - Use configurable default values for pagination arguments in user organization queries - Introduce registerTools helper to streamline MCP tool registration - Refactor pagination argument parsing into a reusable getIntArg function - Add descriptive logging for tool handler execution - Improve code organization for defining and registering MCP tools Signed-off-by: appleboy <appleboy.tw@gmail.com> Reviewed-on: #86 Co-authored-by: appleboy <appleboy.tw@gmail.com> Co-committed-by: appleboy <appleboy.tw@gmail.com>
This commit was merged in pull request #86.
This commit is contained in:
@@ -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) | ||||
} | ||||
|
Reference in New Issue
Block a user