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.
 
 
 
 
 
 

167 lines
4.7 KiB

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
}