Releases: txn2/mcp-data-platform
mcp-data-platform-v1.43.1
Highlights
This release improves the asset viewer UX with inline version navigation, change summaries on save, and public viewer enhancements.
Change Summary on Save
Saving edited content now opens a "What changed?" dialog before committing. The description is sent as an X-Change-Summary header and stored on the version record. Users can skip the dialog, in which case a default summary is stored. This applies to all three content-update surfaces: portal UI, admin UI, and shared editor.
Version Dropdown in Toolbar
Version navigation moves from the sidebar into a toolbar dropdown. Selecting an older version displays its content in a read-only preview with the source editor hidden. A Revert button appears next to the dropdown with a confirmation modal that explains a new version will be created from the selected version's content. The sidebar version history panel remains as a read-only reference list.
Public Viewer Enhancements
- Version badge: Public share pages now show a
v{N}badge in the header next to the content type badge - Markdown source toggle: Public shares of markdown content get a "View Markdown" / "View Rendered" button to switch between raw source and rendered output
Email in CreatedBy
Version records and shares now store the user's email address instead of UUID for display in version history and share listings. This applies to all version-creating operations: content updates, reverts, and asset copies across portal, admin, and MCP surfaces.
Changelog
Features
- feat: asset viewer UX — change summary, version dropdown, public badge, markdown toggle (#249)
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.43.1Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.43.1_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.43.1_linux_amd64.tar.gzmcp-data-platform-v1.43.0
Highlights
This release adds asset version history with full browse and revert capabilities. Every content edit now creates a new immutable version instead of overwriting S3 objects in-place, providing complete change history, content recovery, and audit trail across all three content-update surfaces (portal UI, admin API, MCP tools).
Immutable Versioned Content
Content edits no longer overwrite S3 objects. Each update writes to a new versioned S3 key (portal/{owner}/{asset}/{versionID}/content{ext}), and previous versions remain accessible at their original keys indefinitely. Version numbers are assigned atomically using SELECT FOR UPDATE within a transaction, preventing race conditions when concurrent updates target the same asset.
- New
portal_asset_versionstable tracks every version with its S3 key, content type, size, author, change summary, and timestamp - New
current_versioncolumn onportal_assetsalways reflects the latest version number CreateVersionperforms a single atomic transaction: locks the asset row, increments the version, inserts the version record, and updates the asset'ss3_key/content_type/size_bytes/thumbnail_s3_keyin one commit- Existing assets are backfilled as v1 during migration with no S3 copies needed
- Orphaned S3 objects are cleaned up if the version database write fails after upload
Version History Browsing
All three surfaces expose version history:
- Portal REST API:
GET /api/v1/portal/assets/{id}/versions(paginated),GET /api/v1/portal/assets/{id}/versions/{version}/content - Admin REST API:
GET /api/v1/admin/assets/{id}/versions(paginated),GET /api/v1/admin/assets/{id}/versions/{version}/content - MCP Toolkit:
manage_artifactwithaction: list_versionsreturns version history with total count
Revert to Any Previous Version
Reverting creates a new version (forward-only history) by reading the target version's content from S3, writing it to a new S3 key, and creating a new version record. The original version is never modified.
- Portal REST API:
POST /api/v1/portal/assets/{id}/versions/{version}/revert - Admin REST API:
POST /api/v1/admin/assets/{id}/versions/{version}/revert - MCP Toolkit:
manage_artifactwithaction: revert, asset_id: ..., version: N - Portal revert enforces ownership and editor share permissions; admin revert requires only that the asset is not soft-deleted
Frontend Version History Panel
A new VersionHistoryPanel component in the asset viewer sidebar shows:
- Collapsible version list with version number, date, author, change summary, and size
- Current version highlighted with a "(current)" badge
- Revert button with a confirmation dialog on non-current versions (only for owners and editors)
- Expand/collapse for assets with more than 3 versions
- Integrated into both the portal
AssetViewerPageandAdminAssetViewerPage
Bug Fixes
Provenance Parameter Storage (#247)
The provenance modal showed raw truncated JSON with literal \n instead of formatted SQL. Root cause: summarizeParams() serialized params to JSON then truncated at 200 bytes, producing invalid JSON that the frontend couldn't parse. The string Summary field is replaced with a map[string]any Parameters field on ProvenanceToolCall, so the frontend now reads parameters as a parsed object with no JSON.parse needed.
Sidebar and Share View Fixes (#246)
- Fixed sidebar expand button not working on asset routes by tracking path transitions instead of reacting to sidebar state changes
- Hidden misleading "(0 views)" on user shares where access isn't tracked; view count only shows on public links with > 0 views
- Provenance now shows only Trino queries by default with a "Show all" toggle
Migration Notes
- Database: Migration
000022addscurrent_version INT NOT NULL DEFAULT 1toportal_assetsand creates theportal_asset_versionstable with aUNIQUE(asset_id, version)constraint andON DELETE CASCADEforeign key. Existing assets are backfilled as v1 using their current S3 key (no S3 copies). The migration is safe for zero-downtime deployment. - API: New endpoints on both portal and admin routes:
GET .../versions,GET .../versions/{version}/content,POST .../versions/{version}/revert. These are additive and backward-compatible. - API: The
Assetresponse now includes acurrent_versioninteger field. This is additive. - MCP: The
manage_artifacttool accepts two new actions:list_versionsandrevert. Theversioninput property is new. Existing actions are unchanged. - S3: New content writes use versioned S3 keys (
portal/{owner}/{asset}/{versionID}/content{ext}). Existing S3 objects at the old key pattern are not moved; the v1 backfill row points to the original key.
Changelog
Features
- feat: asset version history with browse and revert (#248)
Bug Fixes
- fix: store full parameters in provenance instead of truncated JSON summary (#247)
- fix: sidebar expand on asset view, share view counts, and provenance filtering (#246)
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.43.0Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.43.0_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.43.0_linux_amd64.tar.gzmcp-data-platform-v1.42.2
Changelog
Bug Fixes
- 8f9349f: fix: store full parameters in provenance instead of truncated JSON summary (#247) (@cjimti)
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.42.2Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.42.2_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.42.2_linux_amd64.tar.gzmcp-data-platform-v1.42.1
Bug Fixes
Sidebar expand button broken on asset view
The sidebar auto-collapses when opening an asset, but clicking the expand arrows at the bottom did nothing — the sidebar would immediately re-collapse. The auto-collapse logic was reacting to sidebar state changes in addition to path changes, creating a loop. Now it only triggers on actual route transitions, so the expand/collapse toggle works as expected while viewing an asset.
Misleading "(0 views)" on user shares
Sharing an asset with a specific user displayed "(0 views)" even though per-user view tracking isn't implemented. View counts are now only shown on public links that have at least one recorded access.
Provenance shows all tool calls equally
The provenance panel now shows only Trino queries by default, since those are the most relevant for understanding how an asset was built. A "Show all" toggle reveals the remaining tool calls (DataHub searches, S3 operations, etc.).
Trino queries shown as raw JSON in provenance modal
Clicking a Trino query in provenance displayed the raw JSON wrapper ({"sql": "SELECT ..."}) instead of the formatted SQL. The modal now extracts and displays the SQL query directly.
mcp-data-platform-v1.42.0
Highlights
This release adds share permission levels (viewer/editor), a Save to My Assets copy workflow, and several portal UX improvements. It also fixes an SSO login bug that caused non-admin users to be immediately logged out.
Share Permission Levels
Asset owners can now choose between Viewer and Editor when sharing with a user. Viewers have read-only access; editors can save changes directly to the original asset (with a confirmation warning). Public links are always viewer-only regardless of what's requested.
- New
permissioncolumn onportal_shares(migration000021) withCHECKconstraint limiting values tovieweroreditor - Existing shares default to
vieweron migration - Permission dropdown in the Share Dialog when sharing with a user
- Permission badges displayed in the Share Dialog's active shares list, on the Shared With Me page, and in the Asset Viewer toolbar
- Editor save shows a confirmation modal: "You are editing a shared asset owned by [owner]. Changes will be visible to the owner and all other recipients."
- Role-based toolbar controls: owners see Delete/Share/Edit/Save; editors see Save (with warning)/Save to My Assets/Download; viewers see Save to My Assets/Download
Save to My Assets
Shared asset recipients (both viewer and editor) can create an independent copy in their own My Assets via a new Save to My Assets button.
- New
POST /api/v1/portal/assets/{id}/copyendpoint reads the original S3 content, writes it to a new S3 key under the current user's namespace, and creates a newportal_assetsrecord - Copies are fully independent — the name gets a " (copy)" suffix and there is no link to the original
- OOM protection: assets larger than 10 MB are rejected with HTTP 413 before reading from S3
- Frontend navigates to My Assets after a successful copy
Shared With Me Page Enhancements
The Shared With Me page now matches My Assets in functionality:
- Thumbnails with background
ThumbnailQueuegeneration - Client-side search, content-type dropdown filter, and tag filter
- Color-coded content-type badges, tags (up to 3), and file size display
- "Shared by" field now shows the sharer's email address instead of a UUID (falls back to UUID for legacy rows)
- Back navigation from a shared asset correctly returns to
/sharedinstead of/
CSV Download Button & Public Viewer Info Modal
- CSV Download: A Download button in the CSV table view header triggers a browser download with the correct asset filename (works in both portal and public share views)
- Public Viewer Info Modal: An info button in the public viewer header opens a modal displaying asset description, creation/update dates, and tags
Bug Fixes
SSO Login Fix for Non-Admin Users
Non-admin users (e.g. analysts) were immediately logged out after a successful SSO login because the Header component unconditionally called useSystemInfo(), which hit GET /api/v1/admin/system/info. The admin middleware returned 401 for non-admins, and the admin API client interpreted all 401s as session expiration — destroying a perfectly valid session.
Fix: useSystemInfo() is now gated on admin status so non-admin users never call the admin endpoint.
Permission System Hardening
- DB errors during permission checks now return HTTP 500 instead of silently failing closed with a misleading HTTP 403
- Consolidated three redundant permission-checking functions (
isSharedWithUser,hasEditorPermission,sharePermissionForUser) into a singlesharePermissionForUserreturning(SharePermission, error) - Reduced cyclomatic complexity across all permission-related handlers (all now under the 10-function threshold)
Migration Notes
- Database: Migration
000021adds apermission TEXT NOT NULL DEFAULT 'viewer'column with aCHECK (permission IN ('viewer', 'editor'))constraint toportal_shares. All existing shares become viewers automatically. The migration is safe for zero-downtime deployment. - API:
GET /api/v1/portal/assets/{id}now returnsis_owner(bool) andshare_permission(string, omitted for owners) in the response body. This is additive and backward-compatible. - API: New endpoint
POST /api/v1/portal/assets/{id}/copyfor the Save to My Assets workflow. - API:
POST /api/v1/portal/assets/{id}/sharesnow accepts an optionalpermissionfield ("viewer"or"editor"; defaults to"viewer").
Changelog
Features
- feat: add CSV download button and public viewer info modal (#239)
- feat: enrich Shared With Me page to match My Assets and fix back navigation (#242)
- feat: share permission levels, Save to My Assets, and email in Shared By (#245)
Bug Fixes
- fix: prevent non-admin users from getting "session expired" after SSO login (#241)
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.42.0Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.42.0_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.42.0_linux_amd64.tar.gzmcp-data-platform-v1.41.3
What's Changed
Enriched Shared With Me Page
The Shared With Me page now matches the feature-rich experience of My Assets (#242, closes #240):
- Thumbnails — shared assets render visual previews via
ThumbnailQueue, matching the My Assets card layout - Client-side search — filter shared assets by name and description
- Content-type filter — dropdown filter by content type (Markdown, SVG, CSV, etc.)
- Tag filter — filter assets by tags
- Color-coded badges — content-type badges with distinct colors per type
- Rich metadata — tags (up to 3), file size, shared-by user, and shared date displayed on each card
Back Navigation Fix
Navigating back from a shared asset now correctly returns to /shared instead of always returning to / (My Assets). The fix tracks the last non-asset route via a ref in AppShell, so the back arrow is context-aware:
- Viewing a shared asset → back returns to Shared With Me
- Viewing a My Assets asset → back returns to My Assets
- Browser back button also respects this behavior
Files Changed
| File | Change |
|---|---|
ui/src/pages/shared/SharedWithMePage.tsx |
Added thumbnails, search, filters, badges, tags, file size, shared-by metadata |
ui/src/components/layout/AppShell.tsx |
Track last non-asset route for context-aware back navigation |
ui/src/pages/viewer/AssetViewerPage.tsx |
Pass navigation context for back button routing |
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.41.3Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.41.3_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.41.3_linux_amd64.tar.gzmcp-data-platform-v1.41.2
Highlights
This patch fixes a bug where non-admin users were immediately logged out after a successful SSO login.
SSO Login Fix for Non-Admin Users
After completing OIDC login, non-admin users (e.g. those with the analyst persona) were immediately shown "Your session has expired. Please sign in again." — even though their session was perfectly valid.
Root cause: Two issues compounding:
- Unconditional admin API call — The
Headercomponent calleduseSystemInfo()for every user, which hits the admin-only/api/v1/admin/system/infoendpoint. Non-admin users received a 401 (insufficient privileges). - Overly aggressive 401 handling — The admin API client treated all 401 responses as session expiration and called
expireSession(), destroying the valid session.
Fix (3 changes, defense in depth):
- Gate the query on admin status —
useSystemInfo(isAdmin)skips the admin API call entirely for non-admin users via React Query'senabledoption - Add
enabledparameter touseSystemInfohook — Accepts a boolean to conditionally disable the query - Remove
expireSession()from the admin API client — A 401 from admin endpoints means "insufficient privileges", not "session invalid". The portal client handles true session expiration independently.
Changelog
Bug Fixes
- fix: prevent non-admin users from getting "session expired" after SSO login (#241)
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.41.2Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.41.2_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.41.2_linux_amd64.tar.gzmcp-data-platform-v1.41.1
Highlights
This patch release adds two UX improvements to the asset portal, building on the CSV support introduced in v1.41.0.
CSV Download Button
The CSV table viewer now includes a Download button in the header bar, positioned to the right of the search input.
- Clicking the button creates a Blob from the raw CSV content and triggers a browser download
- The downloaded file uses the asset's actual name (e.g.,
sales-report.csv) rather than a generic filename - Works in both the authenticated portal and public share links — the asset name is included in the public viewer's content-data JSON payload
Public Viewer Info Modal
Public share links now have an info button (ℹ) in the header bar that opens a modal displaying asset metadata.
- Description: Shown as paragraph text when present
- Created / Updated dates: Formatted in the viewer's locale via
toLocaleString() - Tags: Displayed as pill badges matching the existing badge styling
- Modal closes on Close button click, backdrop click, or Escape key
- Sections with no data (empty description, no tags) are hidden automatically
- Styling follows the existing public viewer design system (CSS variables, light/dark theme support)
Implementation Details
fileNameprop threaded throughAssetViewer→ContentRenderer→CsvRendererfor correct download filenames- Backend (
public.go) now passesDescription,Tags,CreatedAtISO, andUpdatedAtISOto the template data map and includesname,description,tags,createdAt,updatedAtin the content-data JSON - Info modal markup uses Go template conditionals (
{{if .Description}},{{if .Tags}}) for graceful empty-state handling
Changelog
Features
- feat: add CSV download button and public viewer info modal (#239)
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.41.1Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.41.1_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.41.1_linux_amd64.tar.gzmcp-data-platform-v1.41.0
Highlights
This release introduces automatic thumbnail generation for all asset types and adds CSV (text/csv) as a new asset content type with an interactive table viewer.
Asset Thumbnails
Assets now display visual thumbnail previews in the asset grid instead of plain icons. Thumbnails are generated client-side when an asset is first viewed and uploaded to S3 for subsequent display.
- Client-side capture pipeline: HTML and JSX assets are rendered in a sandboxed iframe and captured with html2canvas; Markdown, SVG, and CSV assets are rendered directly in the DOM and captured at 400x300px
- Background queue:
ThumbnailQueueprocesses assets without thumbnails in the background, one at a time, without blocking the UI - Regeneration on save: Editing and saving asset content automatically regenerates the thumbnail
- Server-side storage: New
PUT /assets/:id/thumbnailendpoint stores PNG thumbnails in S3;thumbnail_s3_keycolumn added to the portal assets table (migration000020) - Admin support: Admin asset detail view also displays and regenerates thumbnails
CSV Asset Support
A new text/csv content type joins HTML, JSX, SVG, and Markdown:
- Interactive table preview: Parsed with Papa Parse with dynamic typing, sortable columns (numeric-aware), and a global search filter across all columns
- Performance: Display capped at 500 rows with a "Showing X of Y" footer
- Thumbnails: First 10 rows rendered as a styled HTML table and captured via the DomCapture path
- Source editing: Raw CSV text is editable in the Source tab (plain text mode)
- Public viewer: CSV renders the same interactive table in the public share viewer
- UI polish:
Table2icon from lucide-react, emerald badge color, and a CSV option in the content type filter dropdown
Changelog
Features
- feat: asset thumbnail system with client-side capture and S3 storage (#232)
- feat: add CSV asset support with interactive table preview and thumbnails (#238)
Bug Fixes
- fix: correct postMessage origin check for thumbnail capture iframe (#233)
- fix: thumbnail capture quality — JSX rendering, viewport scaling, Markdown, and save regeneration (#234)
- fix: markdown thumbnail blank capture — replace visibility:hidden with off-screen positioning (#235)
- fix: markdown thumbnail capture race condition — use MutationObserver instead of setTimeout (#236)
- fix: replace html-to-image with html2canvas for markdown/SVG thumbnail capture (#237)
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.41.0Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.41.0_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.41.0_linux_amd64.tar.gzmcp-data-platform-v1.40.5
Fix: Markdown/SVG Thumbnail Capture
v1.40.2–v1.40.4 attempted to fix blank markdown thumbnails but failed because they all kept using html-to-image (toPng), which was the actual broken component. This release replaces it entirely.
Root Cause
html-to-image uses SVG foreignObject internally to capture DOM elements. This produces fully transparent pixels for off-screen elements — regardless of the hiding method (visibility: hidden, left: -9999px, opacity: 0). The markdown thumbnail already in S3 was an 800x600 PNG with 0% opaque pixels, confirmed by fetching and analyzing the pixel data on the production site.
Fix
Replaced html-to-image (toPng) with html2canvas for DomCapture (markdown and SVG thumbnails). html2canvas is already used successfully by IframeCapture for HTML/JSX assets. Tested all combinations on the production site:
| Library | Positioning | Result |
|---|---|---|
toPng |
any | 0% opaque (transparent) |
html2canvas |
opacity: 0 |
white rectangle (respects opacity) |
html2canvas |
left: -9999px |
rendered text, tables, headings |
Removed the html-to-image dependency entirely (~13KB bundle savings).
Verified on production
Injected the fixed capture code on mcp-demo.plexara.io, rendered the ACME Corp Inventory Report markdown, and captured a 400x300 PNG with 100% opaque pixels and 14.7% non-white content (headings, paragraphs, table). Screenshot confirmed visible rendered prose.
Note
Existing blank thumbnails in S3 from earlier versions will need to be regenerated — either by deleting the thumbnail_s3_key or by editing and saving the asset.
Changed Files
ui/src/components/ThumbnailGenerator.tsx—DomCaptureuseshtml2canvasinstead oftoPngui/src/lib/thumbnail.ts— removedcaptureElementfunction andhtml-to-imageimportui/package.json/ui/package-lock.json— removedhtml-to-imagedependency