Tools now advertise open JSON Schemas for their structured output, so a host that composes this toolkit and adds keys to a result no longer breaks schema-validating clients. This release also clears five security advisories and rolls up several dependency updates.
No emitted field changed, and the minimum Go version for library consumers is unchanged (go 1.25.0).
Open output schemas (#85)
What was wrong. All six tools registered typed handlers without an explicit OutputSchema, so the MCP SDK inferred one from the Go structs — and jsonschema-go closes every struct-derived object with additionalProperties: false plus a required list. Measured against v1.3.1:
| Output type | inferred required |
additionalProperties |
|---|---|---|
QueryOutput |
[columns rows row_count stats] |
false |
BrowseOutput |
[level items count] |
false |
ExplainOutput |
[plan type] |
false |
DescribeTableOutput |
[catalog schema table columns column_count] |
false |
ListConnectionsOutput |
[connections count] |
false |
Standalone that was harmless. But under any host that adds keys to structuredContent after the handler returns — an error envelope, a call reference, a trace ID — a client validating results against the advertised schema rejected every Trino result, while accepting results from toolkits that advertise open schemas.
What changed. Each tool now declares an explicit schema: type, properties and items only, with no top-level required and no additionalProperties: false. Extending a result no longer invalidates it.
Error results now survive validation too. The SDK validates structured output even when a handler returns an error result with no typed output — it substitutes the zero value of the output struct, whose nil slices marshal to null. Every slice-backed property therefore admits null as well as an array. Without that, a failed call surfaces as a JSON-RPC protocol error that discards the tool's own message instead of the reason it failed. (Same defect class as txn2/mcp-s3#141.)
New public API
// Toolkit-level, for all tools:
tools.NewToolkit(client, cfg,
tools.WithOutputSchemas(map[tools.ToolName]any{
tools.ToolQuery: map[string]any{
"type": "object",
"properties": map[string]any{
// Slice-backed properties must admit null — see above.
"rows": map[string]any{"type": []string{"array", "null"}},
},
},
}),
)
// Per-registration:
toolkit.RegisterWith(server, tools.ToolQuery,
tools.WithOutputSchema(mySchema),
)
// Read a built-in default (returns a deep copy, safe to modify):
schema := tools.DefaultOutputSchema(tools.ToolQuery)Resolution order is per-registration → toolkit-level → built-in default, matching the existing title, description, annotation and icon overrides.
Security
Five advisories cleared. These were reachable from code this project calls:
| Advisory | Package | Resolved by |
|---|---|---|
| GO-2026-5026 | golang.org/x/net/idna |
x/net → v0.58.0 |
| GO-2026-5942 | golang.org/x/net/dns/dnsmessage |
x/net → v0.58.0 |
| GO-2026-5972 | encoding/asn1 |
toolchain go1.26.6 |
| GO-2026-6090 | crypto/tls |
toolchain go1.26.6 |
| GO-2026-6218 | net/url |
toolchain go1.26.6 |
Two gosec findings were never actually suppressed. internal/server/server.go carried //nolint:gosec comments, but the standalone gosec binary that CI runs honors #nosec, not golangci-lint's //nolint — so both G706 findings failed every scan while appearing handled. Now correctly annotated with a justification. The gosec pin also moved from v2.22.0 to v2.28.0; v2.22.0 lacks the G706 taint rule entirely.
The toolchain go1.26.6 directive applies when building this module. It does not raise the Go version required to import it — the go directive remains 1.25.0.
Dependencies
github.com/modelcontextprotocol/go-sdkv1.6.1 → v1.7.0 (#82)golang.org/x/netv0.55.0 → v0.58.0,x/crypto→ v0.55.0,x/sys→ v0.47.0- Five GitHub Action SHA bumps:
codeql-actionv4.37.3 → v4.37.6,docker/login-actionv4.5.1 → v4.6.0 (#84)
Project quality
make verify now runs the full CI-equivalent suite rather than three of its eight checks: a tool-version parity gate against the CI pins, an 82% coverage floor and 80% patch-coverage gate mirroring codecov, fail-closed security scanning, dead-code analysis, a build check and a release dry-run. The security step previously reported success when the scanner was not installed, which is why the five advisories above had gone unnoticed. CI runs the same govulncheck gate, so an accepted advisory means the same thing locally and on a pull request.
Contributor-facing details are in CLAUDE.md.
Changelog
Features
Others
- 0cd3415: ci: bump actions/checkout from 6 to 7 in the github-actions group (#73) (@dependabot[bot])
- bf82fda: ci: bump actions/setup-go in the github-actions group (#74) (@dependabot[bot])
- 52642d9: ci: bump codecov/codecov-action in the github-actions group (#72) (@dependabot[bot])
- a9405a5: ci: bump the github-actions group across 1 directory with 6 updates (#80) (@dependabot[bot])
- 790e109: ci: bump the github-actions group with 8 updates (#81) (@dependabot[bot])
- 5b89445: ci: bump the github-actions group with 9 updates (#76) (@dependabot[bot])
- 96992ce: deps: bump golang.org/x/crypto from 0.51.0 to 0.52.0 (#78) (@dependabot[bot])
- d01d47f: deps: bump golang.org/x/net from 0.47.0 to 0.55.0 (#75) (@dependabot[bot])
Installation
Claude Desktop (macOS/Windows)
Download the .mcpb bundle for your platform and double-click to install:
- macOS Apple Silicon (M1/M2/M3/M4):
mcp-trino_1.4.0_darwin_arm64.mcpb - macOS Intel:
mcp-trino_1.4.0_darwin_amd64.mcpb - Windows:
mcp-trino_1.4.0_windows_amd64.mcpb
Homebrew (macOS)
brew install txn2/tap/mcp-trinoClaude Code CLI
claude mcp add trino \
-e TRINO_HOST=your-trino-host \
-e TRINO_USER=your-user \
-- mcp-trinoDocker
docker pull ghcr.io/txn2/mcp-trino:v1.4.0Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-trino_1.4.0_linux_amd64.tar.gz.sigstore.json \
mcp-trino_1.4.0_linux_amd64.tar.gz