multicorn-shield 0.7.0 → 0.8.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.
@@ -366,17 +366,39 @@ async function isCursorConnected() {
366
366
  return false;
367
367
  }
368
368
  }
369
- var PLATFORM_LABELS = ["OpenClaw", "Claude Code", "Cursor", "Local MCP / Other"];
369
+ function getWindsurfConfigPath() {
370
+ return join(homedir(), ".codeium", "windsurf", "mcp_config.json");
371
+ }
372
+ async function isWindsurfConnected() {
373
+ try {
374
+ const raw = await readFile(getWindsurfConfigPath(), "utf8");
375
+ const obj = JSON.parse(raw);
376
+ const mcpServers = obj["mcpServers"];
377
+ if (mcpServers === void 0 || typeof mcpServers !== "object") return false;
378
+ for (const entry of Object.values(mcpServers)) {
379
+ if (typeof entry !== "object" || entry === null) continue;
380
+ const rec = entry;
381
+ const url = rec["serverUrl"];
382
+ if (typeof url === "string" && url.includes("multicorn")) return true;
383
+ }
384
+ return false;
385
+ } catch {
386
+ return false;
387
+ }
388
+ }
389
+ var PLATFORM_LABELS = ["OpenClaw", "Claude Code", "Cursor", "Windsurf", "Local MCP / Other"];
370
390
  var PLATFORM_BY_SELECTION = {
371
391
  1: "openclaw",
372
392
  2: "claude-code",
373
393
  3: "cursor",
374
- 4: "other-mcp"
394
+ 4: "windsurf",
395
+ 5: "other-mcp"
375
396
  };
376
397
  var DEFAULT_AGENT_NAMES = {
377
398
  openclaw: "my-openclaw-agent",
378
399
  "claude-code": "my-claude-code-agent",
379
- cursor: "my-cursor-agent"
400
+ cursor: "my-cursor-agent",
401
+ windsurf: "my-windsurf-agent"
380
402
  };
381
403
  async function promptPlatformSelection(ask) {
382
404
  process.stderr.write(
@@ -385,7 +407,8 @@ async function promptPlatformSelection(ask) {
385
407
  const connectedFlags = [
386
408
  await isOpenClawConnected(),
387
409
  isClaudeCodeConnected(),
388
- await isCursorConnected()
410
+ await isCursorConnected(),
411
+ await isWindsurfConnected()
389
412
  ];
390
413
  for (let i = 0; i < PLATFORM_LABELS.length; i++) {
391
414
  const marker = i < connectedFlags.length && connectedFlags[i] ? " " + style.dim("\u25CF detected locally") : "";
@@ -395,13 +418,13 @@ async function promptPlatformSelection(ask) {
395
418
  );
396
419
  }
397
420
  process.stderr.write(
398
- style.dim(" Pick 4 if you want to wrap a local MCP server with multicorn-proxy --wrap.") + "\n"
421
+ style.dim(" Pick 5 if you want to wrap a local MCP server with multicorn-proxy --wrap.") + "\n"
399
422
  );
400
423
  let selection = 0;
401
424
  while (selection === 0) {
402
- const input = await ask("Select (1-4): ");
425
+ const input = await ask("Select (1-5): ");
403
426
  const num = parseInt(input.trim(), 10);
404
- if (num >= 1 && num <= 4) {
427
+ if (num >= 1 && num <= 5) {
405
428
  selection = num;
406
429
  }
407
430
  }
@@ -505,12 +528,14 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
505
528
  return typeof data?.["proxy_url"] === "string" ? data["proxy_url"] : "";
506
529
  }
507
530
  function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
508
- const authHeader = platform === "cursor" ? `Bearer ${apiKey}` : "Bearer YOUR_SHIELD_API_KEY";
531
+ const usesInlineKey = platform === "cursor" || platform === "windsurf";
532
+ const authHeader = usesInlineKey ? `Bearer ${apiKey}` : "Bearer YOUR_SHIELD_API_KEY";
533
+ const urlKey = platform === "windsurf" ? "serverUrl" : "url";
509
534
  const mcpSnippet = JSON.stringify(
510
535
  {
511
536
  mcpServers: {
512
537
  [shortName]: {
513
- url: routingToken,
538
+ [urlKey]: routingToken,
514
539
  headers: {
515
540
  Authorization: authHeader
516
541
  }
@@ -524,11 +549,15 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
524
549
  process.stderr.write("\n" + style.dim("Add this to your OpenClaw agent config:") + "\n\n");
525
550
  } else if (platform === "claude-code") {
526
551
  process.stderr.write("\n" + style.dim("Add this to your Claude Code MCP config:") + "\n\n");
552
+ } else if (platform === "windsurf") {
553
+ process.stderr.write(
554
+ "\n" + style.dim("Add this to ~/.codeium/windsurf/mcp_config.json:") + "\n\n"
555
+ );
527
556
  } else {
528
557
  process.stderr.write("\n" + style.dim("Add this to ~/.cursor/mcp.json:") + "\n\n");
529
558
  }
530
559
  process.stderr.write(style.cyan(mcpSnippet) + "\n\n");
531
- if (platform !== "cursor") {
560
+ if (!usesInlineKey) {
532
561
  process.stderr.write(
533
562
  style.dim(
534
563
  "Replace YOUR_SHIELD_API_KEY with your API key. Find it in Settings > API keys at https://app.multicorn.ai/settings#api-keys"
@@ -547,6 +576,14 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
547
576
  ) + "\n"
548
577
  );
549
578
  }
579
+ if (platform === "windsurf") {
580
+ process.stderr.write(style.dim("Then restart Windsurf (Cmd/Ctrl+Q, then reopen).") + "\n");
581
+ process.stderr.write(
582
+ style.dim(
583
+ "Open the Cascade panel and verify the server appears with a green status indicator."
584
+ ) + "\n"
585
+ );
586
+ }
550
587
  }
551
588
  var DEFAULT_SHIELD_API_BASE_URL = "https://api.multicorn.ai";
552
589
  async function runInit(explicitBaseUrl) {
@@ -636,7 +673,7 @@ async function runInit(explicitBaseUrl) {
636
673
  const selection = await promptPlatformSelection(ask);
637
674
  const selectedPlatform = PLATFORM_BY_SELECTION[selection] ?? "cursor";
638
675
  const selectedLabel = PLATFORM_LABELS[selection - 1] ?? "Cursor";
639
- if (selection === 4) {
676
+ if (selection === 5) {
640
677
  const raw = existing !== null ? { ...existing } : {};
641
678
  raw["apiKey"] = apiKey;
642
679
  raw["baseUrl"] = resolvedBaseUrl;
@@ -885,7 +922,17 @@ An agent for ${selectedLabel} already exists: ${style.cyan(existingForPlatform.n
885
922
  }
886
923
  if (configuredPlatforms.has("cursor")) {
887
924
  blocks.push(
888
- "\n" + style.bold("To complete your Cursor setup:") + "\n \u2192 Restart Cursor to pick up MCP config changes\n"
925
+ "\n" + style.bold("To complete your Cursor setup:") + "\n 1. If you don't have Cursor yet, download it from " + style.cyan("https://cursor.com/downloads") + "\n 2. Open " + style.cyan("~/.cursor/mcp.json") + " and paste the config snippet shown above\n 3. Restart Cursor (or launch it for the first time) to load the new MCP server\n"
926
+ );
927
+ }
928
+ if (configuredPlatforms.has("windsurf")) {
929
+ blocks.push(
930
+ "\n" + style.bold("To complete your Windsurf setup:") + "\n 1. If you don't have Windsurf yet, download it from " + style.cyan("https://windsurf.com/download") + "\n 2. Open " + style.cyan("~/.codeium/windsurf/mcp_config.json") + " and paste the config snippet shown above\n 3. Restart Windsurf (or launch it for the first time) to load the new MCP server\n"
931
+ );
932
+ }
933
+ if (configuredPlatforms.has("windsurf")) {
934
+ blocks.push(
935
+ "\n" + style.bold("To complete your Windsurf setup:") + "\n Config file: " + style.cyan("~/.codeium/windsurf/mcp_config.json") + "\n Restart Windsurf to load the new MCP server.\n"
889
936
  );
890
937
  }
891
938
  if (blocks.length > 0) {
@@ -22358,7 +22358,7 @@ async function writeExtensionBackup(claudeDesktopConfigPath, mcpServers) {
22358
22358
 
22359
22359
  // package.json
22360
22360
  var package_default = {
22361
- version: "0.7.0"};
22361
+ version: "0.8.0"};
22362
22362
 
22363
22363
  // src/package-meta.ts
22364
22364
  var PACKAGE_VERSION = package_default.version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multicorn-shield",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "The control layer for AI agents: permissions, consent, spending limits, and audit logging.",
5
5
  "license": "MIT",
6
6
  "type": "module",