mcp-data-platform-v1.61.10
Highlights
Two apigateway toolkit improvements that ship together because they fix two distinct ways a connection's catalog could leave the operator wedged: the wrong URL prefix on every operation, and a frozen ranking=semantic request that never returned.
Per-spec base path override (#416)
PR #415 auto-derived a spec's URL prefix from servers[0].url in the OpenAPI document. That works when the spec author wrote a servers entry that matches the deployment the operator is targeting. It does not work for two real cases:
- Specs that ship without a
servers[]entry at all (any generator can produce these). - Specs whose
servers[0].urlpoints at the vendor's production host but the operator is targeting a sandbox, proxy, or version-pinned alias whose path differs.
Operators can now set the URL prefix per spec explicitly. The auto-derivation remains the fallback; the override wins when non-empty.
Surface
- Migration
000043addsapi_catalog_specs.base_path TEXT NOT NULL DEFAULT ''. Pre-existing rows backfill to''and the toolkit's empty-string check covers both pre-migration and never-set values uniformly. catalog.SpecEntry.BasePathGo field, normalized at write time bycatalog.NormalizeBasePath: must start with/, must not contain CR/LF/NUL or?/#, trailing slash stripped.catalog.ErrInvalidBasePathis the exported sentinel so the admin handler routes operator-input failures toHTTP 400instead of500.- Admin REST accepts
base_pathon JSON upsert (inline + url source kinds) and?base_path=on multipart upload. Refresh and re-upload preserve the prior value. Catalog clone copies it. - The portal's catalog spec editor exposes a Base path input on all three source tabs (Paste, Upload, URL).
buildConnSpecsresolves the effective base path with operator override winning overservers[0]; both sources route throughcomputeEffectiveBasePathso aconnection.base_urlthat already contains the prefix as a suffix dedupes uniformly and the invoke-time URL join never doubles the segment.
Companion cleanup
Migration 000042 carried a text-only example referencing a downstream client vendor. The example is now generic (Salesforce, Stripe, GitHub) and the em dash in the same paragraph was replaced with a comma. No schema change; comments only.
Background embedding warmer (#417)
api_list_endpoints with ranking=semantic or ranking=hybrid against a multi-hundred-operation catalog timed out before the handler could return. The synchronous embedding population on the first non-lexical call took 30+ seconds against a slow upstream embedder. The MCP request budget expired first and the client surfaced a generic Error occurred during tool execution with no Note. The v1.61.9 fallback-Note machinery shipped in #415 was correct, but the handler did not get to execute it.
This release moves embedding population OFF the request path.
Warmer at registration
addParsedConnectionspawns a background warmer when an embedding provider is wired at the time the connection registers.SetEmbeddingProviderspawns warmers for every already-registered connection so the other startup ordering (toolkit before embedder) is covered too.ReloadConnectioninherits the same path (re-registers viaaddParsedConnection), so a catalog edit produces a fresh warmer against the new operation set.
The warmer runs ensureEmbeddings under a 10-minute background context with mandatory panic recovery: a panicking embedder cannot crash the platform process.
Request path
queryVectorFor no longer does any embedding work. It calls a new checkEmbeddingsReady(c) that returns one of five distinct sentinels so the fallback Note names the exact cause:
| Sentinel | Operator meaning |
|---|---|
errEmbeddingsNoOps |
The connection has no operations; semantic ranking is meaningless. |
errEmbeddingsFailed |
A prior warmer attempt failed definitively; reload the connection to retry. |
errEmbeddingsWarming |
The warmer is in flight; falling back to lexical until ready. |
errEmbeddingsNotStarted |
No warmer ever ran (typically a configuration ordering bug). |
errEmbeddingsZeroVector |
Provider returned the zero vector; points at a misconfigured embedding model. |
Concurrency
conn gains embedInFlight (guarded by the existing embedMu). Read paths take the lock briefly to copy a snapshot and release; the writer holds it only while it swaps the populated slice in, never while the embedder is being called. Concurrent warmer triggers de-duplicate at the embedInFlight check.
Behavior changes worth noting
OperationSummary.PathandEndpointSchemaOutput.Pathreflect the operator's chosen prefix when set; this can differ from what the spec content'sservers[]declares. This is the point of the feature.api_list_endpointswithranking=semanticagainst a connection whose warmer is still in flight returns lexical results with a Note saying"operation embeddings still warming; falling back to lexical until ready". This is the correct cold-start behavior. Once the warmer settles, subsequent calls use the cached embeddings.AddConnectionno longer blocks on the embedder. Startup time is unaffected by the embedder's speed.- A panicking embedder no longer crashes the platform; it marks the affected connection as failed and the operator can reload the connection to retry.
- Catalog spec upsert now validates
base_path; invalid values returnHTTP 400with a message identifying the field.
Changelog
- 7e709ba: feat(apigateway): per-spec base path override; scrub legacy migration comment (#416)
- 01190de: fix(apigateway): warm embeddings at AddConnection, off the request path (#417)
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.10Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.61.10_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.61.10_linux_amd64.tar.gzAcknowledgments
The verification report against v1.61.9 caught two release-note claims that were correct in the source but unreachable in production due to the request-path timeout. The fix in #417 reaches the code paths that were claimed in v1.61.9: ranking=semantic|hybrid fallback Notes now surface, and embedder panics now produce operator-readable diagnostics.