1919class BaseMCPAgent (ABC ):
2020 """Base class with shared functionality for MCPMark agents."""
2121
22- STDIO_SERVICES = ["notion" , "filesystem" , "playwright" , "playwright_webarena" , "postgres" , "insforge" ]
22+ STDIO_SERVICES = [
23+ "notion" ,
24+ "filesystem" ,
25+ "playwright" ,
26+ "playwright_webarena" ,
27+ "postgres" ,
28+ "insforge" ,
29+ ]
2330 HTTP_SERVICES = ["github" , "supabase" ]
2431 DEFAULT_TIMEOUT = 600
2532 COMPACTION_DISABLED_TOKEN = 999_999_999
@@ -70,7 +77,11 @@ def __init__(
7077 )
7178
7279 # Warn if Gemini 3 model uses unsupported reasoning_effort value
73- if self ._is_gemini_3_model () and self .reasoning_effort not in ["default" , "low" , "high" ]:
80+ if self ._is_gemini_3_model () and self .reasoning_effort not in [
81+ "default" ,
82+ "low" ,
83+ "high" ,
84+ ]:
7485 logger .warning (
7586 "Gemini 3 models only support reasoning_effort 'low' or 'high', "
7687 "got '%s'. LiteLLM may map this to the nearest supported value." ,
@@ -179,7 +190,11 @@ def _create_stdio_server(self) -> MCPStdioServer:
179190 raise ValueError ("Test directory required for filesystem service" )
180191 return MCPStdioServer (
181192 command = "npx" ,
182- args = ["-y" , "@modelcontextprotocol/server-filesystem" , str (test_directory )],
193+ args = [
194+ "-y" ,
195+ "@modelcontextprotocol/server-filesystem" ,
196+ str (test_directory ),
197+ ],
183198 )
184199
185200 if self .mcp_service in ("playwright" , "playwright_webarena" ):
@@ -208,10 +223,14 @@ def _create_stdio_server(self) -> MCPStdioServer:
208223 port = self .service_config .get ("port" , 5432 )
209224 username = self .service_config .get ("username" )
210225 password = self .service_config .get ("password" )
211- database = self .service_config .get ("current_database" ) or self .service_config .get ("database" )
226+ database = self .service_config .get (
227+ "current_database"
228+ ) or self .service_config .get ("database" )
212229 if not all ([username , password , database ]):
213230 raise ValueError ("PostgreSQL requires username, password, and database" )
214- database_url = f"postgresql://{ username } :{ password } @{ host } :{ port } /{ database } "
231+ database_url = (
232+ f"postgresql://{ username } :{ password } @{ host } :{ port } /{ database } "
233+ )
215234 return MCPStdioServer (
216235 command = "pipx" ,
217236 args = ["run" , "postgres-mcp" , "--access-mode=unrestricted" ],
@@ -259,11 +278,16 @@ def _count_prompt_tokens_litellm(self, messages: List[Dict[str, Any]]) -> int:
259278 try :
260279 from litellm import token_counter
261280
262- return int (token_counter (model = self .litellm_input_model_name , messages = messages ) or 0 )
281+ return int (
282+ token_counter (model = self .litellm_input_model_name , messages = messages )
283+ or 0
284+ )
263285 except Exception : # pragma: no cover - best effort
264286 return 0
265287
266- def _convert_to_sdk_format (self , messages : List [Dict [str , Any ]]) -> List [Dict [str , Any ]]:
288+ def _convert_to_sdk_format (
289+ self , messages : List [Dict [str , Any ]]
290+ ) -> List [Dict [str , Any ]]:
267291 sdk_format : List [Dict [str , Any ]] = []
268292 function_call_map : Dict [str , str ] = {}
269293
@@ -305,7 +329,9 @@ def _convert_to_sdk_format(self, messages: List[Dict[str, Any]]) -> List[Dict[st
305329 for item in user_content :
306330 if isinstance (item , dict ) and item .get ("type" ) == "text" :
307331 text_parts .append (item .get ("text" , "" ))
308- sdk_format .append ({"content" : "\n " .join (text_parts ), "role" : "user" })
332+ sdk_format .append (
333+ {"content" : "\n " .join (text_parts ), "role" : "user" }
334+ )
309335 else :
310336 sdk_format .append ({"content" : user_content , "role" : "user" })
311337
@@ -324,7 +350,9 @@ def _convert_to_sdk_format(self, messages: List[Dict[str, Any]]) -> List[Dict[st
324350 elif block .get ("type" ) == "thinking" :
325351 thinking_text = block .get ("thinking" , "" )
326352 if thinking_text :
327- text_parts .append (f"<think>\n { thinking_text } \n </think>" )
353+ text_parts .append (
354+ f"<think>\n { thinking_text } \n </think>"
355+ )
328356 elif block .get ("type" ) == "tool_use" :
329357 claude_tool_uses .append (block )
330358 content = "\n " .join (text_parts )
@@ -364,7 +392,9 @@ def _convert_to_sdk_format(self, messages: List[Dict[str, Any]]) -> List[Dict[st
364392 func_name = tool_call .get ("function" , {}).get ("name" , "" )
365393 sdk_format .append (
366394 {
367- "arguments" : tool_call .get ("function" , {}).get ("arguments" , "{}" ),
395+ "arguments" : tool_call .get ("function" , {}).get (
396+ "arguments" , "{}"
397+ ),
368398 "call_id" : call_id ,
369399 "name" : func_name ,
370400 "type" : "function_call" ,
@@ -422,7 +452,9 @@ def _convert_to_sdk_format(self, messages: List[Dict[str, Any]]) -> List[Dict[st
422452
423453 return sdk_format
424454
425- def _convert_to_anthropic_format (self , tools : List [Dict [str , Any ]]) -> List [Dict [str , Any ]]:
455+ def _convert_to_anthropic_format (
456+ self , tools : List [Dict [str , Any ]]
457+ ) -> List [Dict [str , Any ]]:
426458 anthropic_tools = []
427459 for tool in tools :
428460 anthropic_tool = {
@@ -445,7 +477,9 @@ def _is_gemini_3_model(self) -> bool:
445477 model_lower = self .litellm_input_model_name .lower ()
446478 return "gemini-3" in model_lower or "gemini/gemini-3" in model_lower
447479
448- def _simplify_schema_for_gemini (self , schema : Optional [Dict [str , Any ]]) -> Dict [str , Any ]:
480+ def _simplify_schema_for_gemini (
481+ self , schema : Optional [Dict [str , Any ]]
482+ ) -> Dict [str , Any ]:
449483 if not isinstance (schema , dict ):
450484 return schema or {}
451485
@@ -464,14 +498,18 @@ def _simplify_schema_for_gemini(self, schema: Optional[Dict[str, Any]]) -> Dict[
464498 simplified [key ] = self ._simplify_schema_for_gemini (value )
465499 elif isinstance (value , list ) and key not in ("required" , "enum" ):
466500 simplified [key ] = [
467- self ._simplify_schema_for_gemini (item ) if isinstance (item , dict ) else item
501+ self ._simplify_schema_for_gemini (item )
502+ if isinstance (item , dict )
503+ else item
468504 for item in value
469505 ]
470506 else :
471507 simplified [key ] = value
472508 return simplified
473509
474- def _convert_to_openai_format (self , tools : List [Dict [str , Any ]]) -> List [Dict [str , Any ]]:
510+ def _convert_to_openai_format (
511+ self , tools : List [Dict [str , Any ]]
512+ ) -> List [Dict [str , Any ]]:
475513 functions = []
476514 is_gemini = self ._is_gemini_model ()
477515
0 commit comments