Skip to content

Commit 918929d

Browse files
authored
Merge pull request #19 from UiPath/fix/samples
fix: send outgoing message via http
2 parents bfd1eef + 866cb72 commit 918929d

File tree

3 files changed

+38
-37
lines changed

3 files changed

+38
-37
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-mcp"
3-
version = "0.0.14"
3+
version = "0.0.15"
44
description = "UiPath MCP SDK"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.10"

src/uipath_mcp/_cli/_runtime/_runtime.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,17 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
5252
return None
5353

5454
# Set up SignalR client
55-
signalr_url = (
56-
f"{os.environ.get('UIPATH_URL')}/mcp_/wsstunnel?slug={self.server.name}&sessionId={self.server.session_id}"
57-
)
55+
signalr_url = f"{os.environ.get('UIPATH_URL')}/mcp_/wsstunnel?slug={self.server.name}&sessionId={self.server.session_id}"
5856

5957
self.cancel_event = asyncio.Event()
6058

61-
self.signalr_client = SignalRClient(signalr_url, headers={
62-
"X-UiPath-Internal-TenantId": self.context.trace_context.tenant_id,
63-
"X-UiPath-Internal-AccountId": self.context.trace_context.org_id,
64-
})
59+
self.signalr_client = SignalRClient(
60+
signalr_url,
61+
headers={
62+
"X-UiPath-Internal-TenantId": self.context.trace_context.tenant_id,
63+
"X-UiPath-Internal-AccountId": self.context.trace_context.org_id,
64+
},
65+
)
6566
self.signalr_client.on("MessageReceived", self.handle_signalr_message)
6667
self.signalr_client.on("SessionClosed", self.handle_signalr_session_closed)
6768
self.signalr_client.on_error(self.handle_signalr_error)
@@ -82,8 +83,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
8283

8384
# Wait for either the run to complete or cancellation
8485
done, pending = await asyncio.wait(
85-
[run_task, cancel_task],
86-
return_when=asyncio.FIRST_COMPLETED
86+
[run_task, cancel_task], return_when=asyncio.FIRST_COMPLETED
8787
)
8888

8989
# Cancel any pending tasks
@@ -135,9 +135,7 @@ async def handle_signalr_session_closed(self, args: list) -> None:
135135
self.cancel_event.set()
136136

137137
except Exception as e:
138-
logger.error(
139-
f"Error terminating session {session_id}: {str(e)}"
140-
)
138+
logger.error(f"Error terminating session {session_id}: {str(e)}")
141139

142140
async def handle_signalr_message(self, args: list) -> None:
143141
"""
@@ -158,13 +156,13 @@ async def handle_signalr_message(self, args: list) -> None:
158156
# Create and start a new session server
159157
session_server = SessionServer(self.server, session_id)
160158
self.session_servers[session_id] = session_server
161-
await session_server.start(self.signalr_client)
159+
await session_server.start()
162160

163161
# Get the session server for this session
164162
session_server = self.session_servers[session_id]
165163

166164
# Forward the message to the session's MCP server
167-
await session_server.get_messages()
165+
await session_server.get_incoming_messages()
168166

169167
except Exception as e:
170168
logger.error(
@@ -182,9 +180,9 @@ async def handle_signalr_open(self) -> None:
182180
if self.server.session_id:
183181
try:
184182
session_server = SessionServer(self.server, self.server.session_id)
185-
await session_server.start(self.signalr_client)
183+
await session_server.start()
186184
self.session_servers[self.server.session_id] = session_server
187-
await session_server.get_messages()
185+
await session_server.get_incoming_messages()
188186
except Exception as e:
189187
logger.error(f"Error starting session server: {str(e)}")
190188

src/uipath_mcp/_cli/_runtime/_session.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import mcp.types as types
55
from mcp import StdioServerParameters
66
from mcp.client.stdio import stdio_client
7-
from pysignalr.client import SignalRClient
87
from uipath import UiPath
98

109
from .._utils._config import McpServer
@@ -24,8 +23,9 @@ def __init__(self, server_config: McpServer, session_id: str):
2423
self.running = False
2524
self.context_task = None
2625
self._message_queue = asyncio.Queue()
26+
self._uipath = UiPath()
2727

28-
async def start(self, signalr_client: SignalRClient) -> None:
28+
async def start(self) -> None:
2929
"""Start the server process in a separate task."""
3030
if self.running:
3131
logger.info(f"Session {self.session_id} already running")
@@ -41,9 +41,7 @@ async def start(self, signalr_client: SignalRClient) -> None:
4141

4242
# Start the server process in a separate task
4343
self.running = True
44-
self.context_task = asyncio.create_task(
45-
self._run_server(server_params, signalr_client)
46-
)
44+
self.context_task = asyncio.create_task(self._run_server(server_params))
4745
self.context_task.add_done_callback(self._on_task_done)
4846

4947
except Exception as e:
@@ -53,9 +51,7 @@ async def start(self, signalr_client: SignalRClient) -> None:
5351
await self.cleanup()
5452
raise
5553

56-
async def _run_server(
57-
self, server_params: StdioServerParameters, signalr_client: SignalRClient
58-
) -> None:
54+
async def _run_server(self, server_params: StdioServerParameters) -> None:
5955
"""Run the server in proper context managers."""
6056
logger.info(f"Starting server process for session {self.session_id}")
6157
try:
@@ -75,12 +71,7 @@ async def _run_server(
7571
message = await self.read_stream.receive()
7672
json_str = message.model_dump_json()
7773
print(f"Received message from local server: {json_str}")
78-
logger.debug(
79-
f"Session {self.session_id} - sending to SignalR: {json_str[:100]}..."
80-
)
81-
await signalr_client.send(
82-
"OnMessageReceived", [json_str]
83-
)
74+
await self.send_outgoing_message(message)
8475
finally:
8576
# Cancel the consumer when we exit the loop
8677
consumer_task.cancel()
@@ -159,22 +150,34 @@ async def send_message(self, message: types.JSONRPCMessage) -> None:
159150
await self._message_queue.put(message)
160151
logger.debug(f"Session {self.session_id} - message queued for processing")
161152

162-
async def get_messages(self) -> None:
153+
async def get_incoming_messages(self) -> None:
163154
"""Get new messages from UiPath MCP Server."""
164-
uipath = UiPath()
165-
response = uipath.api_client.request(
155+
response = self._uipath.api_client.request(
166156
"GET",
167-
f"mcp_/mcp/{self.server_config.name}/messages?sessionId={self.session_id}",
157+
f"mcp_/mcp/{self.server_config.name}/in/messages?sessionId={self.session_id}",
168158
)
169159
if response.status_code == 200:
170160
messages = response.json()
171-
logger.info(f"Get messages from UiPath MCP Server: {type(messages)} {messages}")
172161
for message in messages:
173-
logger.info(f"Get message from UiPath MCP Server: {type(message)} {message}")
162+
logger.info(f"Incoming message from UiPath MCP Server: {message}")
174163
json_message = types.JSONRPCMessage.model_validate(message)
175164
logger.info(f"Forwarding message to local MCP Server: {message}")
176165
await self.send_message(json_message)
177166

167+
async def send_outgoing_message(self, message: types.JSONRPCMessage) -> None:
168+
"""Send new message to UiPath MCP Server."""
169+
response = self._uipath.api_client.request(
170+
"POST",
171+
f"mcp_/mcp/{self.server_config.name}/out/message?sessionId={self.session_id}",
172+
json=message,
173+
)
174+
if response.status_code == 202:
175+
logger.info(f"Outgoing message sent to UiPath MCP Server: {message}")
176+
else:
177+
logger.error(
178+
f"Failed to send outgoing message to UiPath MCP Server: {response.status_code} {response.text}"
179+
)
180+
178181
async def cleanup(self) -> None:
179182
"""Clean up resources and stop the server."""
180183
logger.info(f"Cleaning up session {self.session_id}")

0 commit comments

Comments
 (0)