@solongate/proxy 0.5.4 → 0.5.6

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 +32 -64
  2. package/dist/init.js +28 -60
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -524,7 +524,7 @@ var init_config = __esm({
524
524
 
525
525
  // src/init.ts
526
526
  var init_exports = {};
527
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, copyFileSync, mkdirSync } from "fs";
527
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync } from "fs";
528
528
  import { resolve as resolve2, join } from "path";
529
529
  import { createInterface } from "readline";
530
530
  function findConfigFile(explicitPath, createIfMissing = false) {
@@ -610,10 +610,7 @@ async function prompt(question) {
610
610
  function parseInitArgs(argv) {
611
611
  const args = argv.slice(2);
612
612
  const options = {
613
- policy: "restricted",
614
- all: false,
615
- dryRun: false,
616
- restore: false
613
+ all: false
617
614
  };
618
615
  for (let i = 0; i < args.length; i++) {
619
616
  switch (args[i]) {
@@ -629,25 +626,12 @@ function parseInitArgs(argv) {
629
626
  case "--all":
630
627
  options.all = true;
631
628
  break;
632
- case "--dry-run":
633
- options.dryRun = true;
634
- break;
635
- case "--restore":
636
- options.restore = true;
637
- break;
638
629
  case "--help":
639
630
  case "-h":
640
631
  printHelp();
641
632
  process.exit(0);
642
633
  }
643
634
  }
644
- if (!POLICY_PRESETS.includes(options.policy)) {
645
- if (!existsSync3(resolve2(options.policy))) {
646
- console.log(`Unknown policy: ${options.policy}`);
647
- console.log(`Available presets: ${POLICY_PRESETS.join(", ")}`);
648
- process.exit(1);
649
- }
650
- }
651
635
  return options;
652
636
  }
653
637
  function printHelp() {
@@ -655,30 +639,19 @@ function printHelp() {
655
639
  SolonGate Init \u2014 Protect your MCP servers in seconds
656
640
 
657
641
  USAGE
658
- solongate-init [options]
642
+ npx @solongate/proxy init --all
659
643
 
660
644
  OPTIONS
661
645
  --config <path> Path to MCP config file (default: auto-detect)
662
- --policy <preset> Policy preset or JSON file (default: restricted)
663
- Presets: ${POLICY_PRESETS.join(", ")}
646
+ --policy <file> Custom policy JSON file (default: restricted)
647
+ Auto-detects policy.json in current directory
664
648
  --api-key <key> SolonGate API key (sg_live_... or sg_test_...)
665
649
  --all Protect all servers without prompting
666
- --dry-run Preview changes without writing
667
- --restore Restore original config from backup
668
650
  -h, --help Show this help message
669
651
 
670
652
  EXAMPLES
671
- solongate-init --api-key sg_live_xxx # Setup with API key
672
- solongate-init --all # Protect everything
673
- solongate-init --policy read-only # Use read-only policy
674
- solongate-init --dry-run # Preview changes
675
- solongate-init --restore # Undo protection
676
-
677
- POLICY PRESETS
678
- restricted Block shell/exec/eval, allow reads and writes (recommended)
679
- read-only Only allow read/list/get/search/query operations
680
- permissive Allow everything (monitoring + audit only)
681
- deny-all Block all tool calls
653
+ npx @solongate/proxy init --all # Protect everything
654
+ npx @solongate/proxy init --all --policy policy.json # With custom policy
682
655
  `;
683
656
  console.log(help);
684
657
  }
@@ -776,16 +749,6 @@ async function main() {
776
749
  console.log(` Config: ${configInfo.path}`);
777
750
  console.log(` Type: ${configInfo.type === "claude-desktop" ? "Claude Desktop" : "MCP JSON"}`);
778
751
  console.log("");
779
- const backupPath = configInfo.path + ".solongate-backup";
780
- if (options.restore) {
781
- if (!existsSync3(backupPath)) {
782
- console.log(" No backup found. Nothing to restore.");
783
- process.exit(1);
784
- }
785
- copyFileSync(backupPath, configInfo.path);
786
- console.log(" Restored original config from backup.");
787
- process.exit(0);
788
- }
789
752
  const config = readConfig(configInfo.path);
790
753
  const serverNames = Object.keys(config.mcpServers);
791
754
  if (serverNames.length === 0) {
@@ -864,8 +827,26 @@ async function main() {
864
827
  console.log(" Invalid API key format. Must start with sg_live_ or sg_test_");
865
828
  process.exit(1);
866
829
  }
830
+ let policyValue = "restricted";
831
+ if (options.policy) {
832
+ const policyPath = resolve2(options.policy);
833
+ if (existsSync3(policyPath)) {
834
+ policyValue = `./${options.policy}`;
835
+ console.log(` Policy: ${policyPath}`);
836
+ } else {
837
+ console.log(` Policy file not found: ${options.policy}`);
838
+ process.exit(1);
839
+ }
840
+ } else {
841
+ const defaultPolicy = resolve2("policy.json");
842
+ if (existsSync3(defaultPolicy)) {
843
+ policyValue = "./policy.json";
844
+ console.log(` Policy: ${defaultPolicy} (auto-detected)`);
845
+ } else {
846
+ console.log(` Policy: restricted (default)`);
847
+ }
848
+ }
867
849
  await sleep(300);
868
- console.log(` Policy: ${options.policy}`);
869
850
  await sleep(150);
870
851
  console.log(` API Key: ${apiKey.slice(0, 12)}...${apiKey.slice(-4)}`);
871
852
  await sleep(150);
@@ -874,23 +855,12 @@ async function main() {
874
855
  const newConfig = { mcpServers: {} };
875
856
  for (const name of serverNames) {
876
857
  if (toProtect.includes(name)) {
877
- newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy);
858
+ newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], policyValue);
878
859
  } else {
879
860
  newConfig.mcpServers[name] = config.mcpServers[name];
880
861
  }
881
862
  }
882
- if (options.dryRun) {
883
- console.log(" --- DRY RUN (no changes written) ---");
884
- console.log("");
885
- console.log(" New config:");
886
- console.log(JSON.stringify(newConfig, null, 2));
887
- process.exit(0);
888
- }
889
863
  await sleep(400);
890
- if (!configInfo.created && !existsSync3(backupPath)) {
891
- copyFileSync(configInfo.path, backupPath);
892
- console.log(` Backup: ${backupPath}`);
893
- }
894
864
  if (configInfo.type === "claude-desktop") {
895
865
  const original = JSON.parse(readFileSync3(configInfo.path, "utf-8"));
896
866
  original.mcpServers = newConfig.mcpServers;
@@ -909,7 +879,7 @@ async function main() {
909
879
  console.log("");
910
880
  for (const name of toProtect) {
911
881
  await sleep(200);
912
- console.log(` \u2713 ${name} \u2014 protected (${options.policy})`);
882
+ console.log(` \u2713 ${name} \u2014 protected`);
913
883
  }
914
884
  for (const name of alreadyProtected) {
915
885
  await sleep(200);
@@ -929,17 +899,15 @@ async function main() {
929
899
  console.log(" \u2502 API key \u2192 Set in .env \u2502");
930
900
  console.log(" \u2502 \u2502");
931
901
  console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
932
- console.log(" \u2502 To undo: npx @solongate/proxy init --restore \u2502");
933
902
  console.log(" \u2502 \u2502");
934
903
  console.log(" \u2502 Restart your MCP client to apply changes. \u2502");
935
904
  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");
936
905
  console.log("");
937
906
  }
938
- var POLICY_PRESETS, SEARCH_PATHS, CLAUDE_DESKTOP_PATHS, sleep, GUARD_SCRIPT, AUDIT_SCRIPT;
907
+ var SEARCH_PATHS, CLAUDE_DESKTOP_PATHS, sleep, GUARD_SCRIPT, AUDIT_SCRIPT;
939
908
  var init_init = __esm({
940
909
  "src/init.ts"() {
941
910
  "use strict";
942
- POLICY_PRESETS = ["restricted", "read-only", "permissive", "deny-all"];
943
911
  SEARCH_PATHS = [
944
912
  ".mcp.json",
945
913
  "mcp.json",
@@ -1162,7 +1130,7 @@ process.stdin.on('end', async () => {
1162
1130
 
1163
1131
  // src/inject.ts
1164
1132
  var inject_exports = {};
1165
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4, copyFileSync as copyFileSync2 } from "fs";
1133
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4, copyFileSync } from "fs";
1166
1134
  import { resolve as resolve3 } from "path";
1167
1135
  import { execSync } from "child_process";
1168
1136
  function parseInjectArgs(argv) {
@@ -1454,7 +1422,7 @@ async function main2() {
1454
1422
  log3(" No backup found. Nothing to restore.");
1455
1423
  process.exit(1);
1456
1424
  }
1457
- copyFileSync2(backupPath, entryFile);
1425
+ copyFileSync(backupPath, entryFile);
1458
1426
  log3(` Restored original file from backup.`);
1459
1427
  log3(` Backup: ${backupPath}`);
1460
1428
  process.exit(0);
@@ -1487,7 +1455,7 @@ async function main2() {
1487
1455
  process.exit(0);
1488
1456
  }
1489
1457
  if (!existsSync4(backupPath)) {
1490
- copyFileSync2(entryFile, backupPath);
1458
+ copyFileSync(entryFile, backupPath);
1491
1459
  log3("");
1492
1460
  log3(` Backup: ${backupPath}`);
1493
1461
  }
package/dist/init.js CHANGED
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/init.ts
4
- import { readFileSync, writeFileSync, existsSync, copyFileSync, mkdirSync } from "fs";
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
5
  import { resolve, join } from "path";
6
6
  import { createInterface } from "readline";
7
- var POLICY_PRESETS = ["restricted", "read-only", "permissive", "deny-all"];
8
7
  var SEARCH_PATHS = [
9
8
  ".mcp.json",
10
9
  "mcp.json",
@@ -95,10 +94,7 @@ async function prompt(question) {
95
94
  function parseInitArgs(argv) {
96
95
  const args = argv.slice(2);
97
96
  const options = {
98
- policy: "restricted",
99
- all: false,
100
- dryRun: false,
101
- restore: false
97
+ all: false
102
98
  };
103
99
  for (let i = 0; i < args.length; i++) {
104
100
  switch (args[i]) {
@@ -114,25 +110,12 @@ function parseInitArgs(argv) {
114
110
  case "--all":
115
111
  options.all = true;
116
112
  break;
117
- case "--dry-run":
118
- options.dryRun = true;
119
- break;
120
- case "--restore":
121
- options.restore = true;
122
- break;
123
113
  case "--help":
124
114
  case "-h":
125
115
  printHelp();
126
116
  process.exit(0);
127
117
  }
128
118
  }
129
- if (!POLICY_PRESETS.includes(options.policy)) {
130
- if (!existsSync(resolve(options.policy))) {
131
- console.log(`Unknown policy: ${options.policy}`);
132
- console.log(`Available presets: ${POLICY_PRESETS.join(", ")}`);
133
- process.exit(1);
134
- }
135
- }
136
119
  return options;
137
120
  }
138
121
  function printHelp() {
@@ -140,30 +123,19 @@ function printHelp() {
140
123
  SolonGate Init \u2014 Protect your MCP servers in seconds
141
124
 
142
125
  USAGE
143
- solongate-init [options]
126
+ npx @solongate/proxy init --all
144
127
 
145
128
  OPTIONS
146
129
  --config <path> Path to MCP config file (default: auto-detect)
147
- --policy <preset> Policy preset or JSON file (default: restricted)
148
- Presets: ${POLICY_PRESETS.join(", ")}
130
+ --policy <file> Custom policy JSON file (default: restricted)
131
+ Auto-detects policy.json in current directory
149
132
  --api-key <key> SolonGate API key (sg_live_... or sg_test_...)
150
133
  --all Protect all servers without prompting
151
- --dry-run Preview changes without writing
152
- --restore Restore original config from backup
153
134
  -h, --help Show this help message
154
135
 
155
136
  EXAMPLES
156
- solongate-init --api-key sg_live_xxx # Setup with API key
157
- solongate-init --all # Protect everything
158
- solongate-init --policy read-only # Use read-only policy
159
- solongate-init --dry-run # Preview changes
160
- solongate-init --restore # Undo protection
161
-
162
- POLICY PRESETS
163
- restricted Block shell/exec/eval, allow reads and writes (recommended)
164
- read-only Only allow read/list/get/search/query operations
165
- permissive Allow everything (monitoring + audit only)
166
- deny-all Block all tool calls
137
+ npx @solongate/proxy init --all # Protect everything
138
+ npx @solongate/proxy init --all --policy policy.json # With custom policy
167
139
  `;
168
140
  console.log(help);
169
141
  }
@@ -467,16 +439,6 @@ async function main() {
467
439
  console.log(` Config: ${configInfo.path}`);
468
440
  console.log(` Type: ${configInfo.type === "claude-desktop" ? "Claude Desktop" : "MCP JSON"}`);
469
441
  console.log("");
470
- const backupPath = configInfo.path + ".solongate-backup";
471
- if (options.restore) {
472
- if (!existsSync(backupPath)) {
473
- console.log(" No backup found. Nothing to restore.");
474
- process.exit(1);
475
- }
476
- copyFileSync(backupPath, configInfo.path);
477
- console.log(" Restored original config from backup.");
478
- process.exit(0);
479
- }
480
442
  const config = readConfig(configInfo.path);
481
443
  const serverNames = Object.keys(config.mcpServers);
482
444
  if (serverNames.length === 0) {
@@ -555,8 +517,26 @@ async function main() {
555
517
  console.log(" Invalid API key format. Must start with sg_live_ or sg_test_");
556
518
  process.exit(1);
557
519
  }
520
+ let policyValue = "restricted";
521
+ if (options.policy) {
522
+ const policyPath = resolve(options.policy);
523
+ if (existsSync(policyPath)) {
524
+ policyValue = `./${options.policy}`;
525
+ console.log(` Policy: ${policyPath}`);
526
+ } else {
527
+ console.log(` Policy file not found: ${options.policy}`);
528
+ process.exit(1);
529
+ }
530
+ } else {
531
+ const defaultPolicy = resolve("policy.json");
532
+ if (existsSync(defaultPolicy)) {
533
+ policyValue = "./policy.json";
534
+ console.log(` Policy: ${defaultPolicy} (auto-detected)`);
535
+ } else {
536
+ console.log(` Policy: restricted (default)`);
537
+ }
538
+ }
558
539
  await sleep(300);
559
- console.log(` Policy: ${options.policy}`);
560
540
  await sleep(150);
561
541
  console.log(` API Key: ${apiKey.slice(0, 12)}...${apiKey.slice(-4)}`);
562
542
  await sleep(150);
@@ -565,23 +545,12 @@ async function main() {
565
545
  const newConfig = { mcpServers: {} };
566
546
  for (const name of serverNames) {
567
547
  if (toProtect.includes(name)) {
568
- newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy);
548
+ newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], policyValue);
569
549
  } else {
570
550
  newConfig.mcpServers[name] = config.mcpServers[name];
571
551
  }
572
552
  }
573
- if (options.dryRun) {
574
- console.log(" --- DRY RUN (no changes written) ---");
575
- console.log("");
576
- console.log(" New config:");
577
- console.log(JSON.stringify(newConfig, null, 2));
578
- process.exit(0);
579
- }
580
553
  await sleep(400);
581
- if (!configInfo.created && !existsSync(backupPath)) {
582
- copyFileSync(configInfo.path, backupPath);
583
- console.log(` Backup: ${backupPath}`);
584
- }
585
554
  if (configInfo.type === "claude-desktop") {
586
555
  const original = JSON.parse(readFileSync(configInfo.path, "utf-8"));
587
556
  original.mcpServers = newConfig.mcpServers;
@@ -600,7 +569,7 @@ async function main() {
600
569
  console.log("");
601
570
  for (const name of toProtect) {
602
571
  await sleep(200);
603
- console.log(` \u2713 ${name} \u2014 protected (${options.policy})`);
572
+ console.log(` \u2713 ${name} \u2014 protected`);
604
573
  }
605
574
  for (const name of alreadyProtected) {
606
575
  await sleep(200);
@@ -620,7 +589,6 @@ async function main() {
620
589
  console.log(" \u2502 API key \u2192 Set in .env \u2502");
621
590
  console.log(" \u2502 \u2502");
622
591
  console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
623
- console.log(" \u2502 To undo: npx @solongate/proxy init --restore \u2502");
624
592
  console.log(" \u2502 \u2502");
625
593
  console.log(" \u2502 Restart your MCP client to apply changes. \u2502");
626
594
  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.4",
3
+ "version": "0.5.6",
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": {