2
0

publicmcp.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package controller
  2. import (
  3. "fmt"
  4. "net/http"
  5. "strconv"
  6. "github.com/bytedance/sonic"
  7. "github.com/gin-gonic/gin"
  8. "github.com/labring/aiproxy/core/common/config"
  9. "github.com/labring/aiproxy/core/controller/utils"
  10. "github.com/labring/aiproxy/core/middleware"
  11. "github.com/labring/aiproxy/core/model"
  12. )
  13. type MCPEndpoint struct {
  14. Host string `json:"host"`
  15. SSE string `json:"sse"`
  16. StreamableHTTP string `json:"streamable_http"`
  17. }
  18. type PublicMCPResponse struct {
  19. model.PublicMCP
  20. Endpoints MCPEndpoint `json:"endpoints"`
  21. }
  22. func (mcp *PublicMCPResponse) MarshalJSON() ([]byte, error) {
  23. type Alias PublicMCPResponse
  24. a := &struct {
  25. *Alias
  26. CreatedAt int64 `json:"created_at"`
  27. UpdateAt int64 `json:"update_at"`
  28. }{
  29. Alias: (*Alias)(mcp),
  30. CreatedAt: mcp.CreatedAt.UnixMilli(),
  31. UpdateAt: mcp.UpdateAt.UnixMilli(),
  32. }
  33. return sonic.Marshal(a)
  34. }
  35. func NewPublicMCPResponse(host string, mcp model.PublicMCP) PublicMCPResponse {
  36. ep := MCPEndpoint{}
  37. switch mcp.Type {
  38. case model.PublicMCPTypeProxySSE,
  39. model.PublicMCPTypeProxyStreamable,
  40. model.PublicMCPTypeEmbed,
  41. model.PublicMCPTypeOpenAPI:
  42. publicMCPHost := config.GetPublicMCPHost()
  43. if publicMCPHost == "" {
  44. ep.Host = host
  45. ep.SSE = fmt.Sprintf("/mcp/public/%s/sse", mcp.ID)
  46. ep.StreamableHTTP = "/mcp/public/" + mcp.ID
  47. } else {
  48. ep.Host = fmt.Sprintf("%s.%s", mcp.ID, publicMCPHost)
  49. ep.SSE = "/sse"
  50. ep.StreamableHTTP = "/mcp"
  51. }
  52. case model.PublicMCPTypeDocs:
  53. }
  54. return PublicMCPResponse{
  55. PublicMCP: mcp,
  56. Endpoints: ep,
  57. }
  58. }
  59. func NewPublicMCPResponses(host string, mcps []model.PublicMCP) []PublicMCPResponse {
  60. responses := make([]PublicMCPResponse, len(mcps))
  61. for i, mcp := range mcps {
  62. responses[i] = NewPublicMCPResponse(host, mcp)
  63. }
  64. return responses
  65. }
  66. // GetPublicMCPs godoc
  67. //
  68. // @Summary Get MCPs
  69. // @Description Get a list of MCPs with pagination and filtering
  70. // @Tags mcp
  71. // @Produce json
  72. // @Security ApiKeyAuth
  73. // @Param page query int false "Page number"
  74. // @Param per_page query int false "Items per page"
  75. // @Param type query string false "MCP type"
  76. // @Param keyword query string false "Search keyword"
  77. // @Param status query int false "MCP status"
  78. // @Success 200 {object} middleware.APIResponse{data=[]PublicMCPResponse}
  79. // @Router /api/mcp/public/ [get]
  80. func GetPublicMCPs(c *gin.Context) {
  81. page, perPage := utils.ParsePageParams(c)
  82. mcpType := model.PublicMCPType(c.Query("type"))
  83. keyword := c.Query("keyword")
  84. status, _ := strconv.Atoi(c.Query("status"))
  85. if status == 0 {
  86. status = int(model.PublicMCPStatusEnabled)
  87. }
  88. mcps, total, err := model.GetPublicMCPs(
  89. page,
  90. perPage,
  91. mcpType,
  92. keyword,
  93. model.PublicMCPStatus(status),
  94. )
  95. if err != nil {
  96. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  97. return
  98. }
  99. middleware.SuccessResponse(c, gin.H{
  100. "mcps": NewPublicMCPResponses(c.Request.Host, mcps),
  101. "total": total,
  102. })
  103. }
  104. // GetAllPublicMCPs godoc
  105. //
  106. // @Summary Get all MCPs
  107. // @Description Get all MCPs with filtering
  108. // @Tags mcp
  109. // @Produce json
  110. // @Security ApiKeyAuth
  111. // @Param status query int false "MCP status"
  112. // @Success 200 {object} middleware.APIResponse{data=[]PublicMCPResponse}
  113. // @Router /api/mcp/public/all [get]
  114. func GetAllPublicMCPs(c *gin.Context) {
  115. status, _ := strconv.Atoi(c.Query("status"))
  116. if status == 0 {
  117. status = int(model.PublicMCPStatusEnabled)
  118. }
  119. mcps, err := model.GetAllPublicMCPs(model.PublicMCPStatus(status))
  120. if err != nil {
  121. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  122. return
  123. }
  124. middleware.SuccessResponse(c, NewPublicMCPResponses(c.Request.Host, mcps))
  125. }
  126. // GetPublicMCPByIDHandler godoc
  127. //
  128. // @Summary Get MCP by ID
  129. // @Description Get a specific MCP by its ID
  130. // @Tags mcp
  131. // @Produce json
  132. // @Security ApiKeyAuth
  133. // @Param id path string true "MCP ID"
  134. // @Success 200 {object} middleware.APIResponse{data=PublicMCPResponse}
  135. // @Router /api/mcp/public/{id} [get]
  136. func GetPublicMCPByIDHandler(c *gin.Context) {
  137. id := c.Param("id")
  138. if id == "" {
  139. middleware.ErrorResponse(c, http.StatusBadRequest, "MCP ID is required")
  140. return
  141. }
  142. mcp, err := model.GetPublicMCPByID(id)
  143. if err != nil {
  144. middleware.ErrorResponse(c, http.StatusNotFound, err.Error())
  145. return
  146. }
  147. middleware.SuccessResponse(c, NewPublicMCPResponse(c.Request.Host, mcp))
  148. }
  149. // CreatePublicMCP godoc
  150. //
  151. // @Summary Create MCP
  152. // @Description Create a new MCP
  153. // @Tags mcp
  154. // @Accept json
  155. // @Produce json
  156. // @Security ApiKeyAuth
  157. // @Param mcp body model.PublicMCP true "MCP object"
  158. // @Success 200 {object} middleware.APIResponse{data=PublicMCPResponse}
  159. // @Router /api/mcp/public/ [post]
  160. func CreatePublicMCP(c *gin.Context) {
  161. var mcp model.PublicMCP
  162. if err := c.ShouldBindJSON(&mcp); err != nil {
  163. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  164. return
  165. }
  166. if err := model.CreatePublicMCP(&mcp); err != nil {
  167. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  168. return
  169. }
  170. middleware.SuccessResponse(c, NewPublicMCPResponse(c.Request.Host, mcp))
  171. }
  172. type UpdatePublicMCPStatusRequest struct {
  173. Status model.PublicMCPStatus `json:"status"`
  174. }
  175. // UpdatePublicMCPStatus godoc
  176. //
  177. // @Summary Update MCP status
  178. // @Description Update the status of an MCP
  179. // @Tags mcp
  180. // @Accept json
  181. // @Produce json
  182. // @Security ApiKeyAuth
  183. // @Param id path string true "MCP ID"
  184. // @Param status body UpdatePublicMCPStatusRequest true "MCP status"
  185. // @Success 200 {object} middleware.APIResponse
  186. // @Router /api/mcp/public/{id}/status [post]
  187. func UpdatePublicMCPStatus(c *gin.Context) {
  188. id := c.Param("id")
  189. if id == "" {
  190. middleware.ErrorResponse(c, http.StatusBadRequest, "MCP ID is required")
  191. return
  192. }
  193. var status UpdatePublicMCPStatusRequest
  194. if err := c.ShouldBindJSON(&status); err != nil {
  195. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  196. return
  197. }
  198. if err := model.UpdatePublicMCPStatus(id, status.Status); err != nil {
  199. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  200. return
  201. }
  202. middleware.SuccessResponse(c, nil)
  203. }
  204. // UpdatePublicMCP godoc
  205. //
  206. // @Summary Update MCP
  207. // @Description Update an existing MCP
  208. // @Tags mcp
  209. // @Accept json
  210. // @Produce json
  211. // @Security ApiKeyAuth
  212. // @Param id path string true "MCP ID"
  213. // @Param mcp body model.PublicMCP true "MCP object"
  214. // @Success 200 {object} middleware.APIResponse{data=PublicMCPResponse}
  215. // @Router /api/mcp/public/{id} [put]
  216. func UpdatePublicMCP(c *gin.Context) {
  217. id := c.Param("id")
  218. if id == "" {
  219. middleware.ErrorResponse(c, http.StatusBadRequest, "MCP ID is required")
  220. return
  221. }
  222. var mcp model.PublicMCP
  223. if err := c.ShouldBindJSON(&mcp); err != nil {
  224. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  225. return
  226. }
  227. mcp.ID = id
  228. if err := model.UpdatePublicMCP(&mcp); err != nil {
  229. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  230. return
  231. }
  232. middleware.SuccessResponse(c, NewPublicMCPResponse(c.Request.Host, mcp))
  233. }
  234. // DeletePublicMCP godoc
  235. //
  236. // @Summary Delete MCP
  237. // @Description Delete an MCP by ID
  238. // @Tags mcp
  239. // @Produce json
  240. // @Security ApiKeyAuth
  241. // @Param id path string true "MCP ID"
  242. // @Success 200 {object} middleware.APIResponse
  243. // @Router /api/mcp/public/{id} [delete]
  244. func DeletePublicMCP(c *gin.Context) {
  245. id := c.Param("id")
  246. if id == "" {
  247. middleware.ErrorResponse(c, http.StatusBadRequest, "MCP ID is required")
  248. return
  249. }
  250. if err := model.DeletePublicMCP(id); err != nil {
  251. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  252. return
  253. }
  254. middleware.SuccessResponse(c, nil)
  255. }
  256. // GetGroupPublicMCPReusingParam godoc
  257. //
  258. // @Summary Get group MCP reusing parameters
  259. // @Description Get reusing parameters for a specific group and MCP
  260. // @Tags mcp
  261. // @Produce json
  262. // @Security ApiKeyAuth
  263. // @Param id path string true "MCP ID"
  264. // @Param group path string true "Group ID"
  265. // @Success 200 {object} middleware.APIResponse{data=model.PublicMCPReusingParam}
  266. // @Router /api/mcp/public/{id}/group/{group}/params [get]
  267. func GetGroupPublicMCPReusingParam(c *gin.Context) {
  268. mcpID := c.Param("id")
  269. groupID := c.Param("group")
  270. if mcpID == "" || groupID == "" {
  271. middleware.ErrorResponse(c, http.StatusBadRequest, "MCP ID and Group ID are required")
  272. return
  273. }
  274. param, err := model.GetPublicMCPReusingParam(mcpID, groupID)
  275. if err != nil {
  276. middleware.ErrorResponse(c, http.StatusNotFound, err.Error())
  277. return
  278. }
  279. middleware.SuccessResponse(c, param)
  280. }
  281. // SaveGroupPublicMCPReusingParam godoc
  282. //
  283. // @Summary Create or update group MCP reusing parameters
  284. // @Description Create or update reusing parameters for a specific group and MCP
  285. // @Tags mcp
  286. // @Accept json
  287. // @Produce json
  288. // @Security ApiKeyAuth
  289. // @Param id path string true "MCP ID"
  290. // @Param group path string true "Group ID"
  291. // @Param params body model.PublicMCPReusingParam true "Reusing parameters"
  292. // @Success 200 {object} middleware.APIResponse
  293. // @Router /api/mcp/public/{id}/group/{group}/params [post]
  294. func SaveGroupPublicMCPReusingParam(c *gin.Context) {
  295. mcpID := c.Param("id")
  296. groupID := c.Param("group")
  297. if mcpID == "" || groupID == "" {
  298. middleware.ErrorResponse(c, http.StatusBadRequest, "MCP ID and Group ID are required")
  299. return
  300. }
  301. var param model.PublicMCPReusingParam
  302. if err := c.ShouldBindJSON(&param); err != nil {
  303. middleware.ErrorResponse(c, http.StatusBadRequest, err.Error())
  304. return
  305. }
  306. param.MCPID = mcpID
  307. param.GroupID = groupID
  308. if err := model.SavePublicMCPReusingParam(&param); err != nil {
  309. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  310. return
  311. }
  312. middleware.SuccessResponse(c, param)
  313. }