Commit Graph

5 Commits

Author SHA1 Message Date
Stéphane Tailland 32d6014b42 refactor(mcp): generate the tool definitions from the spec
The tools: array was hand-maintained and had drifted from openapi.yaml in two
ways that only surfaced when an agent hit them: create-product omitted
productcode and could never succeed, and list-products declared no parameters
so it could not paginate — which let a model answer a product count that looked
right and had not come from the tool's output.

It is now produced by k8s-platform/tools/generate-mcp-tools.py: deck file
openapi2mcp does the conversion, and the wrapper re-injects the five things
Kong's generator cannot emit — per-tool ACLs, the MCP behavioural annotations,
the response schemas the plugin uses for structuredOutput, the real upstream
host, and JSON-only request bodies. Each is a documented gap; see
k8s-platform/MCP-TOOL-GENERATION.md.

tools-policy.yaml carries the ACLs and doubles as the allow-list: an operation
becomes a tool only if the policy names it. Kong would otherwise expose every
operation in the spec, DELETE included, and can express no authorization at all
from a bearer-token spec — silently, exit 0, no warning.

Same three tools as before, same ACLs. What changed: pagination is now
callable, create-product's required list matches the API (quantityinstock
included, which the hand-written repair had missed), each tool declares its
response schema, and the request body is no longer tripled across three
identical content types.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 08:43:36 +02:00
Stéphane Tailland c583d28cff fix(catalog-mcp): create-product could never succeed
The tool's request schema omitted productcode, which catalog-api requires
(ProductRequest in openapi.yaml lists it among the eight required fields).
Since the declared schema is the only thing an MCP caller sees, there was no
input that worked: omit it and the API answers
{"productcode":["This field is required."]}; supply it and ai-mcp-proxy rejects
the call first with "Additional properties are not allowed ('productcode' was
unexpected)".

The schema now mirrors ProductRequest — productcode added, the same eight
fields marked required, and the length and format constraints carried over so
a model reads them rather than guessing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 17:34:06 +02:00
Stéphane Tailland fc6b60c582 Rebuild catalog-mcp consumer groups on the real 5-role model
KongConsumerGroups were still named sttlab-user/sttlab-admin, a leftover
from before the classic-models realm's role model existed. Real users'
JWTs carry realm roles (admin, read_only, product_manager, customer,
support) via consumer_groups_claim, so no group ever matched and every
tool call was rejected with 403 "consumer groups were not found".

Groups now match the realm roles directly; tool ACLs gate on each role's
catalog:read/catalog:write grant from security-model.yaml.
2026-08-21 18:35:02 +02:00
Stéphane Tailland 4a1c772b80 Expose catalog-api under /catalog/v1, decoupled from the backend path
Public routes no longer leak classic-models-api's own /api/v1 prefix.
request-transformer-advanced rewrites to the real backend path per route.
2026-08-21 09:22:33 +02:00
Stéphane Tailland f929a0f7e4 MCP server 2026-08-20 16:26:48 +02:00