package mcp import ( "context" "yunyan/lego/core" "yunyan/lego/core/cbase" "yunyan/lego/sys/log" "yunyan/sys/musicobj" "yunyan/utils" "fmt" "github.com/mark3labs/mcp-go/mcp" ) // 音乐工具(搜索+播放) type tool_music struct { cbase.ModuleCompBase module *Mcp } // 组件初始化接口 func (this *tool_music) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { this.ModuleCompBase.Init(service, module, comp, opt) this.module = module.(*Mcp) return } func (this *tool_music) Start() (err error) { err = this.ModuleCompBase.Start() if this.module.AddTool(ToolGroup_CHINA, this.Tool(), this.Handl) { if err := musicobj.OnInit(this.module.service.GetSettings().Sys["musicobj"]); err != nil { panic(fmt.Sprintf("init sys.musicobj err: %s", err.Error())) } else { log.Infof("init sys.musicobj success!") } } return } func (this *tool_music) Tool() mcp.Tool { return mcp.NewTool("music_search_play", mcp.WithDescription("搜索音乐并返回带播放链接的音乐列表"), mcp.WithString("query", mcp.Description("搜索的音乐关键字 例如:小苹果, 周杰伦, 张学友, 流行音乐等"), mcp.Required(), mcp.DefaultString("热门"), ), mcp.WithNumber("limit", mcp.Description("返回结果数量 (1-20, default 10)"), mcp.DefaultNumber(30), ), mcp.WithNumber("offset", mcp.Description("搜索的音乐偏移量 范围在0到9之间 (默认0)"), mcp.DefaultNumber(0), ), ) } type MusicItem struct { Id int64 `json:"id"` Name string `json:"name"` Singer string `json:"singer"` Image string `json:"image"` Url string `json:"url"` } func (this *tool_music) Handl(ctx context.Context, request mcp.CallToolRequest) (result *mcp.CallToolResult, err error) { var ( query string limit, offset int songslist *musicobj.SearchResultResponse ) if query, err = request.RequireString("query"); err != nil { err = fmt.Errorf("query is required") return } limit = request.GetInt("limit", 30) offset = request.GetInt("offset", 0) if songslist, err = musicobj.SearchMusic(query, limit, offset); err != nil { this.module.Errorln(err) return } if len(songslist.Data.Musics) == 0 { err = fmt.Errorf("no music found") return } musics := make([]*MusicItem, 0, len(songslist.Data.Musics)) for _, v := range songslist.Data.Musics { item := &MusicItem{ Id: v.Id, Name: v.Name, Singer: v.Singer, Image: v.Image, } if urlResp, urlErr := musicobj.MusicUrl(v.Id); urlErr == nil { item.Url = urlResp.Data.URL } musics = append(musics, item) } text := utils.ToString(map[string]interface{}{ "data": musics, "result": "success", }) result = &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: text, }, }, } return }