Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ae5a7b1
add category and hint fields to MCPServer config
maleck13 Apr 1, 2026
a0e1fdd
add discovery meta-tools, session scope store, and broker integration
maleck13 Apr 1, 2026
646cf0f
add session scope filter to tools/list pipeline
maleck13 Apr 1, 2026
7097b68
route broker meta-tools through broker passthrough path
maleck13 Apr 1, 2026
4a88191
ignore superpowers docs in spell check
maleck13 Apr 1, 2026
c734402
add category and hint to MCPServerRegistration CRD, pass through to b…
maleck13 Apr 1, 2026
0ee4d69
ensure broker meta-tools survive all filter stages
maleck13 Apr 1, 2026
14b52ce
fix nil pointer in findToolConflicts for broker meta-tools
maleck13 Apr 1, 2026
e2353fb
add sample MCPServerRegistrations with discovery metadata
maleck13 Apr 1, 2026
331f664
add gateway instructions to initialize response for tool discovery
maleck13 Apr 1, 2026
4177ff4
include category and hint in ConfigChanged check
maleck13 Apr 1, 2026
bd75ed5
add category and hint fields to MCPServer config
maleck13 Apr 1, 2026
b5a914f
add discovery meta-tools, session scope store, and broker integration
maleck13 Apr 1, 2026
dd99eb6
add session scope filter to tools/list pipeline
maleck13 Apr 1, 2026
34b8986
route broker meta-tools through broker passthrough path
maleck13 Apr 1, 2026
49be42a
ignore superpowers docs in spell check
maleck13 Apr 1, 2026
e10c4cc
add category and hint to MCPServerRegistration CRD, pass through to b…
maleck13 Apr 1, 2026
ada3941
ensure broker meta-tools survive all filter stages
maleck13 Apr 1, 2026
c506003
fix nil pointer in findToolConflicts for broker meta-tools
maleck13 Apr 1, 2026
d56e7de
add sample MCPServerRegistrations with discovery metadata
maleck13 Apr 1, 2026
ae2cb69
add gateway instructions to initialize response for tool discovery
maleck13 Apr 1, 2026
f69f2d4
include category and hint in ConfigChanged check
maleck13 Apr 1, 2026
102cf71
add demo servers, discovery threshold, and walkthrough guide
maleck13 Apr 2, 2026
9344896
add demo
maleck13 Apr 2, 2026
aa5dec2
fix bundle
maleck13 Apr 2, 2026
e0b77f1
minor tweaks
maleck13 Apr 2, 2026
142886f
bundle
maleck13 Apr 13, 2026
4689a69
remove un-needed config
maleck13 Apr 13, 2026
b225d0d
add auth filtering to discover_tools/select_tools and virtual server …
maleck13 Apr 15, 2026
e955d53
merge tool-discovery-proposal: add auth filtering, keep threshold hiding
maleck13 Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ build-test-servers: ## Build test server Docker images locally
cd tests/servers/custom-path-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-custom-path-server:latest .
cd tests/servers/oidc-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-oidc-server:latest .
cd tests/servers/everything-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-everything-server:latest .
cd tests/servers/custom-response-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-custom-response-server:latest .
cd tests/servers/custom-response-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-custom-response-server:latest .
cd tests/servers/restaurant-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-restaurant-server:latest .
cd tests/servers/messaging-server && $(CONTAINER_ENGINE) build $(CONTAINER_ENGINE_EXTRA_FLAGS) -t ghcr.io/kuadrant/mcp-gateway/test-messaging-server:latest .

# Build conformance server Docker image
.PHONY: build-conformance-server
Expand All @@ -334,6 +336,8 @@ kind-load-test-servers: kind build-test-servers ## Load test server images into
$(call load-image,ghcr.io/kuadrant/mcp-gateway/test-oidc-server:latest)
$(call load-image,ghcr.io/kuadrant/mcp-gateway/test-everything-server:latest)
$(call load-image,ghcr.io/kuadrant/mcp-gateway/test-custom-response-server:latest)
$(call load-image,ghcr.io/kuadrant/mcp-gateway/test-restaurant-server:latest)
$(call load-image,ghcr.io/kuadrant/mcp-gateway/test-messaging-server:latest)

# Load everything server image into Kind cluster
kind-load-everything-server: kind build-everything-server ## Load everything server image into Kind cluster
Expand Down
12 changes: 12 additions & 0 deletions api/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ type MCPServerRegistrationSpec struct {
// The controller will aggregate these credentials and make them available to the broker via environment variables following the pattern: KAGENTI_{MCP_NAME}_CRED
// +optional
CredentialRef *SecretReference `json:"credentialRef,omitempty"`

// category is a free-text classification of the server's domain.
// Used by the discover_tools meta-tool to present a high-level overview of available servers.
// Defaults to "uncategorised" if not set.
// +optional
Category string `json:"category,omitempty"`

// hint is a short natural-language description of what the server's tools do.
// Used by the discover_tools meta-tool to help agents decide which tools are relevant
// without loading full tool schemas.
// +optional
Hint string `json:"hint,omitempty"`
}

// TargetReference identifies an HTTPRoute that points to MCP servers.
Expand Down
2 changes: 1 addition & 1 deletion bundle/manifests/mcp-gateway.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
capabilities: Basic Install
categories: Integration & Delivery
containerImage: ghcr.io/kuadrant/mcp-controller:latest
createdAt: "2026-04-10T09:45:58Z"
createdAt: "2026-04-13T07:59:55Z"
description: An Envoy-based gateway for Model Context Protocol (MCP) servers
operators.operatorframework.io/builder: operator-sdk-v1.38.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
Expand Down
12 changes: 12 additions & 0 deletions bundle/manifests/mcp.kuadrant.io_mcpserverregistrations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ spec:
spec:
description: spec defines the desired state of MCPServerRegistration.
properties:
category:
description: |-
category is a free-text classification of the server's domain.
Used by the discover_tools meta-tool to present a high-level overview of available servers.
Defaults to "uncategorised" if not set.
type: string
credentialRef:
description: |-
credentialRef references a Secret containing authentication credentials for the MCP server.
Expand All @@ -90,6 +96,12 @@ spec:
required:
- name
type: object
hint:
description: |-
hint is a short natural-language description of what the server's tools do.
Used by the discover_tools meta-tool to help agents decide which tools are relevant
without loading full tool schemas.
type: string
path:
default: /mcp
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ spec:
spec:
description: spec defines the desired state of MCPServerRegistration.
properties:
category:
description: |-
category is a free-text classification of the server's domain.
Used by the discover_tools meta-tool to present a high-level overview of available servers.
Defaults to "uncategorised" if not set.
type: string
credentialRef:
description: |-
credentialRef references a Secret containing authentication credentials for the MCP server.
Expand All @@ -90,6 +96,12 @@ spec:
required:
- name
type: object
hint:
description: |-
hint is a short natural-language description of what the server's tools do.
Used by the discover_tools meta-tool to help agents decide which tools are relevant
without loading full tool schemas.
type: string
path:
default: /mcp
description: |-
Expand Down
11 changes: 9 additions & 2 deletions cmd/mcp-broker-router/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ var (
managerTickerIntervalSecs int64
loglevel int
logFormat string
enforceToolFilteringFlag bool
invalidToolPolicyFlag string
enforceToolFilteringFlag bool
invalidToolPolicyFlag string
discoveryToolThresholdFlag int
)

func main() {
Expand Down Expand Up @@ -135,6 +136,7 @@ func main() {
flag.Int64Var(&managerTickerIntervalSecs, "mcp-check-interval", 60, "interval in seconds for MCP manager backend health checks. Default 60 seconds.")
flag.BoolVar(&enforceToolFilteringFlag, "enforce-tool-filtering", false, "when enabled an x-authorized-tools header will be needed to return any tools")
flag.StringVar(&invalidToolPolicyFlag, "invalid-tool-policy", "FilterOut", "policy for upstream tools with invalid schemas: FilterOut (default) or RejectServer")
flag.IntVar(&discoveryToolThresholdFlag, "discovery-tool-threshold", 10, "when total registered tools exceeds this threshold, new sessions only see discovery meta-tools until select_tools is called. Set 0 to always require discovery.")
flag.Parse()

loggerOpts := &slog.HandlerOptions{}
Expand Down Expand Up @@ -216,6 +218,7 @@ func main() {
broker.WithTrustedHeadersPublicKey(os.Getenv("TRUSTED_HEADER_PUBLIC_KEY")),
broker.WithManagerTickerInterval(managerTickerInterval),
broker.WithInvalidToolPolicy(invalidToolPolicy),
broker.WithDiscoveryToolThreshold(discoveryToolThresholdFlag),
)
brokerServer, mcpServer := setUpHTTPServer(mcpBrokerAddrFlag, mcpBroker, jwtSessionMgr, brokerWriteTimeoutSecs)
routerGRPCServer, router := setUpRouter(mcpBroker, logger, jwtSessionMgr, sessionCache, elicitationMap)
Expand Down Expand Up @@ -396,6 +399,10 @@ func LoadConfig(path string) {
s.URL,
"routable host",
s.Hostname,
"category",
s.Category,
"hint",
s.Hint,
)
}
}
12 changes: 12 additions & 0 deletions config/crd/mcp.kuadrant.io_mcpserverregistrations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ spec:
spec:
description: spec defines the desired state of MCPServerRegistration.
properties:
category:
description: |-
category is a free-text classification of the server's domain.
Used by the discover_tools meta-tool to present a high-level overview of available servers.
Defaults to "uncategorised" if not set.
type: string
credentialRef:
description: |-
credentialRef references a Secret containing authentication credentials for the MCP server.
Expand All @@ -90,6 +96,12 @@ spec:
required:
- name
type: object
hint:
description: |-
hint is a short natural-language description of what the server's tools do.
Used by the discover_tools meta-tool to help agents decide which tools are relevant
without loading full tool schemas.
type: string
path:
default: /mcp
description: |-
Expand Down
84 changes: 84 additions & 0 deletions config/samples/mcpserverregistration-discovery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
# sample MCPServerRegistrations with category and hint fields for tool discovery
apiVersion: mcp.kuadrant.io/v1alpha1
kind: MCPServerRegistration
metadata:
name: test-server1
namespace: mcp-test
labels:
mcp.kuadrant.io/managed: 'true'
spec:
toolPrefix: test1_
category: "greetings utilities"
hint: "greeting tools, time utilities, request header inspection, and slow response simulation"
targetRef:
# Server 1 - Go SDK based (greet, time, slow, headers tools)
group: gateway.networking.k8s.io
kind: HTTPRoute
name: mcp-server1-route
---
apiVersion: mcp.kuadrant.io/v1alpha1
kind: MCPServerRegistration
metadata:
name: test-server2
namespace: mcp-test
labels:
mcp.kuadrant.io/managed: 'true'
spec:
toolPrefix: test2_
category: "greetings authentication"
hint: "hello world greeting, time, header inspection, auth token validation, and slow response tools"
targetRef:
# Server 2 - Go SDK based (hello_world, time, headers, auth1234, slow tools)
group: gateway.networking.k8s.io
kind: HTTPRoute
name: mcp-server2-route
---
apiVersion: mcp.kuadrant.io/v1alpha1
kind: MCPServerRegistration
metadata:
name: test-server3
namespace: mcp-test
labels:
mcp.kuadrant.io/managed: 'true'
spec:
toolPrefix: test3_
category: "math weather"
hint: "mathematical operations (add, dozen, pi), weather forecasts, and time utilities"
targetRef:
# Server 3 - Python FastMCP based (time, add, dozen, pi, get_weather, slow)
group: gateway.networking.k8s.io
kind: HTTPRoute
name: mcp-server3-route
---
apiVersion: mcp.kuadrant.io/v1alpha1
kind: MCPServerRegistration
metadata:
name: restaurant-server
namespace: mcp-test
labels:
mcp.kuadrant.io/managed: 'true'
spec:
toolPrefix: restaurant_
category: "dining reservations"
hint: "search restaurants by cuisine and location, check table availability, make and cancel reservations"
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: mcp-restaurant-server-route
---
apiVersion: mcp.kuadrant.io/v1alpha1
kind: MCPServerRegistration
metadata:
name: messaging-server
namespace: mcp-test
labels:
mcp.kuadrant.io/managed: 'true'
spec:
toolPrefix: messaging_
category: "communication contacts"
hint: "find contacts, send messages via email/sms/slack, view message history, create messaging groups"
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: mcp-messaging-server-route
6 changes: 6 additions & 0 deletions config/test-servers/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,9 @@ resources:
- broken-server-service.yaml
- broken-server-httproute.yaml
- broken-server-deployment.yaml
- restaurant-server-deployment.yaml
- restaurant-server-service.yaml
- restaurant-server-httproute.yaml
- messaging-server-deployment.yaml
- messaging-server-service.yaml
- messaging-server-httproute.yaml
35 changes: 35 additions & 0 deletions config/test-servers/messaging-server-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-messaging-server
labels:
app: mcp-messaging-server
spec:
replicas: 1
selector:
matchLabels:
app: mcp-messaging-server
template:
metadata:
labels:
app: mcp-messaging-server
spec:
containers:
- name: mcp-messaging-server
image: ghcr.io/kuadrant/mcp-gateway/test-messaging-server:latest
imagePullPolicy: Never
command: ["/mcp-test-server"]
args: ["--http", "0.0.0.0:9090"]
ports:
- containerPort: 9090
name: http
env:
- name: LOG_LEVEL
value: "info"
resources:
limits:
memory: "128Mi"
cpu: "100m"
requests:
memory: "64Mi"
cpu: "50m"
20 changes: 20 additions & 0 deletions config/test-servers/messaging-server-httproute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mcp-messaging-server-route
labels:
mcp-server: 'true'
spec:
parentRefs:
- name: mcp-gateway
namespace: gateway-system
hostnames:
- 'messaging-server.mcp.local'
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: mcp-messaging-server
port: 9090
14 changes: 14 additions & 0 deletions config/test-servers/messaging-server-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: mcp-messaging-server
labels:
app: mcp-messaging-server
spec:
ports:
- name: http
port: 9090
targetPort: 9090
selector:
app: mcp-messaging-server
type: ClusterIP
35 changes: 35 additions & 0 deletions config/test-servers/restaurant-server-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-restaurant-server
labels:
app: mcp-restaurant-server
spec:
replicas: 1
selector:
matchLabels:
app: mcp-restaurant-server
template:
metadata:
labels:
app: mcp-restaurant-server
spec:
containers:
- name: mcp-restaurant-server
image: ghcr.io/kuadrant/mcp-gateway/test-restaurant-server:latest
imagePullPolicy: Never
command: ["/mcp-test-server"]
args: ["--http", "0.0.0.0:9090"]
ports:
- containerPort: 9090
name: http
env:
- name: LOG_LEVEL
value: "info"
resources:
limits:
memory: "128Mi"
cpu: "100m"
requests:
memory: "64Mi"
cpu: "50m"
20 changes: 20 additions & 0 deletions config/test-servers/restaurant-server-httproute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mcp-restaurant-server-route
labels:
mcp-server: 'true'
spec:
parentRefs:
- name: mcp-gateway
namespace: gateway-system
hostnames:
- 'restaurant-server.mcp.local'
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: mcp-restaurant-server
port: 9090
Loading
Loading