はじめに
- 本記事ではMCP(Model Context Protocol)クライアントからRPA自動化処理を実行する方法について説明します。
- プロンプトからの自動化ワークフロー実行は既に UiPath Autopilot for Everyone でも実現可能ですが、呼び出し元クライアントはUiPath Assistantが前提になっています。今回解説する連携手順では任意のMCPクライアントからの呼び出しが可能となります。
実際のデモ動画です。
- UiPathが提供するRPA実行環境には Attendedロボット(有人オートメーション) とUnattendedロボット(無人オートメーション) の2種類がありますが、今回はAttendedロボット実行の基本部分について解説したいと思います。
2025年4月現在 UiPath社からは公式にMCP連携するためのソリューションは提供されておりません。本記事ではカスタムのPythonスクリプトで連携を実装しております。もし将来公式なソリューションが提供されましたら、そちらに切り替えを行ってください。
MCP x RPA概要
MCPとは
MCPとは大規模言語モデル(LLM)と外部ツール間のシームレスな連携を可能にする標準化されたインターフェースです。詳細については先駆者の皆さんの分かりやすい記事がいくつかありますのでそちらをご参照いただければと思います。
既にさまざまな製品の連携がMCPによって実装されています。まとめサイトの一例を紹介します。
MCPにおける現状の課題
現在のMCPにはどのような課題があるでしょうか。筆者の個人的な見解を述べさせていただきます。
- 連携するMCPサーバー不足と仕様変更への懸念
- 主要なサービスは既にMCPサーバーが提供されていますが、必ずしもすべて外部システムとMCPで連携できるわけではありません。
- またMCPはまだ発展途上のプロトコルであればため今後企業で安定的に利用できるか、仕様変更によって互換性が維持されるか、については未知数です。
- セキュリティ・ガバナンス機能の欠如
- 外部ツールと連携するためにはアクセス権付与やAPIキーなどの受け渡しが必要となります。更に企業で利用するためには「いつ・誰が・どのようなデータを・どのシステムに連携したか」トレースするためのガバナンス機能も不可欠です。
- 現状のMCPでは開発者がセキュリティキーの安全な保存や監査の機能を考慮して個別に実装する必要があると考えられます。
UiPath連携のメリット
UiPathが提供するオート―メーション基盤では多くのエンタープライズ企業で導入実績があります。
- アクティビティと呼ばれるシステム連携するための部品が数多く提供されております。Integration Service によってAPI連携するための認証を一元管理するためのサービスが利用可能です。更にAPIを持たないWebシステムやWindowsアプリケーションのGUI操作も可能であるため、自動化できないシステムはほとんどありません。これによってMCPサーバーが提供されていない外部システムとの連携も可能になりますし、複数のシステムを跨ったデータの受け渡しもローコードで容易に実装できます。
- UiPathにはガバナンスのための 監査機能 も標準装備しています。このためMCPクライアントからRPAがコールされた場合にも、実行履歴がすべて保存されますので管理者が利用状況を一元的に把握することが可能になります。
RPA連携実装方法
次にMCPとRPA連携の実装方法について4つのステップで解説してゆきます。
実行環境
- Windows 10/11
- UiPath Studio 2024.10以降
- Python 3.11以降
- Claude Desktop
- 開発者モード有効化: Claude for Desktopを起動し、画面左上の「≡」 >「ヘルプ」>「開発者モードを有効」を選択
概要
まず連携方法の概要を説明します。次の3つのパートでそれぞれ実装します。
パート | 実装作業 |
---|---|
外部ツール | UiPath StudioにてRPAワークフローで自動化処理を実装し、UiPath Robotにデプロイ |
MCPサーバー | 1. RPA自動化処理(プロセス)ごとに @mcp.tool() としてPythonの関数を定義2. Python関数内ではプロンプトから自動抽出された引数を受け取り、UiPath Robotをプロセス名と引数を渡して実行できるように実装 3. プロンプト実行時にLLMが適切なPython関数を選択して実行し、結果を表示 |
MCPクライアント | 1. Claude DesktopのconfigファイルにてMCPサーバーを設定 2. プロンプト実行により適切なツール(Python関数)がコールされ、RPA実行できることを確認する |
ステップ1 ~ Hello World連携
まずは最も簡単なケースから始めてみましょう。
RPAワークフロー作成
-
RPA連携するための簡単なワークフローを作成します。UiPath StudioにてWindowsプロジェクトにて、"Hello UiPath!"というメッセージボックスを表示するだけのワークフロー(
hello_uipath
)を作成し、パブリッシュします。- Orchestratorに接続している場合はプロセスとしてデプロイします。
- Orchestratorに接続していない場合は
C:\ProgramData\UiPath\Packages
にパッケージを配置します。
-
UiPath Assistantから
hello_uipath
が実行できることを確認します。 -
コマンドラインでプロセス実行する には
UiRobot.exe execute
を使用します。 -
コマンドプロンプトにて次のコマンドで hello_uipath が実行できることを確認します。
"C:\Program Files\UiPath\Studio\UiRobot.exe" execute --process hello_uipath
MCPサーバーの準備
次にMCPサーバー(stdio)の実行環境を準備します。MCPクイックスタートを参考にします。
-
uv
をインストールします。powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
-
新しいPowerShellコンソールにて作業ディレクトリ(今回は
C:\mcp
) を作成・移動し、uvプロジェクトを作成します。mkdir C:\mcp cd C:\mcp uv init uipath_attended cd uipath_attended uv venv .venv\Scripts\activate uv add mcp[cli] New-Item exec_uipath_attended.py
-
exec_uipath_attended.py
には次の内容を記述します。import asyncio from mcp.server.fastmcp import FastMCP # FastMCP初期化 mcp = FastMCP("execute_hello_uipath") @mcp.tool() async def execute_hello_uipath() -> str: """ hello_uipathプロセスを実行する関数 """ # UiPath Robot実行パス定義 UIPATH_EXECUTABLE = r"C:\Program Files\UiPath\Studio\UiRobot.exe" try: # Windowsサブプロセス非同期起動 process = await asyncio.create_subprocess_exec( UIPATH_EXECUTABLE, "execute", "--process", "hello_uipath" ) # リターンコード取得 if process.returncode == 0: print("Process completed successfully.") else: print(f"Error occurred (code {process.returncode})") except Exception as e: # 例外出力 print(f"Failed to execute UiPath process: {type(e).__name__} - {str(e)}") if __name__ == "__main__": # FastMCP実行 mcp.run(transport='stdio')
MCPクライアント設定
- MCPクライアントの設定を行います。Claude Desktopの設定ファイル(
%AppData%\Claude\claude_desktop_config.json
)を開きます。存在しない場合は新規作成します。次のように設定します。{ "mcpServers": { "uipath_attended": { "command": "uv", "args": [ "--directory", "C:\\mcp\\uipath_attended", "run", "exec_uipath_attended.py" ] } } }
MCP x RPA連携実行
-
Claude Desktopを起動し、トンカチアイコンに
execute_hello_uipath
が表示されることを確認します。表示されない場合やエラーメッセージが表示される場合には%AppData%\Claude\logs
配下のログファイルを確認します。
-
hello_uipathを実行して とプロンプト入力して
hello_uipath
プロセスを実行してみましょう。途中ツール実行の許可を求めるダイアログが表示されますので「このチャットで許可をする」をクリックします。
ステップ2 ~ 入力引数の受け渡し
次に入力引数を受け渡ししてみましょう。
RPAワークフローの修正
- Studioにてhello_uipathのワークフローを次のように改修します。
MCPサーバーの修正
-
MCPサーバーのスクリプト
exec_uipath_attended.py
を下記のように修正します。import asyncio import json from mcp.server.fastmcp import FastMCP # FastMCP初期化 mcp = FastMCP("execute_hello_uipath") @mcp.tool() async def execute_hello_uipath(input: str) -> str: """ hello_uipathプロセスを実行する関数 Args: input: UiPathプロセスに渡す入力文字列 Returns: プロセスの実行結果 """ # UiPath Robot実行パス定義 UIPATH_EXECUTABLE = r"C:\Program Files\UiPath\Studio\UiRobot.exe" try: # 入力パラメータをJSON形式で構築 input_json = json.dumps({"input": input}) # Windowsサブプロセス非同期起動 process = await asyncio.create_subprocess_exec( UIPATH_EXECUTABLE, "execute", "--process", "hello_uipath", "--input", input_json ) # リターンコード取得 if process.returncode == 0: print("Process completed successfully.") else: print(f"Error occurred (code {process.returncode})") except Exception as e: # 例外出力 print(f"Failed to execute UiPath process: {type(e).__name__} - {str(e)}") if __name__ == "__main__": # FastMCP実行 mcp.run(transport='stdio')
MCPクライアントからの実行
次に入力引数が正常に渡されるか確認してみましょう。
-
更新を反映させるためにClaude Desktopを再起動します。
-
hello_uipathに"UiPath Robot"を渡して実行して とプロンプト入力します。
-
"Hello UiPath Robot!" とポップアップメッセージが表示されれば成功です!
- このケースではLLMが"UiPath Robot"を
input
入力引数として抽出し、Pythonのexecute_hello_uipath
関数に渡しています。 - 更にUiRobot.exeコマンドライン実行時に --input パラメーターにJSON形式で
{"input":"UiPath Robot"}
を渡して実行することによって入力引数の受け渡しを実現しています。
- このケースではLLMが"UiPath Robot"を
ステップ3 ~ 複数プロセス登録と出力引数
次のステップとして複数のプロセスを実行できるようにします。また出力引数の受け取りも実装してみましょう。
RPAワークフローの作成
-
RPAチャレンジ を実行するためのワークフローを作成します。
- 入力引数
browser
を渡し、指定ブラウザーにてRPAチャレンジを実行するように実装します。 - 実行結果を出力引数として受け取ります。
- 入力引数
MCPサーバーの修正
-
Pythonコードに次のように変更し関数
execute_rpa_challenge
を追加します。UiPathプロセス名はrpa_challenge
とします。import asyncio import json from mcp.server.fastmcp import FastMCP # FastMCP初期化 mcp = FastMCP("execute_hello_uipath") @mcp.tool() async def execute_hello_uipath(input: str) -> str: """ hello_uipathプロセスを実行する関数 Args: input: UiPathプロセスに渡す入力文字列 Returns: プロセスの実行結果 """ # UiPath Robot実行パス定義 UIPATH_EXECUTABLE = r"C:\Program Files\UiPath\Studio\UiRobot.exe" try: # 入力パラメータをJSON形式で構築 input_json = json.dumps({"input": input}) # Windowsサブプロセス非同期起動 process = await asyncio.create_subprocess_exec( UIPATH_EXECUTABLE, "execute", "--process", "hello_uipath", "--input", input_json ) # リターンコード取得 if process.returncode == 0: print("Process completed successfully.") else: print(f"Error occurred (code {process.returncode})") except Exception as e: # 例外出力 print(f"Failed to execute UiPath process: {type(e).__name__} - {str(e)}") @mcp.tool() async def execute_rpa_challenge(browser: str) -> str: """ RPAチャレンジを実行する関数 Args: input: ブラウザーの種類 Returns: プロセスの実行結果 """ # UiPath Robot実行パス定義 UIPATH_EXECUTABLE = r"C:\Program Files\UiPath\Studio\UiRobot.exe" try: # 入力パラメータをJSON形式で構築 input_json = json.dumps({"browser": browser}) # Windowsサブプロセス非同期起動 process = await asyncio.create_subprocess_exec( UIPATH_EXECUTABLE, "execute", "--process", "rpa_challenge", "--input", input_json, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) # 標準出力と標準エラーを取得 stdout, stderr = await process.communicate() # 日本語Windows環境で一般的なエンコーディング encoding = 'cp932' if process.returncode == 0: output = stdout.decode(encoding).strip() return output or "Process completed successfully." else: error_msg = stderr.decode(encoding).strip() return f"Error occurred (code {process.returncode}): {error_msg}" except Exception as e: # 例外出力 return f"Failed to execute UiPath process: {type(e).__name__} - {str(e)}" if __name__ == "__main__": # FastMCP実行 mcp.run(transport='stdio')
-
EdgeでRPAチャレンジを実行して結果を表示して とプロンプト入力すると
execute_rpa_challenge
関数→rpa_challenge
プロセスが実行され、結果が表示されることを確認します。
ステップ4 ~ コードの共通化と一般化
-
このままでも動作はしますが、Pythonコード全体を眺めてみると重複したコードが存在することに気が付くと思います。これらを共通化したコードを最後に掲載しておきますので、動作確認をしてみてください。
-
また日本語エンコーディング
cp932
もOSより取得し、日本語以外の環境でも動作するように修正しています。import asyncio import json from typing import Dict, Any, Optional from mcp.server.fastmcp import FastMCP import locale # UiPath Robot実行パス定義 UIPATH_EXECUTABLE = r"C:\Program Files\UiPath\Studio\UiRobot.exe" # Systemよりエンコーディング取得 SYSTEM_ENCODING = locale.getpreferredencoding() # FastMCP初期化 mcp = FastMCP("execute_hello_uipath") async def execute_uipath_process(process_name: str, arg_name: str, input_data: str) -> str: """ UiPathプロセスを実行する共通関数 Args: process_name: 実行するUiPathプロセス名 input_data: UiPathプロセスに渡す入力文字列 Returns: プロセスの実行結果 """ try: # 入力パラメータをJSON形式で構築 input_json = json.dumps({arg_name: input_data}) # Windowsサブプロセス非同期起動 process = await asyncio.create_subprocess_exec( UIPATH_EXECUTABLE, "execute", "--process", process_name, "--input", input_json, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) # 標準出力と標準エラーを取得 stdout, stderr = await process.communicate() if process.returncode == 0: output = stdout.decode(SYSTEM_ENCODING).strip() return output or "Process completed successfully." else: error_msg = stderr.decode(SYSTEM_ENCODING).strip() return f"Error occurred (code {process.returncode}): {error_msg}" except Exception as e: # 例外出力 return f"Failed to execute UiPath process: {type(e).__name__} - {str(e)}" @mcp.tool() async def execute_hello_uipath(input: str) -> str: """ hello_uipathプロセスを実行する関数 Args: input: UiPathプロセスに渡す入力文字列 Returns: プロセスの実行結果 """ return await execute_uipath_process("hello_uipath", "input", input) @mcp.tool() async def execute_rpa_challenge(browser: str) -> str: """ RPAチャレンジを実行する関数 Args: browser: ブラウザーの種類 Returns: プロセスの実行結果 """ return await execute_uipath_process("rpa_challenge", "browser", browser) if __name__ == "__main__": # FastMCP実行 mcp.run(transport='stdio')
-
プロセス実行のロジックを共通化することによって、比較的容易にプロセスを追加できるようになりました。余力がありましたら、皆さんが普段お使いのプロセスを関数として追加登録してみてください。
今後に向けて
ここまででUiPathプロセスをMCPクライアントから実行でき、入力引数(1つ)・出力引数の受け渡しが可能であることが分かりました。プロセスも複数登録できることが分かりました。しかしながら次の課題があります。
- 2つ以上の引数をどのように受け渡しすれば良いか?
- プロセスを自動的に登録できないか?UiPath Orchestratorではプロセスの一元管理ができるので、そこから一覧を出力できないか?
長くなりましたのでこれらについては別記事にて解説したいと思います。
最後までお読みいただき有難うございました!