Skip to content
Draft
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
40 changes: 40 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copilot Instructions for Review

Purpose:
- Always use `**get_httpx_client_kwargs()` when creating `httpx.Client` or `httpx.AsyncClient` to ensure correct SSL, proxy, timeouts, and redirects.

Guidance for Copilot:
- When suggesting `httpx.Client(` or `httpx.AsyncClient(`, include `**get_httpx_client_kwargs()`.
- If the user omits it, suggest the corrected version or insert a warning comment.

Preferred patterns:
```python
import httpx
from uipath._utils._ssl_context import get_httpx_client_kwargs

client = httpx.Client(**get_httpx_client_kwargs())
async_client = httpx.AsyncClient(**get_httpx_client_kwargs())

default_client_kwargs = get_httpx_client_kwargs()
client_kwargs = {
**default_client_kwargs,
"base_url": base_url,
"headers": my_headers,
}
client = httpx.Client(**client_kwargs)
async_client = httpx.AsyncClient(**client_kwargs)
```

Anti-patterns (avoid):
```python
client = httpx.Client() # ❌ Missing **get_httpx_client_kwargs()
async_client = httpx.AsyncClient() # ❌ Missing **get_httpx_client_kwargs()
```

Warning to insert if correction isn’t applied:
```python
# WARNING: Use httpx.Client/AsyncClient with **get_httpx_client_kwargs() for proper SSL/proxy configuration.
```

Reference:
- [get_httpx_client_kwargs](https://github.com/UiPath/uipath-python/blob/main/src/uipath/_utils/_ssl_context.py#L37)
3 changes: 3 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ jobs:

- name: Check formatting
run: uv run ruff format --check .

- name: Check httpx.Client() usage
run: uv run python scripts/lint_httpx_client.py
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ dependencies = [
"openinference-instrumentation-langchain>=0.1.56",
"jsonschema-pydantic-converter>=0.1.5",
"jsonpath-ng>=1.7.0",
"mcp>=1.24.0",
"langchain-mcp-adapters>=0.2.1",
]

classifiers = [
Expand Down
2 changes: 2 additions & 0 deletions samples/simple-remote-mcp-agent/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
UIPATH_MCP_SERVER_URL=***
ANTHROPIC_API_KEY=***
21 changes: 21 additions & 0 deletions samples/simple-remote-mcp-agent/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Agent Code Patterns Reference

This document provides practical code patterns for building UiPath coded agents using the UiPath Python SDK.

---

## Documentation Structure

This documentation is split into multiple files for efficient context loading. Load only the files you need:

1. **@.agent/REQUIRED_STRUCTURE.md** - Agent structure patterns and templates
- **When to load:** Creating a new agent or understanding required patterns
- **Contains:** Required Pydantic models (Input, Output), SDK initialization patterns, standard agent template

2. **@.agent/SDK_REFERENCE.md** - Complete SDK API reference
- **When to load:** Calling UiPath SDK methods, working with services (actions, assets, jobs, etc.)
- **Contains:** All SDK services and methods with full signatures and type annotations

3. **@.agent/CLI_REFERENCE.md** - CLI commands documentation
- **When to load:** Working with `uipath init`, `uipath run`, or `uipath eval` commands
- **Contains:** Command syntax, options, usage examples, and workflows
1 change: 1 addition & 0 deletions samples/simple-remote-mcp-agent/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
71 changes: 71 additions & 0 deletions samples/simple-remote-mcp-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# LangGraph Agent with Claude and Tool MCP Servers

This project demonstrates how to create an agent using LangGraph react agent which connects to a Remote MCP Server hosted in UiPath.

## Overview

The agent uses:
- LangGraph for orchestration
- Connects to a Remote MCP server

## Architecture

```mermaid
---
config:
flowchart:
curve: linear
---
graph TD;
__start__([<p>__start__</p>]):::first
agent(agent)
tools(tools)
__end__([<p>__end__</p>]):::last
__start__ --> agent;
tools --> agent;
agent -.-> tools;
agent -.-> __end__;
classDef default fill:#f2f0ff,line-height:1.2
classDef first fill-opacity:0
classDef last fill:#bfb6fc
```

The workflow follows a ReAct pattern:
1. Query is sent to the agent (Claude)
2. Agent decides whether to use tools or provide a final answer
3. If tools are needed, the request is sent to the remote MCP server
4. Results from tools are sent back to the agent
5. Process repeats until the agent has enough information to provide a final answer

## Prerequisites

- Python 3.11+
- `langchain-anthropic`
- `langchain-mcp-adapters`
- `langgraph`
- Anthropic API key set as an environment variable

## Installation

```bash
uv venv -p 3.11 .venv
.venv\Scripts\activate
uv sync
```

Set your API keys and MCP Remote Server URL as environment variables in .env

```bash
ANTHROPIC_API_KEY=your_anthropic_api_key
```

## Debugging

For debugging issues:

1. Check logs for any connection or runtime errors:
```bash
uipath run agent --debug '{"messages": [{"type": "human", "content": "What is 2+2"}]}'
```


4 changes: 4 additions & 0 deletions samples/simple-remote-mcp-agent/bindings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"version": "2.0",
"resources": []
}
5 changes: 5 additions & 0 deletions samples/simple-remote-mcp-agent/entry-points.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://cloud.uipath.com/draft/2024-12/entry-point",
"$id": "entry-points.json",
"entryPoints": []
}
117 changes: 117 additions & 0 deletions samples/simple-remote-mcp-agent/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
from contextlib import asynccontextmanager
from datetime import datetime, timezone
from typing import Sequence

from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from uipath.agent.models.agent import AgentMcpResourceConfig, AgentMcpTool
from uipath.agent.react import AGENT_SYSTEM_PROMPT_TEMPLATE

from uipath_langchain.agent.react import create_agent
from uipath_langchain.agent.tools import create_mcp_tools
from uipath_langchain.chat import OpenAIModels, UiPathChat

# LLM Model Configuration
llm = UiPathChat(
model=OpenAIModels.gpt_5_mini_2025_08_07,
temperature=0.0,
max_tokens=16384,
)


# Input/Output Models
class AgentInput(BaseModel):
pass


class AgentOutput(BaseModel):
content: str | None = Field(None, description="Output content")


# Agent Messages Function
def create_messages(state: AgentInput) -> Sequence[SystemMessage | HumanMessage]:
# Apply system prompt template
current_date = datetime.now(timezone.utc).strftime("%Y-%m-%d")
system_prompt_content = f"""You are an agentic assistant."""
enhanced_system_prompt = (
AGENT_SYSTEM_PROMPT_TEMPLATE.replace("{{systemPrompt}}", system_prompt_content)
.replace("{{currentDate}}", current_date)
.replace("{{agentName}}", "Mr Assistant")
)

return [
SystemMessage(content=enhanced_system_prompt),
HumanMessage(content=f"""Do me an RPA echo of "asdf"."""),
]


mcpTools = [
AgentMcpResourceConfig(
name="uipath-server",
description="a",
folderPath="611ca479-1f38-4abc-b2c6-6a61fa002978",
slug="uipath-server",
availableTools=[],
isEnabled=True,
),
AgentMcpResourceConfig(
name="uipath-server-2",
description="a",
folderPath="611ca479-1f38-4abc-b2c6-6a61fa002978",
slug="uipath-server-2",
availableTools=[],
isEnabled=True,
),
AgentMcpResourceConfig(
name="hello-world",
description="a",
folderPath="611ca479-1f38-4abc-b2c6-6a61fa002978",
slug="hello-world",
availableTools=[],
isEnabled=True,
),
AgentMcpResourceConfig(
name="mcp-hello-world-24-25",
description="a",
folderPath="611ca479-1f38-4abc-b2c6-6a61fa002978",
slug="mcp-hello-world-24-25",
availableTools=[
AgentMcpTool(
name="add",
description="""
Add two numbers together.
Args:
a: First number
b: Second number

Returns:
Sum of a and b
""",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "title": "A"},
"b": {"type": "number", "title": "B"},
},
"required": ["a", "b"],
},
)
],
isEnabled=True,
),
]

all_tools: list[BaseTool] = []


@asynccontextmanager
async def make_graph():
async with create_mcp_tools(mcpTools) as tools:
yield create_agent(
model=llm,
tools=tools + all_tools,
messages=create_messages,
input_schema=AgentInput,
output_schema=AgentOutput,
)
24 changes: 24 additions & 0 deletions samples/simple-remote-mcp-agent/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[project]
name = "simple-remote-mcp-agent"
version = "0.0.1"
description = "simple-remote-mcp-agent"
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]
dependencies = [
"langchain>=1.1.0",
"langchain-anthropic>=1.2.0",
"langgraph>=1.0.4",
"python-dotenv>=1.0.0",
"anthropic>=0.57.1",
"langchain-mcp-adapters>=0.1.14",
"uipath>=2.2.0, <2.3.0",
"uipath-langchain>=0.1.30",
]
requires-python = ">=3.11"

[tool.setuptools]
py-modules = []

[dependency-groups]
dev = [
"uipath-dev>=0.0.5",
]
14 changes: 14 additions & 0 deletions samples/simple-remote-mcp-agent/uipath.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://cloud.uipath.com/draft/2024-12/uipath",
"runtimeOptions": {
"isConversational": false
},
"packOptions": {
"fileExtensionsIncluded": [],
"filesIncluded": [],
"filesExcluded": [],
"directoriesExcluded": [],
"includeUvLock": true
},
"functions": {}
}
Loading