Addition of MCP server

This commit is contained in:
Stéphane Tailland
2026-08-23 15:00:57 +02:00
parent 98a9802360
commit a4967d13ee
11 changed files with 394 additions and 0 deletions
+6
View File
@@ -32,6 +32,12 @@ spec:
AUDIT_LOG_ENDPOINT: http://audit-log-collector.observability.svc.cluster.local/logs AUDIT_LOG_ENDPOINT: http://audit-log-collector.observability.svc.cluster.local/logs
REST_HOSTNAME: customers-dev.sttlab.local REST_HOSTNAME: customers-dev.sttlab.local
TOKEN_EXCHANGE_CLIENT_ID: kong-token-exchange-broker TOKEN_EXCHANGE_CLIENT_ID: kong-token-exchange-broker
# Unused today — same dead variable already present in catalog-api's
# flux-kustomization.yaml (kong/mcp/openid-connect.yaml uses
# API_AUDIENCE for its audience_required/token_exchange target, not
# this). Kept for parity/documentation of what the MCP layer's real
# token audience is meant to be.
MCP_AUDIENCE: '["mcp-customers"]'
substituteFrom: substituteFrom:
- kind: Secret - kind: Secret
name: customers-token-exchange-broker name: customers-token-exchange-broker
+9
View File
@@ -12,3 +12,12 @@ resources:
- rest/audit-log-body-capture.yaml - rest/audit-log-body-capture.yaml
- rest/audit-log-body-capture-bindings.yaml - rest/audit-log-body-capture-bindings.yaml
- rest/pluginbindings.yaml - rest/pluginbindings.yaml
- mcp/service.yaml
- mcp/routes.yaml
- mcp/consumergroups.yaml
- mcp/ai-mcp-proxy.yaml
- mcp/openid-connect.yaml
- mcp/audit-log.yaml
- mcp/audit-log-body-capture.yaml
- mcp/audit-log-body-capture-bindings.yaml
- mcp/pluginbindings.yaml
+102
View File
@@ -0,0 +1,102 @@
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: ${NAME}-customers-mcp-ai-mcp-proxy
namespace: ${NAMESPACE}
plugin: ai-mcp-proxy
config:
mode: conversion-listener
include_consumer_groups: true
tools:
- name: list-customers
description: Retrieves a paginated list of customers in the classic-models CRM.
annotations:
title: List all customers
read_only_hint: true
idempotent_hint: true
destructive_hint: false
open_world_hint: false
acl:
allow:
- admin
- read_only
- product_manager
- customer
- support
method: GET
scheme: http
host: ${REST_HOSTNAME}
path: /customers/v1/customers/
- name: get-customer
description: Retrieves a single customer by customer number.
annotations:
title: Get a customer
read_only_hint: true
idempotent_hint: true
destructive_hint: false
open_world_hint: false
acl:
allow:
- admin
- read_only
- product_manager
- customer
- support
method: GET
scheme: http
host: ${REST_HOSTNAME}
path: /customers/v1/customers/{customernumber}/
parameters:
- name: customernumber
in: path
required: true
description: The customer's unique number.
schema: {}
- name: create-customer
description: Creates a new customer in the CRM.
annotations:
title: Create a customer
read_only_hint: false
idempotent_hint: false
destructive_hint: false
open_world_hint: false
acl:
allow:
- admin
method: POST
scheme: http
host: ${REST_HOSTNAME}
path: /customers/v1/customers/
request_body:
required: true
content:
application/json:
schema:
type: object
properties:
customername:
type: string
contactlastname:
type: string
contactfirstname:
type: string
phone:
type: string
addressline1:
type: string
city:
type: string
country:
type: string
salesrepemployeenumber:
type: integer
creditlimit:
type: string
required:
- customername
- contactlastname
- contactfirstname
- phone
- addressline1
- city
- country
@@ -0,0 +1,35 @@
apiVersion: configuration.konghq.com/v1alpha1
kind: KongPluginBinding
metadata:
name: ${NAME}-customers-mcp-audit-capture-request-binding
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
pluginRef:
name: ${NAME}-customers-mcp-audit-capture-request
targets:
serviceRef:
group: configuration.konghq.com
kind: KongService
name: ${NAME}-customers-mcp
---
apiVersion: configuration.konghq.com/v1alpha1
kind: KongPluginBinding
metadata:
name: ${NAME}-customers-mcp-audit-capture-response-binding
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
pluginRef:
name: ${NAME}-customers-mcp-audit-capture-response
targets:
serviceRef:
group: configuration.konghq.com
kind: KongService
name: ${NAME}-customers-mcp
+27
View File
@@ -0,0 +1,27 @@
# dev only: captures raw request/response bodies into kong.ctx.shared for
# audit-log.yaml's custom_fields_by_lua to read back in the log phase.
# Drop this file (and its bindings) to stop body capture without touching
# audit-log.yaml itself — it degrades gracefully to metadata-only logging.
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: ${NAME}-customers-mcp-audit-capture-request
namespace: ${NAMESPACE}
plugin: pre-function
config:
access:
- "kong.ctx.shared.audit_request_body = kong.request.get_raw_body()"
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: ${NAME}-customers-mcp-audit-capture-response
namespace: ${NAMESPACE}
plugin: post-function
config:
body_filter:
- |
local chunk = ngx.arg[1]
if chunk then
kong.ctx.shared.audit_response_body = (kong.ctx.shared.audit_response_body or "") .. chunk
end
+17
View File
@@ -0,0 +1,17 @@
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: ${NAME}-customers-mcp-audit-log
namespace: ${NAMESPACE}
plugin: http-log
# dev only: the raw Authorization (JWT) header is captured in clear text,
# not acceptable as-is for a non-dev environment. request_body/response_body
# below read from kong.ctx.shared, populated by audit-log-body-capture.yaml
# — nil (and silently omitted) if that file isn't applied.
config:
http_endpoint: ${AUDIT_LOG_ENDPOINT}
method: POST
content_type: application/json
custom_fields_by_lua:
request_body: "return kong.ctx.shared.audit_request_body"
response_body: "return kong.ctx.shared.audit_response_body"
+59
View File
@@ -0,0 +1,59 @@
apiVersion: configuration.konghq.com/v1beta1
kind: KongConsumerGroup
metadata:
name: ${NAME}-admin
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
name: admin
---
apiVersion: configuration.konghq.com/v1beta1
kind: KongConsumerGroup
metadata:
name: ${NAME}-read-only
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
name: read_only
---
apiVersion: configuration.konghq.com/v1beta1
kind: KongConsumerGroup
metadata:
name: ${NAME}-product-manager
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
name: product_manager
---
apiVersion: configuration.konghq.com/v1beta1
kind: KongConsumerGroup
metadata:
name: ${NAME}-customer
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
name: customer
---
apiVersion: configuration.konghq.com/v1beta1
kind: KongConsumerGroup
metadata:
name: ${NAME}-support
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
name: support
+27
View File
@@ -0,0 +1,27 @@
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: ${NAME}-customers-mcp-openid-connect
namespace: ${NAMESPACE}
plugin: openid-connect
config:
issuer: ${OIDC_ISSUER}
audience_required: ${API_AUDIENCE}
auth_methods:
- bearer
display_errors: false
ssl_verify: true
consumer_groups_claim:
- realm_access
- roles
client_id:
- ${TOKEN_EXCHANGE_CLIENT_ID}
client_secret:
- ${TOKEN_EXCHANGE_CLIENT_SECRET}
token_exchange:
subject_token_issuers:
- issuer: ${OIDC_ISSUER}
conditions: {}
request:
audience: ${API_AUDIENCE}
scopes: []
+53
View File
@@ -0,0 +1,53 @@
apiVersion: configuration.konghq.com/v1alpha1
kind: KongPluginBinding
metadata:
name: ${NAME}-customers-mcp-openid-connect-binding
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
pluginRef:
name: ${NAME}-customers-mcp-openid-connect
targets:
serviceRef:
group: configuration.konghq.com
kind: KongService
name: ${NAME}-customers-mcp
---
apiVersion: configuration.konghq.com/v1alpha1
kind: KongPluginBinding
metadata:
name: ${NAME}-customers-mcp-ai-mcp-proxy-binding
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
pluginRef:
name: ${NAME}-customers-mcp-ai-mcp-proxy
targets:
routeRef:
group: configuration.konghq.com
kind: KongRoute
name: ${NAME}-customers-mcp
---
apiVersion: configuration.konghq.com/v1alpha1
kind: KongPluginBinding
metadata:
name: ${NAME}-customers-mcp-audit-log-binding
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
pluginRef:
name: ${NAME}-customers-mcp-audit-log
targets:
serviceRef:
group: configuration.konghq.com
kind: KongService
name: ${NAME}-customers-mcp
+42
View File
@@ -0,0 +1,42 @@
apiVersion: configuration.konghq.com/v1alpha1
kind: KongRoute
metadata:
name: ${NAME}-customers-mcp
namespace: ${NAMESPACE}
spec:
serviceRef:
type: namespacedRef
namespacedRef:
name: ${NAME}-customers-mcp
name: customers-mcp
hosts:
- ${REST_HOSTNAME}
methods:
- POST
- DELETE
paths:
- /customers-mcp
strip_path: false
tags:
- customers
---
apiVersion: configuration.konghq.com/v1alpha1
kind: KongRoute
metadata:
name: ${NAME}-customers-mcp-stream
namespace: ${NAMESPACE}
spec:
serviceRef:
type: namespacedRef
namespacedRef:
name: ${NAME}-customers-mcp
name: customers-mcp-stream
hosts:
- ${REST_HOSTNAME}
methods:
- GET
paths:
- /customers-mcp
strip_path: false
tags:
- customers
+17
View File
@@ -0,0 +1,17 @@
apiVersion: configuration.konghq.com/v1alpha1
kind: KongService
metadata:
name: ${NAME}-customers-mcp
namespace: ${NAMESPACE}
spec:
controlPlaneRef:
type: konnectNamespacedRef
konnectNamespacedRef:
name: ${CONTROL_PLANE_REF_NAME}
name: customers-mcp
host: ${REST_HOSTNAME}
port: 80
protocol: http
path: /
tags:
- customers