@solarisdk/mcp 0.4.0 → 0.5.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 +88 -0
- package/dist/solari-mcp-http.bundle.cjs +57 -1
- package/dist/solari-mcp.bundle.cjs +57 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -294,6 +294,76 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
294
294
|
});
|
|
295
295
|
},
|
|
296
296
|
},
|
|
297
|
+
solari_browser_autologin_status: {
|
|
298
|
+
description: "Check whether this account can sign in to websites automatically, and get a direct " +
|
|
299
|
+
"setup link if it cannot.\n" +
|
|
300
|
+
"Call this when a task will clearly need a login, BEFORE you start — if nothing is set " +
|
|
301
|
+
"up you can tell the user once, up front, with a link, instead of interrupting them " +
|
|
302
|
+
"mid-run. Also worth calling if a login keeps needing a human.\n" +
|
|
303
|
+
"Returns the connected password managers, the sites already configured, and `setupUrl`. " +
|
|
304
|
+
"If `configured` is false, SHOW setupUrl TO THE USER: it opens the page where they " +
|
|
305
|
+
"connect a password manager. You cannot do that step for them — it needs a credential " +
|
|
306
|
+
"that must never pass through you — but the link removes all the guesswork.",
|
|
307
|
+
inputSchema: {},
|
|
308
|
+
handler: async () => {
|
|
309
|
+
const res = await api(cfg, "GET", "/vault/status");
|
|
310
|
+
if (res.status === 501) {
|
|
311
|
+
return text({
|
|
312
|
+
configured: false,
|
|
313
|
+
available: false,
|
|
314
|
+
note: "Automatic sign-in is not available on this deployment.",
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
if (res.status !== 200)
|
|
318
|
+
await apiError(res, "auto-login status");
|
|
319
|
+
const d = (await res.json());
|
|
320
|
+
const managers = d.managers ?? [];
|
|
321
|
+
const sites = d.sites ?? [];
|
|
322
|
+
return text({
|
|
323
|
+
configured: managers.length > 0,
|
|
324
|
+
available: true,
|
|
325
|
+
managers: managers.map((m) => ({ name: m.name, provider: m.provider, vaults: m.vaults })),
|
|
326
|
+
sites,
|
|
327
|
+
setupUrl: d.setupUrl ?? null,
|
|
328
|
+
next: managers.length === 0
|
|
329
|
+
? "No password manager is connected. Show setupUrl to the user — it takes them " +
|
|
330
|
+
"straight to the page where they connect one, after which logins happen with no " +
|
|
331
|
+
"human involved."
|
|
332
|
+
: sites.length === 0
|
|
333
|
+
? "A password manager is connected but no sites use it yet. Add one with " +
|
|
334
|
+
"solari_browser_autologin_site, or the user can do it at setupUrl."
|
|
335
|
+
: "Automatic sign-in is set up. Sessions will log in to these sites on their own.",
|
|
336
|
+
});
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
solari_browser_autologin_site: {
|
|
340
|
+
description: "Tell Solari to sign in to a site automatically using a connected password manager.\n" +
|
|
341
|
+
"`domain` is the site, e.g. 'github.com'. `manager` is the NAME of a connected password " +
|
|
342
|
+
"manager (see solari_browser_autologin_status) — omit it to mean 'remember the session " +
|
|
343
|
+
"but ask a human for a fresh login'. `item` is an optional 'Vault/Item' path for when " +
|
|
344
|
+
"one site has several logins; omit it to match by site.\n" +
|
|
345
|
+
"This only says WHICH credential to use — it never handles the credential itself.",
|
|
346
|
+
inputSchema: {
|
|
347
|
+
domain: z.string(),
|
|
348
|
+
manager: z.string().optional(),
|
|
349
|
+
item: z.string().optional(),
|
|
350
|
+
},
|
|
351
|
+
handler: async (a) => {
|
|
352
|
+
const res = await api(cfg, "POST", "/vault/sites", {
|
|
353
|
+
domain: a.domain,
|
|
354
|
+
...(typeof a.manager === "string" ? { manager: a.manager } : {}),
|
|
355
|
+
...(typeof a.item === "string" ? { item: a.item } : {}),
|
|
356
|
+
});
|
|
357
|
+
if (res.status !== 200)
|
|
358
|
+
await apiError(res, "configure auto-login site");
|
|
359
|
+
const d = (await res.json());
|
|
360
|
+
return text({
|
|
361
|
+
...d,
|
|
362
|
+
next: "Set. The next session that hits a login wall on this site signs in automatically " +
|
|
363
|
+
"if the credential is found; otherwise a human is asked, as before.",
|
|
364
|
+
});
|
|
365
|
+
},
|
|
366
|
+
},
|
|
297
367
|
solari_browser_login: {
|
|
298
368
|
description: "Get this session signed in. Call it the moment you hit a login form, a 2FA prompt, or "
|
|
299
369
|
+ "anything asking for a password — you must never handle credentials yourself.\n"
|
|
@@ -370,6 +440,7 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
370
440
|
// escalate to a human when that cannot work. Best-effort: any failure
|
|
371
441
|
// here just falls through to the handoff below, which is the behaviour
|
|
372
442
|
// that existed before.
|
|
443
|
+
let setupUrl = null;
|
|
373
444
|
try {
|
|
374
445
|
const auto = await api(cfg, "POST", `/sessions/${encodeURIComponent(sessionId)}/autologin`, {});
|
|
375
446
|
if (auto.status === 200) {
|
|
@@ -382,6 +453,12 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
382
453
|
next: "You are signed in — carry on. No human was needed.",
|
|
383
454
|
});
|
|
384
455
|
}
|
|
456
|
+
// Nothing is configured for this site. Remember the setup link so
|
|
457
|
+
// it can be offered alongside the handoff below — the user is
|
|
458
|
+
// already being interrupted, so this is the cheapest possible
|
|
459
|
+
// moment to tell them how to stop being interrupted next time.
|
|
460
|
+
if (r.setupRequired && r.setupUrl)
|
|
461
|
+
setupUrl = r.setupUrl;
|
|
385
462
|
}
|
|
386
463
|
}
|
|
387
464
|
catch {
|
|
@@ -410,6 +487,17 @@ export function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
410
487
|
url: showUrl,
|
|
411
488
|
fullUrl: h.url,
|
|
412
489
|
expiresAt: h.expiresAt,
|
|
490
|
+
// Offered only when the account has NOTHING configured for this site.
|
|
491
|
+
// The user is already being interrupted, so this is the cheapest
|
|
492
|
+
// moment to show them how to stop being interrupted next time.
|
|
493
|
+
...(setupUrl
|
|
494
|
+
? {
|
|
495
|
+
setupUrl,
|
|
496
|
+
tip: "This account has no password manager connected for this site, so a human is " +
|
|
497
|
+
"needed every time. Connecting one at the setupUrl lets future logins happen " +
|
|
498
|
+
"automatically. MENTION THIS TO THE USER along with the sign-in link.",
|
|
499
|
+
}
|
|
500
|
+
: {}),
|
|
413
501
|
next: "Show the url to the user, then call solari_browser_await_login.",
|
|
414
502
|
});
|
|
415
503
|
},
|
|
@@ -112358,7 +112358,7 @@ var SolariClient = class {
|
|
|
112358
112358
|
};
|
|
112359
112359
|
|
|
112360
112360
|
// src/version.ts
|
|
112361
|
-
var VERSION = "0.
|
|
112361
|
+
var VERSION = "0.5.0";
|
|
112362
112362
|
|
|
112363
112363
|
// node_modules/puppeteer-core/lib/esm/puppeteer/index.js
|
|
112364
112364
|
init_index_browser();
|
|
@@ -113865,6 +113865,53 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113865
113865
|
});
|
|
113866
113866
|
}
|
|
113867
113867
|
},
|
|
113868
|
+
solari_browser_autologin_status: {
|
|
113869
|
+
description: "Check whether this account can sign in to websites automatically, and get a direct setup link if it cannot.\nCall this when a task will clearly need a login, BEFORE you start \u2014 if nothing is set up you can tell the user once, up front, with a link, instead of interrupting them mid-run. Also worth calling if a login keeps needing a human.\nReturns the connected password managers, the sites already configured, and `setupUrl`. If `configured` is false, SHOW setupUrl TO THE USER: it opens the page where they connect a password manager. You cannot do that step for them \u2014 it needs a credential that must never pass through you \u2014 but the link removes all the guesswork.",
|
|
113870
|
+
inputSchema: {},
|
|
113871
|
+
handler: async () => {
|
|
113872
|
+
const res = await api2(cfg, "GET", "/vault/status");
|
|
113873
|
+
if (res.status === 501) {
|
|
113874
|
+
return text({
|
|
113875
|
+
configured: false,
|
|
113876
|
+
available: false,
|
|
113877
|
+
note: "Automatic sign-in is not available on this deployment."
|
|
113878
|
+
});
|
|
113879
|
+
}
|
|
113880
|
+
if (res.status !== 200) await apiError(res, "auto-login status");
|
|
113881
|
+
const d = await res.json();
|
|
113882
|
+
const managers = d.managers ?? [];
|
|
113883
|
+
const sites = d.sites ?? [];
|
|
113884
|
+
return text({
|
|
113885
|
+
configured: managers.length > 0,
|
|
113886
|
+
available: true,
|
|
113887
|
+
managers: managers.map((m) => ({ name: m.name, provider: m.provider, vaults: m.vaults })),
|
|
113888
|
+
sites,
|
|
113889
|
+
setupUrl: d.setupUrl ?? null,
|
|
113890
|
+
next: managers.length === 0 ? "No password manager is connected. Show setupUrl to the user \u2014 it takes them straight to the page where they connect one, after which logins happen with no human involved." : sites.length === 0 ? "A password manager is connected but no sites use it yet. Add one with solari_browser_autologin_site, or the user can do it at setupUrl." : "Automatic sign-in is set up. Sessions will log in to these sites on their own."
|
|
113891
|
+
});
|
|
113892
|
+
}
|
|
113893
|
+
},
|
|
113894
|
+
solari_browser_autologin_site: {
|
|
113895
|
+
description: "Tell Solari to sign in to a site automatically using a connected password manager.\n`domain` is the site, e.g. 'github.com'. `manager` is the NAME of a connected password manager (see solari_browser_autologin_status) \u2014 omit it to mean 'remember the session but ask a human for a fresh login'. `item` is an optional 'Vault/Item' path for when one site has several logins; omit it to match by site.\nThis only says WHICH credential to use \u2014 it never handles the credential itself.",
|
|
113896
|
+
inputSchema: {
|
|
113897
|
+
domain: external_exports.string(),
|
|
113898
|
+
manager: external_exports.string().optional(),
|
|
113899
|
+
item: external_exports.string().optional()
|
|
113900
|
+
},
|
|
113901
|
+
handler: async (a2) => {
|
|
113902
|
+
const res = await api2(cfg, "POST", "/vault/sites", {
|
|
113903
|
+
domain: a2.domain,
|
|
113904
|
+
...typeof a2.manager === "string" ? { manager: a2.manager } : {},
|
|
113905
|
+
...typeof a2.item === "string" ? { item: a2.item } : {}
|
|
113906
|
+
});
|
|
113907
|
+
if (res.status !== 200) await apiError(res, "configure auto-login site");
|
|
113908
|
+
const d = await res.json();
|
|
113909
|
+
return text({
|
|
113910
|
+
...d,
|
|
113911
|
+
next: "Set. The next session that hits a login wall on this site signs in automatically if the credential is found; otherwise a human is asked, as before."
|
|
113912
|
+
});
|
|
113913
|
+
}
|
|
113914
|
+
},
|
|
113868
113915
|
solari_browser_login: {
|
|
113869
113916
|
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.",
|
|
113870
113917
|
inputSchema: {
|
|
@@ -113913,6 +113960,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113913
113960
|
});
|
|
113914
113961
|
}
|
|
113915
113962
|
const e = need(sessionId);
|
|
113963
|
+
let setupUrl = null;
|
|
113916
113964
|
try {
|
|
113917
113965
|
const auto = await api2(
|
|
113918
113966
|
cfg,
|
|
@@ -113930,6 +113978,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113930
113978
|
next: "You are signed in \u2014 carry on. No human was needed."
|
|
113931
113979
|
});
|
|
113932
113980
|
}
|
|
113981
|
+
if (r.setupRequired && r.setupUrl) setupUrl = r.setupUrl;
|
|
113933
113982
|
}
|
|
113934
113983
|
} catch {
|
|
113935
113984
|
}
|
|
@@ -113952,6 +114001,13 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
113952
114001
|
url: showUrl,
|
|
113953
114002
|
fullUrl: h.url,
|
|
113954
114003
|
expiresAt: h.expiresAt,
|
|
114004
|
+
// Offered only when the account has NOTHING configured for this site.
|
|
114005
|
+
// The user is already being interrupted, so this is the cheapest
|
|
114006
|
+
// moment to show them how to stop being interrupted next time.
|
|
114007
|
+
...setupUrl ? {
|
|
114008
|
+
setupUrl,
|
|
114009
|
+
tip: "This account has no password manager connected for this site, so a human is needed every time. Connecting one at the setupUrl lets future logins happen automatically. MENTION THIS TO THE USER along with the sign-in link."
|
|
114010
|
+
} : {},
|
|
113955
114011
|
next: "Show the url to the user, then call solari_browser_await_login."
|
|
113956
114012
|
});
|
|
113957
114013
|
}
|
|
@@ -111027,7 +111027,7 @@ var SolariClient = class {
|
|
|
111027
111027
|
};
|
|
111028
111028
|
|
|
111029
111029
|
// src/version.ts
|
|
111030
|
-
var VERSION = "0.
|
|
111030
|
+
var VERSION = "0.5.0";
|
|
111031
111031
|
|
|
111032
111032
|
// node_modules/puppeteer-core/lib/esm/puppeteer/index.js
|
|
111033
111033
|
init_index_browser();
|
|
@@ -112534,6 +112534,53 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112534
112534
|
});
|
|
112535
112535
|
}
|
|
112536
112536
|
},
|
|
112537
|
+
solari_browser_autologin_status: {
|
|
112538
|
+
description: "Check whether this account can sign in to websites automatically, and get a direct setup link if it cannot.\nCall this when a task will clearly need a login, BEFORE you start \u2014 if nothing is set up you can tell the user once, up front, with a link, instead of interrupting them mid-run. Also worth calling if a login keeps needing a human.\nReturns the connected password managers, the sites already configured, and `setupUrl`. If `configured` is false, SHOW setupUrl TO THE USER: it opens the page where they connect a password manager. You cannot do that step for them \u2014 it needs a credential that must never pass through you \u2014 but the link removes all the guesswork.",
|
|
112539
|
+
inputSchema: {},
|
|
112540
|
+
handler: async () => {
|
|
112541
|
+
const res = await api2(cfg, "GET", "/vault/status");
|
|
112542
|
+
if (res.status === 501) {
|
|
112543
|
+
return text({
|
|
112544
|
+
configured: false,
|
|
112545
|
+
available: false,
|
|
112546
|
+
note: "Automatic sign-in is not available on this deployment."
|
|
112547
|
+
});
|
|
112548
|
+
}
|
|
112549
|
+
if (res.status !== 200) await apiError(res, "auto-login status");
|
|
112550
|
+
const d = await res.json();
|
|
112551
|
+
const managers = d.managers ?? [];
|
|
112552
|
+
const sites = d.sites ?? [];
|
|
112553
|
+
return text({
|
|
112554
|
+
configured: managers.length > 0,
|
|
112555
|
+
available: true,
|
|
112556
|
+
managers: managers.map((m) => ({ name: m.name, provider: m.provider, vaults: m.vaults })),
|
|
112557
|
+
sites,
|
|
112558
|
+
setupUrl: d.setupUrl ?? null,
|
|
112559
|
+
next: managers.length === 0 ? "No password manager is connected. Show setupUrl to the user \u2014 it takes them straight to the page where they connect one, after which logins happen with no human involved." : sites.length === 0 ? "A password manager is connected but no sites use it yet. Add one with solari_browser_autologin_site, or the user can do it at setupUrl." : "Automatic sign-in is set up. Sessions will log in to these sites on their own."
|
|
112560
|
+
});
|
|
112561
|
+
}
|
|
112562
|
+
},
|
|
112563
|
+
solari_browser_autologin_site: {
|
|
112564
|
+
description: "Tell Solari to sign in to a site automatically using a connected password manager.\n`domain` is the site, e.g. 'github.com'. `manager` is the NAME of a connected password manager (see solari_browser_autologin_status) \u2014 omit it to mean 'remember the session but ask a human for a fresh login'. `item` is an optional 'Vault/Item' path for when one site has several logins; omit it to match by site.\nThis only says WHICH credential to use \u2014 it never handles the credential itself.",
|
|
112565
|
+
inputSchema: {
|
|
112566
|
+
domain: external_exports.string(),
|
|
112567
|
+
manager: external_exports.string().optional(),
|
|
112568
|
+
item: external_exports.string().optional()
|
|
112569
|
+
},
|
|
112570
|
+
handler: async (a2) => {
|
|
112571
|
+
const res = await api2(cfg, "POST", "/vault/sites", {
|
|
112572
|
+
domain: a2.domain,
|
|
112573
|
+
...typeof a2.manager === "string" ? { manager: a2.manager } : {},
|
|
112574
|
+
...typeof a2.item === "string" ? { item: a2.item } : {}
|
|
112575
|
+
});
|
|
112576
|
+
if (res.status !== 200) await apiError(res, "configure auto-login site");
|
|
112577
|
+
const d = await res.json();
|
|
112578
|
+
return text({
|
|
112579
|
+
...d,
|
|
112580
|
+
next: "Set. The next session that hits a login wall on this site signs in automatically if the credential is found; otherwise a human is asked, as before."
|
|
112581
|
+
});
|
|
112582
|
+
}
|
|
112583
|
+
},
|
|
112537
112584
|
solari_browser_login: {
|
|
112538
112585
|
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.",
|
|
112539
112586
|
inputSchema: {
|
|
@@ -112582,6 +112629,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112582
112629
|
});
|
|
112583
112630
|
}
|
|
112584
112631
|
const e = need(sessionId);
|
|
112632
|
+
let setupUrl = null;
|
|
112585
112633
|
try {
|
|
112586
112634
|
const auto = await api2(
|
|
112587
112635
|
cfg,
|
|
@@ -112599,6 +112647,7 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112599
112647
|
next: "You are signed in \u2014 carry on. No human was needed."
|
|
112600
112648
|
});
|
|
112601
112649
|
}
|
|
112650
|
+
if (r.setupRequired && r.setupUrl) setupUrl = r.setupUrl;
|
|
112602
112651
|
}
|
|
112603
112652
|
} catch {
|
|
112604
112653
|
}
|
|
@@ -112621,6 +112670,13 @@ function makeBrowserToolset(cfg, reg, deps = defaultDeps) {
|
|
|
112621
112670
|
url: showUrl,
|
|
112622
112671
|
fullUrl: h.url,
|
|
112623
112672
|
expiresAt: h.expiresAt,
|
|
112673
|
+
// Offered only when the account has NOTHING configured for this site.
|
|
112674
|
+
// The user is already being interrupted, so this is the cheapest
|
|
112675
|
+
// moment to show them how to stop being interrupted next time.
|
|
112676
|
+
...setupUrl ? {
|
|
112677
|
+
setupUrl,
|
|
112678
|
+
tip: "This account has no password manager connected for this site, so a human is needed every time. Connecting one at the setupUrl lets future logins happen automatically. MENTION THIS TO THE USER along with the sign-in link."
|
|
112679
|
+
} : {},
|
|
112624
112680
|
next: "Show the url to the user, then call solari_browser_await_login."
|
|
112625
112681
|
});
|
|
112626
112682
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.5.0";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solarisdk/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
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": {
|