mcp-data-platform-v1.61.5
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_catalogsandapi_catalog_specs(migration000042_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, soapi_list_endpointsandapi_get_endpoint_schemareflect 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,gmailin a Google Workspace catalog) surface inapi_list_endpointswith distinctspecvalues; an ambiguousapi_invoke_endpointcall 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/jsonpreferred, 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.Controlre-check at connect time to defeat DNS rebinding, caps the response body at 10 MB, refuses redirects, and keeps external$refresolution disabled at the OpenAPI parser. - Upload allowlists OpenAPI MIME types and parses media-type parameters via
mime.ParseMediaTypesoapplication/json; charset=utf-8is 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_specJSONB 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
Storebackends agree on contract.MemoryStore(tests) andPostgresStore(production) return the same sentinel errors (ErrNotFound,ErrConflict,ErrInvalidID,ErrInvalidSpecName) for the same conditions. The PostgresUpdateCatalogprobes existence even when the partial update is empty so admin handlers see consistentErrNotFoundsemantics across backends.
Upgrade notes
- Migration
000042runs on startup. It createsapi_catalogsandapi_catalog_specs. No data backfill; existing connections that carry a legacyopenapi_specfield 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_endpointsfor a migrated connection returns a clear note rather than the legacy field. No silent fallback. - Tool surface changes:
api_get_endpoint_schemais new.api_list_endpointsandapi_invoke_endpointkeep the same outer shape; multi-spec catalogs add aspecfield to results, and ambiguous invocations now return a structured candidate list instead of guessing.
Verification
make verifyclean 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.gowires a realmcp.Server+ toolkit + HTTP client end-to-end and exercisesapi_list_endpoints,api_get_endpoint_schema,api_invoke_endpoint, the reload fan-out path across multiple connections, and the ambiguity-error path.
Changelog
Features
Full diff: v1.61.4...v1.61.5
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.5Artifact 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