@solongate/proxy 0.5.2 → 0.5.4

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.
Files changed (3) hide show
  1. package/dist/index.js +30 -53
  2. package/dist/init.js +18 -52
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -128,9 +128,20 @@ function parseArgs(argv) {
128
128
  break;
129
129
  }
130
130
  }
131
+ if (apiKey && /^\$\{.+\}$/.test(apiKey)) {
132
+ apiKey = void 0;
133
+ }
134
+ if (!apiKey) {
135
+ const dotenvPath = resolve(".env");
136
+ if (existsSync(dotenvPath)) {
137
+ const dotenvContent = readFileSync(dotenvPath, "utf-8");
138
+ const match = dotenvContent.match(/^SOLONGATE_API_KEY=(sg_(?:live|test)_\w+)/m);
139
+ if (match) apiKey = match[1];
140
+ }
141
+ }
131
142
  if (!apiKey) {
132
143
  const envKey = process.env.SOLONGATE_API_KEY;
133
- if (envKey) {
144
+ if (envKey && !/^\$\{.+\}$/.test(envKey)) {
134
145
  apiKey = envKey;
135
146
  } else {
136
147
  throw new Error(
@@ -569,9 +580,9 @@ function isAlreadyProtected(server) {
569
580
  }
570
581
  return false;
571
582
  }
572
- function wrapServer(server, policy, apiKey) {
583
+ function wrapServer(server, policy) {
573
584
  const env = { ...server.env ?? {} };
574
- env.SOLONGATE_API_KEY = apiKey;
585
+ env.SOLONGATE_API_KEY = "${SOLONGATE_API_KEY}";
575
586
  return {
576
587
  command: "npx",
577
588
  args: [
@@ -671,8 +682,8 @@ POLICY PRESETS
671
682
  `;
672
683
  console.log(help);
673
684
  }
674
- function installClaudeCodeHooks(apiKey) {
675
- const hooksDir = resolve2(".claude", "hooks");
685
+ function installHooks() {
686
+ const hooksDir = resolve2(".solongate", "hooks");
676
687
  mkdirSync(hooksDir, { recursive: true });
677
688
  const guardPath = join(hooksDir, "guard.mjs");
678
689
  writeFileSync2(guardPath, GUARD_SCRIPT);
@@ -680,50 +691,15 @@ function installClaudeCodeHooks(apiKey) {
680
691
  const auditPath = join(hooksDir, "audit.mjs");
681
692
  writeFileSync2(auditPath, AUDIT_SCRIPT);
682
693
  console.log(` Created ${auditPath}`);
683
- const settingsPath = resolve2(".claude", "settings.json");
684
- let settings = {};
685
- if (existsSync3(settingsPath)) {
686
- try {
687
- settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
688
- } catch {
689
- }
690
- }
691
- settings.hooks = {
692
- PreToolUse: [
693
- {
694
- matcher: ".*",
695
- hooks: [
696
- {
697
- type: "command",
698
- command: "node .claude/hooks/guard.mjs",
699
- timeout: 5
700
- }
701
- ]
702
- }
703
- ],
704
- PostToolUse: [
705
- {
706
- matcher: ".*",
707
- hooks: [
708
- {
709
- type: "command",
710
- command: "node .claude/hooks/audit.mjs",
711
- timeout: 10,
712
- async: true
713
- }
714
- ]
715
- }
716
- ]
717
- };
718
- const envObj = settings.env || {};
719
- envObj.SOLONGATE_API_KEY = apiKey;
720
- settings.env = envObj;
721
- writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
722
- console.log(` Created ${settingsPath}`);
723
694
  console.log("");
724
- console.log(" Claude Code hooks installed!");
725
- console.log(" PreToolUse \u2192 guard.mjs (blocks dangerous calls)");
726
- console.log(" PostToolUse \u2192 audit.mjs (logs all calls to dashboard)");
695
+ console.log(" Hooks installed in .solongate/hooks/");
696
+ console.log(" guard.mjs \u2192 blocks dangerous calls (pre-execution)");
697
+ console.log(" audit.mjs \u2192 logs all calls to dashboard (post-execution)");
698
+ console.log("");
699
+ console.log(" To activate hooks in your MCP client:");
700
+ console.log(" Claude Code \u2192 .claude/settings.json");
701
+ console.log(" Cursor \u2192 .cursor/settings.json");
702
+ console.log(" Or run: node .solongate/hooks/guard.mjs (stdin: JSON)");
727
703
  }
728
704
  function ensureEnvFile() {
729
705
  const envPath = resolve2(".env");
@@ -898,7 +874,7 @@ async function main() {
898
874
  const newConfig = { mcpServers: {} };
899
875
  for (const name of serverNames) {
900
876
  if (toProtect.includes(name)) {
901
- newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy, apiKey);
877
+ newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy);
902
878
  } else {
903
879
  newConfig.mcpServers[name] = config.mcpServers[name];
904
880
  }
@@ -926,7 +902,7 @@ async function main() {
926
902
  console.log(" Config updated!");
927
903
  console.log("");
928
904
  await sleep(500);
929
- installClaudeCodeHooks(apiKey);
905
+ installHooks();
930
906
  console.log("");
931
907
  await sleep(400);
932
908
  console.log(" \u2500\u2500 Summary \u2500\u2500");
@@ -948,11 +924,12 @@ async function main() {
948
924
  console.log(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
949
925
  console.log(" \u2502 Setup complete! \u2502");
950
926
  console.log(" \u2502 \u2502");
951
- console.log(" \u2502 MCP tools \u2192 Proxy audit logging \u2502");
952
- console.log(" \u2502 Built-in tools \u2192 Hook audit logging \u2502");
927
+ console.log(" \u2502 MCP servers \u2192 Protected via proxy \u2502");
928
+ console.log(" \u2502 AI tools \u2192 Guarded via hooks \u2502");
929
+ console.log(" \u2502 API key \u2192 Set in .env \u2502");
953
930
  console.log(" \u2502 \u2502");
954
931
  console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
955
- console.log(" \u2502 To undo: solongate-init --restore \u2502");
932
+ console.log(" \u2502 To undo: npx @solongate/proxy init --restore \u2502");
956
933
  console.log(" \u2502 \u2502");
957
934
  console.log(" \u2502 Restart your MCP client to apply changes. \u2502");
958
935
  console.log(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
package/dist/init.js CHANGED
@@ -65,9 +65,9 @@ function isAlreadyProtected(server) {
65
65
  }
66
66
  return false;
67
67
  }
68
- function wrapServer(server, policy, apiKey) {
68
+ function wrapServer(server, policy) {
69
69
  const env = { ...server.env ?? {} };
70
- env.SOLONGATE_API_KEY = apiKey;
70
+ env.SOLONGATE_API_KEY = "${SOLONGATE_API_KEY}";
71
71
  return {
72
72
  command: "npx",
73
73
  args: [
@@ -373,8 +373,8 @@ process.stdin.on('end', async () => {
373
373
  process.exit(0);
374
374
  });
375
375
  `;
376
- function installClaudeCodeHooks(apiKey) {
377
- const hooksDir = resolve(".claude", "hooks");
376
+ function installHooks() {
377
+ const hooksDir = resolve(".solongate", "hooks");
378
378
  mkdirSync(hooksDir, { recursive: true });
379
379
  const guardPath = join(hooksDir, "guard.mjs");
380
380
  writeFileSync(guardPath, GUARD_SCRIPT);
@@ -382,50 +382,15 @@ function installClaudeCodeHooks(apiKey) {
382
382
  const auditPath = join(hooksDir, "audit.mjs");
383
383
  writeFileSync(auditPath, AUDIT_SCRIPT);
384
384
  console.log(` Created ${auditPath}`);
385
- const settingsPath = resolve(".claude", "settings.json");
386
- let settings = {};
387
- if (existsSync(settingsPath)) {
388
- try {
389
- settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
390
- } catch {
391
- }
392
- }
393
- settings.hooks = {
394
- PreToolUse: [
395
- {
396
- matcher: ".*",
397
- hooks: [
398
- {
399
- type: "command",
400
- command: "node .claude/hooks/guard.mjs",
401
- timeout: 5
402
- }
403
- ]
404
- }
405
- ],
406
- PostToolUse: [
407
- {
408
- matcher: ".*",
409
- hooks: [
410
- {
411
- type: "command",
412
- command: "node .claude/hooks/audit.mjs",
413
- timeout: 10,
414
- async: true
415
- }
416
- ]
417
- }
418
- ]
419
- };
420
- const envObj = settings.env || {};
421
- envObj.SOLONGATE_API_KEY = apiKey;
422
- settings.env = envObj;
423
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
424
- console.log(` Created ${settingsPath}`);
425
385
  console.log("");
426
- console.log(" Claude Code hooks installed!");
427
- console.log(" PreToolUse \u2192 guard.mjs (blocks dangerous calls)");
428
- console.log(" PostToolUse \u2192 audit.mjs (logs all calls to dashboard)");
386
+ console.log(" Hooks installed in .solongate/hooks/");
387
+ console.log(" guard.mjs \u2192 blocks dangerous calls (pre-execution)");
388
+ console.log(" audit.mjs \u2192 logs all calls to dashboard (post-execution)");
389
+ console.log("");
390
+ console.log(" To activate hooks in your MCP client:");
391
+ console.log(" Claude Code \u2192 .claude/settings.json");
392
+ console.log(" Cursor \u2192 .cursor/settings.json");
393
+ console.log(" Or run: node .solongate/hooks/guard.mjs (stdin: JSON)");
429
394
  }
430
395
  function ensureEnvFile() {
431
396
  const envPath = resolve(".env");
@@ -600,7 +565,7 @@ async function main() {
600
565
  const newConfig = { mcpServers: {} };
601
566
  for (const name of serverNames) {
602
567
  if (toProtect.includes(name)) {
603
- newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy, apiKey);
568
+ newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy);
604
569
  } else {
605
570
  newConfig.mcpServers[name] = config.mcpServers[name];
606
571
  }
@@ -628,7 +593,7 @@ async function main() {
628
593
  console.log(" Config updated!");
629
594
  console.log("");
630
595
  await sleep(500);
631
- installClaudeCodeHooks(apiKey);
596
+ installHooks();
632
597
  console.log("");
633
598
  await sleep(400);
634
599
  console.log(" \u2500\u2500 Summary \u2500\u2500");
@@ -650,11 +615,12 @@ async function main() {
650
615
  console.log(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
651
616
  console.log(" \u2502 Setup complete! \u2502");
652
617
  console.log(" \u2502 \u2502");
653
- console.log(" \u2502 MCP tools \u2192 Proxy audit logging \u2502");
654
- console.log(" \u2502 Built-in tools \u2192 Hook audit logging \u2502");
618
+ console.log(" \u2502 MCP servers \u2192 Protected via proxy \u2502");
619
+ console.log(" \u2502 AI tools \u2192 Guarded via hooks \u2502");
620
+ console.log(" \u2502 API key \u2192 Set in .env \u2502");
655
621
  console.log(" \u2502 \u2502");
656
622
  console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
657
- console.log(" \u2502 To undo: solongate-init --restore \u2502");
623
+ console.log(" \u2502 To undo: npx @solongate/proxy init --restore \u2502");
658
624
  console.log(" \u2502 \u2502");
659
625
  console.log(" \u2502 Restart your MCP client to apply changes. \u2502");
660
626
  console.log(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "MCP security proxy — protect any MCP server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
5
5
  "type": "module",
6
6
  "bin": {