3535# Global Databend client singleton
3636_databend_client = None
3737
38+
3839def get_global_databend_client ():
3940 """Get global Databend client instance (deprecated, use create_databend_client)."""
4041 global _databend_client
@@ -57,12 +58,12 @@ def is_sql_safe(sql: str) -> tuple[bool, str]:
5758
5859 # List of dangerous operations to block in safe mode
5960 dangerous_patterns = [
60- (r' \bDROP\s+' , "DROP operations are not allowed in MCP safe mode" ),
61- (r' \bDELETE\s+' , "DELETE operations are not allowed in MCP safe mode" ),
62- (r' \bTRUNCATE\s+' , "TRUNCATE operations are not allowed in MCP safe mode" ),
63- (r' \bALTER\s+' , "ALTER operations are not allowed in MCP safe mode" ),
64- (r' \bUPDATE\s+' , "UPDATE operations are not allowed in MCP safe mode" ),
65- (r' \bREVOKE\s+' , "REVOKE operations are not allowed in MCP safe mode" ),
61+ (r" \bDROP\s+" , "DROP operations are not allowed in MCP safe mode" ),
62+ (r" \bDELETE\s+" , "DELETE operations are not allowed in MCP safe mode" ),
63+ (r" \bTRUNCATE\s+" , "TRUNCATE operations are not allowed in MCP safe mode" ),
64+ (r" \bALTER\s+" , "ALTER operations are not allowed in MCP safe mode" ),
65+ (r" \bUPDATE\s+" , "UPDATE operations are not allowed in MCP safe mode" ),
66+ (r" \bREVOKE\s+" , "REVOKE operations are not allowed in MCP safe mode" ),
6667 ]
6768
6869 # Check each dangerous pattern
@@ -80,10 +81,12 @@ def create_databend_client():
8081 if config .local_mode :
8182 # Use local in-memory Databend
8283 import databend
84+
8385 return databend .SessionContext ()
8486 else :
8587 # Use remote Databend server
8688 from databend_driver import BlockingDatabendClient
89+
8790 return BlockingDatabendClient (config .dsn )
8891
8992
@@ -105,7 +108,7 @@ def execute_databend_query(sql: str) -> list[dict] | dict:
105108 # Handle local in-memory Databend
106109 result = client .sql (sql )
107110 df = result .to_pandas ()
108- return df .to_dict (' records' )
111+ return df .to_dict (" records" )
109112 else :
110113 # Handle remote Databend server
111114 conn = client .get_conn ()
@@ -165,6 +168,7 @@ def _execute_sql(sql: str) -> dict:
165168 logger .error (error_msg )
166169 return {"status" : "error" , "message" : error_msg }
167170
171+
168172@mcp .tool ()
169173async def execute_sql (sql : str ) -> dict :
170174 """
@@ -246,7 +250,7 @@ async def list_stage_files(stage_name: str, path: Optional[str] = None):
246250 Returns:
247251 Dictionary containing either query results or error information
248252 """
249- if not stage_name .startswith ('@' ):
253+ if not stage_name .startswith ("@" ):
250254 stage_name = f"@{ stage_name } "
251255
252256 if path :
@@ -267,7 +271,9 @@ async def show_connections():
267271
268272
269273@mcp .tool ()
270- async def create_stage (name : str , url : str , connection_name : Optional [str ] = None , ** kwargs ) -> dict :
274+ async def create_stage (
275+ name : str , url : str , connection_name : Optional [str ] = None , ** kwargs
276+ ) -> dict :
271277 """
272278 Create a Databend stage with connection
273279 Args:
@@ -288,7 +294,7 @@ async def create_stage(name: str, url: str, connection_name: Optional[str] = Non
288294
289295 # Add any additional options from kwargs
290296 for key , value in kwargs .items ():
291- if key not in [' name' , ' url' , ' connection_name' ]:
297+ if key not in [" name" , " url" , " connection_name" ]:
292298 sql_parts .append (f"{ key .upper ()} = '{ value } '" )
293299
294300 sql = " " .join (sql_parts )
0 commit comments