@solarisdk/mcp 0.3.3 → 0.4.0
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/dist/browser.js +44 -2
- package/dist/solari-mcp-http.bundle.cjs +29 -4
- package/dist/solari-mcp.bundle.cjs +29 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/browser.js
CHANGED
|
@@ -156,6 +156,8 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
156
156
|
captcha: z.boolean().optional(),
|
|
157
157
|
recording: z.boolean().optional(),
|
|
158
158
|
profileId: z.string().optional(),
|
|
159
|
+
/** Defaults to ON. Pass false to never auto-sign-in on this session. */
|
|
160
|
+
autoLogin: z.boolean().optional(),
|
|
159
161
|
},
|
|
160
162
|
handler: async (a) => {
|
|
161
163
|
// STEALTH IS THE DEFAULT. Models consistently declined to opt in when it
|
|
@@ -203,6 +205,13 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
203
205
|
body.proxy = a.proxy;
|
|
204
206
|
if (a.profileId)
|
|
205
207
|
body.profileId = a.profileId;
|
|
208
|
+
// Auto-login is ON by default. If the account has connected a password
|
|
209
|
+
// manager and configured this site, the gateway signs the session in on
|
|
210
|
+
// its own — the agent never sees or handles the credential. Costs
|
|
211
|
+
// nothing when nothing is configured: the gateway finds no connection
|
|
212
|
+
// and the flow is exactly as before.
|
|
213
|
+
if (a.autoLogin !== false)
|
|
214
|
+
body.autoLogin = true;
|
|
206
215
|
const res = await api(cfg, "POST", "/sessions", body);
|
|
207
216
|
if (res.status !== 201)
|
|
208
217
|
await apiError(res, "session create");
|
|
@@ -286,7 +295,12 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
286
295
|
},
|
|
287
296
|
},
|
|
288
297
|
solari_browser_login: {
|
|
289
|
-
description: "
|
|
298
|
+
description: "Get this session signed in. Call it the moment you hit a login form, a 2FA prompt, or "
|
|
299
|
+
+ "anything asking for a password — you must never handle credentials yourself.\n"
|
|
300
|
+
+ "It tries the account's connected password manager FIRST: if one is set up for this "
|
|
301
|
+
+ "site, you are signed in automatically and NO human is involved — the reply says "
|
|
302
|
+
+ 'signedIn:true and you simply carry on. Otherwise it falls back to asking a human.\n'
|
|
303
|
+
+ "Two ways to call it:\n" +
|
|
290
304
|
"HOT — pass `sessionId` when you are ALREADY on a login wall mid-task. The user gets a " +
|
|
291
305
|
"live view of the exact page you are on and types into it; you resume on that same page.\n" +
|
|
292
306
|
"COLD — pass `profileName` when you know a task will need a login and no session is open " +
|
|
@@ -350,6 +364,29 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
350
364
|
}
|
|
351
365
|
// ── HOT: rescue the live session ─────────────────────────────────
|
|
352
366
|
const e = need(sessionId);
|
|
367
|
+
// Try the account's password manager FIRST. If a vault is connected and
|
|
368
|
+
// this site is configured, the gateway signs in on its own and no human
|
|
369
|
+
// is involved at all — we never see the credential either way. Only
|
|
370
|
+
// escalate to a human when that cannot work. Best-effort: any failure
|
|
371
|
+
// here just falls through to the handoff below, which is the behaviour
|
|
372
|
+
// that existed before.
|
|
373
|
+
try {
|
|
374
|
+
const auto = await api(cfg, "POST", `/sessions/${encodeURIComponent(sessionId)}/autologin`, {});
|
|
375
|
+
if (auto.status === 200) {
|
|
376
|
+
const r = (await auto.json());
|
|
377
|
+
if (r.outcome === "already_authenticated" || r.outcome === "vault_login") {
|
|
378
|
+
return text({
|
|
379
|
+
mode: "auto",
|
|
380
|
+
signedIn: true,
|
|
381
|
+
via: r.outcome === "vault_login" ? "password manager" : "saved session",
|
|
382
|
+
next: "You are signed in — carry on. No human was needed.",
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
/* fall through to the human handoff */
|
|
389
|
+
}
|
|
353
390
|
const res = await api(cfg, "POST", `/sessions/${encodeURIComponent(sessionId)}/handoff`, { reason: a.reason });
|
|
354
391
|
if (res.status !== 200)
|
|
355
392
|
await apiError(res, "handoff request");
|
|
@@ -363,10 +400,15 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
363
400
|
catch {
|
|
364
401
|
/* already gone — that is the point */
|
|
365
402
|
}
|
|
403
|
+
// Prefer the short link when the gateway offers one — it is far easier
|
|
404
|
+
// to relay to someone on a phone. Fall back to the long URL for older
|
|
405
|
+
// gateways that do not return shortUrl yet.
|
|
406
|
+
const showUrl = h.shortUrl ?? h.url;
|
|
366
407
|
return text({
|
|
367
408
|
mode: "hot",
|
|
368
409
|
handoffId: h.handoffId,
|
|
369
|
-
url:
|
|
410
|
+
url: showUrl,
|
|
411
|
+
fullUrl: h.url,
|
|
370
412
|
expiresAt: h.expiresAt,
|
|
371
413
|
next: "Show the url to the user, then call solari_browser_await_login.",
|
|
372
414
|
});
|
|
@@ -112358,7 +112358,7 @@ var SolariClient = class {
|
|
|
112358
112358
|
};
|
|
112359
112359
|
|
|
112360
112360
|
// src/version.ts
|
|
112361
|
-
var VERSION = "0.3.
|
|
112361
|
+
var VERSION = "0.3.4";
|
|
112362
112362
|
|
|
112363
112363
|
// node_modules/puppeteer-core/lib/esm/puppeteer/index.js
|
|
112364
112364
|
init_index_browser();
|
|
@@ -113781,7 +113781,9 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113781
113781
|
/** Defaults to ON (following the pool). Pass false to opt out. */
|
|
113782
113782
|
captcha: external_exports.boolean().optional(),
|
|
113783
113783
|
recording: external_exports.boolean().optional(),
|
|
113784
|
-
profileId: external_exports.string().optional()
|
|
113784
|
+
profileId: external_exports.string().optional(),
|
|
113785
|
+
/** Defaults to ON. Pass false to never auto-sign-in on this session. */
|
|
113786
|
+
autoLogin: external_exports.boolean().optional()
|
|
113785
113787
|
},
|
|
113786
113788
|
handler: async (a2) => {
|
|
113787
113789
|
const stealth = a2.mode !== void 0 ? a2.mode === "stealth" : a2.stealth ?? true;
|
|
@@ -113800,6 +113802,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113800
113802
|
if (a2.recording) body.recording = true;
|
|
113801
113803
|
if (a2.proxy) body.proxy = a2.proxy;
|
|
113802
113804
|
if (a2.profileId) body.profileId = a2.profileId;
|
|
113805
|
+
if (a2.autoLogin !== false) body.autoLogin = true;
|
|
113803
113806
|
const res = await api2(cfg, "POST", "/sessions", body);
|
|
113804
113807
|
if (res.status !== 201) await apiError(res, "session create");
|
|
113805
113808
|
const s = await res.json();
|
|
@@ -113863,7 +113866,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113863
113866
|
}
|
|
113864
113867
|
},
|
|
113865
113868
|
solari_browser_login: {
|
|
113866
|
-
description: "
|
|
113869
|
+
description: "Get this session signed in. Call it the moment you hit a login form, a 2FA prompt, or anything asking for a password \u2014 you must never handle credentials yourself.\nIt tries the account's connected password manager FIRST: if one is set up for this site, you are signed in automatically and NO human is involved \u2014 the reply says signedIn:true and you simply carry on. Otherwise it falls back to asking a human.\nTwo ways to call it:\nHOT \u2014 pass `sessionId` when you are ALREADY on a login wall mid-task. The user gets a live view of the exact page you are on and types into it; you resume on that same page.\nCOLD \u2014 pass `profileName` when you know a task will need a login and no session is open yet. The user signs in once in a profile editor, and every later solari_browser_create({profileId}) starts already authenticated. Prefer this when you can: nobody has to be watching mid-run. The profile is created if it does not exist.\nPass exactly one of the two. Either way, SHOW THE RETURNED URL TO THE USER, then call solari_browser_await_login.\nIn the HOT case your access to that session is REVOKED while the handoff is open \u2014 deliberately, so you cannot observe what they type \u2014 and the link expires in 5 minutes. Cold links last longer and revoke nothing, because there is no session yet.\n`reason` is required and is shown to the user \u2014 say plainly which site is asking and what for, because they are being asked to type a password on your say-so.",
|
|
113867
113870
|
inputSchema: {
|
|
113868
113871
|
sessionId: external_exports.string().optional(),
|
|
113869
113872
|
profileName: external_exports.string().optional(),
|
|
@@ -113910,6 +113913,26 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113910
113913
|
});
|
|
113911
113914
|
}
|
|
113912
113915
|
const e = need(sessionId);
|
|
113916
|
+
try {
|
|
113917
|
+
const auto = await api2(
|
|
113918
|
+
cfg,
|
|
113919
|
+
"POST",
|
|
113920
|
+
`/sessions/${encodeURIComponent(sessionId)}/autologin`,
|
|
113921
|
+
{}
|
|
113922
|
+
);
|
|
113923
|
+
if (auto.status === 200) {
|
|
113924
|
+
const r = await auto.json();
|
|
113925
|
+
if (r.outcome === "already_authenticated" || r.outcome === "vault_login") {
|
|
113926
|
+
return text({
|
|
113927
|
+
mode: "auto",
|
|
113928
|
+
signedIn: true,
|
|
113929
|
+
via: r.outcome === "vault_login" ? "password manager" : "saved session",
|
|
113930
|
+
next: "You are signed in \u2014 carry on. No human was needed."
|
|
113931
|
+
});
|
|
113932
|
+
}
|
|
113933
|
+
}
|
|
113934
|
+
} catch {
|
|
113935
|
+
}
|
|
113913
113936
|
const res = await api2(
|
|
113914
113937
|
cfg,
|
|
113915
113938
|
"POST",
|
|
@@ -113922,10 +113945,12 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113922
113945
|
await e.browser.close();
|
|
113923
113946
|
} catch {
|
|
113924
113947
|
}
|
|
113948
|
+
const showUrl = h.shortUrl ?? h.url;
|
|
113925
113949
|
return text({
|
|
113926
113950
|
mode: "hot",
|
|
113927
113951
|
handoffId: h.handoffId,
|
|
113928
|
-
url:
|
|
113952
|
+
url: showUrl,
|
|
113953
|
+
fullUrl: h.url,
|
|
113929
113954
|
expiresAt: h.expiresAt,
|
|
113930
113955
|
next: "Show the url to the user, then call solari_browser_await_login."
|
|
113931
113956
|
});
|
|
@@ -111027,7 +111027,7 @@ var SolariClient = class {
|
|
|
111027
111027
|
};
|
|
111028
111028
|
|
|
111029
111029
|
// src/version.ts
|
|
111030
|
-
var VERSION = "0.3.
|
|
111030
|
+
var VERSION = "0.3.4";
|
|
111031
111031
|
|
|
111032
111032
|
// node_modules/puppeteer-core/lib/esm/puppeteer/index.js
|
|
111033
111033
|
init_index_browser();
|
|
@@ -112450,7 +112450,9 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112450
112450
|
/** Defaults to ON (following the pool). Pass false to opt out. */
|
|
112451
112451
|
captcha: external_exports.boolean().optional(),
|
|
112452
112452
|
recording: external_exports.boolean().optional(),
|
|
112453
|
-
profileId: external_exports.string().optional()
|
|
112453
|
+
profileId: external_exports.string().optional(),
|
|
112454
|
+
/** Defaults to ON. Pass false to never auto-sign-in on this session. */
|
|
112455
|
+
autoLogin: external_exports.boolean().optional()
|
|
112454
112456
|
},
|
|
112455
112457
|
handler: async (a2) => {
|
|
112456
112458
|
const stealth = a2.mode !== void 0 ? a2.mode === "stealth" : a2.stealth ?? true;
|
|
@@ -112469,6 +112471,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112469
112471
|
if (a2.recording) body.recording = true;
|
|
112470
112472
|
if (a2.proxy) body.proxy = a2.proxy;
|
|
112471
112473
|
if (a2.profileId) body.profileId = a2.profileId;
|
|
112474
|
+
if (a2.autoLogin !== false) body.autoLogin = true;
|
|
112472
112475
|
const res = await api2(cfg, "POST", "/sessions", body);
|
|
112473
112476
|
if (res.status !== 201) await apiError(res, "session create");
|
|
112474
112477
|
const s = await res.json();
|
|
@@ -112532,7 +112535,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112532
112535
|
}
|
|
112533
112536
|
},
|
|
112534
112537
|
solari_browser_login: {
|
|
112535
|
-
description: "
|
|
112538
|
+
description: "Get this session signed in. Call it the moment you hit a login form, a 2FA prompt, or anything asking for a password \u2014 you must never handle credentials yourself.\nIt tries the account's connected password manager FIRST: if one is set up for this site, you are signed in automatically and NO human is involved \u2014 the reply says signedIn:true and you simply carry on. Otherwise it falls back to asking a human.\nTwo ways to call it:\nHOT \u2014 pass `sessionId` when you are ALREADY on a login wall mid-task. The user gets a live view of the exact page you are on and types into it; you resume on that same page.\nCOLD \u2014 pass `profileName` when you know a task will need a login and no session is open yet. The user signs in once in a profile editor, and every later solari_browser_create({profileId}) starts already authenticated. Prefer this when you can: nobody has to be watching mid-run. The profile is created if it does not exist.\nPass exactly one of the two. Either way, SHOW THE RETURNED URL TO THE USER, then call solari_browser_await_login.\nIn the HOT case your access to that session is REVOKED while the handoff is open \u2014 deliberately, so you cannot observe what they type \u2014 and the link expires in 5 minutes. Cold links last longer and revoke nothing, because there is no session yet.\n`reason` is required and is shown to the user \u2014 say plainly which site is asking and what for, because they are being asked to type a password on your say-so.",
|
|
112536
112539
|
inputSchema: {
|
|
112537
112540
|
sessionId: external_exports.string().optional(),
|
|
112538
112541
|
profileName: external_exports.string().optional(),
|
|
@@ -112579,6 +112582,26 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112579
112582
|
});
|
|
112580
112583
|
}
|
|
112581
112584
|
const e = need(sessionId);
|
|
112585
|
+
try {
|
|
112586
|
+
const auto = await api2(
|
|
112587
|
+
cfg,
|
|
112588
|
+
"POST",
|
|
112589
|
+
`/sessions/${encodeURIComponent(sessionId)}/autologin`,
|
|
112590
|
+
{}
|
|
112591
|
+
);
|
|
112592
|
+
if (auto.status === 200) {
|
|
112593
|
+
const r = await auto.json();
|
|
112594
|
+
if (r.outcome === "already_authenticated" || r.outcome === "vault_login") {
|
|
112595
|
+
return text({
|
|
112596
|
+
mode: "auto",
|
|
112597
|
+
signedIn: true,
|
|
112598
|
+
via: r.outcome === "vault_login" ? "password manager" : "saved session",
|
|
112599
|
+
next: "You are signed in \u2014 carry on. No human was needed."
|
|
112600
|
+
});
|
|
112601
|
+
}
|
|
112602
|
+
}
|
|
112603
|
+
} catch {
|
|
112604
|
+
}
|
|
112582
112605
|
const res = await api2(
|
|
112583
112606
|
cfg,
|
|
112584
112607
|
"POST",
|
|
@@ -112591,10 +112614,12 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112591
112614
|
await e.browser.close();
|
|
112592
112615
|
} catch {
|
|
112593
112616
|
}
|
|
112617
|
+
const showUrl = h.shortUrl ?? h.url;
|
|
112594
112618
|
return text({
|
|
112595
112619
|
mode: "hot",
|
|
112596
112620
|
handoffId: h.handoffId,
|
|
112597
|
-
url:
|
|
112621
|
+
url: showUrl,
|
|
112622
|
+
fullUrl: h.url,
|
|
112598
112623
|
expiresAt: h.expiresAt,
|
|
112599
112624
|
next: "Show the url to the user, then call solari_browser_await_login."
|
|
112600
112625
|
});
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.3.
|
|
1
|
+
export declare const VERSION = "0.3.4";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solarisdk/mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Model Context Protocol server for the Solari cloud browser, sandboxes + desktops
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Model Context Protocol server for the Solari cloud browser, sandboxes + desktops \u2014 drive them from Claude Desktop/Cowork, Claude Code, Cursor, etc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"solari-mcp": "./dist/cli.js"
|