Skip to content

Commit bba8aab

Browse files
feat: Add MCP management (#8299)
1 parent 47d135e commit bba8aab

File tree

49 files changed

+2259
-4
lines changed

Some content is hidden

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

49 files changed

+2259
-4
lines changed

Diff for: backend/app/api/v1/entry.go

+2
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,6 @@ var (
6868
favoriteService = service.NewIFavoriteService()
6969

7070
websiteCAService = service.NewIWebsiteCAService()
71+
72+
mcpServerService = service.NewIMcpServerService()
7173
)

Diff for: backend/app/api/v1/mcp_server.go

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package v1
2+
3+
import (
4+
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
5+
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
6+
"github.com/1Panel-dev/1Panel/backend/constant"
7+
"github.com/gin-gonic/gin"
8+
)
9+
10+
// @Tags McpServer
11+
// @Summary List mcp servers
12+
// @Accept json
13+
// @Param request body request.McpServerSearch true "request"
14+
// @Success 200 {object} response.McpServersRes
15+
// @Security ApiKeyAuth
16+
// @Security Timestamp
17+
// @Router /mcp/search [post]
18+
func (b *BaseApi) PageMcpServers(c *gin.Context) {
19+
var req request.McpServerSearch
20+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
21+
return
22+
}
23+
list := mcpServerService.Page(req)
24+
helper.SuccessWithData(c, list)
25+
}
26+
27+
// @Tags McpServer
28+
// @Summary Create mcp server
29+
// @Accept json
30+
// @Param request body request.McpServerCreate true "request"
31+
// @Success 200
32+
// @Security ApiKeyAuth
33+
// @Security Timestamp
34+
// @Router /mcp/server [post]
35+
func (b *BaseApi) CreateMcpServer(c *gin.Context) {
36+
var req request.McpServerCreate
37+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
38+
return
39+
}
40+
err := mcpServerService.Create(req)
41+
if err != nil {
42+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
43+
return
44+
}
45+
helper.SuccessWithOutData(c)
46+
}
47+
48+
// @Tags McpServer
49+
// @Summary Update mcp server
50+
// @Accept json
51+
// @Param request body request.McpServerUpdate true "request"
52+
// @Success 200
53+
// @Security ApiKeyAuth
54+
// @Security Timestamp
55+
// @Router /mcp/server/update [post]
56+
func (b *BaseApi) UpdateMcpServer(c *gin.Context) {
57+
var req request.McpServerUpdate
58+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
59+
return
60+
}
61+
err := mcpServerService.Update(req)
62+
if err != nil {
63+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
64+
return
65+
}
66+
helper.SuccessWithOutData(c)
67+
}
68+
69+
// @Tags McpServer
70+
// @Summary Delete mcp server
71+
// @Accept json
72+
// @Param request body request.McpServerDelete true "request"
73+
// @Success 200
74+
// @Security ApiKeyAuth
75+
// @Security Timestamp
76+
// @Router /mcp/server/del [post]
77+
func (b *BaseApi) DeleteMcpServer(c *gin.Context) {
78+
var req request.McpServerDelete
79+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
80+
return
81+
}
82+
err := mcpServerService.Delete(req.ID)
83+
if err != nil {
84+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
85+
return
86+
}
87+
helper.SuccessWithOutData(c)
88+
}
89+
90+
// @Tags McpServer
91+
// @Summary Operate mcp server
92+
// @Accept json
93+
// @Param request body request.McpServerOperate true "request"
94+
// @Success 200
95+
// @Security ApiKeyAuth
96+
// @Security Timestamp
97+
// @Router /mcp/server/op [post]
98+
func (b *BaseApi) OperateMcpServer(c *gin.Context) {
99+
var req request.McpServerOperate
100+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
101+
return
102+
}
103+
err := mcpServerService.Operate(req)
104+
if err != nil {
105+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
106+
return
107+
}
108+
helper.SuccessWithOutData(c)
109+
}
110+
111+
// @Tags McpServer
112+
// @Summary Bind Domain for mcp server
113+
// @Accept json
114+
// @Param request body request.McpBindDomain true "request"
115+
// @Success 200
116+
// @Security ApiKeyAuth
117+
// @Security Timestamp
118+
// @Router /mcp/domain/bind [post]
119+
func (b *BaseApi) BindMcpDomain(c *gin.Context) {
120+
var req request.McpBindDomain
121+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
122+
return
123+
}
124+
err := mcpServerService.BindDomain(req)
125+
if err != nil {
126+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
127+
return
128+
}
129+
helper.SuccessWithOutData(c)
130+
}
131+
132+
// @Tags McpServer
133+
// @Summary Update bind Domain for mcp server
134+
// @Accept json
135+
// @Param request body request.McpBindDomainUpdate true "request"
136+
// @Success 200
137+
// @Security ApiKeyAuth
138+
// @Security Timestamp
139+
// @Router /mcp/domain/update [post]
140+
func (b *BaseApi) UpdateMcpBindDomain(c *gin.Context) {
141+
var req request.McpBindDomainUpdate
142+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
143+
return
144+
}
145+
err := mcpServerService.UpdateBindDomain(req)
146+
if err != nil {
147+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
148+
return
149+
}
150+
helper.SuccessWithOutData(c)
151+
}
152+
153+
// @Tags McpServer
154+
// @Summary Get bin Domain for mcp server
155+
// @Accept json
156+
// @Success 200 {object} response.McpBindDomainRes
157+
// @Security ApiKeyAuth
158+
// @Security Timestamp
159+
// @Router /mcp/domain/get [get]
160+
func (b *BaseApi) GetMcpBindDomain(c *gin.Context) {
161+
res, err := mcpServerService.GetBindDomain()
162+
if err != nil {
163+
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
164+
return
165+
}
166+
helper.SuccessWithData(c, res)
167+
}

Diff for: backend/app/dto/mcp.go

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dto
2+
3+
type DockerComposeService struct {
4+
Image string `yaml:"image"`
5+
ContainerName string `yaml:"container_name"`
6+
Restart string `yaml:"restart"`
7+
Ports []string `yaml:"ports"`
8+
Environment []string `yaml:"environment"`
9+
Command []string `yaml:"command"`
10+
}

Diff for: backend/app/dto/request/mcp_server.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package request
2+
3+
import "github.com/1Panel-dev/1Panel/backend/app/dto"
4+
5+
type McpServerSearch struct {
6+
dto.PageInfo
7+
Name string `json:"name"`
8+
Sync bool `json:"sync"`
9+
}
10+
11+
type McpServerCreate struct {
12+
Name string `json:"name" validate:"required"`
13+
Command string `json:"command" validate:"required"`
14+
Environments []Environment `json:"environments"`
15+
Volumes []Volume `json:"volumes"`
16+
Port int `json:"port" validate:"required"`
17+
ContainerName string `json:"containerName"`
18+
BaseURL string `json:"baseUrl"`
19+
SsePath string `json:"ssePath"`
20+
HostIP string `json:"hostIP"`
21+
}
22+
23+
type McpServerUpdate struct {
24+
ID uint `json:"id" validate:"required"`
25+
McpServerCreate
26+
}
27+
28+
type Environment struct {
29+
Key string `json:"key"`
30+
Value string `json:"value"`
31+
}
32+
33+
type Volume struct {
34+
Source string `json:"source"`
35+
Target string `json:"target"`
36+
}
37+
38+
type McpServerDelete struct {
39+
ID uint `json:"id" validate:"required"`
40+
}
41+
42+
type McpServerOperate struct {
43+
ID uint `json:"id" validate:"required"`
44+
Operate string `json:"operate" validate:"required"`
45+
}
46+
47+
type McpBindDomain struct {
48+
Domain string `json:"domain" validate:"required"`
49+
SSLID uint `json:"sslID"`
50+
IPList string `json:"ipList"`
51+
}
52+
53+
type McpBindDomainUpdate struct {
54+
WebsiteID uint `json:"websiteID" validate:"required"`
55+
SSLID uint `json:"sslID"`
56+
IPList string `json:"ipList"`
57+
}

Diff for: backend/app/dto/response/mcp_server.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package response
2+
3+
import (
4+
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
5+
"github.com/1Panel-dev/1Panel/backend/app/model"
6+
)
7+
8+
type McpServersRes struct {
9+
Items []McpServerDTO `json:"items"`
10+
Total int64 `json:"total"`
11+
}
12+
13+
type McpServerDTO struct {
14+
model.McpServer
15+
Environments []request.Environment `json:"environments"`
16+
Volumes []request.Volume `json:"volumes"`
17+
}
18+
19+
type McpBindDomainRes struct {
20+
Domain string `json:"domain"`
21+
SSLID uint `json:"sslID"`
22+
AcmeAccountID uint `json:"acmeAccountID"`
23+
AllowIPs []string `json:"allowIPs"`
24+
WebsiteID uint `json:"websiteID"`
25+
ConnUrl string `json:"connUrl"`
26+
}

Diff for: backend/app/model/mcp_server.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package model
2+
3+
type McpServer struct {
4+
BaseModel
5+
Name string `json:"name"`
6+
DockerCompose string `json:"dockerCompose"`
7+
Command string `json:"command"`
8+
ContainerName string `json:"containerName"`
9+
Message string `json:"message"`
10+
Port int `json:"port"`
11+
Status string `json:"status"`
12+
Env string `json:"env"`
13+
BaseURL string `json:"baseUrl"`
14+
SsePath string `json:"ssePath"`
15+
WebsiteID int `json:"websiteID"`
16+
Dir string `json:"dir"`
17+
HostIP string `json:"hostIP"`
18+
}

Diff for: backend/app/repo/mcp_server.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package repo
2+
3+
import "github.com/1Panel-dev/1Panel/backend/app/model"
4+
5+
type McpServerRepo struct {
6+
}
7+
8+
type IMcpServerRepo interface {
9+
Page(page, size int, opts ...DBOption) (int64, []model.McpServer, error)
10+
GetFirst(opts ...DBOption) (*model.McpServer, error)
11+
Create(mcpServer *model.McpServer) error
12+
Save(mcpServer *model.McpServer) error
13+
DeleteBy(opts ...DBOption) error
14+
List(opts ...DBOption) ([]model.McpServer, error)
15+
}
16+
17+
func NewIMcpServerRepo() IMcpServerRepo {
18+
return &McpServerRepo{}
19+
}
20+
21+
func (m McpServerRepo) Page(page, size int, opts ...DBOption) (int64, []model.McpServer, error) {
22+
var servers []model.McpServer
23+
db := getDb(opts...).Model(&model.McpServer{})
24+
count := int64(0)
25+
db = db.Count(&count)
26+
err := db.Limit(size).Offset(size * (page - 1)).Find(&servers).Error
27+
return count, servers, err
28+
}
29+
30+
func (m McpServerRepo) GetFirst(opts ...DBOption) (*model.McpServer, error) {
31+
var mcpServer model.McpServer
32+
if err := getDb(opts...).First(&mcpServer).Error; err != nil {
33+
return nil, err
34+
}
35+
return &mcpServer, nil
36+
}
37+
38+
func (m McpServerRepo) List(opts ...DBOption) ([]model.McpServer, error) {
39+
var mcpServers []model.McpServer
40+
if err := getDb(opts...).Find(&mcpServers).Error; err != nil {
41+
return nil, err
42+
}
43+
return mcpServers, nil
44+
}
45+
46+
func (m McpServerRepo) Create(mcpServer *model.McpServer) error {
47+
return getDb().Create(mcpServer).Error
48+
}
49+
50+
func (m McpServerRepo) Save(mcpServer *model.McpServer) error {
51+
return getDb().Save(mcpServer).Error
52+
}
53+
54+
func (m McpServerRepo) DeleteBy(opts ...DBOption) error {
55+
return getDb(opts...).Delete(&model.McpServer{}).Error
56+
}

Diff for: backend/app/service/entry.go

+2
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,6 @@ var (
4646
phpExtensionsRepo = repo.NewIPHPExtensionsRepo()
4747

4848
favoriteRepo = repo.NewIFavoriteRepo()
49+
50+
mcpServerRepo = repo.NewIMcpServerRepo()
4951
)

0 commit comments

Comments
 (0)