Skip to content

Commit b6dfbd2

Browse files
authored
Merge pull request #1015 from UiPath/feat/mcp_config_schema
feat(mcp_config_schema): add outputschema property
2 parents 4b3d1f3 + 31e8ee2 commit b6dfbd2

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

src/uipath/agent/models/agent.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ class AgentMcpTool(BaseCfg):
189189
name: str = Field(..., alias="name")
190190
description: str = Field(..., alias="description")
191191
input_schema: Dict[str, Any] = Field(..., alias="inputSchema")
192+
output_schema: Optional[Dict[str, Any]] = Field(None, alias="outputSchema")
192193

193194

194195
class AgentMcpResourceConfig(BaseAgentResourceConfig):

tests/agent/models/test_agent.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ def test_agent_with_all_tool_types_loads(self):
434434
assert len(mcp_resource.available_tools) == 2
435435
assert mcp_resource.available_tools[0].name == "get_current_time"
436436
assert mcp_resource.available_tools[1].name == "convert_time"
437+
# Validate that outputSchema is None when not provided in JSON
438+
assert mcp_resource.available_tools[0].output_schema is None
439+
assert mcp_resource.available_tools[1].output_schema is None
437440

438441
# Validate escalation resource with detailed properties
439442
escalation_resource = next(
@@ -1767,3 +1770,112 @@ def test_agent_with_mixed_known_and_unknown_types(self):
17671770
assert (
17681771
config.guardrails[2].action.action_type == AgentGuardrailActionType.UNKNOWN
17691772
)
1773+
1774+
def test_mcp_resource_with_output_schema(self):
1775+
"""Test that AgentDefinition can load MCP resources with outputSchema in tools"""
1776+
1777+
json_data = {
1778+
"version": "1.0.0",
1779+
"id": "test-mcp-output-schema",
1780+
"name": "Agent with MCP Output Schema",
1781+
"metadata": {"isConversational": False, "storageVersion": "36.0.0"},
1782+
"messages": [
1783+
{"role": "System", "content": "You are an agentic assistant."}
1784+
],
1785+
"inputSchema": {"type": "object", "properties": {}},
1786+
"outputSchema": {"type": "object", "properties": {}},
1787+
"settings": {
1788+
"model": "gpt-4o-2024-11-20",
1789+
"maxTokens": 16384,
1790+
"temperature": 0,
1791+
"engine": "basic-v2",
1792+
},
1793+
"resources": [
1794+
{
1795+
"$resourceType": "mcp",
1796+
"folderPath": "solution_folder",
1797+
"slug": "tavily-mcp",
1798+
"availableTools": [
1799+
{
1800+
"name": "tavily-search",
1801+
"description": "Search the web using Tavily API",
1802+
"inputSchema": {
1803+
"type": "object",
1804+
"properties": {
1805+
"query": {
1806+
"type": "string",
1807+
"description": "Search query",
1808+
}
1809+
},
1810+
"required": ["query"],
1811+
},
1812+
"outputSchema": {
1813+
"type": "object",
1814+
"properties": {
1815+
"results": {
1816+
"type": "array",
1817+
"description": "Search results",
1818+
}
1819+
},
1820+
"required": ["results"],
1821+
},
1822+
},
1823+
{
1824+
"name": "tavily-extract",
1825+
"description": "Extract content from URLs",
1826+
"inputSchema": {
1827+
"type": "object",
1828+
"properties": {
1829+
"urls": {
1830+
"type": "array",
1831+
"description": "URLs to extract",
1832+
}
1833+
},
1834+
"required": ["urls"],
1835+
},
1836+
"outputSchema": {
1837+
"type": "object",
1838+
"properties": {"content": {"type": "string"}},
1839+
},
1840+
},
1841+
],
1842+
"name": "tavily",
1843+
"description": "Tavily search and extraction tools",
1844+
"isEnabled": True,
1845+
}
1846+
],
1847+
"features": [],
1848+
"guardrails": [],
1849+
}
1850+
1851+
config: AgentDefinition = TypeAdapter(AgentDefinition).validate_python(
1852+
json_data
1853+
)
1854+
1855+
# Validate MCP resource with outputSchema
1856+
mcp_resources = [
1857+
r for r in config.resources if r.resource_type == AgentResourceType.MCP
1858+
]
1859+
assert len(mcp_resources) == 1
1860+
mcp_resource = mcp_resources[0]
1861+
assert isinstance(mcp_resource, AgentMcpResourceConfig)
1862+
assert mcp_resource.name == "tavily"
1863+
assert mcp_resource.slug == "tavily-mcp"
1864+
assert mcp_resource.description == "Tavily search and extraction tools"
1865+
assert mcp_resource.is_enabled is True
1866+
assert len(mcp_resource.available_tools) == 2
1867+
1868+
# Validate first tool with outputSchema
1869+
tool1 = mcp_resource.available_tools[0]
1870+
assert tool1.name == "tavily-search"
1871+
assert tool1.description == "Search the web using Tavily API"
1872+
assert tool1.input_schema is not None
1873+
assert tool1.output_schema is not None
1874+
assert "results" in tool1.output_schema["properties"]
1875+
assert tool1.output_schema["required"] == ["results"]
1876+
1877+
# Validate second tool with outputSchema
1878+
tool2 = mcp_resource.available_tools[1]
1879+
assert tool2.name == "tavily-extract"
1880+
assert tool2.output_schema is not None
1881+
assert "content" in tool2.output_schema["properties"]

0 commit comments

Comments
 (0)