mcp-data-platform-v1.61.6
Highlights
ParseSpecnow accepts real-world vendor OpenAPI specs. Four documentation-drift patterns that strict kin-openapi rejected but Swagger UI, Postman, and Insomnia all accept are now tolerated, while structural validation that matters for invocation stays strict.- API Catalogs portal panel rebuilt. New form vocabulary (Catalog name / Internal slug / Version), real Radix modal dialogs replacing native
confirm/prompt, alphabetized sidebar, and a layout fix that stops the detail panel from wedging on long catalog IDs. make devseeds through the catalog model.dev/start.shnow provisions anapi-test-fixturecatalog anddefaultcomponent spec via the admin API before registering the connection, soapi_list_endpointsreturns the fixture's operations on first boot.- Example-vendor sweep across code, tests, and docs. Narrow vendor references replaced with Salesforce, Google APIs, GitHub, and Stripe.
OpenAPI parser leniency
pkg/toolkits/apigateway/catalog/fetch.go ParseSpec keeps structural validation (operation IDs, path templating, parameter shapes, security scheme references, request/response schemas, internal $ref resolution) and adds tolerance for four drift patterns:
- Examples that don't match their declared schema type. Vendor specs routinely declare
type: objectand ship string examples. EnabledDisableExamplesValidation(). - Schema patterns using ECMA regex constructs Go's
regexppackage does not support (lookahead, named backreferences). EnabledDisableSchemaPatternValidation(). - Defaults that don't match their declared schema type. Same drift pattern as examples. Enabled
DisableSchemaDefaultsValidation(). type: arrayschemas missing anitemsclause. OpenAPI 3.0 requiresitems, but real specs treat it as "items of unknown shape." A new in-place normalizer (normalizeArrayItems) walks the loaded document and injectsitems: {}for every such schema before strict validation runs. Walkscomponents.schemas,components.parameters,components.headers,components.requestBodies,components.responses(including their headers), and every path/operation's parameters, request body, and responses. Aseenset keyed by*openapi3.Schemapointer prevents ref-cycle recursion.
A new TestParseSpec_RejectsStructuralErrors guards against over-leniency. Empty input, truncated input, missing openapi/info, and unresolved $ref still fail.
API Catalogs portal panel
Form rework
The create form leads with Catalog name (human-readable label). The version field defaults to the current YYYY-MM via a new currentYearMonth() helper. Internal slug auto-derives from the catalog name via slugifyName(). Catalog ID auto-derives from slug plus version. Two touched* flags decouple auto-derivation from manual edits so typed input is never clobbered. Each field carries help text describing what it is FOR, replacing the prior ambiguous Name plus Display name pairing.
The edit form uses the same vocabulary (Catalog name / Internal slug / Version) with per-field help.
Real modal dialogs
Three native window.confirm and window.prompt calls in CatalogsPanel.tsx are replaced with two new components built on @radix-ui/react-dialog:
ConfirmDialog(destructive variant, blocks Escape/overlay-close/Cancel while busy, holds internalbusystate synchronously aroundonConfirm, catches rejections, and renders failures inline via anerrorslot so they aren't hidden behind the Radix overlay).PromptDialog(multi-field form-in-a-modal with per-field help text and an optionalnormalizecallback; seeds field values on everyopentransition only so a parent re-render doesn't clobber typed input).
Spec-delete moved from del.mutate(...) to del.mutateAsync(...) with try/catch routing failures to the dialog's error prop.
Five other panels (ConnectionsPanel, PersonasPanel, KnowledgePage, PersonasPage, OverviewTab) still use window.confirm. Same pattern, different surfaces, deliberately deferred to keep this release scoped.
Layout and navigation
- Sidebar alphabetized. Both portal and admin sections sort case-insensitive with Activity (portal) and Dashboard (admin) pinned at the top as landing views.
- Catalog detail unwedged. A 22-character immutable catalog ID inside a
<code>element with no break opportunities was forcing the detail grid track to its intrinsic min-width, wrapping the title to three lines and the description to a dozen. Grid track changed from1frtominmax(0, 1fr), action buttons (Edit / Clone / Delete) moved to their own row above the title, andbreak-words/break-alladded to long identifiers. - Catalog list track widened from 220px to 280px so display names no longer truncate on a normal viewport. Per-row version chip removed; it was redundant with the group label and the detail-panel header chip and was the reason rows wrapped to two lines.
- Spec name modal clarified. Placeholder changed to
default. Help text explains whatspec_nameis FOR (thespecfield surfaced to the model inapi_list_endpointsfor disambiguation across multi-spec catalogs). Upload tab auto-suggests the spec name from the uploaded filename (basename, lowercased, extension stripped, leading/trailing[-_]trimmed) when the operator hasn't typed one.
Spec-name validation message
The client now auto-lowercases and strips out-of-range characters on input (normalizeSpecName mirrors the server's ValidateSpecName regex including the leading/trailing [-_] trim). The server's ErrInvalidSpecName message now spells out the rule so any future client divergence still produces a useful response.
Dev seed
PR #406 made connection_instances.config.openapi_spec a no-op (the toolkit now reads specs from versioned catalogs via config.catalog_id). dev/start.sh still seeded with the legacy field, so make dev came up with the connection wired but api_list_endpoints returning the migration banner instead of the fixture's 14 operations.
The script now does the catalog dance before registering the connection:
POST /api/v1/admin/api-catalogscreates anapi-test-fixturecatalog (idempotent, accepts 409 on repeat runs).PUT .../specs/defaultupserts the fetchedopenapi.yamlas the default component spec (idempotent, replaces content so the catalog self-heals when the fixture image bumps its spec).- Both connections (
api-test-fixture,oauth-api-dev) carryconfig.catalog_idpointing at the seeded catalog.
Fail-soft: when the fixture container is down or the admin API rejects the call, APITEST_CATALOG_READY stays 0 and the connections register without a catalog reference. api_invoke_endpoint against an explicit method+path still works; api_list_endpoints returns empty until the catalog is seeded.
Example-vendor sweep
Replaced narrow vendor references throughout the codebase with universally recognized APIs:
- "One catalog, many connections" narrative now reads Salesforce sandbox plus production.
- Multi-component catalog example is Google Workspace (Drive, Calendar, Gmail).
- OAuth-bearer-plus-side-header example is
x-goog-user-project.
Affected: README.md, docs/server/api-catalogs.md, docs/server/api-gateway.md, docs/auth/oauth-gateway.md, docs/llms.txt, docs/llms-full.txt, pkg/admin/catalog_handler.go, pkg/authevents/doc.go, pkg/connoauth/refresher.go, pkg/connoauth/source.go, pkg/toolkits/apigateway/config.go, pkg/toolkits/apigateway/invoke.go, cmd/mcp-data-platform/main.go, several test files, and the catalog and connections UI panels.
Coverage backfill
A comment edit in pkg/connoauth/source.go landed inside a previously-untested statement block (the rotated-refresh persist-failure path), which dropped patch coverage below the gate. Two new tests in pkg/connoauth/source_events_test.go close that gap:
TestRefreshRotationPersistFailure_EmitsRotationPersistenceFailedTestRefreshNonRotationPersistFailure_NoEvent
Affected packages
pkg/toolkits/apigateway/catalog(parser, normalizer, tests)pkg/toolkits/apigateway(config, invoke, fixture references)pkg/admin(catalog handler error phrasing)pkg/connoauth(coverage backfill, example-vendor sweep in docs)pkg/authevents(example-vendor sweep in package doc)ui/src/components/ConfirmDialog.tsx(new)ui/src/components/PromptDialog.tsx(new)ui/src/pages/settings/CatalogsPanel.tsx(form rework, modal migration, spec-name normalization, layout)ui/src/components/layout/Sidebar.tsx(alphabetization)dev/start.sh(catalog seed flow)- Docs (
README.md,docs/server/api-catalogs.md,docs/server/api-gateway.md,docs/auth/oauth-gateway.md,docs/llms.txt,docs/llms-full.txt)
Upgrade notes
- No new database migrations. The relevant
000042_api_catalogs.*migrations are from v1.61.0 (PR #406). - No config schema changes.
- Operators upgrading from v1.61.5 with existing catalogs do not need to reload connections. Existing parsed specs continue to work; the new leniency only affects future uploads or re-parses.
- The dev-seed change is contained to
make dev; it has no effect on production deployments.
Pull request
#407 fix(apigateway): tolerate real-world OpenAPI spec drift; catalog UX cleanup
Installation
Homebrew (macOS)
brew install txn2/tap/mcp-data-platformClaude Code CLI
claude mcp add mcp-data-platform -- mcp-data-platformDocker
docker pull ghcr.io/txn2/mcp-data-platform:v1.61.6Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.61.6_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.61.6_linux_amd64.tar.gz