You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

115 lines
2.8 KiB

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
}