mcp-data-platform-v1.57.3
v1.57.3
A trio of operator-facing reliability and quality-of-life fixes — gateway OAuth diagnostics, three open bugs from the Tools-page redesign, and a UI accessibility floor.
Highlights
🔍 Gateway OAuth: upstream rejection reasons now visible (#350)
When a gateway connection's authorization_code OAuth flow completes successfully (token persisted to gateway_oauth_tokens) but the immediate post-token re-dial fails because the upstream MCP server rejects the bearer, the platform previously logged only an unannotated "awaiting reauth" warning. Operators clicking Connect had no diagnostic trail — the actual discover() error from the upstream dial was dropped between layers.
After this release:
- The structured warning includes the dial error:
{"level":"WARN","msg":"gateway: oauth authorization_code connection awaiting reauth","connection":"...","endpoint":"...","error":"connect to https://upstream/...: HTTP 401 Unauthorized"} - The same string flows into
OAuthStatus.LastError, which the admin UI's OAuth status card already renders inline with the Connect button. Operators see why the upstream rejected without leaving the connections page. - A new internal helper,
recordPlaceholderError, keepsLastErrorfresh on theSetTokenStoreplaceholder-retry path so subsequent failures replace stale errors instead of leaving them orphaned.
This is a diagnostic improvement — no OAuth flow semantics changed, no behavior change on the happy path. Pairs naturally with mcp-test v1.0.1's complementary upstream-side log fix.
🛠️ Tools page: three bugs fixed (#351)
Three issues identified during review of the v1.57.x Tools page master-detail redesign that didn't land before the original ship.
1. TOCTOU race in PUT /admin/tools/{name}/visibility
Two admins toggling visibility on different tools concurrently could each load the same starting deny list, append independently, and the second writer would silently overwrite the first — with both UIs reporting success. Lost-update race classic.
Fixed with a dedicated Handler.toolsDenyMu mutex serializing the load → modify → save → ApplyConfigEntry critical section. Response writes happen outside the lock so a slow client cannot block other admins.
In-process serialization is sufficient for single-replica deployments. Multi-replica deployments would additionally need a row-level DB lock or version-token CAS at the config_entries layer; that's a separate concern.
2. Activity tab silent for low-frequency tools on busy platforms
The Tools detail page's Activity card called Breakdown(GroupBy=tool_name, Limit=100) and scanned the result for the requested tool. On platforms with more than 100 distinct tools called within the 24h window, low-frequency tools fell off the breakdown rank and the Activity card rendered "no calls recorded" even when there were calls.
Fixed with a new ToolName filter on audit.BreakdownFilter that scopes the SQL WHERE clause to a specific tool, so per-tool stats no longer depend on top-N ranking. The handler now reads rows[0] directly.
3. Try It tab loses history on tab switch
ToolDetail switch-renders one tab at a time, so TryItTab unmounted whenever the user clicked Activity → Try It. State (history list, latest result, replay context, form version) was lost.
Fixed by extracting a useTryItSession(toolName) hook with intent-based actions (addHistoryEntry, clearHistory, applyReplay, dismissReplay, etc.) and mounting it at ToolDetail's level — which stays alive across tab switches. TryItTab is now a presentational consumer of the session prop.
The hook still resets when toolName changes (mirroring "select a different tool from the list"). A regression test asserts state survives child unmount/remount, so a future refactor that moves the hook back into TryItTab will fail CI rather than silently re-introduce the bug.
📐 12px minimum font size across the admin UI (#352)
The admin and portal UI relied on text-[10px] and text-[9px] Tailwind class overrides for tightly-packed pages — table cells, status pills, metadata labels, badges. At standard viewport DPI those rendered at 10px and 9px respectively, well below the 12px accessibility floor and reported as "barely readable" on the OAuth status panel and similar surfaces.
This release raises the entire UI to a uniform 12px minimum (text-xs).
- 95 occurrences of
text-[10px]upgraded. - 19 occurrences of
text-[9px]upgraded. - One exception: the
oauth.grantmonospace pill is set totext-[11px](11px) rather than 12px because monospaceauthorization_code(17 chars) overflows tight inline pill containers at 12px.
Verified live in the browser: text-xs computes to 12px, text-[11px] computes to 11px. Connection Viewer, Personas, and Keys pages — all dense surfaces — render cleanly at the new sizes with no overflow or broken alignment.
Operators who explicitly want sub-12px UI text should override per-element with text-[Npx] arbitrary values; nothing in the platform engine forces a minimum.
Other improvements
- Pre-existing UI test failures resolved:
MyAssetsPageno longer crashes under jsdom whenlocalStorageis unavailable; Playwrighte2e/**/*.spec.tsfiles no longer get picked up by vitest's runner; the route-sync test distinguishes "missing manifest entry (bug)" from "deliberately excluded (CodeMirror headless crash)" via a documentedexcludedRoutesset. UI test gate goes from 5 red to 39/39 green.
No-op for upgrade
- No config changes required.
- No database migrations.
- All existing OAuth connections, persona configurations, and tool visibility settings keep working without reconfiguration.
Full changelog
5f37238fix(ui): raise minimum font size to 12px across admin surface (#352)3397001fix(tools): resolve three bugs from #340 master-detail redesign (#351)2b29d29fix(gateway): surface discover() error on authorization_code placeholder (#350)
Compare: v1.57.2...v1.57.3
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.57.3Go (library composition)
go get github.com/txn2/mcp-data-platform@v1.57.3Verification
All release artifacts are signed with Cosign (keyless, GitHub Actions OIDC) and ship with SBOMs.
cosign verify-blob --bundle mcp-data-platform_1.57.3_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.57.3_linux_amd64.tar.gzContainer images:
cosign verify ghcr.io/txn2/mcp-data-platform:v1.57.3 \
--certificate-identity-regexp='https://github.com/txn2/mcp-data-platform/.+' \
--certificate-oidc-issuer='https://token.actions.githubusercontent.com'