55import logging
66from typing import Any , Dict , List , Optional
77import asyncpg
8+ from asyncpg .pool import Pool
89from mcp .server .fastmcp import FastMCP , Context
910from pydantic import BaseModel , Field
1011
2930logger .info (f"Using DATABASE_URL: { DATABASE_URL .replace (DATABASE_URL .split ('@' )[0 ].split ('//' )[1 ], '***:***' )} " )
3031
3132# Connection pool for better performance
32- connection_pool = None
33+ connection_pool : Optional [ Pool ] = None
3334
34- async def get_pool ():
35- """Get or create the connection pool."""
35+ async def get_pool () -> Pool :
36+ """Get or create the shared asyncpg connection pool.
37+
38+ Returns:
39+ The initialized asyncpg connection pool.
40+
41+ Raises:
42+ Exception: If the database connection pool cannot be created.
43+ """
3644 global connection_pool
3745 if connection_pool is None :
3846 try :
@@ -49,10 +57,23 @@ async def get_pool():
4957 logger .error (f"❌ Failed to create database connection pool: { str (e )} " )
5058 logger .error ("Connection URL format: postgresql://user:***@host:port/database" )
5159 raise Exception (f"Database connection failed: { str (e )} " )
60+ if connection_pool is None :
61+ raise Exception ("Database connection pool was not initialized" )
5262 return connection_pool
5363
54- async def execute_query (query : str , * args ) -> List [Dict [str , Any ]]:
55- """Execute a query and return results as a list of dictionaries."""
64+ async def execute_query (query : str , * args : Any ) -> List [Dict [str , Any ]]:
65+ """Execute a SQL query and return results as a list of dictionaries.
66+
67+ Args:
68+ query: SQL query string.
69+ *args: Positional query parameters.
70+
71+ Returns:
72+ A list of rows represented as dictionaries.
73+
74+ Raises:
75+ Exception: If the database operation fails.
76+ """
5677 pool = await get_pool ()
5778 async with pool .acquire () as conn :
5879 try :
@@ -61,12 +82,23 @@ async def execute_query(query: str, *args) -> List[Dict[str, Any]]:
6182 except Exception as e :
6283 raise Exception (f"Database error: { str (e )} " )
6384
64- async def execute_non_query (query : str , * args ) -> str :
65- """Execute a non-query (INSERT, UPDATE, DELETE) and return affected rows count."""
85+ async def execute_non_query (query : str , * args : Any ) -> str :
86+ """Execute a SQL statement that does not return rows.
87+
88+ Args:
89+ query: SQL statement string.
90+ *args: Positional query parameters.
91+
92+ Returns:
93+ The asyncpg status string returned from execution.
94+
95+ Raises:
96+ Exception: If the database operation fails.
97+ """
6698 pool = await get_pool ()
6799 async with pool .acquire () as conn :
68100 try :
69- result = await conn .execute (query , * args )
101+ result : str = await conn .execute (query , * args )
70102 return result
71103 except Exception as e :
72104 raise Exception (f"Database error: { str (e )} " )
@@ -1177,11 +1209,12 @@ async def PostgreSQL_get_table_permissions(table_name: str, schema_name: str = "
11771209 return rows
11781210
11791211@mcp .tool ()
1180- async def PostgreSQL_vacuum_analyze_table (table_name : str , ctx : Context , schema_name : str = "public" ) -> str :
1212+ async def PostgreSQL_vacuum_analyze_table (table_name : str , ctx : Context , schema_name : str = "public" ) -> Dict [ str , Any ] :
11811213 """Run VACUUM ANALYZE on a specific table to reclaim space and update statistics.
11821214
11831215 Args:
11841216 table_name: Name of the table
1217+ ctx: MCP request context.
11851218 schema_name: Database schema name (default: public)
11861219 """
11871220 full_table_name = f"{ schema_name } .{ table_name } "
@@ -3487,7 +3520,8 @@ async def PostgreSQL_analyze_connection_pool_efficiency() -> Dict[str, Any]:
34873520
34883521 # Add recommendations
34893522 if 'efficiency_metrics' in result :
3490- metrics = result ['efficiency_metrics' ]
3523+ metrics_any = result ['efficiency_metrics' ]
3524+ metrics : Dict [str , Any ] = metrics_any if isinstance (metrics_any , dict ) else {}
34913525 recommendations = []
34923526
34933527 if metrics .get ('long_idle_transactions' , 0 ) > 0 :
0 commit comments