@sanctuary-framework/mcp-server 0.5.2 → 0.5.3

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/index.d.cts CHANGED
@@ -38,6 +38,8 @@ interface SanctuaryConfig {
38
38
  host: string;
39
39
  /** Bearer token for dashboard auth. If "auto", one is generated at startup. */
40
40
  auth_token?: string;
41
+ /** Auto-open dashboard in default browser on startup. Default: true for localhost. */
42
+ auto_open?: boolean;
41
43
  /** TLS cert/key paths for HTTPS dashboard. */
42
44
  tls?: {
43
45
  cert_path: string;
@@ -1986,6 +1988,8 @@ interface DashboardConfig {
1986
1988
  cert_path: string;
1987
1989
  key_path: string;
1988
1990
  };
1991
+ /** Auto-open the dashboard in the default browser on startup. Default: true for localhost. */
1992
+ auto_open?: boolean;
1989
1993
  }
1990
1994
  declare class DashboardApprovalChannel implements ApprovalChannel {
1991
1995
  private config;
@@ -2133,6 +2137,12 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
2133
2137
  * Broadcast current protection status to connected dashboards.
2134
2138
  */
2135
2139
  broadcastProtectionStatus(data: Record<string, unknown>): void;
2140
+ /**
2141
+ * Open a URL in the system's default browser.
2142
+ * Cross-platform: macOS (open), Linux (xdg-open), Windows (start).
2143
+ * Fails silently — dashboard still works via terminal URL.
2144
+ */
2145
+ private openInBrowser;
2136
2146
  /**
2137
2147
  * Create a pre-authenticated URL for the dashboard.
2138
2148
  * Used by the sanctuary_dashboard_open tool and at startup.
package/dist/index.d.ts CHANGED
@@ -38,6 +38,8 @@ interface SanctuaryConfig {
38
38
  host: string;
39
39
  /** Bearer token for dashboard auth. If "auto", one is generated at startup. */
40
40
  auth_token?: string;
41
+ /** Auto-open dashboard in default browser on startup. Default: true for localhost. */
42
+ auto_open?: boolean;
41
43
  /** TLS cert/key paths for HTTPS dashboard. */
42
44
  tls?: {
43
45
  cert_path: string;
@@ -1986,6 +1988,8 @@ interface DashboardConfig {
1986
1988
  cert_path: string;
1987
1989
  key_path: string;
1988
1990
  };
1991
+ /** Auto-open the dashboard in the default browser on startup. Default: true for localhost. */
1992
+ auto_open?: boolean;
1989
1993
  }
1990
1994
  declare class DashboardApprovalChannel implements ApprovalChannel {
1991
1995
  private config;
@@ -2133,6 +2137,12 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
2133
2137
  * Broadcast current protection status to connected dashboards.
2134
2138
  */
2135
2139
  broadcastProtectionStatus(data: Record<string, unknown>): void;
2140
+ /**
2141
+ * Open a URL in the system's default browser.
2142
+ * Cross-platform: macOS (open), Linux (xdg-open), Windows (start).
2143
+ * Fails silently — dashboard still works via terminal URL.
2144
+ */
2145
+ private openInBrowser;
2136
2146
  /**
2137
2147
  * Create a pre-authenticated URL for the dashboard.
2138
2148
  * Used by the sanctuary_dashboard_open tool and at startup.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { sha256 } from '@noble/hashes/sha256';
2
2
  import { hmac } from '@noble/hashes/hmac';
3
3
  import { readFile, mkdir, writeFile, stat, unlink, readdir, chmod, access } from 'fs/promises';
4
4
  import { join } from 'path';
5
- import { homedir } from 'os';
5
+ import { platform, homedir } from 'os';
6
6
  import { createRequire } from 'module';
7
7
  import { randomBytes as randomBytes$1, createHmac } from 'crypto';
8
8
  import { gcm } from '@noble/ciphers/aes.js';
@@ -14,7 +14,7 @@ import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprot
14
14
  import { createServer as createServer$2 } from 'http';
15
15
  import { createServer as createServer$1 } from 'https';
16
16
  import { readFileSync, statSync } from 'fs';
17
- import { execSync } from 'child_process';
17
+ import { exec, execSync } from 'child_process';
18
18
 
19
19
  var __defProp = Object.defineProperty;
20
20
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -290,6 +290,12 @@ async function loadConfig(configPath) {
290
290
  if (process.env.SANCTUARY_DASHBOARD_AUTH_TOKEN) {
291
291
  config.dashboard.auth_token = process.env.SANCTUARY_DASHBOARD_AUTH_TOKEN;
292
292
  }
293
+ if (process.env.SANCTUARY_DASHBOARD_AUTO_OPEN === "true") {
294
+ config.dashboard.auto_open = true;
295
+ }
296
+ if (process.env.SANCTUARY_DASHBOARD_AUTO_OPEN === "false") {
297
+ config.dashboard.auto_open = false;
298
+ }
293
299
  if (process.env.SANCTUARY_DASHBOARD_TLS_CERT && process.env.SANCTUARY_DASHBOARD_TLS_KEY) {
294
300
  config.dashboard.tls = {
295
301
  cert_path: process.env.SANCTUARY_DASHBOARD_TLS_CERT,
@@ -5712,26 +5718,26 @@ var DashboardApprovalChannel = class {
5712
5718
  const protocol = this.useTLS ? "https" : "http";
5713
5719
  const baseUrl = `${protocol}://${this.config.host}:${this.config.port}`;
5714
5720
  this.httpServer.listen(this.config.port, this.config.host, () => {
5721
+ const sessionUrl = this.authToken ? this.createSessionUrl() : baseUrl;
5715
5722
  process.stderr.write(
5716
5723
  `
5717
5724
  Sanctuary Principal Dashboard: ${baseUrl}
5718
5725
  `
5719
5726
  );
5720
5727
  if (this.authToken) {
5721
- const sessionUrl = this.createSessionUrl();
5722
- process.stderr.write(
5723
- ` Quick open: ${sessionUrl}
5724
- `
5725
- );
5726
5728
  const hint = this.authToken.slice(0, 4) + "..." + this.authToken.slice(-4);
5727
5729
  process.stderr.write(
5728
5730
  ` Auth token: ${hint}
5729
-
5730
5731
  `
5731
5732
  );
5732
- } else {
5733
- process.stderr.write(`
5733
+ }
5734
+ process.stderr.write(`
5734
5735
  `);
5736
+ const isTest = !!(process.env.VITEST || process.env.NODE_ENV === "test" || process.env.CI);
5737
+ const isLocalhost = this.config.host === "127.0.0.1" || this.config.host === "localhost" || this.config.host === "::1";
5738
+ const shouldAutoOpen = !isTest && (this.config.auto_open ?? isLocalhost);
5739
+ if (shouldAutoOpen) {
5740
+ this.openInBrowser(sessionUrl);
5735
5741
  }
5736
5742
  resolve();
5737
5743
  });
@@ -6263,6 +6269,31 @@ data: ${JSON.stringify(data)}
6263
6269
  broadcastProtectionStatus(data) {
6264
6270
  this.broadcastSSE("protection-status", data);
6265
6271
  }
6272
+ /**
6273
+ * Open a URL in the system's default browser.
6274
+ * Cross-platform: macOS (open), Linux (xdg-open), Windows (start).
6275
+ * Fails silently — dashboard still works via terminal URL.
6276
+ */
6277
+ openInBrowser(url) {
6278
+ const os = platform();
6279
+ let cmd;
6280
+ if (os === "darwin") {
6281
+ cmd = `open "${url}"`;
6282
+ } else if (os === "win32") {
6283
+ cmd = `start "" "${url}"`;
6284
+ } else {
6285
+ cmd = `xdg-open "${url}"`;
6286
+ }
6287
+ exec(cmd, (err) => {
6288
+ if (err) {
6289
+ process.stderr.write(
6290
+ ` (Could not auto-open browser. Open the URL above manually.)
6291
+
6292
+ `
6293
+ );
6294
+ }
6295
+ });
6296
+ }
6266
6297
  /**
6267
6298
  * Create a pre-authenticated URL for the dashboard.
6268
6299
  * Used by the sanctuary_dashboard_open tool and at startup.
@@ -12109,7 +12140,8 @@ async function createSanctuaryServer(options) {
12109
12140
  timeout_seconds: policy.approval_channel.timeout_seconds,
12110
12141
  // SEC-002: auto_deny removed — timeout always denies
12111
12142
  auth_token: authToken,
12112
- tls: config.dashboard.tls
12143
+ tls: config.dashboard.tls,
12144
+ auto_open: config.dashboard.auto_open
12113
12145
  });
12114
12146
  dashboard.setDependencies({ policy, baseline, auditLog });
12115
12147
  await dashboard.start();