diff --git a/kong/mcp/ai-mcp-proxy.yaml b/kong/mcp/ai-mcp-proxy.yaml index 7786532..02b34b8 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,216 +15,560 @@ config: mode: conversion-listener include_consumer_groups: true tools: - - name: list-orders - description: Retrieves a paginated list of orders in the classic-models CRM. - annotations: - title: List all orders - 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: /sales/v1/orders/ - - name: get-order - description: Retrieves a single order by order number. - annotations: - title: Get an order - 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: /sales/v1/orders/{ordernumber}/ - parameters: - - name: ordernumber - in: path - required: true - description: The order's unique number. - schema: {} - - name: get-order-orderdetails - description: Retrieves all line items for a specific order. - annotations: - title: Get order line items - 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: /sales/v1/orders/{ordernumber}/order-details/ - parameters: - - name: ordernumber - in: path - required: true - description: The order's unique number. - schema: {} - - name: create-order - description: Creates a new order in the CRM. - annotations: - title: Create an order - read_only_hint: false - idempotent_hint: false - destructive_hint: false - open_world_hint: false - # Verified against OrderPermission.check() (authentication/permissions.py): - # admin always passes; customer passes if get_customer_number(user) is - # not None; support passes unconditionally at this class-level check - # (object-level restricts support to status-only on *existing* orders, - # which doesn't apply to create — no object yet). read_only/ - # product_manager only pass for SAFE_METHODS, excluded here. - acl: - allow: - - admin - - customer - - support - method: POST - scheme: http - host: ${REST_HOSTNAME} - path: /sales/v1/orders/ - request_body: - required: true + - annotations: + title: List all orders + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve a paginated list of all customer orders with their status and details. + method: GET + name: list-orders + 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: /sales/v1/orders/ + 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 order information + properties: + ordernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + orderdate: + type: string + format: date + requireddate: + type: string + format: date + shippeddate: + type: string + format: date + nullable: true + status: + type: string + maxLength: 15 + comments: + type: string + nullable: true + customernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + required: + - customernumber + - orderdate + - ordernumber + - requireddate + - status + - annotations: + title: Get a specific order + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve detailed information about a specific order by its order number. + method: GET + name: get-order + parameters: + - description: A unique value identifying this order. + in: path + name: ordernumber + required: true + schema: + type: integer + path: /sales/v1/orders/{ordernumber}/ + acl: + allow: + - admin + - read_only + - product_manager + - customer + - support + scheme: http + host: ${REST_HOSTNAME} + responses: + '200': + content: + application/json: + schema: + type: object + description: Customer order information properties: ordernumber: type: integer + maximum: 2147483647 + minimum: -2147483648 orderdate: type: string + format: date requireddate: type: string + format: date shippeddate: type: string + format: date + nullable: true status: type: string + maxLength: 15 comments: type: string + nullable: true customernumber: type: integer + maximum: 2147483647 + minimum: -2147483648 required: - - ordernumber - - orderdate - - requireddate - - status - - customernumber - - name: list-orderdetails - description: Retrieves a paginated list of order line items in the classic-models CRM. - annotations: - title: List all order line items - 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: /sales/v1/orderdetails/ - - name: get-orderdetail - description: Retrieves a single order line item by order number and product code. - annotations: - title: Get an order line item - 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: /sales/v1/orderdetails/{ordernumber}/{productcode}/ - parameters: - - name: ordernumber - in: path - required: true - description: The order's unique number. - schema: {} - - name: productcode - in: path - required: true - description: The product's unique code. - schema: {} - - name: create-orderdetail - description: Adds a new line item to an order. - annotations: - title: Create an order line item - read_only_hint: false - idempotent_hint: false - destructive_hint: false - open_world_hint: false - # Verified against OrderScopedPermission.check() (Orderdetail's base - # permission class) — same shape as create-order above: admin, - # customer (if get_customer_number is not None), support (class-level - # unconditional pass) allowed; read_only/product_manager excluded - # (SAFE_METHODS only). - acl: - allow: - - admin - - customer - - support - method: POST - scheme: http - host: ${REST_HOSTNAME} - path: /sales/v1/orderdetails/ - request_body: - required: true + - customernumber + - orderdate + - ordernumber + - requireddate + - status + - annotations: + title: Get order details by order + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve all line items for a specific order. This endpoint supports order fulfillment + and invoice generation. + method: GET + name: get-order-order-details + parameters: + - description: The order number + in: path + name: ordernumber + required: true + schema: + type: integer + - 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: /sales/v1/orders/{ordernumber}/order-details/ + 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: Order line items with product details + properties: + id: + type: integer + readOnly: true + quantityordered: + type: integer + maximum: 2147483647 + minimum: -2147483648 + priceeach: + type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ + orderlinenumber: + type: integer + maximum: 32767 + minimum: -32768 + ordernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + productcode: + type: string + required: + - id + - orderlinenumber + - ordernumber + - priceeach + - productcode + - quantityordered + - annotations: + title: Create a new order + read_only_hint: false + idempotent_hint: false + destructive_hint: false + open_world_hint: false + description: Create a new customer order with order date, required date, and status information. + method: POST + name: create-order + path: /sales/v1/orders/ + request_body: + content: + application/json: + schema: + properties: + comments: + type: string + customernumber: + type: integer + orderdate: + type: string + ordernumber: + type: integer + requireddate: + type: string + shippeddate: + type: string + status: + type: string + required: + - customernumber + - orderdate + - ordernumber + - requireddate + - status + type: object + required: true + acl: + allow: + - admin + - customer + - support + scheme: http + host: ${REST_HOSTNAME} + responses: + '201': + content: + application/json: + schema: + type: object + description: Customer order information properties: ordernumber: type: integer - productcode: + maximum: 2147483647 + minimum: -2147483648 + orderdate: type: string + format: date + requireddate: + type: string + format: date + shippeddate: + type: string + format: date + nullable: true + status: + type: string + maxLength: 15 + comments: + type: string + nullable: true + customernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + required: + - customernumber + - orderdate + - ordernumber + - requireddate + - status + - annotations: + title: List all order details + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve a paginated list of all order line items with product and quantity information. + method: GET + name: list-order-details + 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: /sales/v1/orderdetails/ + 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: Order line items with product details + properties: + id: + type: integer + readOnly: true + quantityordered: + type: integer + maximum: 2147483647 + minimum: -2147483648 + priceeach: + type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ + orderlinenumber: + type: integer + maximum: 32767 + minimum: -32768 + ordernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + productcode: + type: string + required: + - id + - orderlinenumber + - ordernumber + - priceeach + - productcode + - quantityordered + - annotations: + title: Get a specific order detail + read_only_hint: true + idempotent_hint: true + destructive_hint: false + open_world_hint: false + description: Retrieve a specific line item from an order using the composite key (orderNumber, productCode). + method: GET + name: get-order-detail + parameters: + - description: The order number + in: path + name: ordernumber + required: true + schema: + type: integer + - description: The product code + in: path + name: productcode + required: true + schema: + type: string + path: /sales/v1/orderdetails/{ordernumber}/{productcode}/ + acl: + allow: + - admin + - read_only + - product_manager + - customer + - support + scheme: http + host: ${REST_HOSTNAME} + responses: + '200': + content: + application/json: + schema: + type: object + description: Order line items with product details + properties: + id: + type: integer + readOnly: true quantityordered: type: integer + maximum: 2147483647 + minimum: -2147483648 priceeach: type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ orderlinenumber: type: integer + maximum: 32767 + minimum: -32768 + ordernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + productcode: + type: string required: - - ordernumber - - productcode - - quantityordered - - priceeach - - orderlinenumber + - id + - orderlinenumber + - ordernumber + - priceeach + - productcode + - quantityordered + - annotations: + title: Create a new order detail + read_only_hint: false + idempotent_hint: false + destructive_hint: false + open_world_hint: false + description: Add a new line item to an existing order with product code, quantity, and price. + method: POST + name: create-order-detail + path: /sales/v1/orderdetails/ + request_body: + content: + application/json: + schema: + properties: + orderlinenumber: + type: integer + ordernumber: + type: integer + priceeach: + type: string + productcode: + type: string + quantityordered: + type: integer + required: + - orderlinenumber + - ordernumber + - priceeach + - productcode + - quantityordered + type: object + required: true + acl: + allow: + - admin + - customer + - support + scheme: http + host: ${REST_HOSTNAME} + responses: + '201': + content: + application/json: + schema: + type: object + description: Order line items with product details + properties: + id: + type: integer + readOnly: true + quantityordered: + type: integer + maximum: 2147483647 + minimum: -2147483648 + priceeach: + type: string + format: decimal + pattern: ^-?\d{0,8}(?:\.\d{0,2})?$ + orderlinenumber: + type: integer + maximum: 32767 + minimum: -32768 + ordernumber: + type: integer + maximum: 2147483647 + minimum: -2147483648 + productcode: + type: string + required: + - id + - orderlinenumber + - ordernumber + - priceeach + - productcode + - quantityordered diff --git a/kong/mcp/tools-policy.yaml b/kong/mcp/tools-policy.yaml new file mode 100644 index 0000000..5371239 --- /dev/null +++ b/kong/mcp/tools-policy.yaml @@ -0,0 +1,28 @@ +# 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: sales-mcp + +tools: + list-orders: + allow: [admin, read_only, product_manager, customer, support] + get-order: + allow: [admin, read_only, product_manager, customer, support] + get-order-order-details: + allow: [admin, read_only, product_manager, customer, support] + create-order: + allow: [admin, customer, support] + list-order-details: + allow: [admin, read_only, product_manager, customer, support] + get-order-detail: + allow: [admin, read_only, product_manager, customer, support] + create-order-detail: + allow: [admin, customer, support]