Build a company policy chat agent with UiPath MCP Server & LangChain

Share at:

Company policy chat agent

Keep the policies, lose the hassle

Let’s be honest—company policies matter, and they’re not going anywhere.

But the reality is that common questions like “What’s the standard laptop I can have?”, “How do I expense $10 of API calls?”, or “Does this type of software use comply with company rules?” often feel complex, frustrating, and time-consuming—creating friction rather than flow.

A dedicated, contextualized, secured agent such that employees can ask and act on the company policy can fix that. Let’s how that experience would look like and how one can implement it within UiPath.

UiPath MCP server + LangChain ask and act on company policy via chat agent

Build a policy agent for your company

This one is super simple, and it almost feels like a shame not to implement it. As in a recipe, the main ingredients you need are:

  1. Your company policy text file

  2. LangChain company policy agent

  3. UiPath MCP Server

  4. Claude Desktop (or similar)

  5. (Optional) API Workflow for sending e-mails

MCP

Let’s take it step by step.

Company policy text

Write the company policies you want the Agent to be aware of and save them in a plain txt file (e.g., company_policy.txt). Fictional policy extract below:

Paid Time Off (PTO): • PTO requests for less than 5 days require at least 1 day advance notice. • PTO requests for 5 days or more require at least 5 days advance notice. • Employees are encouraged to plan their PTO in advance to ensure adequate coverage and minimal disruption to team operations. • All PTO requests must be submitted via email to the employee’s manager • For absences of 5 days or more, the PTO request email must also include: • A designated point of contact or persona who will take ownership of key responsibilities or hand off critical work during the employee’s absence.

Create context grounding index from the policy text

In your UiPath platform account, in Orchestrator create a new Storage Bucket and upload the company_policy.txt file to it

MCP 1
MCP

With this, one can create a context grounding index based on the company_policy.txtby using Storage Bucket as data source.

MCP

Build and deploy the company policy agent to UiPath

The Coded Agent is built with the LangGraph framework and has a single node called policythat based on the user ask and company policy composes response via an LLM call

MCP 1

# Build the state graph builder = StateGraph(GraphInput, output=GraphOutput) builder.add_node("policy", policy_node) builder.add_edge(START, "policy") builder.add_edge("policy", END)

# Compile the graph graph = builder.compile()

Specifically, it:

  • Ingests the company policy context via a UiPath SDK ContextGroundingRetrievercall (getcontextdata_async in Annexes)

async def policy_node(state: GraphInput) -> GraphOutput: retriever = ContextGroundingRetriever( index_name="company-policy-index", number_of_results=100, ) try: context_data= await get_context_data_async(retriever, state.question) except IndexNotFound: context_data = system_prompt

  • And feeds the systemprompt, userquestion and companypolicycontextto an LLM call.

llm = UiPathAzureChatOpenAI(model="gpt-4o-2024-08-06")

system_prompt = """You are an advanced AI assistant specializing in answering questions about <> internal company policies...."""

### messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": state.question}, {"role":"user", "content": context_data[0].page_content}] ### result = await llm.ainvoke(messages)

After building the Coded Agents one should:

MCP
MCP
MCP
  • Add a Process in Orchestrator and set the environment configuration

Expose the policy agent via UiPath MCP Server

Build a UiPath MCP Server directly in the UiPath platform by adding the company-policy agent as a tool and specifying a proper agent description. Once the UiPath MCP Server is built, copy the URL to be configured with the Claude Desktop app.

MCP

Setup and use Claude Desktop app

To grant secured access to the company policy one can configure Claude Desktop app to point to the UiPath MCP Server that exposes the companypolicyagent as a tool.

Get a personal access token (PAT)

To generate a Personal Access Token (PAT) In UiPath Orchestrator go to User → Preferences → Personal Access Token.

MCP

Set the Name and Expiration date and add as scope the Orchestrator API Access (All).

MCP
MCP

Copy the PAT it will be used to configure Claude Desktop app.

Setup Claude Desktop

If not already available, download and install the Claude Desktop app. In the app Settings go to Developer-> Edit Config.

MCP

This will open the claudedesktopconfig.jsonwhere the list of MCP Servers is defined. Example:

"CompanyPolicy": { "command": "npx", "args": [ "-y", "mcp-remote", "https:< UiPath MCP Server URL>", "--header", "Authorization:${AUTH_HEADER}" ], "env": { "AUTH_HEADER": "Bearer <YOUR Personal Access Token>" } }

MCP

Restart Claude Desktop to load the MCP configuration. The tools exposed by the MCP Server should be available and used whenever a related prompt like “I need to buy 10$ worth of API calls from OpenAI, what should I do per my company policy?“ is given.

MCP

Annexes

Coded agent source code:

from langchain_anthropic import ChatAnthropic from langgraph.graph import END, START, MessagesState, StateGraph from langgraph.prebuilt import create_react_agent from pydantic import BaseModel from uipath_langchain.retrievers import ContextGroundingRetriever from langchain_core.documents import Document from uipath.models import InvokeProcess, IngestionInProgressException import httpx from uipath_langchain.chat.models import UiPathAzureChatOpenAI from langchain_openai import ChatOpenAI

class IndexNotFound(Exception): pass

# Define system prompt for company policy agent system_prompt = """You are an advanced AI assistant specializing in answering questions about <> internal company policies... """

llm = ChatOpenAI( model="gpt-4o", temperature=0, max_tokens=4000, timeout=30, max_retries=2, )

class GraphInput(BaseModel): """Input for the company policy agent graph.""" question: str

class GraphOutput(BaseModel): """Output for the company policy agent graph.""" response: str

async def get_context_data_async(retriever: ContextGroundingRetriever, question: str) -> list[Document]: no_of_retries = 5 context_data = None data_queried = False while no_of_retries != 0: try: context_data = await retriever.ainvoke(question) data_queried = True break except IngestionInProgressException as ex: logger.info(ex.message) no_of_retries -= 1 logger.info(f"{no_of_retries} retries left") time.sleep(5) except httpx.HTTPStatusError as err: if err.response.status_code == 404: raise IndexNotFound raise if not data_queried: raise Exception("Ingestion is taking too long.") return context_data

async def policy_node(state: GraphInput) -> GraphOutput: retriever = ContextGroundingRetriever( index_name="company-policy-index", number_of_results=100, ) try: context_data= await get_context_data_async(retriever, state.question) except IndexNotFound: context_data = system_prompt

messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": state.question}, {"role":"user", "content": context_data[0].page_content} ]

"""Process a company policy question and return a structured answer.""" user_message = f"""Please answer the following company policy question. Use clear section headers for each relevant policy area (Procurement Policy, Equipment Acquisition, PTO Policy). If the question is outside these topics, politely state your scope.\n\nQuestion: {state.question}""" result = await llm.ainvoke(messages) return GraphOutput(response=result.content)

# Build the state graph builder = StateGraph(GraphInput, output=GraphOutput) builder.add_node("policy", policy_node) builder.add_edge(START, "policy") builder.add_edge("policy", END)

# Compile the graph graph = builder.compile()

Eusebiu Jecan
Eusebiu Jecan

Principal Product Manager, UiPath

Get articles from automation experts in your inbox

Subscribe
Get articles from automation experts in your inbox

Sign up today and we'll email you the newest articles every week.

Thank you for subscribing!

Thank you for subscribing! Each week, we'll send the best automation blog posts straight to your inbox.

Ask AI about...Ask AI...