Skip to content

Commit d4a571f

Browse files
author
piexlMax(奇淼
committed
feat(mcp): 增加API Lister Mcp,为前端页面提供api结构
1 parent 1e3c968 commit d4a571f

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed

server/mcp/api_lister.go

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

0 commit comments

Comments
 (0)