CONTROL_PLANE_ID=$(curl -X GET "https://us.api.konghq.com/v2/control-planes?filter%5Bname%5D%5Beq%5D=context-mesh-demo" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" | jq -r ".data[0].id"
)Deploy an MCP server with Context Mesh and Kong Operator
Install Kong Operator 2.3 with the mcp-server feature gate, create a Konnect-managed control plane and data plane, then create and deploy the MCP server with the Konnect API.
Prerequisites
Konnect personal access token
-
Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.
-
Export the token and the Konnect API URL for your region:
export KONNECT_TOKEN='YOUR_KONNECT_PAT' export KONNECT_CONTROL_PLANE_URL='us.api.konghq.com'
Kubernetes cluster
Set up a local Kubernetes cluster. This example uses minikube:
minikube startOnce started, open a separate terminal window, and activate load balancing on your cluster:
minikube tunnelType your password when prompted. Leave this window open on the side as you follow this guide.
Claude Code
- Install Claude Code:
curl -fsSL https://claude.ai/install.sh | bash - Verify the installation:
claude --version
OpenWeatherMap account and API key
- Create an account at openweathermap.org
- Generate an API key (may take several hours to activate)
export OPENWEATHERMAP_API_KEY='<your-api-key'OpenWeather OpenAPI spec
Download the OpenWeatherMap OpenAPI specification. You upload this file to Konnect later in this guide:
curl -O https://developer.konghq.com/assets/context-mesh/openweathermap.jsonAdd the Kong Helm repository
Map the name kong to the Kong Helm charts URL and download the latest chart index:
helm repo add kong https://charts.konghq.com
helm repo updateInstall Kong Operator
Kong Gateway needs Kong Operator to run a Context Mesh MCP server:
helm upgrade --install kong-operator kong/kong-operator -n kong \
--create-namespace \
--set image.tag=2.3 \
--set env.ENABLE_CONTROLLER_KONNECT=true \
--set env.FEATURE_GATES=mcp-serverThis command creates the kong namespace containing:
- The operator itself (
kong-operator-kong-operator-controller-manager). - CustomResourceDefinitions (CRDs) that add resource types such as
DataPlaneto your Kubernetes cluster. - Role-based access control (RBAC) rules that let the operator manage those resources on your behalf.
- Webhook configurations that validate the resources before they’re applied.
Wait for the Kong Operator deployment to become available before you create any Konnect resources:
kubectl -n kong wait --for=condition=Available=true --timeout=120s \
deployment/kong-operator-kong-operator-controller-managerDeploy a Konnect control plane and data plane
The following manifest creates the four resources that Kong Operator needs to run a Konnect-managed data plane in your cluster:
KonnectAPIAuthConfiguration: Authenticates Kong Operator against the Konnect API with your personal access token. TheserverURLis read fromKONNECT_CONTROL_PLANE_URL, so it points at whichever region your account uses.KonnectGatewayControlPlane: Creates a control plane namedcontext-mesh-demoin Konnect. This is the control plane you attach the MCP server to in a later step.KonnectExtension: Links the cluster to that control plane and provisions the mTLS certificates the data plane uses to connect to it.DataPlane: Deploys three Kong Gateway 3.16 proxy replicas. TheKonnectExtensionreference configures them to run in hybrid mode and pull their configuration fromcontext-mesh-demo.
Apply the manifest:
kubectl apply -f - <<EOF
kind: KonnectAPIAuthConfiguration
apiVersion: konnect.konghq.com/v1alpha1
metadata:
name: konnect-api-auth
namespace: default
spec:
type: token
token: ${KONNECT_TOKEN}
serverURL: ${KONNECT_CONTROL_PLANE_URL}
---
kind: KonnectGatewayControlPlane
apiVersion: konnect.konghq.com/v1alpha2
metadata:
name: test
namespace: default
spec:
createControlPlaneRequest:
name: context-mesh-demo
labels:
app: context-mesh-demo
konnect:
authRef:
name: konnect-api-auth
---
kind: KonnectExtension
apiVersion: konnect.konghq.com/v1alpha2
metadata:
name: my-konnect-config
namespace: default
spec:
konnect:
controlPlane:
ref:
type: konnectNamespacedRef
konnectNamespacedRef:
name: test
---
apiVersion: gateway-operator.konghq.com/v1beta1
kind: DataPlane
metadata:
name: dataplane
namespace: default
spec:
extensions:
- kind: KonnectExtension
name: my-konnect-config
group: konnect.konghq.com
deployment:
replicas: 3
podTemplateSpec:
spec:
containers:
- name: proxy
image: kong/kong-gateway:3.16
EOFWait for the data plane to be ready
kubectl wait --timeout=3m dataplane dataplane -n default --for=condition=ReadyGet the control plane ID
Retrieve the context-mesh-demo control plane ID that Kong Operator created. You’ll use it to attach it to the MCP server when you deploy it:
Add the OpenWeather API as a source
A source holds the OpenAPI specification that Context Mesh generates the MCP server from. The specification is sent as a single JSON string, so build the request body from the file you downloaded:
jq -n --rawfile spec openweathermap.json '{
"name": "openweathermap",
"display_name": "OpenWeatherMap Current Weather API",
"description": "Current weather data from OpenWeatherMap",
"labels": {},
"type": "api",
"source": {
"type": "raw",
"config": {"spec": $spec}
}
}' > source.jsonCreate the source:
SOURCE_ID=$(curl -X POST "https://us.api.konghq.com/v1/context-sources" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json "$(cat source.json)" | jq -r ".id"
)The name must be unique within your organization and can only contain lowercase letters, digits, periods, and hyphens.
Create the MCP server
Create the MCP server:
MCP_SERVER_ID=$(curl -X POST "https://us.api.konghq.com/v1/context-interfaces" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"name": "openweather-service",
"display_name": "OpenWeather Service",
"description": "Code Mode MCP server for the OpenWeatherMap API",
"labels": {}
}' | jq -r ".id"
)The MCP server has no sources yet. Map the OpenWeather source to it:
SOURCE_MAPPING_ID=$(curl -X POST "https://us.api.konghq.com/v1/context-interfaces/$MCP_SERVER_ID/context-source-mappings" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"context_source_id": "'$SOURCE_ID'"
}' | jq -r ".id"
)To expose more than one API or MCP server through the same MCP server, repeat this call for each source.
Deploy the MCP server
Mapping the MCP server to a control plane deploys it. Set mode to basic to let Konnect manage the underlying Kubernetes workload with its defaults:
CP_MAPPING_ID=$(curl -X POST "https://us.api.konghq.com/v1/context-interfaces/$MCP_SERVER_ID/control-plane-mappings" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"control_plane_id": "'$CONTROL_PLANE_ID'",
"mode": "basic"
}' | jq -r ".id"
)Wait for the MCP server pod to be ready
Kong Operator runs the MCP server as an mcpserver- prefixed deployment in the default namespace of your cluster. Wait for its pod to appear, then wait for it to become ready:
until kubectl get pods -n default -o name | grep -q '^pod/mcpserver-'; do sleep 5; done
kubectl wait --for=condition=Ready --timeout=3m -n default \
$(kubectl get pods -n default -o name | grep '^pod/mcpserver-')Confirm that the pod is running:
kubectl get pods -n default | grep mcpserverThe output looks like this:
mcpserver-test-45675cb3-764b4d6d6c-q2gnp 1/1 Running 0 57mIf the pod stays in
PendingorCrashLoopBackOff, check its logs withkubectl logs -n default <pod-name>.
The MCP runtime is now exposed at /mcp/openweather-service.
Add the OpenWeather MCP server to Claude
Connect the MCP server to an agent:
claude mcp add --transport http context-mesh-weather http://localhost/mcp/openweather-service \
--header "X-Upstream-Api-Key: ${OPENWEATHERMAP_API_KEY}"Validate
Start Claude Code:
claudeVerify that the local context-mesh-weather MCP is in your list:
/mcpIf the MCP appears as disabled, select it and enable it. You might need to input your sudo password on the minikube tunnel terminal for this step.
Try a prompt in Claude Code:
Tell me the weather in Hawaii.Cleanup
Delete the MCP server
Stop the MCP server by deleting its control plane mapping, then delete the MCP server and its source:
Delete the control plane mapping:
curl -X DELETE "https://us.api.konghq.com/v1/context-interfaces/$MCP_SERVER_ID/control-plane-mappings/$CP_MAPPING_ID" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN"Delete the MCP server:
curl -X DELETE "https://us.api.konghq.com/v1/context-interfaces/$MCP_SERVER_ID" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN"Delete the MCP source:
curl -X DELETE "https://us.api.konghq.com/v1/context-sources/$SOURCE_ID" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN"Delete the control plane and data plane
kubectl delete -n default dataplane dataplane
kubectl delete -n default konnectextension my-konnect-config
kubectl delete -n default konnectgatewaycontrolplane test
kubectl delete -n default konnectapiauthconfiguration konnect-api-authDeleting the KonnectGatewayControlPlane also deletes the context-mesh-demo control plane in Konnect. Run this step even if you plan to repeat the guide: control plane names must be unique within an organization, so a leftover context-mesh-demo makes the next run fail with a 409 Conflict and the data plane never becomes ready.
Uninstall Kong Operator
helm uninstall kong-operator -n kong
kubectl delete namespace kong