package mcp import ( "context" "yunyan/lego/core" "yunyan/lego/core/cbase" "yunyan/lego/sys/log" "yunyan/sys/amap" "fmt" "github.com/mark3labs/mcp-go/mcp" ) // 搜索卡片 结构统一化输出 type MapsSearchCard struct { Items []MapsSearchItem `json:"items"` } // 搜索条目 type MapsSearchItem struct { Name string `json:"name"` Addr string `json:"addr"` Tag string `json:"tag"` Rating string `json:"rating"` Distance string `json:"distance"` Images []string `json:"images"` } // 周边搜索 type tool_gaode_map_around_search struct { cbase.ModuleCompBase module *Mcp } // 组件初始化接口 func (this *tool_gaode_map_around_search) 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_gaode_map_around_search) Start() (err error) { err = this.ModuleCompBase.Start() if this.module.AddTool(ToolGroup_CHINA, this.Tool(), this.Handl) { if err := amap.OnInit(this.module.service.GetSettings().Sys["amap"]); err != nil { panic(fmt.Sprintf("init sys.amap err: %s", err.Error())) } else { log.Infof("init sys.amap success!") } } return } func (this *tool_gaode_map_around_search) Tool() (tool mcp.Tool) { return mcp.NewTool("gaode_map_around_search", mcp.WithDescription("搜索周边附近相关信息,,比如搜索周边餐厅,酒店,景点等"), mcp.WithString("lng", mcp.Description("经度坐标 例如:116.434307"), mcp.Required(), ), mcp.WithString("lat", mcp.Description("经度坐标 例如:39.90909"), mcp.Required(), ), mcp.WithString("radius", mcp.Description("搜索范围 半径,默认5000米,单位:米 例如:5000"), mcp.DefaultString("5000"), ), mcp.WithString("keywords", mcp.Description("搜索内容 例如:餐厅"), mcp.Required(), ), ) } // Handl 工具处理接口 // 参数: // - ctx: 上下文 // - request: MCP 工具调用请求 // // 返回值: // - result: MCP 工具调用结果 // - err: 处理过程中的错误 // // 异常: // - 无(不主动 panic) func (this *tool_gaode_map_around_search) Handl(ctx context.Context, request mcp.CallToolRequest) (result *mcp.CallToolResult, err error) { var ( lng, lat, radius, keywords string location *amap.LocationResponse searchResult *amap.POIResponse context string card *MapsSearchCard ) this.module.Debug("tool_gaode_map_around_search", log.Field{Key: "request.Params.Arguments", Value: request.GetRawArguments()}, ) if lng, err = request.RequireString("lng"); err != nil { err = fmt.Errorf("必要参数丢失") context = "获取目标地址失败" return } if lat, err = request.RequireString("lat"); err != nil { err = fmt.Errorf("必要参数丢失") context = "获取目标地址失败" return } if keywords, err = request.RequireString("keywords"); err != nil { err = fmt.Errorf("keywords读取失败") log.Error("keywords读取失败") return } radius = request.GetString("radius", "10000") if location, err = amap.Coordinate(lng, lat); err == nil { searchResult, err = amap.POISearch(location.Locations, radius, keywords) } if err != nil { context = "周边搜索失败" this.module.Debug("tool_gaode_map_around_search fail", log.Field{Key: "location", Value: location}, log.Field{Key: "radius", Value: radius}, log.Field{Key: "keywords", Value: keywords}, log.Field{Key: "searchResult", Value: searchResult}, log.Field{Key: "err", Value: err}, ) return } else { card = &MapsSearchCard{ Items: make([]MapsSearchItem, 0), } context = "" for _, v := range searchResult.POIs { item := MapsSearchItem{ Name: v.Name, Addr: v.Address, Distance: v.Distance, Tag: v.Business.Tag, Rating: v.Business.Rating, } context += fmt.Sprintf("名称:%s,地址:%s,评分:%s,距离:%s,标签:%s;", item.Name, item.Addr, item.Rating, item.Distance, item.Tag) for _, v1 := range v.Photos { item.Images = append(item.Images, v1.URL) } card.Items = append(card.Items, item) } this.module.Debug("tool_gaode_map_around_search success", log.Field{Key: "location", Value: location}, log.Field{Key: "radius", Value: radius}, log.Field{Key: "keywords", Value: keywords}, log.Field{Key: "searchResult", Value: searchResult}, ) } result = &mcp.CallToolResult{ Content: []mcp.Content{ mcp.TextContent{ Type: "text", Text: context, }, }, } // if card != nil { // result.Meta = map[string]interface{}{ // "card_travel": card, // } // } return }