Skip to content

Commit 492c5d3

Browse files
authored
Add all in one mcp (#1978)
1 parent 037c71a commit 492c5d3

File tree

14 files changed

+318
-75
lines changed

14 files changed

+318
-75
lines changed

plugins/wasm-go/mcp-servers/README.md

+73-7
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,56 @@ func (t MyTool) Call(ctx server.HttpContext, s server.Server) error {
128128
}
129129
```
130130

131+
## Tool Loading
132+
133+
For better organization, you can create a separate file to load all your tools:
134+
135+
```go
136+
// tools/load_tools.go
137+
package tools
138+
139+
import (
140+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
141+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp/server"
142+
)
143+
144+
func LoadTools(server *mcp.MCPServer) server.Server {
145+
return server.AddMCPTool("my_tool", &MyTool{}).
146+
AddMCPTool("another_tool", &AnotherTool{})
147+
// Add more tools as needed
148+
}
149+
```
150+
151+
This approach to organizing code facilitates integration with the all-in-one MCP server plugin. The all-in-one plugin combines multiple MCP servers into a single plugin, reducing the overhead of deploying multiple plugins on the gateway.
152+
153+
### All-in-One Integration
154+
155+
The all-in-one plugin packages multiple MCP servers into a single WASM binary. Each MCP server maintains its own identity and configuration, but they share the same plugin instance. Here's an example of how multiple MCP servers are integrated in the all-in-one plugin:
156+
157+
```go
158+
// all-in-one/main.go
159+
package main
160+
161+
import (
162+
amap "amap-tools/tools"
163+
quark "quark-search/tools"
164+
165+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
166+
)
167+
168+
func main() {}
169+
170+
func init() {
171+
mcp.LoadMCPServer(mcp.AddMCPServer("quark-search",
172+
quark.LoadTools(&mcp.MCPServer{})))
173+
mcp.LoadMCPServer(mcp.AddMCPServer("amap-tools",
174+
amap.LoadTools(&mcp.MCPServer{})))
175+
mcp.InitMCPServer()
176+
}
177+
```
178+
179+
The configuration for the all-in-one plugin follows the same pattern as individual MCP server plugins. The `name` field in the server configuration is used to identify and route requests to the appropriate MCP server within the all-in-one plugin.
180+
131181
## Main Entry Point
132182

133183
The main.go file is the entry point for your MCP server. It registers your tools and resources:
@@ -139,21 +189,37 @@ package main
139189
import (
140190
"my-mcp-server/tools"
141191

142-
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp/server"
192+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
143193
)
144194

145195
func main() {}
146196

147197
func init() {
148-
myMCPServer := &server.MCPServer{}
149-
server.Load(server.AddMCPServer(
150-
"my-mcp-server", // Server name
151-
myMCPServer.AddMCPTool("my_tool", &tools.MyTool{}), // Register tools
152-
// Add more tools as needed
153-
))
198+
mcp.LoadMCPServer(mcp.AddMCPServer("my-mcp-server",
199+
tools.LoadTools(&mcp.MCPServer{})))
200+
mcp.InitMCPServer()
154201
}
155202
```
156203

204+
## Plugin Configuration
205+
206+
When deploying your MCP server as a Higress plugin, you need to configure it in the Higress configuration. Here's an example configuration:
207+
208+
```yaml
209+
server:
210+
# MCP server name - MUST match the name used in mcp.AddMCPServer() in your code
211+
name: my-mcp-server
212+
# MCP server configuration
213+
config:
214+
apiKey: your-api-key-here
215+
# Optional: If configured, acts as a whitelist - only tools listed here can be called
216+
tools:
217+
- my_tool
218+
- another_tool
219+
```
220+
221+
> **Important**: The `name` field in the server configuration must exactly match the server name used in the `mcp.AddMCPServer()` call in your code. This is how the system identifies which MCP server should handle the request.
222+
157223
## Dependencies
158224

159225
Your MCP server must use a specific version of the wasm-go SDK that supports Go 1.24's WebAssembly compilation features:

plugins/wasm-go/mcp-servers/README_zh.md

+73-7
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,56 @@ func (t MyTool) Call(ctx server.HttpContext, s server.Server) error {
125125
}
126126
```
127127

128+
## 工具加载
129+
130+
为了更好地组织代码,您可以创建一个单独的文件来加载所有工具:
131+
132+
```go
133+
// tools/load_tools.go
134+
package tools
135+
136+
import (
137+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
138+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp/server"
139+
)
140+
141+
func LoadTools(server *mcp.MCPServer) server.Server {
142+
return server.AddMCPTool("my_tool", &MyTool{}).
143+
AddMCPTool("another_tool", &AnotherTool{})
144+
// 根据需要添加更多工具
145+
}
146+
```
147+
148+
以这种方式组织代码,可以方便被 all-in-one 目录下的 MCP server 插件集成。all-in-one 插件将所有 MCP server 的逻辑打包到一个插件里,从而降低网关上部署多个插件带来的额外开销。
149+
150+
### All-in-One 集成
151+
152+
all-in-one 插件将多个 MCP server 打包到一个 WASM 二进制文件中。每个 MCP server 保持自己的身份和配置,但它们共享同一个插件实例。以下是 all-in-one 插件中集成多个 MCP server 的示例:
153+
154+
```go
155+
// all-in-one/main.go
156+
package main
157+
158+
import (
159+
amap "amap-tools/tools"
160+
quark "quark-search/tools"
161+
162+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
163+
)
164+
165+
func main() {}
166+
167+
func init() {
168+
mcp.LoadMCPServer(mcp.AddMCPServer("quark-search",
169+
quark.LoadTools(&mcp.MCPServer{})))
170+
mcp.LoadMCPServer(mcp.AddMCPServer("amap-tools",
171+
amap.LoadTools(&mcp.MCPServer{})))
172+
mcp.InitMCPServer()
173+
}
174+
```
175+
176+
all-in-one 插件的配置方式与所有 MCP server 插件都是一样的,都是通过 server 配置中的 name 字段来找到对应的 MCP server。
177+
128178
## 主入口点
129179

130180
main.go 文件是 MCP 服务器的入口点。它注册工具和资源:
@@ -136,21 +186,37 @@ package main
136186
import (
137187
"my-mcp-server/tools"
138188

139-
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp/server"
189+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
140190
)
141191

142192
func main() {}
143193

144194
func init() {
145-
myMCPServer := &server.MCPServer{}
146-
server.Load(server.AddMCPServer(
147-
"my-mcp-server", // 服务器名称
148-
myMCPServer.AddMCPTool("my_tool", &tools.MyTool{}), // 注册工具
149-
// 根据需要添加更多工具
150-
))
195+
mcp.LoadMCPServer(mcp.AddMCPServer("my-mcp-server",
196+
tools.LoadTools(&mcp.MCPServer{})))
197+
mcp.InitMCPServer()
151198
}
152199
```
153200

201+
## 插件配置
202+
203+
当将您的 MCP 服务器部署为 Higress 插件时,您需要在 Higress 配置中进行配置。以下是一个示例配置:
204+
205+
```yaml
206+
server:
207+
# MCP 服务器名称 - 必须与代码中 mcp.AddMCPServer() 调用时使用的名称完全一致
208+
name: my-mcp-server
209+
# MCP 服务器配置
210+
config:
211+
apiKey: 您的API密钥
212+
# 可选:如果配置了,则起到白名单作用 - 只有列在这里的工具才能被调用
213+
tools:
214+
- my_tool
215+
- another_tool
216+
```
217+
218+
> **重要提示**:server 配置中的 `name` 字段必须与代码中 `mcp.AddMCPServer()` 调用时使用的服务器名称完全一致。系统通过这个名称来识别应该由哪个 MCP 服务器处理请求。
219+
154220
## 依赖项
155221

156222
您的 MCP 服务器必须使用支持 Go 1.24 WebAssembly 编译功能的特定版本的 wasm-go SDK:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module all-in-one
2+
3+
go 1.24.1
4+
5+
replace quark-search => ../quark-search
6+
7+
replace amap-tools => ../amap-tools
8+
9+
require (
10+
amap-tools v0.0.0-00010101000000-000000000000
11+
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329145934-61b36a20cd9c
12+
quark-search v0.0.0-00010101000000-000000000000
13+
)
14+
15+
require (
16+
github.com/bahlo/generic-list-go v0.2.0 // indirect
17+
github.com/buger/jsonparser v1.1.1 // indirect
18+
github.com/google/uuid v1.3.0 // indirect
19+
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20250323151219-d75620c61711 // indirect
20+
github.com/invopop/jsonschema v0.13.0 // indirect
21+
github.com/mailru/easyjson v0.7.7 // indirect
22+
github.com/tidwall/gjson v1.17.3 // indirect
23+
github.com/tidwall/match v1.1.1 // indirect
24+
github.com/tidwall/pretty v1.2.0 // indirect
25+
github.com/tidwall/resp v0.1.1 // indirect
26+
github.com/tidwall/sjson v1.2.5 // indirect
27+
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
28+
gopkg.in/yaml.v3 v3.0.1 // indirect
29+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329145934-61b36a20cd9c h1:giBV8e7p0qxRdBsCu4AjXbpUI8sNiGkEtPNWEXf6fA4=
2+
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329145934-61b36a20cd9c/go.mod h1:csP9Mpkc+gVgbZsizCdcYSy0LJrQA+//RcnZBInyknc=
3+
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
4+
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
5+
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
6+
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
10+
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
11+
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20250323151219-d75620c61711 h1:n5sZwSZWQ5uKS69hu50/0gliTFrIJ1w+g/FSdIIiZIs=
12+
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20250323151219-d75620c61711/go.mod h1:tRI2LfMudSkKHhyv1uex3BWzcice2s/l8Ah8axporfA=
13+
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
14+
github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
15+
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
16+
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
17+
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
18+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
19+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
20+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
21+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
22+
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
23+
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
24+
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
25+
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
26+
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
27+
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
28+
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
29+
github.com/tidwall/resp v0.1.1 h1:Ly20wkhqKTmDUPlyM1S7pWo5kk0tDu8OoC/vFArXmwE=
30+
github.com/tidwall/resp v0.1.1/go.mod h1:3/FrruOBAxPTPtundW0VXgmsQ4ZBA0Aw714lVYgwFa0=
31+
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
32+
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
33+
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
34+
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
35+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
36+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
37+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
38+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2022 Alibaba Group Holding Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
amap "amap-tools/tools"
19+
quark "quark-search/tools"
20+
21+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
22+
)
23+
24+
func main() {}
25+
26+
func init() {
27+
mcp.LoadMCPServer(mcp.AddMCPServer("quark-search",
28+
quark.LoadTools(&mcp.MCPServer{})))
29+
mcp.LoadMCPServer(mcp.AddMCPServer("amap-tools",
30+
amap.LoadTools(&mcp.MCPServer{})))
31+
mcp.InitMCPServer()
32+
}

plugins/wasm-go/mcp-servers/amap-tools/go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.24
55
toolchain go1.24.1
66

77
require (
8-
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329122411-e07be585ff55
8+
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329145934-61b36a20cd9c
99
github.com/tidwall/gjson v1.17.3
1010
)
1111

plugins/wasm-go/mcp-servers/amap-tools/go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329122411-e07be585ff55 h1:yGPhs3VhC4Mj4SmbaLcKSZ1sV8wRW/eGf/13P0c2+S8=
2-
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329122411-e07be585ff55/go.mod h1:csP9Mpkc+gVgbZsizCdcYSy0LJrQA+//RcnZBInyknc=
1+
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329145934-61b36a20cd9c h1:giBV8e7p0qxRdBsCu4AjXbpUI8sNiGkEtPNWEXf6fA4=
2+
github.com/alibaba/higress/plugins/wasm-go v1.4.4-0.20250329145934-61b36a20cd9c/go.mod h1:csP9Mpkc+gVgbZsizCdcYSy0LJrQA+//RcnZBInyknc=
33
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
44
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
55
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=

plugins/wasm-go/mcp-servers/amap-tools/main.go

+4-17
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,13 @@ package main
1717
import (
1818
"amap-tools/tools"
1919

20-
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp/server"
20+
"github.com/alibaba/higress/plugins/wasm-go/pkg/mcp"
2121
)
2222

2323
func main() {}
2424

2525
func init() {
26-
amapServer := &server.MCPServer{}
27-
server.Load(server.AddMCPServer(
28-
"amap-tools",
29-
amapServer.AddMCPTool("maps_geo", &tools.GeoRequest{}).
30-
AddMCPTool("maps_bicycling", &tools.BicyclingRequest{}).
31-
AddMCPTool("maps_direction_transit_integrated", &tools.TransitIntegratedRequest{}).
32-
AddMCPTool("maps_ip_location", &tools.IPLocationRequest{}).
33-
AddMCPTool("maps_weather", &tools.WeatherRequest{}).
34-
AddMCPTool("maps_direction_driving", &tools.DrivingRequest{}).
35-
AddMCPTool("maps_around_search", &tools.AroundSearchRequest{}).
36-
AddMCPTool("maps_search_detail", &tools.SearchDetailRequest{}).
37-
AddMCPTool("maps_regeocode", &tools.ReGeocodeRequest{}).
38-
AddMCPTool("maps_text_search", &tools.TextSearchRequest{}).
39-
AddMCPTool("maps_distance", &tools.DistanceRequest{}).
40-
AddMCPTool("maps_direction_walking", &tools.WalkingRequest{}),
41-
))
26+
mcp.LoadMCPServer(mcp.AddMCPServer("amap-tools",
27+
tools.LoadTools(&mcp.MCPServer{})))
28+
mcp.InitMCPServer()
4229
}

plugins/wasm-go/mcp-servers/amap-tools/server/server.go

-33
This file was deleted.

0 commit comments

Comments
 (0)