Skip to content

mcp-data-platform-v1.61.5

Choose a tag to compare

@github-actions github-actions released this 14 May 23:22
· 119 commits to main since this release
11bc4d8

Highlights

OpenAPI specs describe the API, not the credential pointed at it. Until now, every connection record carried its own copy of the spec, so deployments with multiple connections to the same upstream (a Salesforce sandbox and a Salesforce production org, or multi-tenant Google Workspace customers) ended up with the same multi-MB document pasted into each record, and those copies drifted. v1.61.5 promotes specs to first-class, versioned API catalogs that are owned globally and referenced by connections, adds the missing api_get_endpoint_schema tool so models can read per-endpoint detail without invoking blind, and gives operators three safe ways to ingest a spec: paste, file upload, or HTTPS URL fetch with strict SSRF protection.

What's new

API catalogs are first-class

  • New tables api_catalogs and api_catalog_specs (migration 000042_api_catalogs). Each (name, version) pair is its own catalog row; a single catalog can back many connections.
  • Mutations (create / update / delete spec, refresh from URL) fan out to every referencing connection via Toolkit.ReloadConnectionsByCatalog, so api_list_endpoints and api_get_endpoint_schema reflect new content without a process restart.
  • Catalog deletion is refused while any connection still references it.
  • Catalog ID is operator-chosen and immutable; editing display fields preserves it so downstream references stay valid. Rename-by-clone is the upgrade path.
  • Operations defined in multiple component specs under one catalog (e.g. drive, calendar, gmail in a Google Workspace catalog) surface in api_list_endpoints with distinct spec values; an ambiguous api_invoke_endpoint call returns a structured error listing candidates.

api_get_endpoint_schema tool

Third tool in the API gateway alongside api_list_endpoints and api_invoke_endpoint. Returns parameters, request body, and per-status response schemas for one operation so the model can construct a valid invocation without trial and error.

  • Output omits security, securitySchemes, servers, and vendor extensions by construction; the connection is already authenticated.
  • Capped at ~50 KB with depth-8 schema walking; large nested schemas are summarized rather than truncated mid-structure.
  • Multi-content-type operations pick the schema deterministically (application/json preferred, otherwise alphabetically-first) so the model gets a stable shape across calls.

Three spec-ingestion paths

The portal's new "API Catalogs" settings panel offers Paste, Upload, and URL tabs.

  • URL fetch is HTTPS-only, rejects private / loopback / link-local / CGNAT IP ranges with DNS pre-resolution plus a Dialer.Control re-check at connect time to defeat DNS rebinding, caps the response body at 10 MB, refuses redirects, and keeps external $ref resolution disabled at the OpenAPI parser.
  • Upload allowlists OpenAPI MIME types and parses media-type parameters via mime.ParseMediaType so application/json; charset=utf-8 is accepted.
  • Paste is unchanged structurally; the same parser is shared across all three paths.

Portal UI

  • New Settings, API Catalogs panel with create / clone / delete, header edit, and a three-tab spec modal (Paste / Upload / URL).
  • Settings, Connections editor swaps its old OpenAPI textarea for a catalog dropdown. Connections still carrying a legacy openapi_spec JSONB value render a migration banner prompting the operator to pick a catalog.

Notable design decisions

  • Specs are stored as plain TEXT, not encrypted JSONB. They are public API documentation; the secret material (credential, oauth2_client_secret, etc.) stays in the existing encrypted connection config. Inheriting encryption from a neighboring column would have burned CPU and broken indexing for zero security gain.
  • Both Store backends agree on contract. MemoryStore (tests) and PostgresStore (production) return the same sentinel errors (ErrNotFound, ErrConflict, ErrInvalidID, ErrInvalidSpecName) for the same conditions. The Postgres UpdateCatalog probes existence even when the partial update is empty so admin handlers see consistent ErrNotFound semantics across backends.

Upgrade notes

  • Migration 000042 runs on startup. It creates api_catalogs and api_catalog_specs. No data backfill; existing connections that carry a legacy openapi_spec field continue to function, but the toolkit no longer reads that field and affected connections render a migration banner until an operator selects a catalog.
  • Until a catalog is assigned, api_list_endpoints for a migrated connection returns a clear note rather than the legacy field. No silent fallback.
  • Tool surface changes: api_get_endpoint_schema is new. api_list_endpoints and api_invoke_endpoint keep the same outer shape; multi-spec catalogs add a spec field to results, and ambiguous invocations now return a structured candidate list instead of guessing.

Verification

  • make verify clean on merge: fmt, race tests, lint with --new-from-rev=origin/main, gosec, govulncheck, semgrep, dead-code, mutation testing, doc-check, GoReleaser dry-run.
  • Patch coverage 87.4% (threshold 80%).
  • Integration test in pkg/platform/apigateway_catalog_test.go wires a real mcp.Server + toolkit + HTTP client end-to-end and exercises api_list_endpoints, api_get_endpoint_schema, api_invoke_endpoint, the reload fan-out path across multiple connections, and the ambiguity-error path.

Changelog

Features

  • 11bc4d8: feat(apigateway): versioned API catalogs + api_get_endpoint_schema (#406) (@cjimti)

Full diff: v1.61.4...v1.61.5

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.5

Artifact verification

All release artifacts are signed with Cosign. Verify with:

cosign verify-blob --bundle mcp-data-platform_1.61.5_linux_amd64.tar.gz.sigstore.json \
  mcp-data-platform_1.61.5_linux_amd64.tar.gz