mcp-data-platform-v1.56.2
Highlights
Fix: trino_export failed on MinIO with XMinioInvalidObjectName (#337)
trino_export was rejected by MinIO-backed S3 deployments for every export — even with plain ASCII names like "Loyalty Customers by DBA" — with:
S3 upload failed: s3 put: failed to put object: operation error S3: PutObject,
https response error StatusCode: 400, ...
api error XMinioInvalidObjectName: Object name contains unsupported characters.
Root cause. The S3 object key was built with fmt.Sprintf("%s/%s/%s/content%s", deps.S3Prefix, ...). The default S3Prefix is "artifacts/" (trailing slash, pkg/platform/config.go:135), producing artifacts//{userID}/{assetID}/content.csv — consecutive slashes. MinIO rejects keys with // per its strict object-name validation; AWS S3 silently accepted them, which is why this only surfaced on MinIO. The portal toolkit was already using path.Join (pkg/toolkits/portal/toolkit.go:480,672), which collapses redundant slashes — trino_export is now consistent with that pattern.
Fix. Replace fmt.Sprintf with a new buildExportS3Key helper that uses path.Join and additionally:
- Sanitizes the user-ID path segment so OIDC subjects containing
:/@(e.g.,apikey:admin, email-as-subject) and other non-[A-Za-z0-9._-]characters become portable. - Collapses an all-dots user-ID segment (
".","..","...") to"_"sopath.Clean's path-navigation semantics cannot escape the configured prefix. - Trims any leading
"/"on the joined key (MinIO rejects keys that start with/).
Asset name sanitization. A user-facing name is also normalized before storage: em/en dashes (—, –), figure dash, horizontal bar, minus sign, smart quotes (curly single, curly double, low-9, high-reversed-9), ellipsis (…), non-breaking space, control characters, BOM, zero-width spacing chars, bidi marks (U+200E/U+200F), embedding/override controls (U+202A–U+202E), invisible math operators (U+2061–U+2064), and Unicode variation selectors (U+FE00–U+FE0F) are stripped or mapped to ASCII equivalents. Whitespace runs are collapsed. The same name doubles as the download filename in Content-Disposition (pkg/portal/public.go:213), so portability matters beyond just storage.
If a name is composed entirely of zero-width / control characters and sanitizes to "", the request fails with the existing name is required validator rather than persisting an empty-named asset.
Tool description. The MCP tool description and the name schema description now include an explicit naming hint so calling agents produce portable input from the start: ASCII letters, digits, spaces, hyphens, and dots; non-ASCII punctuation is auto-normalized.
Retrieval safety. Sanitization is symmetric. Every read path (pkg/portal/handler.go:430,938,1023,1889, pkg/portal/public.go:243,271) uses the stored asset.S3Key written at upload time, not a recomputed key. Existing assets created on AWS S3 with //-containing keys retain those keys in the database and continue to work on AWS; only newly-created assets use the sanitized form.
Tests. New table-driven tests cover 21 sanitization cases (each Unicode replacement, control/zero-width stripping, whitespace handling, real-world mixed input), 14 user-ID cases (UUIDs, apikey:, email, slash injection, backslash, single/double/triple/all-dot edge cases, dot-among-letters), 8 S3-key build cases (each asserts the result contains no // and does not start with /), and integration assertions through validateAndPrepare for sanitization, empty-after-sanitize, and the post-sanitization length cap (a 100-ellipsis name expands to 300 chars and is correctly rejected by maxExportNameLength).
Dependency / CI Bumps
- docker: bump alpine from
2510918to5b10f43(#333) - ci: bump
goreleaser/goreleaser-actionfrom 7.0.0 to 7.1.0 (#334) - ci: bump
actions/setup-nodefrom 6.3.0 to 6.4.0 (#335) - ci: bump
github/codeql-actionfrom 4.35.1 to 4.35.2 (#336)
Upgrade Notes
- MinIO and other strict S3 backends: Upgrade required to use
trino_export. No data migration is needed; the fix takes effect for the next export. - AWS S3 deployments: No functional change to retrieval. New exports will store the sanitized form (e.g.,
Q1 — Sales Report→Q1 - Sales Report); pre-existing rows are untouched. Anything matching on the previous display string for newly-created assets should expect ASCII-normalized values.
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.56.2Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-data-platform_1.56.2_linux_amd64.tar.gz.sigstore.json \
mcp-data-platform_1.56.2_linux_amd64.tar.gzChangelog
- 29bcbfd — fix: trino_export S3 key portability and name sanitization (#337) (@cjimti)
- 3367cd0 — ci: bump github/codeql-action from 4.35.1 to 4.35.2 (#336) (@dependabot[bot])
- 0c78709 — ci: bump actions/setup-node from 6.3.0 to 6.4.0 (#335) (@dependabot[bot])
- 09903c1 — ci: bump goreleaser/goreleaser-action from 7.0.0 to 7.1.0 (#334) (@dependabot[bot])
- 7307db6 — docker: bump alpine from
2510918to5b10f43(#333) (@dependabot[bot])