package mcp import ( "context" "encoding/json" "fmt" "yunyan/lego/core" "yunyan/lego/core/cbase" "yunyan/lego/sys/log" lgmigu "yunyan/sys/migu" "github.com/google/uuid" "github.com/mark3labs/mcp-go/mcp" ) type tool_migu_music struct { cbase.ModuleCompBase module *Mcp } func (this *tool_migu_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_migu_music) Start() (err error) { err = this.ModuleCompBase.Start() if this.module.AddTool(ToolGroup_CHINA, this.Tool(), this.Handl) { if initErr := lgmigu.OnInit(this.module.service.GetSettings().Sys["migu"]); initErr != nil { panic(fmt.Sprintf("init sys.migu err: %s", initErr.Error())) } else { log.Infof("init sys.migu success!") } } return } func (this *tool_migu_music) Tool() mcp.Tool { return mcp.NewTool("migu_music_search", mcp.WithDescription("通过咪咕灵犀搜索音乐,返回带播放信息的音乐列表卡片"), mcp.WithString("query", mcp.Description("搜索的音乐关键字,例如:小苹果、周杰伦、流行音乐等"), mcp.Required(), ), ) } // MiguMusicCard 单条咪咕音乐卡片(H5/模板卡片的原始结构) type MiguMusicCard struct { Type string `json:"type"` // "2"=H5, "3"=模板 Data json.RawMessage `json:"data"` // 咪咕返回的原始卡片数据 } func (this *tool_migu_music) Handl(ctx context.Context, request mcp.CallToolRequest) (result *mcp.CallToolResult, err error) { query, err := request.RequireString("query") if err != nil { err = fmt.Errorf("query is required") return } reqId := uuid.NewString() miguReq := &lgmigu.Request{ ReqId: reqId, Messages: []lgmigu.Message{{Role: "user", Content: fmt.Sprintf("帮我搜索并播放:%s", query)}}, Stream: true, Session: &lgmigu.Session{SessionId: reqId}, } ch := make(chan *lgmigu.StreamResp, 8) go func() { if e := lgmigu.Chat(ctx, miguReq, ch); e != nil { log.Errorf("migu music search err: %v", e) } }() var cards []*MiguMusicCard for sr := range ch { if sr == nil || len(sr.Choices) == 0 { continue } c := sr.Choices[0] if c.Delta.Content == nil { continue } switch c.Delta.Content.Type { case lgmigu.ContentTypeH5, lgmigu.ContentTypeTemplate: cards = append(cards, &MiguMusicCard{ Type: c.Delta.Content.Type, Data: c.Delta.Content.Data, }) } } var text string if len(cards) == 0 { text = fmt.Sprintf(`{"result":"no_music","message":"未找到相关音乐:%s"}`, query) } else { b, _ := json.Marshal(map[string]interface{}{ "result": "success", "data": cards, }) text = string(b) } result = &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: text, }, }, } return }