diff --git a/kong/mcp/ai-mcp-proxy.yaml b/kong/mcp/ai-mcp-proxy.yaml index 3a355dd..692a9e4 100644 --- a/kong/mcp/ai-mcp-proxy.yaml +++ b/kong/mcp/ai-mcp-proxy.yaml @@ -1,3 +1,10 @@ +# GENERATED — do not edit. Edit openapi.yaml or tools-policy.yaml, then: +# k8s-platform/tools/generate-mcp-tools.py +# +# Produced by `deck file openapi2mcp`, then post-processed to add the ACLs, +# the MCP behavioural annotations, the response schemas, the real upstream +# host and the JSON-only bodies that Kong's generator does not emit. Each of +# those is a documented gap — see k8s-platform/MCP-TOOL-GENERATION.md. apiVersion: configuration.konghq.com/v1 kind: KongPlugin metadata: @@ -8,95 +15,328 @@ 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 + - annotations: + title: List all customers + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve a paginated list of all customers with their contact and credit information. + method: GET + name: list-customers + parameters: + - description: A page number within the paginated result set. + in: query + name: page + required: false + schema: + type: integer + - description: Number of results to return per page. + in: query + name: page_size + required: false + schema: + type: integer + path: /customers/v1/customers/ + acl: + allow: + - admin + - read_only + - product_manager + - customer + - support + scheme: http + host: ${REST_HOSTNAME} + responses: + '200': content: application/json: schema: type: object properties: + count: + type: integer + example: 123 + next: + type: string + nullable: true + format: uri + example: http://api.example.org/accounts/?page=4 + previous: + type: string + nullable: true + format: uri + example: http://api.example.org/accounts/?page=2 + results: + type: array + items: + type: object + description: Customer information and contact details + properties: + customernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + customername: + type: string + maxLength: 50 + contactlastname: + type: string + maxLength: 50 + contactfirstname: + type: string + maxLength: 50 + phone: + type: string + maxLength: 50 + addressline1: + type: string + maxLength: 50 + addressline2: + type: string + nullable: true + maxLength: 50 + city: + type: string + maxLength: 50 + state: + type: string + nullable: true + maxLength: 50 + postalcode: + type: string + nullable: true + maxLength: 15 + country: + type: string + maxLength: 50 + creditlimit: + type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ + nullable: true + salesrepemployeenumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + nullable: true + required: + - addressline1 + - city + - contactfirstname + - contactlastname + - country + - customername + - customernumber + - phone + - annotations: + title: Get a specific customer + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve detailed information about a specific customer by their customer number. + method: GET + name: get-customer + parameters: + - description: A unique value identifying this customer. + in: path + name: customernumber + required: true + schema: + type: integer + path: /customers/v1/customers/{customernumber}/ + acl: + allow: + - admin + - read_only + - product_manager + - customer + - support + scheme: http + host: ${REST_HOSTNAME} + responses: + '200': + content: + application/json: + schema: + type: object + description: Customer information and contact details + properties: + customernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 customername: type: string + maxLength: 50 contactlastname: type: string + maxLength: 50 contactfirstname: type: string + maxLength: 50 phone: type: string + maxLength: 50 addressline1: type: string + maxLength: 50 + addressline2: + type: string + nullable: true + maxLength: 50 city: type: string + maxLength: 50 + state: + type: string + nullable: true + maxLength: 50 + postalcode: + type: string + nullable: true + maxLength: 15 country: type: string - salesrepemployeenumber: - type: integer + maxLength: 50 creditlimit: type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ + nullable: true + salesrepemployeenumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + nullable: true required: - - customername - - contactlastname - - contactfirstname - - phone - - addressline1 - - city - - country + - addressline1 + - city + - contactfirstname + - contactlastname + - country + - customername + - customernumber + - phone + - annotations: + title: Create a new customer + read_only_hint: false + idempotent_hint: false + destructive_hint: false + open_world_hint: false + description: Add a new customer to the system with their contact details and credit limit. + method: POST + name: create-customer + path: /customers/v1/customers/ + request_body: + content: + application/json: + schema: + properties: + addressline1: + type: string + addressline2: + type: string + city: + type: string + contactfirstname: + type: string + contactlastname: + type: string + country: + type: string + creditlimit: + type: string + customername: + type: string + customernumber: + type: integer + phone: + type: string + postalcode: + type: string + salesrepemployeenumber: + type: integer + state: + type: string + required: + - addressline1 + - city + - contactfirstname + - contactlastname + - country + - customername + - customernumber + - phone + type: object + required: true + acl: + allow: + - admin + scheme: http + host: ${REST_HOSTNAME} + responses: + '201': + content: + application/json: + schema: + type: object + description: Customer information and contact details + properties: + customernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + customername: + type: string + maxLength: 50 + contactlastname: + type: string + maxLength: 50 + contactfirstname: + type: string + maxLength: 50 + phone: + type: string + maxLength: 50 + addressline1: + type: string + maxLength: 50 + addressline2: + type: string + nullable: true + maxLength: 50 + city: + type: string + maxLength: 50 + state: + type: string + nullable: true + maxLength: 50 + postalcode: + type: string + nullable: true + maxLength: 15 + country: + type: string + maxLength: 50 + creditlimit: + type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ + nullable: true + salesrepemployeenumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + nullable: true + required: + - addressline1 + - city + - contactfirstname + - contactlastname + - country + - customername + - customernumber + - phone diff --git a/kong/mcp/tools-policy.yaml b/kong/mcp/tools-policy.yaml new file mode 100644 index 0000000..d57708b --- /dev/null +++ b/kong/mcp/tools-policy.yaml @@ -0,0 +1,20 @@ +# Which operations of openapi.yaml become MCP tools, and who may call each. +# +# This file is the allow-list as well as the ACL: an operation that is not +# named here does not become a tool. Kong's generator exposes every operation +# it finds and can express no authorization at all from a bearer-token spec — +# see k8s-platform/MCP-TOOL-GENERATION.md, limits 1 and 5. +# +# `allow` lists consumer groups, which come from realm_access.roles in the end +# user's own token. Kong applies them at tools/list, so a caller never sees a +# tool it may not call. + +mcp_name: customers-mcp + +tools: + list-customers: + allow: [admin, read_only, product_manager, customer, support] + get-customer: + allow: [admin, read_only, product_manager, customer, support] + create-customer: + allow: [admin]