Skip to content

Commit 53fc506

Browse files
committed
Allow read-only queries that do not start with SELECT keyword
- I was finding it a bit restrictive to disallow any query that doesn't start with "SELECT" because it is often useful to start a select statement with a CTE ("WITH"), and to occasionally use SHOW or DESCRIBE - therefore, in the handler for the query tool, instead of disallowing any query that doesn't start with the SELECT keyword, parse the query into its component statements and disallow if any of those component statements is a non-read-only operation - add a dependency on sqlglot, for parsing the query
1 parent 6af6532 commit 53fc506

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

mcp_server_snowflake/main.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from mcp.server.models import InitializationOptions
2323
from mcp.server.lowlevel import NotificationOptions
2424
from dotenv import load_dotenv
25+
import sqlglot
26+
from sqlglot.errors import ParseError
2527

2628
from mcp_server_snowflake.utils.snowflake_conn import (
2729
SnowflakeConfig,
@@ -346,9 +348,16 @@ async def handle_execute_query(
346348
)
347349
]
348350

349-
# Validate that the query is read-only (SELECT statement)
350-
query = query.strip()
351-
if not query.upper().startswith("SELECT "):
351+
# Validate that the query is read-only
352+
try:
353+
parsed_statements = sqlglot.parse(query, dialect="snowflake")
354+
read_only_types = {'select', 'show', 'describe', 'explain', 'with'}
355+
356+
for stmt in parsed_statements:
357+
if stmt.key.lower() not in read_only_types:
358+
raise ParseError(f"Error: Only read-only queries are allowed. Found statement type: {stmt.key}")
359+
360+
except ParseError:
352361
return [
353362
mcp_types.TextContent(
354363
type="text",

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies = [
1616
"cryptography>=41.0.0",
1717
"mcp",
1818
"anyio>=3.7.1",
19+
"sqlglot>=11.5.5"
1920
]
2021

2122
[project.scripts]

uv.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)