Skip to content

Commit b18bd14

Browse files
authored
Merge pull request #513 from chaitin/feat/mcp-hub-restart-20260414
feat: 完成 MCP Hub 用户私有配置接入
2 parents 8496944 + 86068c2 commit b18bd14

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+28232
-47
lines changed

backend/biz/git/handler/v1/identity.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ func NewGitIdentityHandler(i *do.Injector) (*GitIdentityHandler, error) {
4949
// @Accept json
5050
// @Produce json
5151
// @Security MonkeyCodeAIAuth
52-
// @Success 200 {object} web.Resp{data=[]domain.GitIdentity} "成功"
53-
// @Failure 500 {object} web.Resp "服务器内部错误"
52+
// @Success 200 {object} web.Resp{data=[]domain.GitIdentity} "成功"
53+
// @Failure 500 {object} web.Resp "服务器内部错误"
5454
// @Router /api/v1/users/git-identities [get]
5555
func (h *GitIdentityHandler) List(c *web.Context) error {
5656
user := middleware.GetUser(c)
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package v1
2+
3+
import (
4+
"log/slog"
5+
6+
"github.com/GoYoko/web"
7+
"github.com/samber/do"
8+
9+
"github.com/chaitin/MonkeyCode/backend/domain"
10+
"github.com/chaitin/MonkeyCode/backend/errcode"
11+
"github.com/chaitin/MonkeyCode/backend/middleware"
12+
)
13+
14+
type MCPHandler struct {
15+
usecase domain.UserMCPUsecase
16+
logger *slog.Logger
17+
}
18+
19+
func NewMCPHandler(i *do.Injector) (*MCPHandler, error) {
20+
w := do.MustInvoke[*web.Web](i)
21+
logger := do.MustInvoke[*slog.Logger](i)
22+
usecase := do.MustInvoke[domain.UserMCPUsecase](i)
23+
auth := do.MustInvoke[*middleware.AuthMiddleware](i)
24+
targetActive := do.MustInvoke[*middleware.TargetActiveMiddleware](i)
25+
26+
h := &MCPHandler{
27+
logger: logger.With("component", "handler.mcp"),
28+
usecase: usecase,
29+
}
30+
31+
v1 := w.Group("/api/v1/users/mcp")
32+
v1.Use(auth.Auth(), targetActive.TargetActive())
33+
v1.GET("/upstreams", web.BindHandler(h.ListUpstreams))
34+
v1.POST("/upstreams", web.BindHandler(h.CreateUpstream))
35+
v1.PUT("/upstreams/:id", web.BindHandler(h.UpdateUpstream))
36+
v1.DELETE("/upstreams/:id", web.BindHandler(h.DeleteUpstream))
37+
v1.POST("/upstreams/:id/sync", web.BindHandler(h.SyncUpstream))
38+
v1.PUT("/tools/:id", web.BindHandler(h.UpdateToolSetting))
39+
40+
return h, nil
41+
}
42+
43+
// ListUpstreams 获取当前用户的 MCP Upstream 列表
44+
//
45+
// @Summary 获取当前用户的 MCP Upstream 列表
46+
// @Description 获取当前登录用户可管理的 MCP Upstream 列表
47+
// @Tags 【用户】MCP 配置
48+
// @Accept json
49+
// @Produce json
50+
// @Param req query domain.CursorReq true "游标分页请求"
51+
// @Security MonkeyCodeAIAuth
52+
// @Success 200 {object} web.Resp{data=domain.ListUserMCPUpstreamsResp} "成功"
53+
// @Failure 401 {object} web.Resp "未授权"
54+
// @Failure 500 {object} web.Resp "服务器内部错误"
55+
// @Router /api/v1/users/mcp/upstreams [get]
56+
func (h *MCPHandler) ListUpstreams(c *web.Context, req domain.CursorReq) error {
57+
user := middleware.GetUser(c)
58+
resp, err := h.usecase.ListUpstreams(c.Request().Context(), user.ID, req)
59+
if err != nil {
60+
return errcode.ErrDatabaseQuery.Wrap(err)
61+
}
62+
return c.Success(resp)
63+
}
64+
65+
// CreateUpstream 创建当前用户的 MCP Upstream
66+
//
67+
// @Summary 创建当前用户的 MCP Upstream
68+
// @Description 为当前登录用户创建自定义 MCP Upstream
69+
// @Tags 【用户】MCP 配置
70+
// @Accept json
71+
// @Produce json
72+
// @Security MonkeyCodeAIAuth
73+
// @Param req body domain.CreateUserMCPUpstreamReq true "创建 MCP Upstream 请求"
74+
// @Success 200 {object} web.Resp{data=domain.MCPUpstream} "成功"
75+
// @Failure 400 {object} web.Resp "请求参数错误"
76+
// @Failure 401 {object} web.Resp "未授权"
77+
// @Failure 500 {object} web.Resp "服务器内部错误"
78+
// @Router /api/v1/users/mcp/upstreams [post]
79+
func (h *MCPHandler) CreateUpstream(c *web.Context, req domain.CreateUserMCPUpstreamReq) error {
80+
user := middleware.GetUser(c)
81+
resp, err := h.usecase.CreateUpstream(c.Request().Context(), user.ID, req)
82+
if err != nil {
83+
return errcode.ErrDatabaseOperation.Wrap(err)
84+
}
85+
return c.Success(resp)
86+
}
87+
88+
// UpdateUpstream 更新当前用户的 MCP Upstream
89+
//
90+
// @Summary 更新当前用户的 MCP Upstream
91+
// @Description 更新当前登录用户指定的 MCP Upstream 配置
92+
// @Tags 【用户】MCP 配置
93+
// @Accept json
94+
// @Produce json
95+
// @Security MonkeyCodeAIAuth
96+
// @Param id path string true "MCP Upstream ID"
97+
// @Param req body domain.UpdateUserMCPUpstreamReq true "更新 MCP Upstream 请求"
98+
// @Success 200 {object} web.Resp{} "成功"
99+
// @Failure 400 {object} web.Resp "请求参数错误"
100+
// @Failure 401 {object} web.Resp "未授权"
101+
// @Failure 404 {object} web.Resp "资源不存在"
102+
// @Failure 500 {object} web.Resp "服务器内部错误"
103+
// @Router /api/v1/users/mcp/upstreams/{id} [put]
104+
func (h *MCPHandler) UpdateUpstream(c *web.Context, req domain.UpdateUserMCPUpstreamReq) error {
105+
user := middleware.GetUser(c)
106+
if err := h.usecase.UpdateUpstream(c.Request().Context(), user.ID, req.ID, req); err != nil {
107+
return errcode.ErrDatabaseOperation.Wrap(err)
108+
}
109+
return c.Success(nil)
110+
}
111+
112+
// DeleteUpstream 删除当前用户的 MCP Upstream
113+
//
114+
// @Summary 删除当前用户的 MCP Upstream
115+
// @Description 删除当前登录用户指定的 MCP Upstream
116+
// @Tags 【用户】MCP 配置
117+
// @Accept json
118+
// @Produce json
119+
// @Security MonkeyCodeAIAuth
120+
// @Param id path string true "MCP Upstream ID"
121+
// @Success 200 {object} web.Resp{} "成功"
122+
// @Failure 400 {object} web.Resp "请求参数错误"
123+
// @Failure 401 {object} web.Resp "未授权"
124+
// @Failure 404 {object} web.Resp "资源不存在"
125+
// @Failure 500 {object} web.Resp "服务器内部错误"
126+
// @Router /api/v1/users/mcp/upstreams/{id} [delete]
127+
func (h *MCPHandler) DeleteUpstream(c *web.Context, req domain.DeleteUserMCPUpstreamReq) error {
128+
user := middleware.GetUser(c)
129+
if err := h.usecase.DeleteUpstream(c.Request().Context(), user.ID, req.ID); err != nil {
130+
return errcode.ErrDatabaseOperation.Wrap(err)
131+
}
132+
return c.Success(nil)
133+
}
134+
135+
// SyncUpstream 同步当前用户的 MCP Upstream
136+
//
137+
// @Summary 同步当前用户的 MCP Upstream
138+
// @Description 触发当前登录用户指定 MCP Upstream 的工具同步
139+
// @Tags 【用户】MCP 配置
140+
// @Accept json
141+
// @Produce json
142+
// @Security MonkeyCodeAIAuth
143+
// @Param id path string true "MCP Upstream ID"
144+
// @Success 200 {object} web.Resp{} "成功"
145+
// @Failure 400 {object} web.Resp "请求参数错误"
146+
// @Failure 401 {object} web.Resp "未授权"
147+
// @Failure 404 {object} web.Resp "资源不存在"
148+
// @Failure 500 {object} web.Resp "服务器内部错误"
149+
// @Router /api/v1/users/mcp/upstreams/{id}/sync [post]
150+
func (h *MCPHandler) SyncUpstream(c *web.Context, req domain.SyncUserMCPUpstreamReq) error {
151+
user := middleware.GetUser(c)
152+
if err := h.usecase.SyncUpstream(c.Request().Context(), user.ID, req.ID); err != nil {
153+
return errcode.ErrDatabaseOperation.Wrap(err)
154+
}
155+
return c.Success(nil)
156+
}
157+
158+
// UpdateToolSetting 更新当前用户的 MCP Tool 开关配置
159+
//
160+
// @Summary 更新当前用户的 MCP Tool 开关配置
161+
// @Description 更新当前登录用户指定 MCP Tool 的启用状态
162+
// @Tags 【用户】MCP 配置
163+
// @Accept json
164+
// @Produce json
165+
// @Security MonkeyCodeAIAuth
166+
// @Param id path string true "MCP Tool ID"
167+
// @Param req body domain.UpdateUserMCPToolSettingReq true "更新 MCP Tool 开关请求"
168+
// @Success 200 {object} web.Resp{} "成功"
169+
// @Failure 400 {object} web.Resp "请求参数错误"
170+
// @Failure 401 {object} web.Resp "未授权"
171+
// @Failure 404 {object} web.Resp "资源不存在"
172+
// @Failure 500 {object} web.Resp "服务器内部错误"
173+
// @Router /api/v1/users/mcp/tools/{id} [put]
174+
func (h *MCPHandler) UpdateToolSetting(c *web.Context, req domain.UpdateUserMCPToolSettingReq) error {
175+
user := middleware.GetUser(c)
176+
if err := h.usecase.UpdateToolSetting(c.Request().Context(), user.ID, req.ID, req.Enabled); err != nil {
177+
return errcode.ErrDatabaseOperation.Wrap(err)
178+
}
179+
return c.Success(nil)
180+
}

backend/biz/setting/register.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,19 @@ import (
1212
func ProvideSetting(i *do.Injector) {
1313
do.Provide(i, repo.NewModelRepo)
1414
do.Provide(i, repo.NewImageRepo)
15+
do.Provide(i, repo.NewMCPRepo)
1516
do.Provide(i, usecase.NewModelUsecase)
1617
do.Provide(i, usecase.NewImageUsecase)
18+
do.Provide(i, usecase.NewUserMCPSyncClient)
19+
do.Provide(i, usecase.NewUserMCPUsecase)
1720
do.Provide(i, v1.NewModelHandler)
1821
do.Provide(i, v1.NewImageHandler)
22+
do.Provide(i, v1.NewMCPHandler)
1923
}
2024

2125
// InvokeSetting 触发 setting 模块的 handler 初始化
2226
func InvokeSetting(i *do.Injector) {
2327
do.MustInvoke[*v1.ModelHandler](i)
2428
do.MustInvoke[*v1.ImageHandler](i)
29+
do.MustInvoke[*v1.MCPHandler](i)
2530
}

0 commit comments

Comments
 (0)