mcp-trino-v0.8.0
What's New
Read-Only trino_query and New trino_execute Tool
trino_query is now strictly read-only. Write operations (INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, TRUNCATE, GRANT, REVOKE, MERGE, CALL) are rejected before they reach Trino, with a clear error message directing users to the new trino_execute tool.
The new trino_execute tool handles all write operations without restrictions.
Before (v0.7.x):
trino_querycould run both reads and writes — MCP clients had no way to know which calls were safe
After (v0.8.0):
trino_query— read-only, annotated withReadOnlyHint: true— MCP clients can auto-approvetrino_execute— unrestricted, annotated withDestructiveHint: true— MCP clients will prompt for confirmation
MCP Tool Annotations
Both tools now carry proper MCP annotations so AI clients can make informed decisions about auto-approval:
| Tool | ReadOnlyHint | DestructiveHint | IdempotentHint |
|---|---|---|---|
trino_query |
true | - | true |
trino_execute |
- | true | - |
Write Detection
Write SQL is detected by matching statement-initial keywords, handling:
- Case-insensitive matching (
INSERT,insert,Insert) - Leading whitespace and tabs
- SQL comments (
-- commentand/* block */) before the keyword - All 12 write keywords:
INSERT,UPDATE,DELETE,DROP,CREATE,ALTER,TRUNCATE,GRANT,REVOKE,MERGE,CALL,EXECUTE
The detection is exposed as a public IsWriteSQL() function for use in custom middleware and interceptors.
Three Layers of Write Control
- Tool semantics (this release) —
trino_queryalways rejects writes,trino_executealways allows them - Instance-level ReadOnly interceptor — when
MCP_TRINO_EXT_READONLY=true, blocks writes on bothtrino_queryandtrino_execute - Custom interceptors — add your own
QueryInterceptorfor tenant isolation, audit, or policy enforcement
For Library Users
If you import mcp-trino as a Go library, the new tool registers automatically via RegisterAll(). No code changes required.
// trino_execute is registered alongside trino_query
toolkit := tools.NewToolkit(client, tools.DefaultConfig())
toolkit.RegisterAll(server) // registers all 8 tools including trino_executeTo use IsWriteSQL() in custom middleware:
import "github.com/txn2/mcp-trino/pkg/tools"
if tools.IsWriteSQL(sql) {
// handle write operation
}Breaking Changes
trino_querynow rejects write SQL that it previously accepted. If you have workflows that usetrino_queryfor writes, switch them totrino_execute.AllTools()returns 8 tools (was 7).QueryTools()returns 3 (was 2).
Files Changed
| File | Change |
|---|---|
pkg/tools/execute.go |
New — trino_execute handler and ExecuteInput type |
pkg/tools/query.go |
Add IsWriteSQL(), writePattern regex, read-only enforcement in handleQuery |
pkg/tools/names.go |
Add ToolExecute constant, update AllTools() and QueryTools() |
pkg/tools/annotations.go |
ToolQuery gets ReadOnlyHint: true, ToolExecute gets DestructiveHint: true |
pkg/tools/descriptions.go |
Updated descriptions for both tools |
pkg/tools/toolkit.go |
Register ToolExecute in registerTool() |
pkg/tools/options.go |
Updated docs to reference ToolExecute |
pkg/extensions/readonly.go |
ReadOnly interceptor now checks ToolExecute |
Upgrading
go get github.com/txn2/mcp-trino@v0.8.0If you use trino_query for write operations, update those calls to use trino_execute instead.
Changelog
- feat: split trino_query into read-only query and unrestricted execute tools (#39)
Full diff: v0.6.2...v0.8.0
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_0.8.0_darwin_arm64.mcpb - macOS Intel:
mcp-trino_0.8.0_darwin_amd64.mcpb - Windows:
mcp-trino_0.8.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:v0.8.0Verification
All release artifacts are signed with Cosign. Verify with:
cosign verify-blob --bundle mcp-trino_0.8.0_linux_amd64.tar.gz.sigstore.json \
mcp-trino_0.8.0_linux_amd64.tar.gz