Summary
query_asset_tool is documented as a read-only SQL tool, but the implementation does not appear to enforce that boundary before executing the query request.
Why this matters
The MCP server is used by AI clients and agents, so tool contracts need to be enforced in code rather than only described in prompts/docstrings. If a tool is presented as read-only, callers and operators will reasonably assume the server prevents non-read-only SQL from being submitted.
This is especially important because the README's "Read-Only Access" configuration restricts metadata/DQ write tools, but does not include query_asset_tool. An operator could therefore configure what looks like a read-only MCP server while still leaving SQL execution enabled.
Code paths
modelcontextprotocol/server.py: query_asset_tool says: "CRITICAL: Use READ-ONLY queries to retrieve data. Write and modify queries are not supported by this tool."
modelcontextprotocol/tools/query.py: query_asset() validates only that sql and connection_qualified_name are non-empty, then builds QueryRequest(sql=sql, ...) and calls client.queries.stream(request=query_request).
modelcontextprotocol/README.md: the "Read-Only Access" example does not restrict query_asset_tool.
Expected behavior
The MCP layer should enforce the documented read-only contract before constructing or executing QueryRequest.
Possible fixes:
- Add SQL validation before
QueryRequest is created.
- Allow only an explicit conservative set of read-only statement types, based on the tool's intended scope.
- Reject multi-statement or ambiguous SQL unless safely parsed and intentionally supported.
- Add unit tests for allowed read-only statements and rejected non-read-only statements.
- Update README guidance so read-only deployments either restrict
query_asset_tool or clearly document what protection it provides.
Impact
This would make the server safer for agent-driven use, reduce surprises for admins configuring read-only access, and align the implementation with the tool's documented behavior.
Summary
query_asset_toolis documented as a read-only SQL tool, but the implementation does not appear to enforce that boundary before executing the query request.Why this matters
The MCP server is used by AI clients and agents, so tool contracts need to be enforced in code rather than only described in prompts/docstrings. If a tool is presented as read-only, callers and operators will reasonably assume the server prevents non-read-only SQL from being submitted.
This is especially important because the README's "Read-Only Access" configuration restricts metadata/DQ write tools, but does not include
query_asset_tool. An operator could therefore configure what looks like a read-only MCP server while still leaving SQL execution enabled.Code paths
modelcontextprotocol/server.py:query_asset_toolsays: "CRITICAL: Use READ-ONLY queries to retrieve data. Write and modify queries are not supported by this tool."modelcontextprotocol/tools/query.py:query_asset()validates only thatsqlandconnection_qualified_nameare non-empty, then buildsQueryRequest(sql=sql, ...)and callsclient.queries.stream(request=query_request).modelcontextprotocol/README.md: the "Read-Only Access" example does not restrictquery_asset_tool.Expected behavior
The MCP layer should enforce the documented read-only contract before constructing or executing
QueryRequest.Possible fixes:
QueryRequestis created.query_asset_toolor clearly document what protection it provides.Impact
This would make the server safer for agent-driven use, reduce surprises for admins configuring read-only access, and align the implementation with the tool's documented behavior.