Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[project]
name = "uipath-mcp"
version = "0.0.103"
version = "0.0.104"
description = "UiPath MCP SDK"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
dependencies = [
"mcp==1.11.0",
"pysignalr==1.3.0",
"uipath>=2.1.54, <2.2.0",
"uipath>=2.1.108, <2.2.0",
]
classifiers = [
"Development Status :: 3 - Alpha",
Expand Down
24 changes: 19 additions & 5 deletions src/uipath_mcp/_cli/_runtime/_exception.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
from typing import Optional
from enum import Enum
from typing import Optional, Union

from uipath._cli._runtime._contracts import UiPathErrorCategory, UiPathRuntimeError
from uipath._cli._runtime._contracts import (
UiPathBaseRuntimeError,
UiPathErrorCategory,
UiPathErrorCode,
)


class UiPathMcpRuntimeError(UiPathRuntimeError):
class McpErrorCode(Enum):
CONFIGURATION_ERROR = "CONFIGURATION_ERROR"
SERVER_NOT_FOUND = "SERVER_NOT_FOUND"
REGISTRATION_ERROR = "REGISTRATION_ERROR"
INITIALIZATION_ERROR = "INITIALIZATION_ERROR"


class UiPathMcpRuntimeError(UiPathBaseRuntimeError):
"""Custom exception for MCP runtime errors with structured error information."""

def __init__(
self,
code: str,
code: Union[McpErrorCode, UiPathErrorCode],
title: str,
detail: str,
category: UiPathErrorCategory = UiPathErrorCategory.UNKNOWN,
status: Optional[int] = None,
):
super().__init__(code, title, detail, category, status, prefix="MCP")
super().__init__(
code.value, title, detail, category, status, prefix="LlamaIndex"
)
29 changes: 15 additions & 14 deletions src/uipath_mcp/_cli/_runtime/_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
from uipath._cli._runtime._contracts import (
UiPathBaseRuntime,
UiPathErrorCategory,
UiPathErrorCode,
UiPathRuntimeResult,
)
from uipath.tracing import LlmOpsHttpExporter

from .._utils._config import McpServer
from ._context import UiPathMcpRuntimeContext, UiPathServerType
from ._exception import UiPathMcpRuntimeError
from ._exception import McpErrorCode, UiPathMcpRuntimeError
from ._session import SessionServer

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -56,15 +57,15 @@ async def validate(self) -> None:
"""Validate runtime inputs and load MCP server configuration."""
if self.context.config is None:
raise UiPathMcpRuntimeError(
"CONFIGURATION_ERROR",
McpErrorCode.CONFIGURATION_ERROR,
"Missing configuration",
"Configuration is required.",
UiPathErrorCategory.SYSTEM,
)

if self.context.entrypoint is None:
raise UiPathMcpRuntimeError(
"CONFIGURATION_ERROR",
McpErrorCode.CONFIGURATION_ERROR,
"Missing entrypoint",
"Entrypoint is required.",
UiPathErrorCategory.SYSTEM,
Expand All @@ -73,7 +74,7 @@ async def validate(self) -> None:
self._server = self.context.config.get_server(self.context.entrypoint)
if not self._server:
raise UiPathMcpRuntimeError(
"SERVER_NOT_FOUND",
McpErrorCode.SERVER_NOT_FOUND,
"MCP server not found",
f"Server '{self.context.entrypoint}' not found in configuration",
UiPathErrorCategory.DEPLOYMENT,
Expand All @@ -88,31 +89,31 @@ def _validate_auth(self) -> None:
uipath_url = os.environ.get("UIPATH_URL")
if not uipath_url:
raise UiPathMcpRuntimeError(
"CONFIGURATION_ERROR",
McpErrorCode.CONFIGURATION_ERROR,
"Missing UIPATH_URL environment variable",
"Please run 'uipath auth'.",
UiPathErrorCategory.USER,
)

if not self.context.trace_context:
raise UiPathMcpRuntimeError(
"CONFIGURATION_ERROR",
McpErrorCode.CONFIGURATION_ERROR,
"Missing trace context",
"Trace context is required for SignalR connection.",
UiPathErrorCategory.SYSTEM,
)

if not self.context.trace_context.tenant_id:
raise UiPathMcpRuntimeError(
"CONFIGURATION_ERROR",
McpErrorCode.CONFIGURATION_ERROR,
"Missing tenant ID",
"Please run 'uipath auth'.",
UiPathErrorCategory.SYSTEM,
)

if not self.context.trace_context.org_id:
raise UiPathMcpRuntimeError(
"CONFIGURATION_ERROR",
McpErrorCode.CONFIGURATION_ERROR,
"Missing organization ID",
"Please run 'uipath auth'.",
UiPathErrorCategory.SYSTEM,
Expand Down Expand Up @@ -152,7 +153,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
folder_path = os.environ.get("UIPATH_FOLDER_PATH")
if not folder_path:
raise UiPathMcpRuntimeError(
"REGISTRATION_ERROR",
McpErrorCode.REGISTRATION_ERROR,
"No UIPATH_FOLDER_PATH or UIPATH_FOLDER_KEY environment variable set.",
"Please set the UIPATH_FOLDER_PATH or UIPATH_FOLDER_KEY environment variable.",
UiPathErrorCategory.USER,
Expand All @@ -162,7 +163,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
)
if not self.context.folder_key:
raise UiPathMcpRuntimeError(
"REGISTRATION_ERROR",
McpErrorCode.REGISTRATION_ERROR,
"Folder NOT FOUND. Invalid UIPATH_FOLDER_PATH environment variable.",
"Please set the UIPATH_FOLDER_PATH or UIPATH_FOLDER_KEY environment variable.",
UiPathErrorCategory.USER,
Expand Down Expand Up @@ -235,7 +236,7 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
raise
detail = f"Error: {str(e)}"
raise UiPathMcpRuntimeError(
"EXECUTION_ERROR",
UiPathErrorCode.EXECUTION_ERROR,
"MCP Runtime execution failed",
detail,
UiPathErrorCategory.USER,
Expand Down Expand Up @@ -421,7 +422,7 @@ async def _register(self) -> None:
if server_stderr_output:
error_message += f"\nServer error output:\n{server_stderr_output}"
raise UiPathMcpRuntimeError(
"INITIALIZATION_ERROR",
McpErrorCode.INITIALIZATION_ERROR,
"Server initialization failed",
error_message,
UiPathErrorCategory.DEPLOYMENT,
Expand All @@ -433,7 +434,7 @@ async def _register(self) -> None:
try:
if not tools_result:
raise UiPathMcpRuntimeError(
"INITIALIZATION_ERROR",
McpErrorCode.INITIALIZATION_ERROR,
"Server initialization failed",
"Failed to get tools list from server",
UiPathErrorCategory.DEPLOYMENT,
Expand Down Expand Up @@ -478,7 +479,7 @@ async def _register(self) -> None:
)

raise UiPathMcpRuntimeError(
"REGISTRATION_ERROR",
McpErrorCode.REGISTRATION_ERROR,
"Failed to register MCP Server",
str(e),
UiPathErrorCategory.SYSTEM,
Expand Down
Loading
Loading