package util import ( "context" "fmt" "strings" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" "fwh-toolbox-server/cmd/mcp/tools/helper" ) func registerFormatTools(s *server.MCPServer) { s.AddTool( mcp.NewTool("util_parse_sn", mcp.WithDescription(`解析 FranklinWH 设备 SN 序列号的含义。 SN 格式: {产品代码}{版本}{工厂}{年}{周}{序号} 示例: 10060006A03X25310091 - 1006: 产品代码 (aGate=1006, aPower=1005, aHub/PowerLink=1002) - 0006: 硬件版本 - A: 工厂代码 - 03: 版本标识 - X: 预留 - 25: 年份(2025) - 31: 周数 - 0091: 序号`), mcp.WithString("sn", mcp.Required(), mcp.Description("设备 SN 序列号")), ), handleParseSN, ) } func handleParseSN(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { sn, err := req.RequireString("sn") if err != nil { return helper.ParamError("sn"), nil } sn = strings.TrimSpace(sn) if len(sn) < 20 { return helper.ParamInvalidError("sn", "SN 长度不足,标准长度为 20 位"), nil } // 解析产品类型 productCode := sn[0:4] var productName string switch productCode { case "1006": productName = "aGate (网关)" case "1005": productName = "aPower (储能电池)" case "1002": productName = "aHub / PowerLink" case "1003": productName = "MPPT" default: productName = "未知产品" } hwVersion := sn[4:8] factory := string(sn[8]) verFlag := sn[9:11] year := sn[12:14] week := sn[14:16] serial := sn[16:] result := map[string]any{ "sn": sn, "productCode": productCode, "productName": productName, "hwVersion": hwVersion, "factory": factory, "versionFlag": verFlag, "year": fmt.Sprintf("20%s", year), "week": week, "serialNumber": serial, "summary": fmt.Sprintf("%s | HW:%s | 工厂:%s | 20%s年第%s周 | 序号:%s", productName, hwVersion, factory, year, week, serial), } return helper.JSONResultOrFileAuto(result), nil }