88import  logging 
99import  os 
1010import  time 
11- from   datetime   import  datetime 
12- from  typing  import  Optional , Annotated ,  Any ,  Dict 
11+ import  datetime 
12+ from  typing  import  Optional , Annotated 
1313from  pydantic  import  Field 
14- from  sysdig_client  import  ApiException 
1514from  fastmcp .prompts .prompt  import  PromptMessage , TextContent 
1615from  fastmcp .exceptions  import  ToolError 
17- from  starlette .requests  import  Request 
16+ from  fastmcp .server .context  import  Context 
17+ from  sysdig_client  import  ApiException 
1818from  sysdig_client .api  import  SecureEventsApi 
19- from  utils .sysdig .old_sysdig_api  import  OldSysdigApi 
20- from  fastmcp .server .dependencies  import  get_http_request 
19+ from  utils .sysdig .legacy_sysdig_api  import  LegacySysdigApi 
2120from  utils .query_helpers  import  create_standard_response 
22- from  utils .sysdig .client_config  import  get_configuration 
2321from  utils .app_config  import  AppConfig 
24- from  utils .sysdig .api  import  initialize_api_client 
2522
2623
2724class  EventsFeedTools :
@@ -32,55 +29,23 @@ class EventsFeedTools:
3229
3330    def  __init__ (self , app_config : AppConfig ):
3431        self .app_config  =  app_config 
35-         logging .basicConfig (format = "%(asctime)s-%(process)d-%(levelname)s- %(message)s" , level = self .app_config .log_level ())
3632        self .log  =  logging .getLogger (__name__ )
3733
38-     def  init_client (self , old_api : bool  =  False ) ->  SecureEventsApi  |  OldSysdigApi :
39-         """ 
40-         Initializes the SecureEventsApi client from the request state. 
41-         If the request does not have the API client initialized, it will create a new instance 
42-         using the Sysdig Secure token and host from the environment variables. 
43-         Args: 
44-             old_api (bool): If True, initializes the OldSysdigApi client instead of SecureEventsApi. 
45-         Returns: 
46-             SecureEventsApi | OldSysdigApi: An instance of the SecureEventsApi or OldSysdigApi client. 
47-         """ 
48-         secure_events_api : SecureEventsApi  =  None 
49-         old_sysdig_api : OldSysdigApi  =  None 
50-         transport  =  self .app_config .transport ()
51-         if  transport  in  ["streamable-http" , "sse" ]:
52-             # Try to get the HTTP request 
53-             self .log .debug ("Attempting to get the HTTP request to initialize the Sysdig API client." )
54-             request : Request  =  get_http_request ()
55-             secure_events_api  =  request .state .api_instances ["secure_events" ]
56-             old_sysdig_api  =  request .state .api_instances ["old_sysdig_api" ]
57-         else :
58-             # If running in STDIO mode, we need to initialize the API client from environment variables 
59-             self .log .debug ("Running in STDIO mode, initializing the Sysdig API client from environment variables." )
60-             cfg  =  get_configuration ()
61-             api_client  =  initialize_api_client (cfg )
62-             secure_events_api  =  SecureEventsApi (api_client )
63-             # Initialize the old Sysdig API client for process tree requests 
64-             old_cfg  =  get_configuration (old_api = True )
65-             old_sysdig_api  =  initialize_api_client (old_cfg )
66-             old_sysdig_api  =  OldSysdigApi (old_sysdig_api )
67- 
68-         if  old_api :
69-             return  old_sysdig_api 
70-         return  secure_events_api 
71- 
72-     def  tool_get_event_info (self , event_id : str ) ->  dict :
34+     def  tool_get_event_info (self , ctx : Context , event_id : str ) ->  dict :
7335        """ 
7436        Retrieves detailed information for a specific security event. 
7537
7638        Args: 
39+             ctx (Context): Context to use. 
7740            event_id (str): The unique identifier of the security event. 
7841
7942        Returns: 
8043            Event: The Event object containing detailed information about the specified event. 
8144        """ 
8245        # Init of the sysdig client 
83-         secure_events_api  =  self .init_client ()
46+         api_instances : dict  =  ctx .get_state ("api_instances" )
47+         secure_events_api : SecureEventsApi  =  api_instances .get ("secure_events" )
48+ 
8449        try :
8550            # Get the HTTP request 
8651            start_time  =  time .time ()
@@ -98,6 +63,7 @@ def tool_get_event_info(self, event_id: str) -> dict:
9863
9964    def  tool_list_runtime_events (
10065        self ,
66+         ctx : Context ,
10167        cursor : Optional [str ] =  None ,
10268        scope_hours : int  =  1 ,
10369        limit : int  =  50 ,
@@ -136,6 +102,7 @@ def tool_list_runtime_events(
136102        cluster name, or an optional filter expression. 
137103
138104        Args: 
105+             ctx (Context): Context to use. 
139106            cursor (Optional[str]): Cursor for pagination. 
140107            scope_hours (int): Number of hours back from now to include events. Defaults to 1. 
141108            limit (int): Maximum number of events to return. Defaults to 50. 
@@ -144,7 +111,9 @@ def tool_list_runtime_events(
144111        Returns: 
145112            dict: A dictionary containing the results of the runtime events query, including pagination information. 
146113        """ 
147-         secure_events_api  =  self .init_client ()
114+         api_instances : dict  =  ctx .get_state ("api_instances" )
115+         secure_events_api : SecureEventsApi  =  api_instances .get ("secure_events" )
116+ 
148117        start_time  =  time .time ()
149118        # Compute time window 
150119        now_ns  =  time .time_ns ()
@@ -176,7 +145,7 @@ def tool_list_runtime_events(
176145
177146    # A tool to retrieve all the process-tree information for a specific event.Add commentMore actions 
178147
179-     def  tool_get_event_process_tree (self , event_id : str ) ->  dict :
148+     def  tool_get_event_process_tree (self , ctx :  Context ,  event_id : str ) ->  dict :
180149        """ 
181150        Retrieves the process tree for a specific security event. 
182151        Not every event has a process tree, so this may return an empty tree. 
@@ -191,12 +160,14 @@ def tool_get_event_process_tree(self, event_id: str) -> dict:
191160            ToolError: If there is an error constructing or processing the response. 
192161        """ 
193162        try :
163+             api_instances : dict  =  ctx .get_state ("api_instances" )
164+             legacy_api_client : LegacySysdigApi  =  api_instances .get ("legacy_sysdig_api" )
165+ 
194166            start_time  =  time .time ()
195167            # Get process tree branches 
196-             old_api_client  =  self .init_client (old_api = True )
197-             branches  =  old_api_client .request_process_tree_branches (event_id )
168+             branches  =  legacy_api_client .request_process_tree_branches (event_id )
198169            # Get process tree 
199-             tree  =  old_api_client .request_process_tree_trees (event_id )
170+             tree  =  legacy_api_client .request_process_tree_trees (event_id )
200171
201172            # Parse the response (tolerates empty bodies) 
202173            branches_std  =  create_standard_response (results = branches , execution_time_ms = (time .time () -  start_time ) *  1000 )
@@ -209,7 +180,7 @@ def tool_get_event_process_tree(self, event_id: str) -> dict:
209180                "tree" : tree_std .get ("results" , {}),
210181                "metadata" : {
211182                    "execution_time_ms" : execution_time ,
212-                     "timestamp" : datetime .utcnow ( ).isoformat ()  +  "Z" ,
183+                     "timestamp" : datetime .datetime . now ( datetime . UTC ).isoformat (). replace ( "+00:00" ,  "Z" ) ,
213184                },
214185            }
215186
@@ -222,7 +193,7 @@ def tool_get_event_process_tree(self, event_id: str) -> dict:
222193                    "tree" : {},
223194                    "metadata" : {
224195                        "execution_time_ms" : (time .time () -  start_time ) *  1000 ,
225-                         "timestamp" : datetime .utcnow ( ).isoformat ()  +  "Z" ,
196+                         "timestamp" : datetime .datetime . now ( datetime . UTC ).isoformat (). replace ( "+00:00" ,  "Z" ) ,
226197                        "note" : "Process tree not available for this event" 
227198                    },
228199                }
0 commit comments