Skip to content

Commit 326a8ef

Browse files
syn-zhuclaude
andcommitted
feat: add MCP server endpoint for dynamic tool discovery and invocation
Add a Streamable HTTP MCP server endpoint to the kmcp controller, enabling agents to dynamically discover, introspect, and invoke tools on any MCPServer in the cluster at runtime. This mirrors the pattern already established by kagent-controller's A2A MCP endpoint (list_agents / invoke_agent) but for MCP server interactions. New tools exposed at :8083/mcp: - list_mcp_servers: List MCPServer CRs (name, namespace, status, port) - list_tools: Connect to a specific MCPServer and return its tool catalog - call_tool: Invoke a specific tool on a specific MCPServer Includes: - MCP handler with session caching and automatic reconnection - HTTP server wrapper implementing manager.Runnable - --mcp-bind-address flag (default :8083, set to 0 to disable) - Helm chart updates (values, deployment port, MCP service) - Comprehensive unit tests (18 test cases) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Simon Zhu <simon.zhu@mongodb.com>
1 parent 1b77729 commit 326a8ef

11 files changed

Lines changed: 1049 additions & 24 deletions

File tree

go.mod

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ toolchain go1.24.3
77
require (
88
github.com/fatih/color v1.18.0
99
github.com/mark3labs/mcp-go v0.33.0
10+
github.com/modelcontextprotocol/go-sdk v1.2.0
1011
github.com/onsi/ginkgo/v2 v2.21.0
1112
github.com/onsi/gomega v1.35.1
1213
github.com/spf13/cobra v1.8.1
1314
github.com/stoewer/go-strcase v1.3.0
15+
github.com/stretchr/testify v1.9.0
1416
go.uber.org/multierr v1.11.0
15-
golang.org/x/text v0.19.0
17+
golang.org/x/text v0.26.0
1618
gopkg.in/yaml.v3 v3.0.1
1719
k8s.io/api v0.32.0
1820
k8s.io/apimachinery v0.32.0
@@ -48,8 +50,9 @@ require (
4850
github.com/google/btree v1.1.3 // indirect
4951
github.com/google/cel-go v0.22.0 // indirect
5052
github.com/google/gnostic-models v0.6.8 // indirect
51-
github.com/google/go-cmp v0.6.0 // indirect
53+
github.com/google/go-cmp v0.7.0 // indirect
5254
github.com/google/gofuzz v1.2.0 // indirect
55+
github.com/google/jsonschema-go v0.3.0 // indirect
5356
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
5457
github.com/google/uuid v1.6.0 // indirect
5558
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
@@ -63,6 +66,7 @@ require (
6366
github.com/modern-go/reflect2 v1.0.2 // indirect
6467
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
6568
github.com/pkg/errors v0.9.1 // indirect
69+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
6670
github.com/prometheus/client_golang v1.19.1 // indirect
6771
github.com/prometheus/client_model v0.6.1 // indirect
6872
github.com/prometheus/common v0.55.0 // indirect
@@ -81,13 +85,13 @@ require (
8185
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
8286
go.uber.org/zap v1.27.0 // indirect
8387
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
84-
golang.org/x/net v0.30.0 // indirect
85-
golang.org/x/oauth2 v0.23.0 // indirect
86-
golang.org/x/sync v0.8.0 // indirect
87-
golang.org/x/sys v0.26.0 // indirect
88-
golang.org/x/term v0.25.0 // indirect
88+
golang.org/x/net v0.41.0 // indirect
89+
golang.org/x/oauth2 v0.30.0 // indirect
90+
golang.org/x/sync v0.15.0 // indirect
91+
golang.org/x/sys v0.33.0 // indirect
92+
golang.org/x/term v0.32.0 // indirect
8993
golang.org/x/time v0.7.0 // indirect
90-
golang.org/x/tools v0.26.0 // indirect
94+
golang.org/x/tools v0.34.0 // indirect
9195
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
9296
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
9397
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect

go.sum

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
5353
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
5454
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
5555
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
56+
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
57+
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
5658
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
5759
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
5860
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
@@ -62,11 +64,13 @@ github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs
6264
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
6365
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
6466
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
65-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
66-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
67+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
68+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
6769
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
6870
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
6971
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
72+
github.com/google/jsonschema-go v0.3.0 h1:6AH2TxVNtk3IlvkkhjrtbUc4S8AvO0Xii0DxIygDg+Q=
73+
github.com/google/jsonschema-go v0.3.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
7074
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
7175
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
7276
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -97,6 +101,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
97101
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
98102
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
99103
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
104+
github.com/modelcontextprotocol/go-sdk v1.2.0 h1:Y23co09300CEk8iZ/tMxIX1dVmKZkzoSBZOpJwUnc/s=
105+
github.com/modelcontextprotocol/go-sdk v1.2.0/go.mod h1:6fM3LCm3yV7pAs8isnKLn07oKtB0MP9LHd3DfAcKw10=
100106
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
101107
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
102108
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -180,36 +186,36 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
180186
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
181187
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
182188
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
183-
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
184-
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
185-
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
186-
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
189+
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
190+
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
191+
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
192+
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
187193
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
188194
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
189195
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
190-
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
191-
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
196+
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
197+
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
192198
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
193199
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
194200
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
195201
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
196202
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
197-
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
198-
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
199-
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
200-
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
203+
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
204+
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
205+
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
206+
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
201207
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
202208
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
203-
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
204-
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
209+
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
210+
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
205211
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
206212
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
207213
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
208214
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
209215
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
210216
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
211-
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
212-
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
217+
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
218+
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
213219
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
214220
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
215221
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

helm/kmcp/templates/_helpers.tpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,10 @@ Create controller manager container args
8383
{{- if .Values.controller.metrics.enabled }}
8484
{{- $args = append $args (printf "--metrics-bind-address=%s" .Values.controller.metrics.bindAddress) }}
8585
{{- end }}
86+
{{- if .Values.controller.mcpServer.enabled }}
87+
{{- $args = append $args (printf "--mcp-bind-address=%s" .Values.controller.mcpServer.bindAddress) }}
88+
{{- else }}
89+
{{- $args = append $args "--mcp-bind-address=0" }}
90+
{{- end }}
8691
{{- toYaml $args }}
8792
{{- end }}

helm/kmcp/templates/deployment.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ spec:
4646
name: health
4747
protocol: TCP
4848
{{- end }}
49+
{{- if .Values.controller.mcpServer.enabled }}
50+
- containerPort: {{ .Values.controller.mcpServer.bindAddress | regexFind "[0-9]+" }}
51+
name: mcp
52+
protocol: TCP
53+
{{- end }}
4954
{{- if .Values.controller.env }}
5055
env:
5156
{{- toYaml .Values.controller.env | nindent 8 }}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{{- if .Values.controller.mcpServer.enabled }}
2+
apiVersion: v1
3+
kind: Service
4+
metadata:
5+
name: {{ include "kmcp.fullname" . }}-mcp
6+
namespace: {{ include "kmcp.namespace" . }}
7+
labels:
8+
{{- include "kmcp.labels" . | nindent 4 }}
9+
spec:
10+
type: ClusterIP
11+
ports:
12+
- name: mcp
13+
port: {{ .Values.controller.mcpServer.bindAddress | regexFind "[0-9]+" }}
14+
targetPort: {{ .Values.controller.mcpServer.bindAddress | regexFind "[0-9]+" }}
15+
protocol: TCP
16+
selector:
17+
{{- include "kmcp.selectorLabels" . | nindent 4 }}
18+
{{- end }}

helm/kmcp/values.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ controller:
4545
bindAddress: ":8443"
4646
secureServing: true
4747

48+
# MCP server endpoint configuration
49+
mcpServer:
50+
enabled: true
51+
bindAddress: ":8083"
52+
4853
env: []
4954

5055
# Pod annotations

pkg/app/app.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
kagentdevv1alpha1 "github.com/kagent-dev/kmcp/api/v1alpha1"
4242
"github.com/kagent-dev/kmcp/pkg/controller"
4343
"github.com/kagent-dev/kmcp/pkg/controller/transportadapter"
44+
mcppkg "github.com/kagent-dev/kmcp/pkg/mcp"
4445
// +kubebuilder:scaffold:imports
4546
)
4647

@@ -74,6 +75,7 @@ type Config struct {
7475
ProbeAddr string
7576
SecureMetrics bool
7677
EnableHTTP2 bool
78+
MCPAddr string
7779
}
7880

7981
func (cfg *Config) SetFlags(commandLine *flag.FlagSet) {
@@ -109,6 +111,8 @@ func (cfg *Config) SetFlags(commandLine *flag.FlagSet) {
109111
commandLine.StringVar(&cfg.Webhook.CertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.")
110112
commandLine.BoolVar(&cfg.EnableHTTP2, "enable-http2", false,
111113
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
114+
commandLine.StringVar(&cfg.MCPAddr, "mcp-bind-address", ":8083",
115+
"The address the MCP server endpoint binds to. Set to 0 to disable.")
112116
}
113117

114118
// PluginFactory creates a TranslatorPlugin when provided with the client and scheme.
@@ -288,6 +292,20 @@ func Start(getExtensionConfig GetExtensionConfig) {
288292
}
289293
// +kubebuilder:scaffold:builder
290294

295+
// Start MCP server if enabled
296+
if cfg.MCPAddr != "0" {
297+
mcpHandler, err := mcppkg.NewMCPHandler(mgr.GetClient())
298+
if err != nil {
299+
setupLog.Error(err, "unable to create MCP handler")
300+
os.Exit(1)
301+
}
302+
mcpServer := mcppkg.NewServer(mcpHandler, cfg.MCPAddr)
303+
if err := mgr.Add(mcpServer); err != nil {
304+
setupLog.Error(err, "unable to add MCP server to manager")
305+
os.Exit(1)
306+
}
307+
}
308+
291309
if metricsCertWatcher != nil {
292310
setupLog.Info("Adding metrics certificate watcher to manager")
293311
if err := mgr.Add(metricsCertWatcher); err != nil {

0 commit comments

Comments
 (0)