@minicor/mcp-server 2.0.3 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -124
- package/dist/__tests__/helpers.test.js +3 -3
- package/dist/__tests__/tfa-client.test.d.ts +2 -0
- package/dist/__tests__/tfa-client.test.d.ts.map +1 -0
- package/dist/__tests__/tfa-client.test.js +191 -0
- package/dist/__tests__/tfa-client.test.js.map +1 -0
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +7 -4
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/inspect-scripts.d.ts +1 -1
- package/dist/inspect-scripts.js +1 -1
- package/dist/lds-client.d.ts +1 -1
- package/dist/lds-client.js +2 -2
- package/dist/prompts/build-rpa.d.ts.map +1 -1
- package/dist/prompts/build-rpa.js +37 -9
- package/dist/prompts/build-rpa.js.map +1 -1
- package/dist/prompts/tfa-guide.d.ts +3 -0
- package/dist/prompts/tfa-guide.d.ts.map +1 -0
- package/dist/prompts/tfa-guide.js +178 -0
- package/dist/prompts/tfa-guide.js.map +1 -0
- package/dist/tfa-client.d.ts +45 -0
- package/dist/tfa-client.d.ts.map +1 -0
- package/dist/tfa-client.js +116 -0
- package/dist/tfa-client.js.map +1 -0
- package/dist/tools/tfa.d.ts +3 -0
- package/dist/tools/tfa.d.ts.map +1 -0
- package/dist/tools/tfa.js +146 -0
- package/dist/tools/tfa.js.map +1 -0
- package/dist/tools/vm-rpa.js +12 -12
- package/dist/tools/vm-rpa.js.map +1 -1
- package/dist/tools/vm.js +4 -4
- package/dist/tools/workflow-ops.js +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAoB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,eAAe,GAEhB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Python script generators for VM UI inspection.
|
|
3
3
|
*
|
|
4
4
|
* Each function returns a Python script string that, when executed on the VM
|
|
5
|
-
* via
|
|
5
|
+
* via MDS /execute, prints structured JSON to stdout for the agent to parse.
|
|
6
6
|
*/
|
|
7
7
|
export type InspectMode = "window_list" | "screen_info" | "element_at_point" | "element_tree" | "focused_element";
|
|
8
8
|
export type InspectFramework = "auto" | "uiautomation" | "pywinauto" | "jab";
|
package/dist/inspect-scripts.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Python script generators for VM UI inspection.
|
|
3
3
|
*
|
|
4
4
|
* Each function returns a Python script string that, when executed on the VM
|
|
5
|
-
* via
|
|
5
|
+
* via MDS /execute, prints structured JSON to stdout for the agent to parse.
|
|
6
6
|
*/
|
|
7
7
|
export function generateInspectScript(params) {
|
|
8
8
|
const fw = params.framework ?? "auto";
|
package/dist/lds-client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stateless HTTP client for the
|
|
2
|
+
* Stateless HTTP client for the Minicor Desktop Service (MDS).
|
|
3
3
|
*
|
|
4
4
|
* Every method receives the base URL (Cloudflare Tunnel) and optional auth
|
|
5
5
|
* credentials so the caller (tool handler) can pull them from session state.
|
package/dist/lds-client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stateless HTTP client for the
|
|
2
|
+
* Stateless HTTP client for the Minicor Desktop Service (MDS).
|
|
3
3
|
*
|
|
4
4
|
* Every method receives the base URL (Cloudflare Tunnel) and optional auth
|
|
5
5
|
* credentials so the caller (tool handler) can pull them from session state.
|
|
@@ -19,7 +19,7 @@ async function request(url, init) {
|
|
|
19
19
|
const res = await fetch(url, init);
|
|
20
20
|
if (!res.ok) {
|
|
21
21
|
const body = await res.text().catch(() => "");
|
|
22
|
-
throw new Error(`
|
|
22
|
+
throw new Error(`MDS ${init?.method ?? "GET"} ${url} returned ${res.status}: ${body}`);
|
|
23
23
|
}
|
|
24
24
|
return res.json();
|
|
25
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-rpa.d.ts","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"build-rpa.d.ts","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,QAmT5C"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export function register({ server }) {
|
|
3
|
-
server.prompt("build-rpa-workflow", "Iteratively build an RPA workflow on a VM using the
|
|
4
|
-
workspaceId: z.string().describe("
|
|
3
|
+
server.prompt("build-rpa-workflow", "Iteratively build an RPA workflow on a VM using the Minicor Desktop Service. Guides you through connecting to the VM, researching the target app's UI framework, taking screenshots, inspecting UI elements, writing and testing RPA scripts, and saving each working step as a Minicor workflow flow.", {
|
|
4
|
+
workspaceId: z.string().describe("Minicor workspace ID"),
|
|
5
5
|
task: z
|
|
6
6
|
.string()
|
|
7
7
|
.describe("Description of what to automate (e.g. 'Log into Centricity, navigate to Documents, download the latest report')"),
|
|
@@ -18,7 +18,7 @@ export function register({ server }) {
|
|
|
18
18
|
role: "user",
|
|
19
19
|
content: {
|
|
20
20
|
type: "text",
|
|
21
|
-
text: `You are building an RPA workflow on the Minicor platform. Your goal is to iteratively create automation steps that run on a VM via the
|
|
21
|
+
text: `You are building an RPA workflow on the Minicor platform. Your goal is to iteratively create automation steps that run on a VM via the Minicor Desktop Service (MDS).
|
|
22
22
|
|
|
23
23
|
## Task
|
|
24
24
|
${task}
|
|
@@ -48,9 +48,11 @@ Screenshots alone are unreliable for reading data (resolution issues, misreads).
|
|
|
48
48
|
## Strategy Selection (BEFORE writing any automation)
|
|
49
49
|
|
|
50
50
|
### For Web/Browser Targets:
|
|
51
|
-
- Chrome runs on the VM with \`--remote-debugging-port=9222\`
|
|
52
51
|
- Use **CDP via Python websocket** for page manipulation (fastest, most reliable for anti-bot sites)
|
|
53
|
-
-
|
|
52
|
+
- The MDS provides an isolated Chrome instance per execution via \`/execute/browser\`
|
|
53
|
+
- Multiple browser automations run **in parallel** on the same VM — each gets its own Chrome
|
|
54
|
+
- Scripts always use \`127.0.0.1:9222\` — the MDS transparently routes to the correct Chrome instance
|
|
55
|
+
- Use CDP \`Page.captureScreenshot\` for screenshots within the browser tab
|
|
54
56
|
- Check if the site has usable internal APIs (inspect network traffic via CDP \`fetch\` interception)
|
|
55
57
|
- If clean APIs exist and are stable → consider direct \`requests\`/\`httpx\` instead of UI automation
|
|
56
58
|
- If anti-bot protection exists (Cloudflare, reCAPTCHA) → CDP through the VM browser avoids detection
|
|
@@ -61,16 +63,33 @@ Screenshots alone are unreliable for reading data (resolution issues, misreads).
|
|
|
61
63
|
- **Electron / web-based desktop** → \`pywinauto\` or \`pyautogui\`
|
|
62
64
|
- **Legacy Win32** → \`uiautomation\`
|
|
63
65
|
- Start with \`uiautomation\` if unsure.
|
|
66
|
+
- Desktop scripts use \`/execute\` and run **one at a time** per VM (the physical screen is shared)
|
|
67
|
+
|
|
68
|
+
### Mixed Browser + Desktop (IMPORTANT)
|
|
69
|
+
Some browser automations need to interact with the physical screen — for example:
|
|
70
|
+
- Clicking OS-level alerts or confirmation dialogs
|
|
71
|
+
- File upload/download dialogs (native file picker)
|
|
72
|
+
- Browser notifications or permission prompts
|
|
73
|
+
- CAPTCHA solving that requires clicking outside the browser
|
|
74
|
+
|
|
75
|
+
**These automations CANNOT use \`/execute/browser\`** because they need the screen, which is shared.
|
|
76
|
+
Use \`/execute\` instead and treat them like desktop automations — they run one at a time per VM.
|
|
77
|
+
|
|
78
|
+
When building a workflow, determine which category it falls into:
|
|
79
|
+
- **Pure CDP** (all interaction via \`Runtime.evaluate\`, \`Page.navigate\`, etc.) → \`/execute/browser\` — parallel-safe
|
|
80
|
+
- **Needs screen interaction** (any \`pyautogui\`, OS dialogs, file pickers) → \`/execute\` — one at a time
|
|
64
81
|
|
|
65
82
|
## Browser Automation via CDP (Python WebSocket)
|
|
66
83
|
|
|
67
|
-
Chrome
|
|
84
|
+
Your Python scripts connect to Chrome via the Chrome DevTools Protocol. The MDS handles Chrome lifecycle and port routing transparently — scripts always use port 9222.
|
|
85
|
+
|
|
86
|
+
**Dispatch:** Use \`dispatchPattern: "browser"\` when saving with \`create_rpa_flow\`. This routes to \`/execute/browser\` which provides an isolated Chrome instance.
|
|
68
87
|
|
|
69
88
|
### How CDP Works:
|
|
70
89
|
1. Discover tabs: \`GET http://127.0.0.1:9222/json\`
|
|
71
90
|
2. Connect via WebSocket to the target tab's \`webSocketDebuggerUrl\`
|
|
72
91
|
3. Use \`Runtime.evaluate\` to execute JavaScript in the page context
|
|
73
|
-
4. Use \`
|
|
92
|
+
4. Use CDP \`Page.captureScreenshot\` for screenshots
|
|
74
93
|
|
|
75
94
|
### CDP Starter Template:
|
|
76
95
|
\`\`\`python
|
|
@@ -107,10 +126,17 @@ ws.close()
|
|
|
107
126
|
- **Button clicks by text**: Use \`querySelectorAll("button").forEach()\` + \`textContent.trim()\` matching — more resilient than IDs or classes that change
|
|
108
127
|
- **Credentials**: Use \`\\\${username}\` / \`\\\${password}\` interpolated from JS wrapper variables sourced from \`{{config.xxx}}\` — NEVER hardcode
|
|
109
128
|
- **Waits**: \`time.sleep()\` between navigations (8-15s for page loads, 1-3s for UI actions)
|
|
110
|
-
- **Verification**:
|
|
129
|
+
- **Verification**: Use CDP \`Page.captureScreenshot\` for per-tab screenshots
|
|
111
130
|
- **Dropdown handling**: Click to open, then use \`querySelectorAll\` to find options by text and click
|
|
112
131
|
- **Tab management**: If multiple tabs open, filter \`/json\` response by URL or title
|
|
113
132
|
|
|
133
|
+
### Parallel Execution Notes:
|
|
134
|
+
- \`/execute/browser\` runs your script with its own Chrome instance — multiple workflows can run at the same time on one VM
|
|
135
|
+
- \`/execute\` runs your script without Chrome — for desktop automation or mixed browser+desktop scripts
|
|
136
|
+
- The MDS transparently rewrites \`127.0.0.1:9222\` in your script to the correct Chrome port — you never need to handle ports
|
|
137
|
+
- Recordings from \`/execute/browser\` capture only the browser tab (CDP screencast), not the full desktop
|
|
138
|
+
- Recordings from \`/execute\` capture the full desktop (MSS screen recording)
|
|
139
|
+
|
|
114
140
|
## Procedure
|
|
115
141
|
|
|
116
142
|
### 1. Connect to the VM
|
|
@@ -150,7 +176,9 @@ Before writing any automation:
|
|
|
150
176
|
**e. SAVE — Call \`create_rpa_flow\` (only after c + d pass)**
|
|
151
177
|
- Pass the validated Python script, step name, description, flowId, and executionOrder
|
|
152
178
|
- The tool handles all JS wrapping automatically
|
|
153
|
-
-
|
|
179
|
+
- For browser/CDP automations: set \`dispatchPattern: "browser"\` — routes to \`/execute/browser\` (parallel-safe)
|
|
180
|
+
- For desktop automations: use default \`dispatchPattern: "cloudflare_tunnel"\` — routes to \`/execute\`
|
|
181
|
+
- For mixed browser+desktop: use default \`dispatchPattern: "cloudflare_tunnel"\` — runs one at a time
|
|
154
182
|
|
|
155
183
|
### 5. Data Passing Between Steps (CRITICAL)
|
|
156
184
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-rpa.js","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAY;IAC3C,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB,wSAAwS,EACxS;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxD,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,CACP,iHAAiH,CAClH;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,uFAAuF,CACxF;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,sEAAsE,CACvE;KACJ,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;EAGhB,IAAI;;;EAGJ,OAAO;;;MAGH,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,2BAA2B,UAAU,+BAA+B,CAAC,CAAC,CAAC,8CAA8C
|
|
1
|
+
{"version":3,"file":"build-rpa.js","sourceRoot":"","sources":["../../src/prompts/build-rpa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAY;IAC3C,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB,wSAAwS,EACxS;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxD,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,CACP,iHAAiH,CAClH;QACH,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,uFAAuF,CACxF;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,sEAAsE,CACvE;KACJ,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;EAGhB,IAAI;;;EAGJ,OAAO;;;MAGH,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,2BAA2B,UAAU,+BAA+B,CAAC,CAAC,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAoH1I,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAmJsC;iBAC9C;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa-guide.d.ts","sourceRoot":"","sources":["../../src/prompts/tfa-guide.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,QAsL5C"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function register({ server }) {
|
|
3
|
+
server.prompt("2fa-workflow-guide", "Guide for handling 2FA/OTP challenges in RPA workflows — provisioning phone numbers and email addresses, registering TOTP secrets, and auto-resolving OTP codes during automation runs.", {
|
|
4
|
+
workspaceId: z.string().describe("Minicor workspace ID"),
|
|
5
|
+
scenario: z
|
|
6
|
+
.string()
|
|
7
|
+
.optional()
|
|
8
|
+
.describe("Specific 2FA scenario (e.g. 'site sends SMS OTP on login', 'TOTP authenticator app required', 'email verification code')"),
|
|
9
|
+
}, async ({ workspaceId, scenario }) => ({
|
|
10
|
+
messages: [
|
|
11
|
+
{
|
|
12
|
+
role: "user",
|
|
13
|
+
content: {
|
|
14
|
+
type: "text",
|
|
15
|
+
text: `You are setting up 2FA/OTP handling for an RPA workflow on the Minicor platform.
|
|
16
|
+
|
|
17
|
+
## Workspace
|
|
18
|
+
ID: ${workspaceId}${scenario ? `\n\n## Scenario\n${scenario}` : ""}
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
The \`tfa_*\` tools let you provision phone numbers and email addresses, store TOTP secrets, and automatically resolve 2FA challenges during RPA workflow execution. All data is scoped to the workspace.
|
|
23
|
+
|
|
24
|
+
## Available Tools
|
|
25
|
+
|
|
26
|
+
### Channel Provisioning
|
|
27
|
+
| Tool | Purpose |
|
|
28
|
+
|------|---------|
|
|
29
|
+
| \`tfa_provision_phone\` | Buy a Twilio phone number — SMS webhook is auto-configured |
|
|
30
|
+
| \`tfa_provision_email\` | Generate a Mailgun email address for OTP capture |
|
|
31
|
+
| \`tfa_list_channels\` | List all provisioned phone numbers and email addresses |
|
|
32
|
+
| \`tfa_delete_channel\` | Remove a channel (releases Twilio number if phone) |
|
|
33
|
+
|
|
34
|
+
### TOTP Secrets
|
|
35
|
+
| Tool | Purpose |
|
|
36
|
+
|------|---------|
|
|
37
|
+
| \`tfa_register_secret\` | Store a TOTP secret (base32 or otpauth:// URI), encrypted at rest |
|
|
38
|
+
| \`tfa_list_secrets\` | List stored secrets for the workspace |
|
|
39
|
+
| \`tfa_delete_secret\` | Remove a stored secret |
|
|
40
|
+
| \`tfa_generate_totp\` | Get the current 6-digit code + seconds until expiry |
|
|
41
|
+
| \`tfa_verify_totp\` | Verify a code against a stored secret |
|
|
42
|
+
| \`tfa_parse_qr\` | Decode a QR code image to extract TOTP params |
|
|
43
|
+
|
|
44
|
+
### OTP Challenge Resolution
|
|
45
|
+
| Tool | Purpose |
|
|
46
|
+
|------|---------|
|
|
47
|
+
| \`tfa_request_sms_otp\` | Wait for an SMS OTP (blocks until it arrives or times out) |
|
|
48
|
+
| \`tfa_request_email_otp\` | Wait for an email OTP (blocks until it arrives or times out) |
|
|
49
|
+
| \`tfa_get_challenge\` | Check the status of a pending challenge |
|
|
50
|
+
| \`tfa_resolve_challenge\` | Manually resolve (for captchas or Slack-provided codes) |
|
|
51
|
+
| \`tfa_cancel_challenge\` | Cancel a pending challenge |
|
|
52
|
+
|
|
53
|
+
## Workflow Patterns
|
|
54
|
+
|
|
55
|
+
### Pattern 1 — TOTP Authenticator App
|
|
56
|
+
|
|
57
|
+
When a site requires a 6-digit authenticator code:
|
|
58
|
+
|
|
59
|
+
1. **One-time setup:** Register the TOTP secret
|
|
60
|
+
- If you have the base32 secret: \`tfa_register_secret\` with \`value\`
|
|
61
|
+
- If you have a QR code: \`tfa_parse_qr\` → \`tfa_register_secret\` with extracted params
|
|
62
|
+
- If you have an otpauth:// URI: \`tfa_register_secret\` with \`uri\`
|
|
63
|
+
|
|
64
|
+
2. **During workflow execution:** Generate the code on demand
|
|
65
|
+
- Call \`tfa_generate_totp\` with the \`secretId\`
|
|
66
|
+
- Returns \`{ code: "482901", expiresIn: 14 }\`
|
|
67
|
+
- If \`expiresIn\` is < 5 seconds, wait and call again for a fresh code
|
|
68
|
+
- Type the code into the 2FA input field
|
|
69
|
+
|
|
70
|
+
**Example RPA flow integration:**
|
|
71
|
+
\`\`\`
|
|
72
|
+
Step 1: Navigate to login page, enter credentials, submit
|
|
73
|
+
Step 2: Site shows "Enter authenticator code"
|
|
74
|
+
→ Call tfa_generate_totp(secretId)
|
|
75
|
+
→ Type the code into the input
|
|
76
|
+
→ Submit
|
|
77
|
+
Step 3: Continue with authenticated session
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
### Pattern 2 — SMS OTP
|
|
81
|
+
|
|
82
|
+
When a site sends a verification code via SMS:
|
|
83
|
+
|
|
84
|
+
1. **One-time setup:** Provision a phone number
|
|
85
|
+
- \`tfa_provision_phone\` → returns \`{ id: "ch_xxx", address: "+1XXXXXXXXXX" }\`
|
|
86
|
+
- Register this phone number with the target site
|
|
87
|
+
|
|
88
|
+
2. **During workflow execution:**
|
|
89
|
+
- Trigger the SMS send (click "Send code", etc.)
|
|
90
|
+
- Immediately call \`tfa_request_sms_otp\` with the \`channelId\`
|
|
91
|
+
- The call blocks until the SMS arrives (up to \`timeoutSeconds\`)
|
|
92
|
+
- Returns the parsed OTP code
|
|
93
|
+
- Type it into the verification field
|
|
94
|
+
|
|
95
|
+
**Timing matters:** Call \`tfa_request_sms_otp\` AFTER triggering the SMS send but BEFORE the code expires. The tool creates a challenge and waits for the SMS webhook to resolve it.
|
|
96
|
+
|
|
97
|
+
### Pattern 3 — Email OTP
|
|
98
|
+
|
|
99
|
+
Same flow as SMS but with email:
|
|
100
|
+
|
|
101
|
+
1. **One-time setup:** \`tfa_provision_email\` → \`rpa-xxxx@otp.minicor.com\`
|
|
102
|
+
2. Register this email address with the target site
|
|
103
|
+
3. **During execution:** Trigger email → \`tfa_request_email_otp\` → type code
|
|
104
|
+
|
|
105
|
+
### Pattern 4 — QR Code Enrollment (Automated TOTP Setup)
|
|
106
|
+
|
|
107
|
+
When setting up 2FA on a new account and the site shows a QR code:
|
|
108
|
+
|
|
109
|
+
1. Take a screenshot of the QR code (\`vm_screenshot\` or \`vm_screenshot_region\`)
|
|
110
|
+
2. Call \`tfa_parse_qr\` with the screenshot (base64 or URL)
|
|
111
|
+
3. Call \`tfa_register_secret\` with the extracted \`uri\`
|
|
112
|
+
4. Call \`tfa_generate_totp\` to get the first code
|
|
113
|
+
5. Enter the code to verify and complete enrollment
|
|
114
|
+
|
|
115
|
+
### Pattern 5 — Manual/Captcha Fallback
|
|
116
|
+
|
|
117
|
+
For captchas or cases where auto-parsing fails:
|
|
118
|
+
|
|
119
|
+
1. The 2FA service posts to Slack (if configured) with a screenshot
|
|
120
|
+
2. A human replies in the Slack thread with the solution
|
|
121
|
+
3. Or call \`tfa_resolve_challenge\` directly with the value
|
|
122
|
+
|
|
123
|
+
## Integration with RPA Workflows
|
|
124
|
+
|
|
125
|
+
### Storing the Secret/Channel ID in Config Stores
|
|
126
|
+
|
|
127
|
+
After provisioning, store the IDs in a config store so workflows can reference them:
|
|
128
|
+
|
|
129
|
+
\`\`\`
|
|
130
|
+
1. tfa_provision_phone → get channelId "ch_abc123"
|
|
131
|
+
2. update_config_property on the workflow's config store:
|
|
132
|
+
key: "sms_channel_id", value: "ch_abc123"
|
|
133
|
+
3. In the workflow JS wrapper, reference {{config.sms_channel_id}}
|
|
134
|
+
\`\`\`
|
|
135
|
+
|
|
136
|
+
Similarly for TOTP secrets:
|
|
137
|
+
\`\`\`
|
|
138
|
+
1. tfa_register_secret → get secretId "sec_xyz789"
|
|
139
|
+
2. update_config_property: key: "totp_secret_id", value: "sec_xyz789"
|
|
140
|
+
3. Reference {{config.totp_secret_id}} in the workflow
|
|
141
|
+
\`\`\`
|
|
142
|
+
|
|
143
|
+
### 2FA Step in a Workflow
|
|
144
|
+
|
|
145
|
+
A typical 2FA step is an HTTP_REQUEST flow that calls the 2FA service directly:
|
|
146
|
+
|
|
147
|
+
\`\`\`javascript
|
|
148
|
+
(data) => {
|
|
149
|
+
return {
|
|
150
|
+
"lam.httpRequest": {
|
|
151
|
+
"method": "POST",
|
|
152
|
+
"url": "https://tfa-otp.minicor.com/secrets/{{config.totp_secret_id}}/generate",
|
|
153
|
+
"headers": {
|
|
154
|
+
"X-API-Key": "{{config.workspace_api_key}}",
|
|
155
|
+
"Content-Type": "application/json"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
\`\`\`
|
|
161
|
+
|
|
162
|
+
The next step can then read the code from \`data.step_N.response.code\` and use it in the RPA script.
|
|
163
|
+
|
|
164
|
+
## Best Practices
|
|
165
|
+
|
|
166
|
+
- **Provision channels once, reuse forever.** Don't buy a new phone number for every workflow — use \`tfa_list_channels\` to find existing ones.
|
|
167
|
+
- **Store IDs in config stores.** This keeps workflow definitions portable and avoids hardcoding.
|
|
168
|
+
- **Check \`expiresIn\` for TOTP.** If less than 5 seconds remain, wait for the next code cycle.
|
|
169
|
+
- **Set reasonable timeouts** for SMS/email OTP. Default is 120s. Increase for sites that are slow to send.
|
|
170
|
+
- **Delete unused channels** to avoid recurring costs — \`tfa_delete_channel\` releases the Twilio number.
|
|
171
|
+
- **One phone/email per site** unless the site requires unique numbers per account.
|
|
172
|
+
- **Use \`tfa_verify_totp\`** during setup to confirm the secret was registered correctly before relying on it in production workflows.`,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=tfa-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa-guide.js","sourceRoot":"","sources":["../../src/prompts/tfa-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAY;IAC3C,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB,yLAAyL,EACzL;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxD,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,0HAA0H,CAC3H;KACJ,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACpC,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE;;;MAGZ,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wIA0JsE;iBAC7H;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateless HTTP client for the 2FA OTP service.
|
|
3
|
+
*
|
|
4
|
+
* Every method receives the base URL and workspace API key so the caller
|
|
5
|
+
* (tool handler) can resolve them from session/cache.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getTfaBaseUrl(): string;
|
|
8
|
+
export declare function provisionPhone(baseUrl: string, apiKey: string): Promise<unknown>;
|
|
9
|
+
export declare function provisionEmail(baseUrl: string, apiKey: string): Promise<unknown>;
|
|
10
|
+
export declare function listChannels(baseUrl: string, apiKey: string, opts?: {
|
|
11
|
+
type?: string;
|
|
12
|
+
}): Promise<unknown>;
|
|
13
|
+
export declare function deleteChannel(baseUrl: string, apiKey: string, channelId: string): Promise<void>;
|
|
14
|
+
export declare function createSecret(baseUrl: string, apiKey: string, data: {
|
|
15
|
+
type: "totp";
|
|
16
|
+
name: string;
|
|
17
|
+
site?: string;
|
|
18
|
+
value?: string;
|
|
19
|
+
uri?: string;
|
|
20
|
+
}): Promise<unknown>;
|
|
21
|
+
export declare function listSecrets(baseUrl: string, apiKey: string, opts?: {
|
|
22
|
+
site?: string;
|
|
23
|
+
}): Promise<unknown>;
|
|
24
|
+
export declare function deleteSecret(baseUrl: string, apiKey: string, secretId: string): Promise<void>;
|
|
25
|
+
export declare function generateTotp(baseUrl: string, apiKey: string, secretId: string): Promise<unknown>;
|
|
26
|
+
export declare function verifyTotp(baseUrl: string, apiKey: string, secretId: string, code: string): Promise<unknown>;
|
|
27
|
+
export declare function parseQr(baseUrl: string, apiKey: string, data: {
|
|
28
|
+
image?: string;
|
|
29
|
+
imageUrl?: string;
|
|
30
|
+
}): Promise<unknown>;
|
|
31
|
+
export declare function requestSmsOtp(baseUrl: string, apiKey: string, data: {
|
|
32
|
+
channelId: string;
|
|
33
|
+
timeoutSeconds?: number;
|
|
34
|
+
}): Promise<unknown>;
|
|
35
|
+
export declare function requestEmailOtp(baseUrl: string, apiKey: string, data: {
|
|
36
|
+
channelId: string;
|
|
37
|
+
timeoutSeconds?: number;
|
|
38
|
+
}): Promise<unknown>;
|
|
39
|
+
export declare function getChallenge(baseUrl: string, apiKey: string, challengeId: string): Promise<unknown>;
|
|
40
|
+
export declare function resolveChallenge(baseUrl: string, apiKey: string, challengeId: string, data: {
|
|
41
|
+
value: string;
|
|
42
|
+
resolvedBy?: string;
|
|
43
|
+
}): Promise<unknown>;
|
|
44
|
+
export declare function cancelChallenge(baseUrl: string, apiKey: string, challengeId: string): Promise<unknown>;
|
|
45
|
+
//# sourceMappingURL=tfa-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa-client.d.ts","sourceRoot":"","sources":["../src/tfa-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAiCD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAEnE;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAEnE;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,oBAMzB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAIrF;AAID,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,oBAMF;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,oBAMzB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iBAInF;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,oBAInF;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,oBAMb;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,oBAM5C;AAID,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,oBAMrD;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,oBAMrD;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAEtF;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,oBAM7C;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAIzF"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateless HTTP client for the 2FA OTP service.
|
|
3
|
+
*
|
|
4
|
+
* Every method receives the base URL and workspace API key so the caller
|
|
5
|
+
* (tool handler) can resolve them from session/cache.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_BASE_URL = "https://tfa-otp.minicor.com";
|
|
8
|
+
export function getTfaBaseUrl() {
|
|
9
|
+
return process.env.TFA_OTP_URL || DEFAULT_BASE_URL;
|
|
10
|
+
}
|
|
11
|
+
function normalizeUrl(base) {
|
|
12
|
+
return base.replace(/\/+$/, "");
|
|
13
|
+
}
|
|
14
|
+
async function request(url, apiKey, init) {
|
|
15
|
+
const res = await fetch(url, {
|
|
16
|
+
...init,
|
|
17
|
+
headers: {
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
"X-API-Key": apiKey,
|
|
20
|
+
...init?.headers,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
const body = await res.text().catch(() => "");
|
|
25
|
+
throw new Error(`2FA API ${init?.method ?? "GET"} ${url} returned ${res.status}: ${body}`);
|
|
26
|
+
}
|
|
27
|
+
if (res.status === 204)
|
|
28
|
+
return undefined;
|
|
29
|
+
return res.json();
|
|
30
|
+
}
|
|
31
|
+
function url(base, path) {
|
|
32
|
+
return `${normalizeUrl(base)}${path}`;
|
|
33
|
+
}
|
|
34
|
+
// ── Channels ──────────────────────────────────────────────────
|
|
35
|
+
export async function provisionPhone(baseUrl, apiKey) {
|
|
36
|
+
return request(url(baseUrl, "/channels/phone"), apiKey, { method: "POST" });
|
|
37
|
+
}
|
|
38
|
+
export async function provisionEmail(baseUrl, apiKey) {
|
|
39
|
+
return request(url(baseUrl, "/channels/email"), apiKey, { method: "POST" });
|
|
40
|
+
}
|
|
41
|
+
export async function listChannels(baseUrl, apiKey, opts) {
|
|
42
|
+
const params = new URLSearchParams();
|
|
43
|
+
if (opts?.type)
|
|
44
|
+
params.set("type", opts.type);
|
|
45
|
+
const qs = params.toString();
|
|
46
|
+
return request(url(baseUrl, `/channels${qs ? `?${qs}` : ""}`), apiKey);
|
|
47
|
+
}
|
|
48
|
+
export async function deleteChannel(baseUrl, apiKey, channelId) {
|
|
49
|
+
return request(url(baseUrl, `/channels/${channelId}`), apiKey, {
|
|
50
|
+
method: "DELETE",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// ── Secrets ───────────────────────────────────────────────────
|
|
54
|
+
export async function createSecret(baseUrl, apiKey, data) {
|
|
55
|
+
return request(url(baseUrl, "/secrets"), apiKey, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
body: JSON.stringify(data),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export async function listSecrets(baseUrl, apiKey, opts) {
|
|
61
|
+
const params = new URLSearchParams();
|
|
62
|
+
if (opts?.site)
|
|
63
|
+
params.set("site", opts.site);
|
|
64
|
+
const qs = params.toString();
|
|
65
|
+
return request(url(baseUrl, `/secrets${qs ? `?${qs}` : ""}`), apiKey);
|
|
66
|
+
}
|
|
67
|
+
export async function deleteSecret(baseUrl, apiKey, secretId) {
|
|
68
|
+
return request(url(baseUrl, `/secrets/${secretId}`), apiKey, {
|
|
69
|
+
method: "DELETE",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export async function generateTotp(baseUrl, apiKey, secretId) {
|
|
73
|
+
return request(url(baseUrl, `/secrets/${secretId}/generate`), apiKey, {
|
|
74
|
+
method: "POST",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export async function verifyTotp(baseUrl, apiKey, secretId, code) {
|
|
78
|
+
return request(url(baseUrl, `/secrets/${secretId}/verify`), apiKey, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
body: JSON.stringify({ code }),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
export async function parseQr(baseUrl, apiKey, data) {
|
|
84
|
+
return request(url(baseUrl, "/secrets/parse-qr"), apiKey, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
body: JSON.stringify(data),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// ── Challenges ────────────────────────────────────────────────
|
|
90
|
+
export async function requestSmsOtp(baseUrl, apiKey, data) {
|
|
91
|
+
return request(url(baseUrl, "/challenges/sms-otp"), apiKey, {
|
|
92
|
+
method: "POST",
|
|
93
|
+
body: JSON.stringify(data),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
export async function requestEmailOtp(baseUrl, apiKey, data) {
|
|
97
|
+
return request(url(baseUrl, "/challenges/email-otp"), apiKey, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
body: JSON.stringify(data),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export async function getChallenge(baseUrl, apiKey, challengeId) {
|
|
103
|
+
return request(url(baseUrl, `/challenges/${challengeId}`), apiKey);
|
|
104
|
+
}
|
|
105
|
+
export async function resolveChallenge(baseUrl, apiKey, challengeId, data) {
|
|
106
|
+
return request(url(baseUrl, `/challenges/${challengeId}/resolve`), apiKey, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
body: JSON.stringify(data),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export async function cancelChallenge(baseUrl, apiKey, challengeId) {
|
|
112
|
+
return request(url(baseUrl, `/challenges/${challengeId}`), apiKey, {
|
|
113
|
+
method: "DELETE",
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=tfa-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa-client.js","sourceRoot":"","sources":["../src/tfa-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa.d.ts","sourceRoot":"","sources":["../../src/tools/tfa.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA4C5C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,QAqPtC"}
|