api_lister.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package mcpTool
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/flipped-aurora/gin-vue-admin/server/global"
  7. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  8. "github.com/mark3labs/mcp-go/mcp"
  9. "go.uber.org/zap"
  10. )
  11. // 注册工具
  12. func init() {
  13. // 注册工具将在enter.go中统一处理
  14. RegisterTool(&ApiLister{})
  15. }
  16. // ApiInfo API信息结构
  17. type ApiInfo struct {
  18. ID uint `json:"id,omitempty"` // 数据库ID(仅数据库API有)
  19. Path string `json:"path"` // API路径
  20. Description string `json:"description,omitempty"` // API描述
  21. ApiGroup string `json:"apiGroup,omitempty"` // API组
  22. Method string `json:"method"` // HTTP方法
  23. Source string `json:"source"` // 来源:database 或 gin
  24. }
  25. // ApiListResponse API列表响应结构
  26. type ApiListResponse struct {
  27. Success bool `json:"success"`
  28. Message string `json:"message"`
  29. DatabaseApis []ApiInfo `json:"databaseApis"` // 数据库中的API
  30. GinApis []ApiInfo `json:"ginApis"` // gin框架中的API
  31. TotalCount int `json:"totalCount"` // 总数量
  32. }
  33. // ApiLister API列表工具
  34. type ApiLister struct{}
  35. // New 创建API列表工具
  36. func (a *ApiLister) New() mcp.Tool {
  37. return mcp.NewTool("list_all_apis",
  38. mcp.WithDescription(`获取系统中所有的API接口,分为两组:
  39. **功能说明:**
  40. - 返回数据库中已注册的API列表
  41. - 返回gin框架中实际注册的路由API列表
  42. - 帮助前端判断是使用现有API还是需要创建新的API,如果api在前端未使用且需要前端调用的时候,请到api文件夹下对应模块的js中添加方法并暴露给当前业务调用
  43. **返回数据结构:**
  44. - databaseApis: 数据库中的API记录(包含ID、描述、分组等完整信息)
  45. - ginApis: gin路由中的API(仅包含路径和方法),需要AI根据路径自行揣摩路径的业务含义,例如:/api/user/:id 表示根据用户ID获取用户信息`),
  46. )
  47. }
  48. // Handle 处理API列表请求
  49. func (a *ApiLister) Handle(_ context.Context, _ mcp.CallToolRequest) (*mcp.CallToolResult, error) {
  50. // 获取数据库中的API
  51. databaseApis, err := a.getDatabaseApis()
  52. if err != nil {
  53. global.GVA_LOG.Error("获取数据库API失败", zap.Error(err))
  54. errorResponse := ApiListResponse{
  55. Success: false,
  56. Message: "获取数据库API失败: " + err.Error(),
  57. }
  58. resultJSON, _ := json.Marshal(errorResponse)
  59. return &mcp.CallToolResult{
  60. Content: []mcp.Content{
  61. mcp.TextContent{
  62. Type: "text",
  63. Text: string(resultJSON),
  64. },
  65. },
  66. }, nil
  67. }
  68. // 获取gin路由中的API
  69. ginApis, err := a.getGinApis()
  70. if err != nil {
  71. global.GVA_LOG.Error("获取gin路由API失败", zap.Error(err))
  72. errorResponse := ApiListResponse{
  73. Success: false,
  74. Message: "获取gin路由API失败: " + err.Error(),
  75. }
  76. resultJSON, _ := json.Marshal(errorResponse)
  77. return &mcp.CallToolResult{
  78. Content: []mcp.Content{
  79. mcp.TextContent{
  80. Type: "text",
  81. Text: string(resultJSON),
  82. },
  83. },
  84. }, nil
  85. }
  86. // 构建响应
  87. response := ApiListResponse{
  88. Success: true,
  89. Message: "获取API列表成功",
  90. DatabaseApis: databaseApis,
  91. GinApis: ginApis,
  92. TotalCount: len(databaseApis) + len(ginApis),
  93. }
  94. global.GVA_LOG.Info("API列表获取成功",
  95. zap.Int("数据库API数量", len(databaseApis)),
  96. zap.Int("gin路由API数量", len(ginApis)),
  97. zap.Int("总数量", response.TotalCount))
  98. resultJSON, err := json.Marshal(response)
  99. if err != nil {
  100. return nil, fmt.Errorf("序列化结果失败: %v", err)
  101. }
  102. return &mcp.CallToolResult{
  103. Content: []mcp.Content{
  104. mcp.TextContent{
  105. Type: "text",
  106. Text: string(resultJSON),
  107. },
  108. },
  109. }, nil
  110. }
  111. // getDatabaseApis 获取数据库中的所有API
  112. func (a *ApiLister) getDatabaseApis() ([]ApiInfo, error) {
  113. var apis []system.SysApi
  114. err := global.GVA_DB.Model(&system.SysApi{}).Order("api_group ASC, path ASC").Find(&apis).Error
  115. if err != nil {
  116. return nil, err
  117. }
  118. // 转换为ApiInfo格式
  119. var result []ApiInfo
  120. for _, api := range apis {
  121. result = append(result, ApiInfo{
  122. ID: api.ID,
  123. Path: api.Path,
  124. Description: api.Description,
  125. ApiGroup: api.ApiGroup,
  126. Method: api.Method,
  127. Source: "database",
  128. })
  129. }
  130. return result, nil
  131. }
  132. // getGinApis 获取gin路由中的所有API(包含被忽略的API)
  133. func (a *ApiLister) getGinApis() ([]ApiInfo, error) {
  134. // 从gin路由信息中获取所有API
  135. var result []ApiInfo
  136. for _, route := range global.GVA_ROUTERS {
  137. result = append(result, ApiInfo{
  138. Path: route.Path,
  139. Method: route.Method,
  140. Source: "gin",
  141. })
  142. }
  143. return result, nil
  144. }