Skip to main content
Glama
README.md
# Infor RPA Dev Skill

[![Infor](https://img.shields.io/badge/Infor-RPA%202026.x-0070C0?style=flat-square&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0xMiAyQzYuNDggMiAyIDYuNDggMiAxMnM0LjQ4IDEwIDEwIDEwIDEwLTQuNDggMTAtMTBTMTcuNTIgMiAxMiAyek0xMSA3aDJ2NmgtMlY3em0wIDhoMnYyaC0ydi0yeiIvPjwvc3ZnPg==)](https://www.infor.com)
[![Claude Code](https://img.shields.io/badge/Claude%20Code-Skill-6B46C1?style=flat-square)](https://claude.ai/code)
[![Platform](https://img.shields.io/badge/Platform-Windows%2011-0078D6?style=flat-square&logo=windows)](https://www.microsoft.com/windows)
[![Python](https://img.shields.io/badge/Python-3.8%2B-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org)
[![FastMCP](https://img.shields.io/badge/FastMCP-2.14.7-FF6B35?style=flat-square)](https://github.com/jlowin/fastmcp)
[![License](https://img.shields.io/badge/License-Internal-grey?style=flat-square)]()
[![Status](https://img.shields.io/badge/Status-Production%20Ready-brightgreen?style=flat-square)]()

A production-grade **Claude Code skill** for the full Infor RPA Studio 2026.x development lifecycle — understand, debug, edit, and build `.xaml` workflows and `project.json` manifests, grounded in a real installed Studio instance and a reflected 182-activity oracle.

---

## Table of Contents

- [Overview](#overview)
- [Requirements](#requirements)
- [MCP Local Setup](#mcp-local-setup)
- [Skills & Capabilities](#skills--capabilities)
- [What This Skill Covers](#what-this-skill-covers)
- [MCP Server Capabilities](#mcp-server-capabilities)
- [Project Structure](#project-structure)
- [Getting Started](#getting-started)
- [Validation Engine](#validation-engine)
- [Guardrails](#guardrails)
- [Contributing](#contributing)

---

## Overview

**infor-rpa-dev** consolidates three sources into a single authoritative skill:

| Source | Contribution |
|---|---|
| `infor-rpa-codegen` (Claude skill) | Generation patterns, Build Gate loop |
| `Kiro-Infor-RPA-Kit` | Validation linter, reference project |
| Live Studio 2026.04.1 install | DLL-reflected activity oracle, manifest boilerplate |

All activity names, namespaces, property types, API endpoints, and XAML patterns are **looked up — never guessed**. The linter enforces 25+ load traps and is calibrated to zero ERRORs on the bundled reference project.

---

## Requirements

- **OS:** Windows 10/11
- **Infor RPA Studio:** 2026.x installed under `C:\Program Files\Infor\RPA`
- **Claude Code:** Latest CLI version
- **Python:** 3.8+ on `PATH`
- **fastmcp:** `==2.14.7` (pinned — 3.x is a breaking rewrite)

```powershell
pip install "fastmcp==2.14.7"
```

> **Version lock:** Do **not** upgrade `fastmcp` beyond `2.x`. `fastmcp 3.x` dropped the `FastMCP` server class and is a different product. `mcp-atlassian` also requires `fastmcp<2.15.0`.

---

## MCP Local Setup

> ⚠️ **This repo ships with one developer's machine baked into it.** The registration examples in
> earlier versions of this README (and the `sourceFiles[].filePath` entries inside
> `assets/studio-reference-project/project.json`) point at `C:\Users\hthotapalli\...` — that's the
> original author's Windows profile, not a placeholder. Anywhere you see `hthotapalli` or `<username>`
> below, **replace it with your own Windows username** (or better, use the full path to wherever *you*
> cloned this repo — see step 2). The `project.json` sample paths don't need manual fixing: Studio
> rewrites `filePath` itself the next time it saves that project, and the skill only ever reads that
> file for its namespace/assembly boilerplate, never for a literal path.

**1. Clone this repo somewhere stable.** Any folder works — the server resolves its own asset paths
relative to `mcp-server/server.py` (`SKILL_DIR = Path(__file__).resolve().parent.parent`), so nothing is
hardcoded to `.kiro\skills\infor-rpa-dev`. That's just the conventional install location Kiro's skill
loader expects; a plain clone anywhere is fine as long as the `args` path below matches it.

```powershell
git clone <this-repo-url> C:\Users\<your-username>\.kiro\skills\infor-rpa-dev
```

**2. Install the pinned MCP dependency** (system Python is fine — no venv required):

```powershell
pip install "fastmcp==2.14.7"
```

**3. Register the server** in `~/.kiro/settings/mcp.json` (create the file if it doesn't exist yet).
Point `command` at your Python interpreter and `args` at the **absolute path** to `server.py` inside
*your* clone from step 1:

```json
{
  "infor-rpa-mcp": {
    "command": "C:\\Users\\<your-username>\\AppData\\Local\\Programs\\Python\\Python313\\python.exe",
    "args": ["C:\\Users\\<your-username>\\.kiro\\skills\\infor-rpa-dev\\mcp-server\\server.py"]
  }
}
```

`command` can also just be `"python"` if it's already on `PATH` — use the full `python.exe` path only if
you have multiple Python installs and need to pin one.

**4. Verify it starts clean.** Run the server directly once to catch import/path errors before Kiro does:

```powershell
python C:\Users\<your-username>\.kiro\skills\infor-rpa-dev\mcp-server\server.py
```

It will sit idle waiting for a stdio client (that's expected for an MCP server) — no traceback means the
oracle/asset paths resolved correctly. `Ctrl+C` to exit, then restart Kiro / Claude Code so it picks up
the new `mcp.json` entry.

**5. Smoke-test from a chat session.** Once registered, ask the assistant something that forces a tool
call, e.g. *"use infor-rpa-mcp to search_activities for 'send email'"* — a JSON result back means the
tools, the oracle, and the API-spec index are all wired correctly.

**Troubleshooting:**
- `ModuleNotFoundError: fastmcp` → the `pip install` above targeted a different Python than `command`
  points to; check with `python -m pip show fastmcp`.
- Server registers but every tool call errors → `args` path doesn't match where you actually cloned the
  repo, or has a typo in the username segment.
- `fastmcp` import works but behaves unexpectedly → you're on `fastmcp>=3.0`; reinstall the pinned
  `2.14.7` (see Requirements above).
- This server is **fully local and offline** — it only ever reads files under this repo's `assets/` and
  `references/`. It's a different, separate thing from the optional Atlassian MCP (`mcp-atlassian`) the
  skill *also* reaches for live Confluence/Jira grounding (§6 of `SKILL.md`) — that one talks to your
  Atlassian tenant over the network and is registered independently.

---

## Skills & Capabilities

The skill operates in **five distinct modes**, each with its own scope and safety gate.

### Mode 1 — UNDERSTAND / REVIEW (read-only)

Trace an existing RPA project without writing anything:

- Map `project.json → "main"` entry workflow → all invoked sub-workflows
- Audit argument/data flow, integration boundaries, serverless agent contracts
- Detect broken `InvokeWorkflow` references, type mismatches, serverless violations
- Report structure, naming, and logging standard gaps

> No Build Gate required. No XAML is written.

---

### Mode 2 — DEBUG (read-only analysis)

Diagnose Studio load errors, runtime failures, and behavioral bugs:

- Match the symptom (Studio error text, log line, wrong output) to the root cause
- Cross-reference `references/known-load-errors.md` (18 KB, 25+ categorized load traps)
- Identify: namespace mismatch, `Nothing`/empty expression, wrong VB.NET API, bad property type
- Propose the minimal fix and validate it via the linter before presenting

> No Build Gate required. Analysis only.

---

### Mode 3 — EDIT / EXTEND / CUSTOMIZE (writes XAML)

Modify existing workflows to meet new requirements:

- Add/remove activities, adjust logic, refactor, optimize, rename arguments
- Preserve the namespace block, naming conventions, and logging standard
- Touch the minimum number of files; append to `sourceFiles` when adding workflows
- Validate every touched file to zero ERRORs before presenting

> **Build Gate required** — requirements confirmed on paper before XAML is written.

---

### Mode 4 — BUILD / SCAFFOLD (full project generation)

Create a new RPA project from scratch:

- Scaffold the project folder: `{Name}_DDMMYYYY_RpaDev` under `Desktop\InforRPA_Projects`
- Clone `project.json` manifest from the golden reference (2026.04.1 canonical)
- Author entry workflow + sub-workflows using the activity oracle and XAML patterns
- Every activity property confirmed via MCP before use; every OutArgument defensively initialized

> **Build Gate required** — happy path + every failure path mapped on paper first.

---

### Mode 5 — VERIFY (Generate → Validate → Fix loop)

Mandatory post-generation quality gate:

- Run `validate_rpa_project(path)` or `validate_xaml_file(path)` via MCP
- Fix every `ERROR`-level issue; `WARNING`/`STYLE` are advisory
- Re-run until the linter exits `0`
- Only files that pass may be presented to the user

> All previous modes feed into Verify. No generated workflow ships without a clean linter pass.

---

### Knowledge Base (24 Reference Files, ~250 KB)

| Reference File | Contents |
|---|---|
| `activity-catalogue.md` | 45 KB — every activity + exact property signatures |
| `ionapi-endpoint-guide.md` | 47 KB — 466 ION API endpoints indexed by intent |
| `xaml-structure.md` | 23 KB — namespace block, assemblies, ViewState, root boilerplate |
| `best-practices.md` | 25 KB — error handling, scoping, defensive init patterns |
| `known-load-errors.md` | 18 KB — load trap symptom → cause → fix |
| `rpa-xaml-authoring-patterns.md` | 17 KB — manifest/namespace block, ION API patterns |
| `studio-golden-skeletons.md` | 17 KB — ground truth from real Studio output |
| `activity-signatures.md` | 24 KB — per-property .NET types across all activities |
| `rpa-xaml-type-validation.md` | 15 KB — WF4 type system, per-property validation rules |
| `lnip-patterns.md` | 14 KB — LN Invoice Processing domain patterns |
| `project-structure.md` | 14 KB — multi-file layout, dependencies, argumentsMap |
| `project-json-template.md` | 11 KB — failproof manifest creation (Method A & B) |
| `naming-conventions.md` | 11 KB — file/arg/var/DisplayName standards |
| `ion-api-patterns.md` | 12 KB — `.ReadAsJson` chains, IDM, Review Center, IDP |
| `expression-patterns.md` | 9.8 KB — VB.NET idioms, LINQ, JSON, OData |
| `assembly-prefix-map.md` | 6.3 KB — full namespace/prefix/assembly binding surface |
| `rpa-graph-azure-oauth.md` | 8.2 KB — Microsoft Graph email/file auth |
| `rpa-bot-review-center.md` | 11 KB — Review Center lifecycle |
| `log-format-standard.md` | 7.8 KB — standard log line/section formatting |
| `rpa-studio-activities-2026.md` | 19 KB — broad activity reference + serverless matrix |
| `data-flow-patterns.md` | 6.2 KB — InvokeWorkflow data flow |
| `mcp-knowledge-sourcing.md` | 5.3 KB — live Confluence/Jira sourcing guardrails |
| `docs-index.md` | 2.3 KB — pointers to official Infor 2026 PDFs |

---

## What This Skill Covers

High-level summary only — every claim below is backed by a generated/verified reference file, linked
inline, so this README doesn't drift out of sync with the actual oracle.

### Activity coverage

The oracle (`assets/activity-types.json`, reflected off the installed DLLs) currently covers **182
activities across 22 DLLs**, spanning every `Infor.Activities.*` pack plus the standard WF4 control-flow
set (`Sequence`, `If`, `ForEach`, `TryCatch`, `While`, `DoWhile`, `Switch`, `Flowchart`, `StateMachine`, …):

| Pack | ~# activities | Serverless-safe? | Covers |
|---|---|---|---|
| `Infor.Activities.Sys` | 48 | ✅ | Logging, file/JSON/string utils, dialogs |
| `Infor.Activities.Web` | 34 | ❌ (UI automation) | Browser automation, selectors |
| `Infor.Activities.Email` | 23 | ✅ Graph variants only | Read/send/move/download Outlook mail |
| `Infor.Activities.Desktop` | 13 | ❌ (UI automation) | Desktop/UI automation |
| `Infor.Activities.Excel` | 13 | ❌ (local COM) | Local `.xlsx` read/write |
| `Infor.Activities.ExcelOnline` | 13 | ✅ | Excel via Graph/OneDrive |
| `Infor.Activities.OneDrive` | 11 | ✅ | OneDrive/SharePoint files |
| `Infor.Activities.SharePointList` | 6 | ✅ | SharePoint list CRUD |
| `Infor.Activities.Datatable` | 5 | ✅ | `DataTable` build/filter/iterate |
| `Infor.Activities.Cloud` | 4 | ✅ | Cloud storage/object ops |
| `Infor.Activities.Workflow`, `.IONAPI`, `.HTTPRequests`, `.OCR`, `.Debug`, `.AI` | 1–few each | mostly ✅ | `InvokeWorkflow`, `IONAPIRequestWizard`, `HTTPRequestWizard`, OCR/IDP, debug helpers, GenAI (runtime-only) |
| `Infor.RPA.*` support packs (`Utilities`, `OCR`, `Security`, `Commons`, `Forms`, `Utility.Editor`) | — | referenced, not dropped | `ResponseObject`/`.ReadAsJson()`, credential vault, shared runtime types |

Full pack → namespace → prefix → serverless-safety matrix: `references/assembly-prefix-map.md`. Full
per-activity prose + usage patterns: `references/activity-catalogue.md` (1200+ lines, includes the
standard WF4 activities). Custom/tenant activity packs (e.g. a bespoke `Infor.Activities.QueueAPI`) are
**not** catalogued — the skill confirms those from the installed DLL or its source instead of guessing.

### Property/type coverage

Every activity property in the oracle carries its exact reflected .NET type, not a guess. The two
categories that matter for whether a XAML file loads in Studio at all:

- **Argument-wrapped properties** — `InArgument<T>` / `OutArgument<T>` / `InOutArgument<T>` — these
  *can* be bound to a `[variable]` expression. Covers everything from primitives (`String`, `Int32`,
  `Boolean`) to `iru:ResponseObject` (API responses), `njl:JObject`/`JArray`/`JToken` (JSON),
  `scg:Dictionary`/`IDictionary` (config + `InvokeWorkflow` arguments), `List(Of String)` (email
  recipients), and `s:String[]` (pipe-split values).
- **Plain (non-Argument) properties** — a bare `Boolean`/`String`/`Int32` on the activity itself (e.g.
  `MarkAsRead`, `ContinueOnError`) — these accept a **literal only** (`True`, `"text"`, `42`); binding one
  to `[variable]` is a guaranteed Studio load failure, and the linter (below) catches it for every
  property in the oracle, not just a hand-picked list.

Full per-property type tables and the WF4 type-system rules (array syntax, `IDictionary` vs `Dictionary`,
etc.): `references/rpa-xaml-type-validation.md`. Exact signatures for every reflected class:
`references/activity-signatures.md` and `assets/activity-types.json` directly.

### How MCP works

The MCP server (`mcp-server/server.py`) is a **FastMCP 2.14.7** stdio server. Kiro (or Claude Code)
launches it as a subprocess per the config in [MCP Local Setup](#mcp-local-setup); the assistant then
calls its tools mid-conversation instead of trusting its own memory of an activity name or endpoint. Two
things worth being explicit about:

1. **It's 100% local and read-only.** Every tool call reads a bundled file under this repo's `assets/`
   or `references/` — `activity-types.json` for the oracle, `api-specs/*.json` for endpoints,
   `known-load-errors.md` for error lookups. No network call happens inside `server.py`.
2. **It's a different thing from the Atlassian MCP.** The skill *separately* reaches for a live
   `mcp-atlassian` (or `claude_ai_Atlassian`) server for tenant-specific Confluence/Jira grounding
   (`references/mcp-knowledge-sourcing.md`) — that one *does* talk to your Atlassian instance over the
   network and is registered independently of `infor-rpa-mcp`. Don't confuse the two when troubleshooting
   connectivity.

The full tool list with signatures and example calls is next, in **MCP Server Capabilities**.

---

## MCP Server Capabilities

The MCP server (`mcp-server/server.py`) is a **FastMCP 2.14.7** instance registered in Kiro as
`infor-rpa-mcp`. It exposes **11 tools** — 3 activity-oracle lookups, 3 validation wrappers, 3 project
utilities, an API-endpoint search, and an error-symptom lookup. All reads are from bundled assets — no
network calls. See [MCP Local Setup](#mcp-local-setup) for how to register it.

### Tools

#### `lookup_activity(class_name: str) → dict`

Returns exact property signatures for one Infor activity class from the 182-activity DLL-reflected oracle. Accepts fully-qualified or short class name. Falls back across `activity-types.json` → `activity-types-supplemental.json` → `activity-type-overrides.json`. Returns a `xamlPattern` field with a minimal valid XAML skeleton.

```python
lookup_activity("IONAPIRequestWizard")
# → { "class": "Infor.Activities.IONAPI.IONAPIRequestWizard",
#     "properties": { "ServiceName": "InArgument<String>", ... },
#     "xamlPattern": "<ionapi:IONAPIRequestWizard ...>" }
```

---

#### `lookup_activities(class_names: list[str]) → list[dict]`

Batch variant of `lookup_activity`. Resolves multiple activity classes in one call.

---

#### `search_activities(query: str, limit: int = 20) → list[dict]`

Keyword search across the full 182-activity registry. Returns matching activities with class name and property signatures.

```python
search_activities("send email outlook", limit=5)
```

---

#### `validate_xaml_file(file_path: str) → dict`

Validates a single `.xaml` workflow or `project.json` against all 25+ linter rules. Returns:

```json
{
  "passed": true,
  "errors": [],
  "warnings": ["..."],
  "style": ["..."]
}
```

---

#### `validate_rpa_project(project_path: str) → dict`

Validates every `.xaml` file and `project.json` in a project directory. Returns per-file results and an aggregate `passed` boolean.

---

#### `validate_xaml_batch(file_paths: list[str]) → list[dict]`

Validates an explicit list of `.xaml` / `project.json` files in one MCP call.

---

#### `search_api_endpoint(query: str, limit: int = 10) → list[dict]`

Searches 466 Infor ION API endpoints across 25 bundled OpenAPI specs. Returns matching endpoints with service, HTTP method, path, and summary.

```python
search_api_endpoint("purchase order approve", limit=5)
# → [{ "service": "LN", "method": "POST", "path": "/PurchaseOrders/{id}/approve", ... }]
```

**Covered Services (25 OpenAPI specs):**

`AIDataModeling` · `ColemanAIPlatform` · `DataLake` · `IDM_Api` · `InfoRpa` · `ION_Pulse` · `LN_OData` · `RPAReviewCenter` · `SessionService` · and 16 more.

---

#### `lookup_error(error_text: str) → dict`

Searches the known-load-errors catalogue for matching symptoms and returns up to 3 sections with cause and fix.

```python
lookup_error("The type 'Infor.Activities.Sys.Activities.LogExecutionMessage' was not found")
```

---

#### `get_studio_version() → dict`

Detects the installed Infor RPA Studio version by reading the newest `project.json` under `%LOCALAPPDATA%\InforRPA`. Used only to clone the `studioVersion` value into new manifests.

---

#### `create_project_folder(project_name: str, base_path: str = "") → dict`

Creates a new RPA project folder following the standard naming convention:

```
{project_name}_DDMMYYYY_RpaDev
# e.g. ION_PO_Fetch_30062026_RpaDev
```

Defaults to `Desktop\InforRPA_Projects` when `base_path` is not provided.

---

#### `read_rpa_project(project_path: str) → dict`

Reads and parses `project.json` from a project directory. Extracts `studioVersion`, `dependencies`, `packages`, and `sourceFiles` for manifest cloning.

---

---

## Project Structure

```
infor-rpa-dev/
├── SKILL.md                          # 33 KB — skill definition, guardrails, reference map
├── mcp-server/
│   └── server.py                     # 13 KB — FastMCP server (11 tools + 5 resources)
├── assets/
│   ├── activity-types.json           # 163 KB — 182 activities, DLL-reflected oracle
│   ├── activity-types-supplemental.json
│   ├── activity-type-overrides.json
│   ├── api-specs/                    # 25 OpenAPI specs (~466 ION API endpoints)
│   ├── studio-reference-project/     # Real loadable Studio 2026.04.1 project (11 .xaml + manifest)
│   ├── studio-templates/             # Empty workflow shells (Sequence, Flowchart, StateMachine)
│   └── lnip/                         # LN Invoice Processing domain patterns
├── references/                       # 24 markdown files, ~250 KB
│   └── ...
├── scripts/
│   ├── validate_rpa.py               # 30 KB — heuristic linter (25+ load trap rules)
│   ├── extract_signatures.py         # Regenerate activity-signatures.md from reference project
│   ├── extract_dll_types.ps1         # Refresh oracle from installed DLLs (post Studio upgrade)
│   ├── extract_api_index.py          # Regenerate ionapi-endpoint-guide.md
│   └── test_linter_coverage.py       # Verify linter correctness
└── .claude/
    └── settings.local.json           # Claude Code permission config
```

---

## Getting Started

### 1. Register the MCP Server

Follow [MCP Local Setup](#mcp-local-setup) above — clone the repo, `pip install "fastmcp==2.14.7"`, and
add an `infor-rpa-mcp` entry to `~/.kiro/settings/mcp.json` pointing at *your* clone (not
`hthotapalli`'s).

### 2. Open a Project in Claude Code

```
> Understand this RPA project: C:\InforRPA_Projects\MyBot_30062026_RpaDev
```

### 3. Build a New Bot

```
> Build an RPA bot that fetches open POs from ION API and logs them to IDM
```

The skill will:
1. Call `create_project_folder` to scaffold the folder
2. Run the Build Gate — map every workflow on paper before writing XAML
3. Look up every activity via `lookup_activity` before using it
4. Search `search_api_endpoint` for the right ION API paths
5. Author XAML grounded in the oracle and golden skeletons
6. Call `validate_rpa_project` and fix all ERRORs before presenting

---

## Validation Engine

`scripts/validate_rpa.py` is a 30 KB heuristic linter calibrated to zero ERRORs on the bundled reference project. It enforces:

| Category | Rules |
|---|---|
| **Root structure** | `x:Class` must be `RehostedWorkflowDesigner.Workflow`; root must be `Activity` |
| **Namespace integrity** | All used prefixes declared; no hallucinated assemblies (`Infor.RPA.IONAPI`, etc.) |
| **IdRef / ViewState** | No duplicate IdRefs; no orphaned ViewStateData entries |
| **VisualBasicSettings** | Rejects the fatal `<mva:VisualBasicSettings>` block form |
| **ActivityAction wrappers** | DelegateInArgument must be inside `ActivityAction.Argument` on TryCatch/ForEach |
| **Bare List<T> properties** | Uninitialized List properties flagged via type metadata |
| **LogExecutionMessage** | Rejects `IsError=` attribute and expression-based LogType |
| **InvokeWorkflow** | Rejects nested `<iaw:InvokeWorkflow.Arguments>` form; OutputArguments must bind IDictionary |
| **Type traps** | Paren array syntax `x:String()`; `.Get(Nothing)` C# API in VB; `vbCrLf` without import |
| **Assign activity** | Rejects empty `Value=""` and empty `<InArgument/>` bodies |
| **project.json** | Schema, core keys, `name` field (no brackets), studioVersion format, dependency whitelist |

**Exit codes:** `0` = clean (no ERRORs); `1` = ERRORs present. WARNINGs and STYLE findings never fail the build.

---

## Guardrails

- **No hallucination:** Every activity class, namespace, property, and endpoint is looked up via MCP or a reference file — never generated from memory.
- **Build Gate mandatory:** No XAML or `project.json` is written before requirements are confirmed on paper (happy path + every failure path).
- **Zero ERRORs required:** Generated workflows are never presented until `validate_rpa_project` exits `0`.
- **Platform isolation:** Strictly Infor RPA Studio 2026.x only — no UiPath, Power Automate, Blue Prism, or Automation Anywhere patterns.
- **Defensive init:** All `OutArgument` variables are initialized to safe defaults before the first `TryCatch`.
- **Minimal footprint:** Edit/Extend mode touches the minimum number of files; never rewrites unrelated workflows.

---

## Contributing

1. **Refresh the activity oracle** after a Studio upgrade:
   ```powershell
   .\scripts\extract_dll_types.ps1
   ```
2. **Verify the linter** still passes on the reference project:
   ```powershell
   python scripts/test_linter_coverage.py
   python scripts/validate_rpa.py assets/studio-reference-project
   ```
3. **Add new API specs** to `assets/api-specs/` and regenerate the endpoint guide:
   ```powershell
   python scripts/extract_api_index.py
   ```

---

## Author

**Harshavardhan Reddy Thotapalli**  
harshavardhanreddy.thotapalli@infor.com  
Infor — RPA Platform Engineering

---

*Grounded in Infor RPA Studio 2026.04.1 · Validated against production serverless agents · fastmcp 2.14.7*