Skip to content

Commit 85300f9

Browse files
Add MCP servers support on /mcp/ endpoint (#41)
* The plugin now can act as an MCP proxy for multiple MCP servers. * The behavior is the same as for the rest of the plugin, except that the endpoint to use is /mcp. --------- Signed-off-by: Julien Barbot <jubarbot@cisco.com> Co-authored-by: ataldir <ataldir@cisco.com>
1 parent 1e987e8 commit 85300f9

File tree

8 files changed

+587
-10
lines changed

8 files changed

+587
-10
lines changed

configs/mcp.oas.json

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
{
2+
"x-tyk-api-gateway": {
3+
"info": {
4+
"id": "tyk-mcp-id",
5+
"name": "MCP services",
6+
"state": {
7+
"active": true
8+
}
9+
},
10+
"upstream": {
11+
"url": "http://"
12+
},
13+
"server": {
14+
"listenPath": {
15+
"value": "/mcp/",
16+
"strip": true
17+
}
18+
},
19+
"middleware": {
20+
"global": {
21+
"pluginConfig": {
22+
"data": {
23+
"enabled": true,
24+
"value": {
25+
"mcpServers": {
26+
"github": {
27+
"command": "docker",
28+
"args": [
29+
"run",
30+
"-i",
31+
"--rm",
32+
"-e",
33+
"GITHUB_PERSONAL_ACCESS_TOKEN",
34+
"ghcr.io/github/github-mcp-server"
35+
],
36+
"env": ["GITHUB_PERSONAL_ACCESS_TOKEN=${GITHUB_PERSONAL_ACCESS_TOKEN}"]
37+
}
38+
}
39+
}
40+
},
41+
"driver": "goplugin"
42+
},
43+
"postPlugins": [
44+
{
45+
"enabled": true,
46+
"functionName": "ProcessMCPQuery",
47+
"path": "middleware/agent-bridge-plugin.so"
48+
}
49+
]
50+
}
51+
}
52+
},
53+
"openapi": "3.0.1",
54+
"info": {
55+
"title": "MCP",
56+
"description": "Call configured MCP server tools",
57+
"version": "0.0.1"
58+
},
59+
"servers": [
60+
{
61+
"url": "/"
62+
}
63+
],
64+
"paths": {
65+
"/init": {
66+
"post": {
67+
"summary": "Initialize MCP servers",
68+
"requestBody": {
69+
"content": {
70+
"text/plain": {
71+
"schema": {
72+
"type": "string"
73+
}
74+
}
75+
},
76+
"required": true
77+
},
78+
"responses": {
79+
"200": {
80+
"description": "MCP initialization state.",
81+
"content": {}
82+
}
83+
}
84+
}
85+
},
86+
"/": {
87+
"post": {
88+
"summary": "Call an MCP server from a natural language query",
89+
"requestBody": {
90+
"content": {
91+
"text/plain": {
92+
"schema": {
93+
"type": "string"
94+
}
95+
}
96+
},
97+
"required": true
98+
},
99+
"responses": {
100+
"200": {
101+
"description": "NLQ Response.",
102+
"content": {}
103+
}
104+
}
105+
}
106+
}
107+
},
108+
"components": {}
109+
}

go.work.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
253253
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
254254
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
255255
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
256+
github.com/kelindar/search v0.4.0 h1:mj3U26qB6BQJr9/6Q1vHS/I40CQ6Mhb5iJfmfI2e/mY=
257+
github.com/kelindar/search v0.4.0/go.mod h1:7goLXnzQ6b0vMJr9SKWmABblTrJgPG3rVwp3yz2Lo5Q=
256258
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
257259
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
258260
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -386,7 +388,6 @@ github.com/snowflakedb/gosnowflake v1.7.2/go.mod h1:03tW856vc3ceM4rJuj7KO4dzqN7q
386388
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
387389
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
388390
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
389-
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
390391
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
391392
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
392393
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@@ -401,7 +402,6 @@ github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwD
401402
github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
402403
github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
403404
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
404-
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
405405
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
406406
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
407407
github.com/trinodb/trino-go-client v0.313.0/go.mod h1:YpZf2WAClFhU+n0ZhdkmMbugYaMRM/mjywiQru0wpeQ=
@@ -475,6 +475,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
475475
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
476476
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
477477
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
478+
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
478479
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
479480
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
480481
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -490,6 +491,7 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
490491
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
491492
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
492493
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
494+
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
493495
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
494496
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
495497
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

plugins/agent_bridge_acp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright (c) 2025 Cisco and/or its affiliates.
1+
// Copyright AGNTCY Contributors (https://github.com/agntcy)
22
// SPDX-License-Identifier: Apache-2.0
33

44
package main

plugins/agent_bridge_config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ func getConfigValue(defaultValue string, configData map[string]any, configMapKey
9292
return ret
9393
}
9494

95+
func getEnvOrDefault(value string, envKey string, defaultValue string) string {
96+
if value == "" {
97+
value = os.Getenv(envKey)
98+
if value == "" {
99+
value = defaultValue
100+
}
101+
}
102+
return value
103+
}
104+
95105
func parseConfigData(apiId string, configData map[string]any) (*PluginDataConfig, error) {
96106
logger.Debugf("[+] Parsing config for api id: %s", apiId)
97107

0 commit comments

Comments
 (0)