Skip to content

mcp-data-platform-v1.61.6

Choose a tag to compare

@github-actions github-actions released this 15 May 16:58
· 118 commits to main since this release
f5c50af

Highlights

  • ParseSpec now 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 dev seeds through the catalog model. dev/start.sh now provisions an api-test-fixture catalog and default component spec via the admin API before registering the connection, so api_list_endpoints returns 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:

  1. Examples that don't match their declared schema type. Vendor specs routinely declare type: object and ship string examples. Enabled DisableExamplesValidation().
  2. Schema patterns using ECMA regex constructs Go's regexp package does not support (lookahead, named backreferences). Enabled DisableSchemaPatternValidation().
  3. Defaults that don't match their declared schema type. Same drift pattern as examples. Enabled DisableSchemaDefaultsValidation().
  4. type: array schemas missing an items clause. OpenAPI 3.0 requires items, but real specs treat it as "items of unknown shape." A new in-place normalizer (normalizeArrayItems) walks the loaded document and injects items: {} for every such schema before strict validation runs. Walks components.schemas, components.parameters, components.headers, components.requestBodies, components.responses (including their headers), and every path/operation's parameters, request body, and responses. A seen set keyed by *openapi3.Schema pointer 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 internal busy state synchronously around onConfirm, catches rejections, and renders failures inline via an error slot so they aren't hidden behind the Radix overlay).
  • PromptDialog (multi-field form-in-a-modal with per-field help text and an optional normalize callback; seeds field values on every open transition 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 from 1fr to minmax(0, 1fr), action buttons (Edit / Clone / Delete) moved to their own row above the title, and break-words / break-all added 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 what spec_name is FOR (the spec field surfaced to the model in api_list_endpoints for 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:

  1. POST /api/v1/admin/api-catalogs creates an api-test-fixture catalog (idempotent, accepts 409 on repeat runs).
  2. PUT .../specs/default upserts the fetched openapi.yaml as the default component spec (idempotent, replaces content so the catalog self-heals when the fixture image bumps its spec).
  3. Both connections (api-test-fixture, oauth-api-dev) carry config.catalog_id pointing 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_EmitsRotationPersistenceFailed
  • TestRefreshNonRotationPersistFailure_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-platform

Claude Code CLI

claude mcp add mcp-data-platform -- mcp-data-platform

Docker

docker pull ghcr.io/txn2/mcp-data-platform:v1.61.6

Verification

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