44import mcp .types as types
55from mcp import StdioServerParameters
66from mcp .client .stdio import stdio_client
7+ from opentelemetry import trace
78from uipath import UiPath
9+ from uipath .tracing import traced , wait_for_tracers
810
911from .._utils ._config import McpServer
1012from ._logger import LoggerAdapter
1113
1214logger = logging .getLogger (__name__ )
15+ tracer = trace .get_tracer (__name__ )
1316
1417
1518class SessionServer :
@@ -57,33 +60,38 @@ async def _run_server(self, server_params: StdioServerParameters) -> None:
5760 logger .info (f"Starting server process for session { self .session_id } " )
5861 try :
5962 stderr_adapter = LoggerAdapter (logger )
60- async with stdio_client (server_params , errlog = stderr_adapter ) as (
61- read ,
62- write ,
63- ):
64- self .read_stream , self .write_stream = read , write
65- logger .info (f"Session { self .session_id } - stdio client started" )
63+ with tracer .start_as_current_span (self .server_config .name ) as root_span :
64+ root_span .set_attribute ("session_id" , self .session_id )
65+ root_span .set_attribute (
66+ "server_params" , server_params .model_dump_json ()
67+ )
68+ async with stdio_client (server_params , errlog = stderr_adapter ) as (
69+ read ,
70+ write ,
71+ ):
72+ self .read_stream , self .write_stream = read , write
73+ logger .info (f"Session { self .session_id } - stdio client started" )
6674
67- logger .info (f"Session { self .session_id } - MCP session initialized" )
75+ logger .info (f"Session { self .session_id } - MCP session initialized" )
6876
69- # Start the message consumer task
70- consumer_task = asyncio .create_task (self ._consume_messages ())
77+ # Start the message consumer task
78+ consumer_task = asyncio .create_task (self ._consume_messages ())
7179
72- # Process incoming messages from the server
73- try :
74- while True :
75- print ("Waiting for messages..." )
76- message = await self .read_stream .receive ()
77- json_str = message .model_dump_json ()
78- print (f"Received message from local server: { json_str } " )
79- await self .send_outgoing_message (message )
80- finally :
81- # Cancel the consumer when we exit the loop
82- consumer_task .cancel ()
80+ # Process incoming messages from the server
8381 try :
84- await consumer_task
85- except asyncio .CancelledError :
86- pass
82+ while True :
83+ print ("Waiting for messages..." )
84+ message = await self .read_stream .receive ()
85+ json_str = message .model_dump_json ()
86+ print (f"Received message from local server: { json_str } " )
87+ await self .send_outgoing_message (message )
88+ finally :
89+ # Cancel the consumer when we exit the loop
90+ consumer_task .cancel ()
91+ try :
92+ await consumer_task
93+ except asyncio .CancelledError :
94+ pass
8795
8896 except Exception as e :
8997 logger .error (
@@ -155,6 +163,7 @@ async def send_message(self, message: types.JSONRPCMessage) -> None:
155163 await self ._message_queue .put (message )
156164 logger .debug (f"Session { self .session_id } - message queued for processing" )
157165
166+ @traced
158167 async def get_incoming_messages (self ) -> None :
159168 """Get new messages from UiPath MCP Server."""
160169 response = self ._uipath .api_client .request (
@@ -169,6 +178,7 @@ async def get_incoming_messages(self) -> None:
169178 logger .info (f"Forwarding message to local MCP Server: { message } " )
170179 await self .send_message (json_message )
171180
181+ @traced
172182 async def send_outgoing_message (self , message : types .JSONRPCMessage ) -> None :
173183 """Send new message to UiPath MCP Server."""
174184 response = self ._uipath .api_client .request (
@@ -210,4 +220,5 @@ async def cleanup(self) -> None:
210220 self .read_stream = None
211221 self .write_stream = None
212222 self .mcp_session = None
223+ wait_for_tracers ()
213224 logger .info (f"Cleanup completed for session { self .session_id } " )
0 commit comments