@minicor/mcp-server 2.0.4 → 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 +23 -0
- 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/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.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/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,6 +106,28 @@ Use the `get_lds_setup_guide` tool for detailed step-by-step instructions.
|
|
|
106
106
|
| `test_workflow_step` | Run a single step in isolation |
|
|
107
107
|
| `preview_flow_changes` / `compare_flow_versions` | Diff code before deploying |
|
|
108
108
|
|
|
109
|
+
### 2FA / OTP
|
|
110
|
+
|
|
111
|
+
| Tool | What it does |
|
|
112
|
+
| --------------------- | -------------------------------------------------------------------- |
|
|
113
|
+
| `tfa_provision_phone` | Buy a Twilio phone number for the workspace (SMS webhook auto-configured) |
|
|
114
|
+
| `tfa_provision_email` | Generate a Mailgun email address for OTP capture |
|
|
115
|
+
| `tfa_list_channels` | List all provisioned phone numbers and email addresses |
|
|
116
|
+
| `tfa_delete_channel` | Remove a channel (releases Twilio number if phone) |
|
|
117
|
+
| `tfa_register_secret` | Store a TOTP secret (base32 or otpauth:// URI), encrypted at rest |
|
|
118
|
+
| `tfa_list_secrets` | List stored TOTP secrets for the workspace |
|
|
119
|
+
| `tfa_delete_secret` | Remove a stored TOTP secret |
|
|
120
|
+
| `tfa_generate_totp` | Get the current 6-digit TOTP code + seconds until expiry |
|
|
121
|
+
| `tfa_verify_totp` | Verify a TOTP code against a stored secret |
|
|
122
|
+
| `tfa_parse_qr` | Parse a QR code image to extract TOTP parameters |
|
|
123
|
+
| `tfa_request_sms_otp` | Wait for an SMS OTP (blocks until SMS arrives or timeout) |
|
|
124
|
+
| `tfa_request_email_otp` | Wait for an email OTP (blocks until email arrives or timeout) |
|
|
125
|
+
| `tfa_get_challenge` | Check the status of a pending challenge |
|
|
126
|
+
| `tfa_resolve_challenge` | Manually resolve a challenge (for captchas or Slack-provided codes)|
|
|
127
|
+
| `tfa_cancel_challenge`| Cancel a pending challenge |
|
|
128
|
+
|
|
129
|
+
Workflows that encounter 2FA prompts use these tools to auto-resolve OTP challenges. Provision channels once per workspace, store the IDs in config stores, and reference them with `{{config.sms_channel_id}}` or `{{config.totp_secret_id}}` at runtime.
|
|
130
|
+
|
|
109
131
|
### Config Stores
|
|
110
132
|
|
|
111
133
|
| Tool | What it does |
|
|
@@ -132,6 +154,7 @@ Scripts reference credentials as `{{config.propertyKey}}` — resolved at runtim
|
|
|
132
154
|
| `build-rpa-workflow` | Guided automation building: strategy selection, iterative build loop, Minicor testing, deployment |
|
|
133
155
|
| `debug-workflow-execution` | Analyze a failed execution with VM-aware debugging and replay |
|
|
134
156
|
| `minicor-workflow-guide` | Full workflow specification: step types, data access, keywords, libraries |
|
|
157
|
+
| `2fa-workflow-guide` | Handling 2FA in workflows: provisioning channels, TOTP secrets, auto-resolving OTP codes |
|
|
135
158
|
|
|
136
159
|
## Auth
|
|
137
160
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tfa-client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import * as tfa from "../tfa-client.js";
|
|
3
|
+
describe("getTfaBaseUrl", () => {
|
|
4
|
+
const original = process.env.TFA_OTP_URL;
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
if (original !== undefined) {
|
|
7
|
+
process.env.TFA_OTP_URL = original;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
delete process.env.TFA_OTP_URL;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
it("returns default when env var is unset", () => {
|
|
14
|
+
delete process.env.TFA_OTP_URL;
|
|
15
|
+
expect(tfa.getTfaBaseUrl()).toBe("https://tfa-otp.minicor.com");
|
|
16
|
+
});
|
|
17
|
+
it("returns env var when set", () => {
|
|
18
|
+
process.env.TFA_OTP_URL = "http://localhost:3847";
|
|
19
|
+
expect(tfa.getTfaBaseUrl()).toBe("http://localhost:3847");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe("tfa-client HTTP calls", () => {
|
|
23
|
+
const BASE = "https://tfa-otp.minicor.com";
|
|
24
|
+
const API_KEY = "test-key-123";
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
vi.stubGlobal("fetch", vi.fn());
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
vi.restoreAllMocks();
|
|
30
|
+
});
|
|
31
|
+
function mockFetch(status, body) {
|
|
32
|
+
fetch.mockResolvedValue({
|
|
33
|
+
ok: status >= 200 && status < 300,
|
|
34
|
+
status,
|
|
35
|
+
json: () => Promise.resolve(body),
|
|
36
|
+
text: () => Promise.resolve(JSON.stringify(body)),
|
|
37
|
+
headers: new Headers({ "content-type": "application/json" }),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function lastFetchCall() {
|
|
41
|
+
const calls = fetch.mock.calls;
|
|
42
|
+
return { url: calls[0][0], init: calls[0][1] };
|
|
43
|
+
}
|
|
44
|
+
// ── Channels ──
|
|
45
|
+
it("provisionPhone calls POST /channels/phone with API key header", async () => {
|
|
46
|
+
mockFetch(201, { id: "ch_123", address: "+15551234567" });
|
|
47
|
+
const result = await tfa.provisionPhone(BASE, API_KEY);
|
|
48
|
+
const { url, init } = lastFetchCall();
|
|
49
|
+
expect(url).toBe(`${BASE}/channels/phone`);
|
|
50
|
+
expect(init.method).toBe("POST");
|
|
51
|
+
expect(init.headers["X-API-Key"]).toBe(API_KEY);
|
|
52
|
+
expect(result).toEqual({ id: "ch_123", address: "+15551234567" });
|
|
53
|
+
});
|
|
54
|
+
it("provisionEmail calls POST /channels/email", async () => {
|
|
55
|
+
mockFetch(201, { id: "ch_456", address: "rpa-abc@otp.minicor.com" });
|
|
56
|
+
await tfa.provisionEmail(BASE, API_KEY);
|
|
57
|
+
const { url, init } = lastFetchCall();
|
|
58
|
+
expect(url).toBe(`${BASE}/channels/email`);
|
|
59
|
+
expect(init.method).toBe("POST");
|
|
60
|
+
});
|
|
61
|
+
it("listChannels calls GET /channels with optional type filter", async () => {
|
|
62
|
+
mockFetch(200, []);
|
|
63
|
+
await tfa.listChannels(BASE, API_KEY, { type: "phone" });
|
|
64
|
+
const { url } = lastFetchCall();
|
|
65
|
+
expect(url).toBe(`${BASE}/channels?type=phone`);
|
|
66
|
+
});
|
|
67
|
+
it("listChannels omits query string when no filter", async () => {
|
|
68
|
+
mockFetch(200, []);
|
|
69
|
+
await tfa.listChannels(BASE, API_KEY);
|
|
70
|
+
const { url } = lastFetchCall();
|
|
71
|
+
expect(url).toBe(`${BASE}/channels`);
|
|
72
|
+
});
|
|
73
|
+
it("deleteChannel calls DELETE /channels/:id", async () => {
|
|
74
|
+
fetch.mockResolvedValue({
|
|
75
|
+
ok: true,
|
|
76
|
+
status: 204,
|
|
77
|
+
json: () => Promise.resolve(undefined),
|
|
78
|
+
text: () => Promise.resolve(""),
|
|
79
|
+
headers: new Headers(),
|
|
80
|
+
});
|
|
81
|
+
await tfa.deleteChannel(BASE, API_KEY, "ch_123");
|
|
82
|
+
const { url, init } = lastFetchCall();
|
|
83
|
+
expect(url).toBe(`${BASE}/channels/ch_123`);
|
|
84
|
+
expect(init.method).toBe("DELETE");
|
|
85
|
+
});
|
|
86
|
+
// ── Secrets ──
|
|
87
|
+
it("createSecret sends TOTP secret data", async () => {
|
|
88
|
+
mockFetch(201, { id: "sec_123" });
|
|
89
|
+
await tfa.createSecret(BASE, API_KEY, {
|
|
90
|
+
type: "totp",
|
|
91
|
+
name: "Acme",
|
|
92
|
+
value: "JBSWY3DPEHPK3PXP",
|
|
93
|
+
site: "acme.com",
|
|
94
|
+
});
|
|
95
|
+
const { url, init } = lastFetchCall();
|
|
96
|
+
expect(url).toBe(`${BASE}/secrets`);
|
|
97
|
+
expect(init.method).toBe("POST");
|
|
98
|
+
const body = JSON.parse(init.body);
|
|
99
|
+
expect(body.type).toBe("totp");
|
|
100
|
+
expect(body.name).toBe("Acme");
|
|
101
|
+
expect(body.value).toBe("JBSWY3DPEHPK3PXP");
|
|
102
|
+
});
|
|
103
|
+
it("createSecret supports otpauth URI", async () => {
|
|
104
|
+
mockFetch(201, { id: "sec_456" });
|
|
105
|
+
await tfa.createSecret(BASE, API_KEY, {
|
|
106
|
+
type: "totp",
|
|
107
|
+
name: "Acme",
|
|
108
|
+
uri: "otpauth://totp/Acme:user@example.com?secret=JBSWY3DPEHPK3PXP",
|
|
109
|
+
});
|
|
110
|
+
const body = JSON.parse(lastFetchCall().init.body);
|
|
111
|
+
expect(body.uri).toContain("otpauth://");
|
|
112
|
+
expect(body.value).toBeUndefined();
|
|
113
|
+
});
|
|
114
|
+
it("listSecrets with site filter", async () => {
|
|
115
|
+
mockFetch(200, []);
|
|
116
|
+
await tfa.listSecrets(BASE, API_KEY, { site: "acme.com" });
|
|
117
|
+
expect(lastFetchCall().url).toBe(`${BASE}/secrets?site=acme.com`);
|
|
118
|
+
});
|
|
119
|
+
it("generateTotp calls POST /secrets/:id/generate", async () => {
|
|
120
|
+
mockFetch(200, { code: "482901", expiresIn: 14 });
|
|
121
|
+
const result = await tfa.generateTotp(BASE, API_KEY, "sec_123");
|
|
122
|
+
expect(lastFetchCall().url).toBe(`${BASE}/secrets/sec_123/generate`);
|
|
123
|
+
expect(result).toEqual({ code: "482901", expiresIn: 14 });
|
|
124
|
+
});
|
|
125
|
+
it("verifyTotp sends code in body", async () => {
|
|
126
|
+
mockFetch(200, { valid: true, delta: 0 });
|
|
127
|
+
await tfa.verifyTotp(BASE, API_KEY, "sec_123", "482901");
|
|
128
|
+
const { url, init } = lastFetchCall();
|
|
129
|
+
expect(url).toBe(`${BASE}/secrets/sec_123/verify`);
|
|
130
|
+
expect(JSON.parse(init.body)).toEqual({ code: "482901" });
|
|
131
|
+
});
|
|
132
|
+
it("parseQr sends imageUrl", async () => {
|
|
133
|
+
mockFetch(200, { uri: "otpauth://totp/...", secretPreview: "****PXP" });
|
|
134
|
+
await tfa.parseQr(BASE, API_KEY, { imageUrl: "https://example.com/qr.png" });
|
|
135
|
+
const body = JSON.parse(lastFetchCall().init.body);
|
|
136
|
+
expect(body.imageUrl).toBe("https://example.com/qr.png");
|
|
137
|
+
});
|
|
138
|
+
// ── Challenges ──
|
|
139
|
+
it("requestSmsOtp sends channelId and timeout", async () => {
|
|
140
|
+
mockFetch(200, { status: "resolved", resolution: { value: "123456" } });
|
|
141
|
+
await tfa.requestSmsOtp(BASE, API_KEY, {
|
|
142
|
+
channelId: "ch_phone1",
|
|
143
|
+
timeoutSeconds: 60,
|
|
144
|
+
});
|
|
145
|
+
const body = JSON.parse(lastFetchCall().init.body);
|
|
146
|
+
expect(body.channelId).toBe("ch_phone1");
|
|
147
|
+
expect(body.timeoutSeconds).toBe(60);
|
|
148
|
+
});
|
|
149
|
+
it("requestEmailOtp hits /challenges/email-otp", async () => {
|
|
150
|
+
mockFetch(200, { status: "resolved" });
|
|
151
|
+
await tfa.requestEmailOtp(BASE, API_KEY, { channelId: "ch_email1" });
|
|
152
|
+
expect(lastFetchCall().url).toBe(`${BASE}/challenges/email-otp`);
|
|
153
|
+
});
|
|
154
|
+
it("getChallenge hits GET /challenges/:id", async () => {
|
|
155
|
+
mockFetch(200, { id: "chal_1", status: "pending" });
|
|
156
|
+
await tfa.getChallenge(BASE, API_KEY, "chal_1");
|
|
157
|
+
expect(lastFetchCall().url).toBe(`${BASE}/challenges/chal_1`);
|
|
158
|
+
});
|
|
159
|
+
it("resolveChallenge sends value and resolvedBy", async () => {
|
|
160
|
+
mockFetch(200, { status: "resolved" });
|
|
161
|
+
await tfa.resolveChallenge(BASE, API_KEY, "chal_1", {
|
|
162
|
+
value: "xK9mP2",
|
|
163
|
+
resolvedBy: "manual",
|
|
164
|
+
});
|
|
165
|
+
const { url, init } = lastFetchCall();
|
|
166
|
+
expect(url).toBe(`${BASE}/challenges/chal_1/resolve`);
|
|
167
|
+
expect(JSON.parse(init.body)).toEqual({
|
|
168
|
+
value: "xK9mP2",
|
|
169
|
+
resolvedBy: "manual",
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
it("cancelChallenge calls DELETE /challenges/:id", async () => {
|
|
173
|
+
mockFetch(200, { status: "cancelled" });
|
|
174
|
+
await tfa.cancelChallenge(BASE, API_KEY, "chal_1");
|
|
175
|
+
const { url, init } = lastFetchCall();
|
|
176
|
+
expect(url).toBe(`${BASE}/challenges/chal_1`);
|
|
177
|
+
expect(init.method).toBe("DELETE");
|
|
178
|
+
});
|
|
179
|
+
// ── Error handling ──
|
|
180
|
+
it("throws on non-ok response with status and body", async () => {
|
|
181
|
+
mockFetch(404, { error: "Not found" });
|
|
182
|
+
await expect(tfa.getChallenge(BASE, API_KEY, "bad_id")).rejects.toThrow(/2FA API.*404/);
|
|
183
|
+
});
|
|
184
|
+
// ── URL normalization ──
|
|
185
|
+
it("strips trailing slashes from base URL", async () => {
|
|
186
|
+
mockFetch(200, []);
|
|
187
|
+
await tfa.listChannels("https://example.com///", API_KEY);
|
|
188
|
+
expect(lastFetchCall().url).toBe("https://example.com/channels");
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
//# sourceMappingURL=tfa-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa-client.test.js","sourceRoot":"","sources":["../../src/__tests__/tfa-client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAExC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAEzC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,uBAAuB,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,MAAM,IAAI,GAAG,6BAA6B,CAAC;IAC3C,MAAM,OAAO,GAAG,cAAc,CAAC;IAE/B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,SAAS,SAAS,CAAC,MAAc,EAAE,IAAa;QAC7C,KAAkC,CAAC,iBAAiB,CAAC;YACpD,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG;YACjC,MAAM;YACN,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;YACjC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,EAAE,IAAI,OAAO,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;SAC7D,CAAC,CAAC;IACL,CAAC;IAED,SAAS,aAAa;QACpB,MAAM,KAAK,GAAI,KAAkC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7D,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAgB,EAAE,CAAC;IAC1E,CAAC;IAED,iBAAiB;IAEjB,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,iBAAiB,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,CAAE,IAAI,CAAC,OAAkC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACrE,MAAM,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,iBAAiB,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnB,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,MAAM,EAAE,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,sBAAsB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnB,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,EAAE,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACvD,KAAkC,CAAC,iBAAiB,CAAC;YACpD,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;YACtC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,IAAI,OAAO,EAAE;SACvB,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAEhB,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAClC,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE;YACpC,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,kBAAkB;YACzB,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAClC,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE;YACpC,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,8DAA8D;SACpE,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnB,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3D,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,wBAAwB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,SAAS,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAChE,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,2BAA2B,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,SAAS,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACzD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,yBAAyB,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,SAAS,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC;QACxE,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,4BAA4B,EAAE,CAAC,CAAC;QAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,mBAAmB;IAEnB,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxE,MAAM,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE;YACrC,SAAS,EAAE,WAAW;YACtB,cAAc,EAAE,EAAE;SACnB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QACvC,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QACrE,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,uBAAuB,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QACvC,MAAM,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE;YAClD,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,4BAA4B,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAc,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;QACxC,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,uBAAuB;IAEvB,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,SAAS,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACvC,MAAM,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACrE,cAAc,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAE1B,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnB,MAAM,GAAG,CAAC,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AA4DH,wBAAgB,UAAU,IAAI,MAAM,CAKnC"}
|
package/dist/index.js
CHANGED
|
@@ -17,9 +17,11 @@ import { register as registerConfigStores } from "./tools/config-stores.js";
|
|
|
17
17
|
import { register as registerSyncTools } from "./tools/sync-tools.js";
|
|
18
18
|
import { register as registerVm } from "./tools/vm.js";
|
|
19
19
|
import { register as registerVmRpa } from "./tools/vm-rpa.js";
|
|
20
|
+
import { register as registerTfa } from "./tools/tfa.js";
|
|
20
21
|
import { register as registerWorkflowGuide } from "./prompts/workflow-guide.js";
|
|
21
22
|
import { register as registerDebugExecution } from "./prompts/debug-execution.js";
|
|
22
23
|
import { register as registerBuildRpa } from "./prompts/build-rpa.js";
|
|
24
|
+
import { register as registerTfaGuide } from "./prompts/tfa-guide.js";
|
|
23
25
|
// ─── Token management ────────────────────────────────────────
|
|
24
26
|
const REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
25
27
|
function readStoredTokens() {
|
|
@@ -152,9 +154,11 @@ function registerAll() {
|
|
|
152
154
|
registerSyncTools(deps);
|
|
153
155
|
registerVm(deps);
|
|
154
156
|
registerVmRpa(deps);
|
|
157
|
+
registerTfa(deps);
|
|
155
158
|
registerWorkflowGuide(deps);
|
|
156
159
|
registerDebugExecution(deps);
|
|
157
160
|
registerBuildRpa(deps);
|
|
161
|
+
registerTfaGuide(deps);
|
|
158
162
|
}
|
|
159
163
|
// ─── Main ────────────────────────────────────────────────────
|
|
160
164
|
async function main() {
|
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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"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ok, text } from "../helpers.js";
|
|
3
|
+
import * as tfa from "../tfa-client.js";
|
|
4
|
+
// Workspace API key cache: workspaceId → apiKey
|
|
5
|
+
const apiKeyCache = new Map();
|
|
6
|
+
async function resolveApiKey(deps, workspaceId) {
|
|
7
|
+
const cached = apiKeyCache.get(workspaceId);
|
|
8
|
+
if (cached)
|
|
9
|
+
return cached;
|
|
10
|
+
const keys = await deps.client().listApiKeys(workspaceId);
|
|
11
|
+
const arr = Array.isArray(keys) ? keys : keys?.data ?? [];
|
|
12
|
+
const active = arr.find((k) => k.status !== "revoked") ?? arr[0];
|
|
13
|
+
if (!active?.key) {
|
|
14
|
+
throw new Error(`No API key found for workspace ${workspaceId}. Create one in the Minicor dashboard first.`);
|
|
15
|
+
}
|
|
16
|
+
apiKeyCache.set(workspaceId, active.key);
|
|
17
|
+
return active.key;
|
|
18
|
+
}
|
|
19
|
+
async function tfaSafe(deps, workspaceId, fn) {
|
|
20
|
+
try {
|
|
21
|
+
const apiKey = await resolveApiKey(deps, workspaceId);
|
|
22
|
+
const baseUrl = tfa.getTfaBaseUrl();
|
|
23
|
+
const result = await fn(baseUrl, apiKey);
|
|
24
|
+
if (result === undefined)
|
|
25
|
+
return text("Done.");
|
|
26
|
+
return ok(result);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
// Clear cache on auth errors so next call re-resolves
|
|
30
|
+
if (e.message?.includes("401") || e.message?.includes("403")) {
|
|
31
|
+
apiKeyCache.delete(workspaceId);
|
|
32
|
+
}
|
|
33
|
+
return text(`Error: ${e.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function register(deps) {
|
|
37
|
+
const { server } = deps;
|
|
38
|
+
// ── Channels ──────────────────────────────────────────────
|
|
39
|
+
server.tool("tfa_provision_phone", "Purchase a new Twilio phone number for this workspace. SMS webhook is auto-configured. Use tfa_list_channels to see it afterward.", {
|
|
40
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
41
|
+
}, async ({ workspaceId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.provisionPhone(base, key)));
|
|
42
|
+
server.tool("tfa_provision_email", "Generate a unique Mailgun email address for this workspace. Emails sent to this address are captured automatically for OTP extraction.", {
|
|
43
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
44
|
+
}, async ({ workspaceId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.provisionEmail(base, key)));
|
|
45
|
+
server.tool("tfa_list_channels", "List all phone numbers and email addresses registered for this workspace", {
|
|
46
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
47
|
+
type: z
|
|
48
|
+
.enum(["phone", "email"])
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("Filter by channel type"),
|
|
51
|
+
}, async ({ workspaceId, type }) => tfaSafe(deps, workspaceId, (base, key) => tfa.listChannels(base, key, { type })));
|
|
52
|
+
server.tool("tfa_delete_channel", "Remove a phone or email channel. If it's a Twilio phone number, the number is released.", {
|
|
53
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
54
|
+
channelId: z.string().describe("Channel ID (e.g. ch_abc123)"),
|
|
55
|
+
}, async ({ workspaceId, channelId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.deleteChannel(base, key, channelId)));
|
|
56
|
+
// ── Secrets ───────────────────────────────────────────────
|
|
57
|
+
server.tool("tfa_register_secret", "Store a TOTP authenticator secret for this workspace. Accepts either a raw base32 secret or an otpauth:// URI. The secret is encrypted at rest.", {
|
|
58
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
59
|
+
name: z.string().describe("Label for this secret (e.g. site name)"),
|
|
60
|
+
value: z.string().optional().describe("Raw base32 TOTP secret"),
|
|
61
|
+
uri: z
|
|
62
|
+
.string()
|
|
63
|
+
.optional()
|
|
64
|
+
.describe("otpauth:// URI (alternative to value)"),
|
|
65
|
+
site: z.string().optional().describe("Site this secret is for"),
|
|
66
|
+
}, async ({ workspaceId, name, value, uri, site }) => {
|
|
67
|
+
if (!value && !uri) {
|
|
68
|
+
return text("Error: Either 'value' (base32) or 'uri' (otpauth://) is required.");
|
|
69
|
+
}
|
|
70
|
+
return tfaSafe(deps, workspaceId, (base, key) => tfa.createSecret(base, key, { type: "totp", name, value, uri, site }));
|
|
71
|
+
});
|
|
72
|
+
server.tool("tfa_list_secrets", "List all stored TOTP secrets for this workspace", {
|
|
73
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
74
|
+
site: z.string().optional().describe("Filter by site"),
|
|
75
|
+
}, async ({ workspaceId, site }) => tfaSafe(deps, workspaceId, (base, key) => tfa.listSecrets(base, key, { site })));
|
|
76
|
+
server.tool("tfa_delete_secret", "Remove a stored TOTP secret", {
|
|
77
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
78
|
+
secretId: z.string().describe("Secret ID (e.g. sec_abc123)"),
|
|
79
|
+
}, async ({ workspaceId, secretId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.deleteSecret(base, key, secretId)));
|
|
80
|
+
server.tool("tfa_generate_totp", "Generate the current 6-digit TOTP code for a stored secret. Returns the code and seconds until it expires.", {
|
|
81
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
82
|
+
secretId: z.string().describe("Secret ID (e.g. sec_abc123)"),
|
|
83
|
+
}, async ({ workspaceId, secretId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.generateTotp(base, key, secretId)));
|
|
84
|
+
server.tool("tfa_verify_totp", "Verify a TOTP code against a stored secret. Returns whether the code is valid and the time delta.", {
|
|
85
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
86
|
+
secretId: z.string().describe("Secret ID (e.g. sec_abc123)"),
|
|
87
|
+
code: z.string().describe("6-digit TOTP code to verify"),
|
|
88
|
+
}, async ({ workspaceId, secretId, code }) => tfaSafe(deps, workspaceId, (base, key) => tfa.verifyTotp(base, key, secretId, code)));
|
|
89
|
+
server.tool("tfa_parse_qr", "Parse a QR code image (base64 or URL) to extract TOTP parameters like secret, issuer, algorithm. Useful for automated 2FA enrollment.", {
|
|
90
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
91
|
+
image: z
|
|
92
|
+
.string()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe("Base64-encoded QR code image"),
|
|
95
|
+
imageUrl: z
|
|
96
|
+
.string()
|
|
97
|
+
.optional()
|
|
98
|
+
.describe("URL of the QR code image"),
|
|
99
|
+
}, async ({ workspaceId, image, imageUrl }) => {
|
|
100
|
+
if (!image && !imageUrl) {
|
|
101
|
+
return text("Error: Either 'image' (base64) or 'imageUrl' is required.");
|
|
102
|
+
}
|
|
103
|
+
return tfaSafe(deps, workspaceId, (base, key) => tfa.parseQr(base, key, { image, imageUrl }));
|
|
104
|
+
});
|
|
105
|
+
// ── Challenges ────────────────────────────────────────────
|
|
106
|
+
server.tool("tfa_request_sms_otp", "Wait for an SMS OTP code. Creates a challenge and blocks until the SMS arrives via Twilio or the timeout expires. Returns the OTP code.", {
|
|
107
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
108
|
+
channelId: z
|
|
109
|
+
.string()
|
|
110
|
+
.describe("Phone channel ID. Use tfa_list_channels to find it."),
|
|
111
|
+
timeoutSeconds: z
|
|
112
|
+
.number()
|
|
113
|
+
.optional()
|
|
114
|
+
.default(120)
|
|
115
|
+
.describe("Max seconds to wait (default 120)"),
|
|
116
|
+
}, async ({ workspaceId, channelId, timeoutSeconds }) => tfaSafe(deps, workspaceId, (base, key) => tfa.requestSmsOtp(base, key, { channelId, timeoutSeconds })));
|
|
117
|
+
server.tool("tfa_request_email_otp", "Wait for an email OTP code. Creates a challenge and blocks until the email arrives via Mailgun or the timeout expires. Returns the OTP code.", {
|
|
118
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
119
|
+
channelId: z
|
|
120
|
+
.string()
|
|
121
|
+
.describe("Email channel ID. Use tfa_list_channels to find it."),
|
|
122
|
+
timeoutSeconds: z
|
|
123
|
+
.number()
|
|
124
|
+
.optional()
|
|
125
|
+
.default(120)
|
|
126
|
+
.describe("Max seconds to wait (default 120)"),
|
|
127
|
+
}, async ({ workspaceId, channelId, timeoutSeconds }) => tfaSafe(deps, workspaceId, (base, key) => tfa.requestEmailOtp(base, key, { channelId, timeoutSeconds })));
|
|
128
|
+
server.tool("tfa_get_challenge", "Check the status of a pending 2FA challenge", {
|
|
129
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
130
|
+
challengeId: z.string().describe("Challenge ID"),
|
|
131
|
+
}, async ({ workspaceId, challengeId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.getChallenge(base, key, challengeId)));
|
|
132
|
+
server.tool("tfa_resolve_challenge", "Manually resolve a 2FA challenge with a value. Use this for captcha solutions or when auto-parsing failed and a human provided the code via Slack.", {
|
|
133
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
134
|
+
challengeId: z.string().describe("Challenge ID"),
|
|
135
|
+
value: z.string().describe("The OTP code or captcha solution"),
|
|
136
|
+
resolvedBy: z
|
|
137
|
+
.string()
|
|
138
|
+
.optional()
|
|
139
|
+
.describe("Who resolved it (default: 'manual')"),
|
|
140
|
+
}, async ({ workspaceId, challengeId, value, resolvedBy }) => tfaSafe(deps, workspaceId, (base, key) => tfa.resolveChallenge(base, key, challengeId, { value, resolvedBy })));
|
|
141
|
+
server.tool("tfa_cancel_challenge", "Cancel a pending 2FA challenge", {
|
|
142
|
+
workspaceId: z.number().describe("Workspace ID"),
|
|
143
|
+
challengeId: z.string().describe("Challenge ID"),
|
|
144
|
+
}, async ({ workspaceId, challengeId }) => tfaSafe(deps, workspaceId, (base, key) => tfa.cancelChallenge(base, key, challengeId)));
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=tfa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfa.js","sourceRoot":"","sources":["../../src/tools/tfa.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minicor/mcp-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "Desktop and browser RPA automation, workflow management, and AI-powered debugging for the Minicor platform. Formerly Laminar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|