@solarisdk/mcp 0.2.1 → 0.2.2

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 CHANGED
@@ -86,6 +86,7 @@ Chat, Code and Cowork alike.
86
86
  | `SOLARI_API_KEY` | ✅ | — | unified `slr_live_…` key (works on both gateways) |
87
87
  | `SOLARI_BASE_URL` | | `https://api.getsolari.com` | sandbox/desktop gateway |
88
88
  | `SOLARI_BROWSER_URL` | | `SOLARI_BASE_URL` → prod | cloud-browser gateway (differs from `SOLARI_BASE_URL` on staging) |
89
+ | `SOLARI_BROWSER_API_KEY` | | `SOLARI_API_KEY` | separate key for the browser gateway, for environments where the browser and desktop key stores are split |
89
90
 
90
91
  ## Tools
91
92
 
package/dist/http.js CHANGED
@@ -29,22 +29,35 @@ async function validateKey(key) {
29
29
  const until = keyOkUntil.get(h);
30
30
  if (until && until > Date.now())
31
31
  return true;
32
- try {
33
- const res = await fetch(`${BROWSER_URL}/profiles`, {
34
- headers: { authorization: `Bearer ${key}` },
35
- signal: AbortSignal.timeout(10_000),
36
- });
37
- if (res.ok) {
38
- keyOkUntil.set(h, Date.now() + 60_000);
39
- return true;
32
+ // Prod's browser and desktop gateways have separate key stores — a key is
33
+ // acceptable if EITHER accepts it (its tool calls on the other surface will
34
+ // fail with that gateway's own auth error).
35
+ const probes = [
36
+ `${BROWSER_URL}/profiles`,
37
+ `${process.env.SOLARI_BASE_URL ?? "https://api.getsolari.com"}/sandboxes?limit=1`,
38
+ ];
39
+ let sawDefinitiveReject = false;
40
+ for (const url of probes) {
41
+ try {
42
+ const res = await fetch(url, {
43
+ headers: { authorization: `Bearer ${key}` },
44
+ signal: AbortSignal.timeout(10_000),
45
+ });
46
+ if (res.ok) {
47
+ keyOkUntil.set(h, Date.now() + 60_000);
48
+ return true;
49
+ }
50
+ if (res.status === 401 || res.status === 403)
51
+ sawDefinitiveReject = true;
52
+ // Other statuses: inconclusive (gateway hiccup) — keep probing.
53
+ }
54
+ catch {
55
+ /* transient — inconclusive */
40
56
  }
41
- // Gateway auth can negative-cache a freshly minted key for a few seconds;
42
- // treat only a definitive 401/403 as invalid.
43
- return res.status !== 401 && res.status !== 403;
44
- }
45
- catch {
46
- return true; // don't lock customers out on our own transient errors
47
57
  }
58
+ // Reject only when at least one gateway definitively said no and none said
59
+ // yes; if everything was inconclusive, don't lock customers out on our blip.
60
+ return !sawDefinitiveReject;
48
61
  }
49
62
  function bearer(req) {
50
63
  const m = /^Bearer\s+(.+)$/i.exec(req.headers.authorization ?? "");
package/dist/server.js CHANGED
@@ -212,8 +212,10 @@ export function buildServerParts(client, browserCfg) {
212
212
  });
213
213
  // The cloud-browser gateway is a separate service from the sandbox/desktop
214
214
  // gateway (same domain in prod, different domains on staging).
215
+ // Prod's browser + desktop gateways have separate key stores today; allow a
216
+ // browser-specific key (falls back to the shared one).
215
217
  const bCfg = browserCfg ?? {
216
- apiKey,
218
+ apiKey: process.env.SOLARI_BROWSER_API_KEY ?? apiKey,
217
219
  baseUrl: process.env.SOLARI_BROWSER_URL ??
218
220
  process.env.SOLARI_BASE_URL ??
219
221
  "https://api.getsolari.com",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solarisdk/mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Model Context Protocol server for the Solari cloud browser, sandboxes + desktops — drive them from Claude Desktop/Cowork, Claude Code, Cursor, etc.",
5
5
  "type": "module",
6
6
  "bin": {