package system import ( "context" "os" "path/filepath" "strings" "text/template" "unicode" systemReq "git.echol.cn/loser/Go-Web-Template/server/model/system/request" ) type McpService struct{} func (s *McpService) CreateToolTemplate(_ context.Context, info systemReq.McpToolTemplateRequest) (string, error) { serverRoot := resolveServiceServerRoot() templatePath := filepath.Join(serverRoot, "resource", "mcp", "tools.tpl") targetDir := filepath.Join(serverRoot, "mcp") files, err := template.New(filepath.Base(templatePath)).Funcs(template.FuncMap{ "title": toToolStructName, }).ParseFiles(templatePath) if err != nil { return "", err } fileName := toToolFileName(info.Name) targetPath := filepath.Join(targetDir, fileName+".go") f, err := os.Create(targetPath) if err != nil { return "", err } defer f.Close() if err := files.Execute(f, info); err != nil { return "", err } return targetPath, nil } func resolveServiceServerRoot() string { if cwd, err := os.Getwd(); err == nil { if filepath.Base(cwd) == "server" { return cwd } if _, err := os.Stat(filepath.Join(cwd, "server")); err == nil { return filepath.Join(cwd, "server") } return cwd } return "server" } func toToolFileName(name string) string { var b strings.Builder for index, r := range name { if unicode.IsUpper(r) { if index > 0 { b.WriteByte('_') } b.WriteRune(unicode.ToLower(r)) continue } if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { b.WriteRune(unicode.ToLower(r)) continue } b.WriteByte('_') } return strings.Trim(b.String(), "_") } func toToolStructName(name string) string { parts := strings.FieldsFunc(name, func(r rune) bool { return !(unicode.IsLetter(r) || unicode.IsDigit(r)) }) var b strings.Builder for _, part := range parts { if part == "" { continue } runes := []rune(strings.ToLower(part)) runes[0] = unicode.ToUpper(runes[0]) b.WriteString(string(runes)) } if b.Len() == 0 { return "CustomTool" } return b.String() }