MCP route
The
mcproute custom resource definition (CRD) provides content switching for Model Context Protocol (MCP) traffic and attaches it to Gateway resources managed by NetScaler® Kubernetes Gateway Controller. MCP clients select an upstream MCP server with the x-netscaler-target-mcp-server request header, and the mcproute routes each request to the matching backend Service.
NetScaler Kubernetes Gateway Controller provides the following capabilities for an
mcproute:
-
Content switching to multiple MCP servers using the
MCPTargetServerheader match on thex-netscaler-target-mcp-serverheader. -
Standard path and header matches, plus a
policyExpressionpassthrough for advanced NetScaler policy expressions. -
A
default: truecatch-all rule for traffic that no other rule matches. -
Per-rule and per-backend NetScaler policy CRDs attached through
ExtensionReffilters, includingrewritepolicy,ratelimit,mcpprofile, andauthpolicyfor authentication. -
Core Gateway API filters (
RequestHeaderModifier,ResponseHeaderModifier,RequestRedirect,URLRewrite, andRequestMirror) at the rule level. -
ExternalNameService backends for MCP servers that are reached by FQDN.
Note:
Use the
MCPTargetServer match type on the x-netscaler-target-mcp-server header to route by MCP server. The header value has the form <host>/<path>, and NetScaler matches on the host portion.
Deploy the mcproute CRD
The mcproute CRD is in the mcproute.yaml file in the NetScaler Ingress Controller GitHub repository. The NetScaler Kubernetes Gateway Controller Helm chart also installs it. Deploy the CRD using the following command:
kubectl create -f https://raw.githubusercontent.com/netscaler/netscaler-k8s-ingress-controller/master/crd/mcp/mcproute.yaml
Note:
Do not modify the CRD deployment YAML file.
mcproute CRD attributes
The following table lists the top-level attributes available under
spec for the mcproute CRD.
| Attribute | Description | Supported values |
|---|---|---|
rules |
List of routing rules that this route matches the traffic against. This field is required. | Array of rules (maximum 128) |
parentRefs |
References to the Gateway resources that this route is attached to. |
Array (maximum 32) |
hostnames |
Set of hostnames matched against the HTTP Host header to select this route. Wildcard prefixes (*.) are allowed. IP addresses are not allowed. |
Array of RFC 1123 hostnames (maximum 16) |
parentRefs attributes
The following table lists
parentRefs attributes.
| Attribute | Description | Supported values |
|---|---|---|
name |
Name of the referent Gateway. This field is required. |
String |
group |
Group of the referent. When unspecified, gateway.networking.k8s.io is inferred. |
String |
kind |
Kind of the referent. | Default: Gateway |
namespace |
Namespace of the referent. Defaults to the local namespace of the route. | String |
port |
Network port that this route targets on the Gateway. |
Integer (1–65535) |
sectionName |
Name of the Gateway listener to attach to. |
String |
rules attributes
Each entry in
rules supports the following attributes.
| Attribute | Description | Supported values |
|---|---|---|
matches |
List of matches that select this rule. Within one match, a request must meet all the conditions that you set: path, each header in headers, and policyExpression. If the rule has more than one match, the request must meet at least one of the matches. |
Array (maximum 128) |
backendRefs |
List of backend Service resources that this rule routes traffic to. |
Array (maximum 16) |
filters |
NetScaler policy CRDs and Gateway API filters to apply to this rule. | Array (maximum 16) |
default |
Marks this rule as the catch-all. Set true on exactly one rule, with no matches, to handle traffic that no other rule matches. |
Boolean (default false) |
matches attributes
The following table lists matches attributes.
| Attribute | Description | Supported values |
|---|---|---|
path |
HTTP request path matcher. | type: Exact, PathPrefix (default), RegularExpression; value: string |
headers |
HTTP request header matchers. Use the MCPTargetServer type on the x-netscaler-target-mcp-server header for MCP server routing. |
name, value, type: Exact (default), RegularExpression, MCPTargetServer |
policyExpression |
NetScaler advanced policy expression. A request must meet it in addition to the other conditions of the same match. If the expression uses a logical OR, put the whole expression in parentheses. | String |
backendRefs attributes
The following table lists
backendRefs attributes.
| Attribute | Description | Supported values |
|---|---|---|
name |
Name of the backend Service resource. This field is required. |
String |
port |
Service port to use for this backend. This field is required. | Integer (1–65535) |
group |
API group of the referent. Use "" for a core Service. |
String |
kind |
Kubernetes resource kind of the referent. | Default: Service |
namespace |
Namespace of the backend. Defaults to, and must equal, the route namespace. | String |
weight |
Proportion of traffic to send to this backend. Backends in a rule are currently load balanced evenly, so this value is accepted but not yet applied. | Integer (default 1) |
filters |
Per-backend NetScaler policy CRDs attached through ExtensionRef. Supported on single-backend rules only. |
Array (maximum 16) |
filters attributes
The following table lists filters attributes.
| Attribute | Description | Supported values |
|---|---|---|
type |
Type of filter to apply. | ExtensionRef, RequestHeaderModifier, ResponseHeaderModifier, RequestRedirect, URLRewrite, RequestMirror |
extensionRef |
Reference to a NetScaler policy CRD (group, kind, name — all required). Supported kinds are rewritepolicy, ratelimit, bot, waf, appqoepolicy, owasppolicy, sslprofile, httpprofile, tcpprofile, mcpprofile, and authpolicy. |
Object |
Note:
Per-backend
filters support the ExtensionRef type only, with the kinds rewritepolicy, ratelimit, bot, waf, appqoepolicy, owasppolicy, and authpolicy. The sslprofile, httpprofile, tcpprofile, and mcpprofile kinds are attached at the rule level. The core Gateway API filter types follow standard Gateway API HTTPRoute filter semantics.
How to write the route configuration
In the
mcproute YAML definition, set the kind as mcproute. In the spec section, add the parentRefs that attach the route to a Gateway, and one or more rules that match and route the traffic.
Keep the following guidelines in mind:
-
The
rulesfield is mandatory. -
Use the
MCPTargetServermatch on thex-netscaler-target-mcp-serverheader to route by MCP server. -
Set
default: trueon one rule, with no matches, as the catch-all. -
Attach policy CRDs through
ExtensionReffilters at the rule or backend level. Attach a BACKENDmcpprofileto inject the MCP token into upstream requests. -
Reference an
ExternalNameService to reach an MCP server by FQDN.
Sample route configurations
Route to multiple MCP servers by target server
The following configuration routes requests to different MCP servers based on the
x-netscaler-target-mcp-server header, with a catch-all rule for all other traffic.
apiVersion: citrix.com/v1
kind: mcproute
metadata:
name: mcp-routes
namespace: default
spec:
parentRefs:
- name: mcp-gateway
rules:
- matches:
- headers:
- name: x-netscaler-target-mcp-server
type: MCPTargetServer
value: api.githubcopilot.com
backendRefs:
- name: github-svc
port: 443
- matches:
- headers:
- name: x-netscaler-target-mcp-server
type: MCPTargetServer
value: mcp.atlassian.com
backendRefs:
- name: atlassian-svc
port: 443
- default: true
backendRefs:
- name: default-svc
port: 443
Attach a backend profile and a rate limit to a rule
The following configuration attaches a BACKEND
mcpprofile and a ratelimit CRD to a routing rule through ExtensionRef filters.
apiVersion: citrix.com/v1
kind: mcproute
metadata:
name: mcp-github-route
namespace: default
spec:
parentRefs:
- name: mcp-gateway
rules:
- matches:
- headers:
- name: x-netscaler-target-mcp-server
type: MCPTargetServer
value: api.githubcopilot.com
filters:
- type: ExtensionRef
extensionRef:
group: citrix.com
kind: mcpprofile
name: github-mcp-backend
- type: ExtensionRef
extensionRef:
group: citrix.com
kind: ratelimit
name: mcp-tool-limit
backendRefs:
- name: github-svc
port: 443
Route to an ExternalName backend
The following configuration routes traffic to an MCP server that is reached by FQDN through an
ExternalName Service.
apiVersion: v1
kind: Service
metadata:
name: remote-mcp-svc
namespace: default
spec:
type: ExternalName
externalName: mcp.example.com
ports:
- port: 443
targetPort: 443
protocol: TCP
---
apiVersion: citrix.com/v1
kind: mcproute
metadata:
name: mcp-externalname-route
namespace: default
spec:
parentRefs:
- name: mcp-gateway
rules:
- matches:
- headers:
- name: x-netscaler-target-mcp-server
type: MCPTargetServer
value: mcp.example.com
backendRefs:
- name: remote-mcp-svc
port: 443
Add a NetScaler policy expression to a match
Use
policyExpression to add a NetScaler advanced policy expression to a match. A request must meet the expression and all the other conditions of the match. If the expression uses a logical OR (||), put the whole expression in parentheses. Without parentheses, NetScaler can select the rule for a request that does not meet the other conditions of the match. The following configuration sends requests for the GitHub MCP server to github-svc only when the x-tenant header is team-a. Other requests go to the catch-all rule.
apiVersion: citrix.com/v1
kind: mcproute
metadata:
name: mcp-routes-by-tenant
namespace: default
spec:
parentRefs:
- name: mcp-gateway
rules:
- matches:
- headers:
- name: x-netscaler-target-mcp-server
type: MCPTargetServer
value: api.githubcopilot.com
policyExpression: 'HTTP.REQ.HEADER("x-tenant").EQ("team-a")'
backendRefs:
- name: github-svc
port: 443
- default: true
backendRefs:
- name: default-svc
port: 443