@solongate/proxy 0.5.0 → 0.5.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/dist/index.js +24 -9
- package/dist/init.js +23 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -569,8 +569,10 @@ function isAlreadyProtected(server) {
|
|
|
569
569
|
}
|
|
570
570
|
return false;
|
|
571
571
|
}
|
|
572
|
-
function wrapServer(server, policy) {
|
|
573
|
-
const
|
|
572
|
+
function wrapServer(server, policy, apiKey) {
|
|
573
|
+
const env = { ...server.env ?? {} };
|
|
574
|
+
env.SOLONGATE_API_KEY = apiKey;
|
|
575
|
+
return {
|
|
574
576
|
command: "npx",
|
|
575
577
|
args: [
|
|
576
578
|
"-y",
|
|
@@ -581,12 +583,9 @@ function wrapServer(server, policy) {
|
|
|
581
583
|
"--",
|
|
582
584
|
server.command,
|
|
583
585
|
...server.args ?? []
|
|
584
|
-
]
|
|
586
|
+
],
|
|
587
|
+
env
|
|
585
588
|
};
|
|
586
|
-
if (server.env && Object.keys(server.env).length > 0) {
|
|
587
|
-
result.env = { ...server.env };
|
|
588
|
-
}
|
|
589
|
-
return result;
|
|
590
589
|
}
|
|
591
590
|
async function prompt(question) {
|
|
592
591
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -792,6 +791,7 @@ async function main() {
|
|
|
792
791
|
console.log("");
|
|
793
792
|
console.log(` ${_c.dim}${_c.italic}Init Setup${_c.reset}`);
|
|
794
793
|
console.log("");
|
|
794
|
+
await sleep(400);
|
|
795
795
|
const configInfo = findConfigFile(options.configPath, true);
|
|
796
796
|
if (!configInfo) {
|
|
797
797
|
console.log(" No MCP config found and could not create one.");
|
|
@@ -816,6 +816,7 @@ async function main() {
|
|
|
816
816
|
console.log(" No MCP servers found in config.");
|
|
817
817
|
process.exit(1);
|
|
818
818
|
}
|
|
819
|
+
await sleep(300);
|
|
819
820
|
console.log(` Found ${serverNames.length} MCP server(s):`);
|
|
820
821
|
console.log("");
|
|
821
822
|
const toProtect = [];
|
|
@@ -823,6 +824,7 @@ async function main() {
|
|
|
823
824
|
const skipped = [];
|
|
824
825
|
for (const name of serverNames) {
|
|
825
826
|
const server = config.mcpServers[name];
|
|
827
|
+
await sleep(200);
|
|
826
828
|
if (isAlreadyProtected(server)) {
|
|
827
829
|
alreadyProtected.push(name);
|
|
828
830
|
console.log(` [protected] ${name}`);
|
|
@@ -856,6 +858,7 @@ async function main() {
|
|
|
856
858
|
process.exit(0);
|
|
857
859
|
}
|
|
858
860
|
console.log("");
|
|
861
|
+
await sleep(300);
|
|
859
862
|
ensureEnvFile();
|
|
860
863
|
console.log("");
|
|
861
864
|
let apiKey = options.apiKey || process.env.SOLONGATE_API_KEY || "";
|
|
@@ -885,14 +888,17 @@ async function main() {
|
|
|
885
888
|
console.log(" Invalid API key format. Must start with sg_live_ or sg_test_");
|
|
886
889
|
process.exit(1);
|
|
887
890
|
}
|
|
891
|
+
await sleep(300);
|
|
888
892
|
console.log(` Policy: ${options.policy}`);
|
|
893
|
+
await sleep(150);
|
|
889
894
|
console.log(` API Key: ${apiKey.slice(0, 12)}...${apiKey.slice(-4)}`);
|
|
895
|
+
await sleep(150);
|
|
890
896
|
console.log(` Protecting: ${toProtect.join(", ")}`);
|
|
891
897
|
console.log("");
|
|
892
898
|
const newConfig = { mcpServers: {} };
|
|
893
899
|
for (const name of serverNames) {
|
|
894
900
|
if (toProtect.includes(name)) {
|
|
895
|
-
newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy);
|
|
901
|
+
newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy, apiKey);
|
|
896
902
|
} else {
|
|
897
903
|
newConfig.mcpServers[name] = config.mcpServers[name];
|
|
898
904
|
}
|
|
@@ -904,6 +910,7 @@ async function main() {
|
|
|
904
910
|
console.log(JSON.stringify(newConfig, null, 2));
|
|
905
911
|
process.exit(0);
|
|
906
912
|
}
|
|
913
|
+
await sleep(400);
|
|
907
914
|
if (!configInfo.created && !existsSync3(backupPath)) {
|
|
908
915
|
copyFileSync(configInfo.path, backupPath);
|
|
909
916
|
console.log(` Backup: ${backupPath}`);
|
|
@@ -915,22 +922,29 @@ async function main() {
|
|
|
915
922
|
} else {
|
|
916
923
|
writeFileSync2(configInfo.path, JSON.stringify(newConfig, null, 2) + "\n");
|
|
917
924
|
}
|
|
925
|
+
await sleep(300);
|
|
918
926
|
console.log(" Config updated!");
|
|
919
927
|
console.log("");
|
|
928
|
+
await sleep(500);
|
|
920
929
|
installClaudeCodeHooks(apiKey);
|
|
921
930
|
console.log("");
|
|
931
|
+
await sleep(400);
|
|
922
932
|
console.log(" \u2500\u2500 Summary \u2500\u2500");
|
|
923
933
|
console.log("");
|
|
924
934
|
for (const name of toProtect) {
|
|
935
|
+
await sleep(200);
|
|
925
936
|
console.log(` \u2713 ${name} \u2014 protected (${options.policy})`);
|
|
926
937
|
}
|
|
927
938
|
for (const name of alreadyProtected) {
|
|
939
|
+
await sleep(200);
|
|
928
940
|
console.log(` \u25CF ${name} \u2014 already protected`);
|
|
929
941
|
}
|
|
930
942
|
for (const name of skipped) {
|
|
943
|
+
await sleep(200);
|
|
931
944
|
console.log(` \u25CB ${name} \u2014 skipped`);
|
|
932
945
|
}
|
|
933
946
|
console.log("");
|
|
947
|
+
await sleep(500);
|
|
934
948
|
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");
|
|
935
949
|
console.log(" \u2502 Setup complete! \u2502");
|
|
936
950
|
console.log(" \u2502 \u2502");
|
|
@@ -944,7 +958,7 @@ async function main() {
|
|
|
944
958
|
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");
|
|
945
959
|
console.log("");
|
|
946
960
|
}
|
|
947
|
-
var POLICY_PRESETS, SEARCH_PATHS, CLAUDE_DESKTOP_PATHS, GUARD_SCRIPT, AUDIT_SCRIPT;
|
|
961
|
+
var POLICY_PRESETS, SEARCH_PATHS, CLAUDE_DESKTOP_PATHS, sleep, GUARD_SCRIPT, AUDIT_SCRIPT;
|
|
948
962
|
var init_init = __esm({
|
|
949
963
|
"src/init.ts"() {
|
|
950
964
|
"use strict";
|
|
@@ -955,6 +969,7 @@ var init_init = __esm({
|
|
|
955
969
|
".claude/mcp.json"
|
|
956
970
|
];
|
|
957
971
|
CLAUDE_DESKTOP_PATHS = process.platform === "win32" ? [join(process.env["APPDATA"] ?? "", "Claude", "claude_desktop_config.json")] : process.platform === "darwin" ? [join(process.env["HOME"] ?? "", "Library", "Application Support", "Claude", "claude_desktop_config.json")] : [join(process.env["HOME"] ?? "", ".config", "claude", "claude_desktop_config.json")];
|
|
972
|
+
sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
958
973
|
GUARD_SCRIPT = `#!/usr/bin/env node
|
|
959
974
|
/**
|
|
960
975
|
* SolonGate Guard Hook for Claude Code (PreToolUse)
|
package/dist/init.js
CHANGED
|
@@ -11,6 +11,7 @@ var SEARCH_PATHS = [
|
|
|
11
11
|
".claude/mcp.json"
|
|
12
12
|
];
|
|
13
13
|
var CLAUDE_DESKTOP_PATHS = process.platform === "win32" ? [join(process.env["APPDATA"] ?? "", "Claude", "claude_desktop_config.json")] : process.platform === "darwin" ? [join(process.env["HOME"] ?? "", "Library", "Application Support", "Claude", "claude_desktop_config.json")] : [join(process.env["HOME"] ?? "", ".config", "claude", "claude_desktop_config.json")];
|
|
14
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
14
15
|
function findConfigFile(explicitPath, createIfMissing = false) {
|
|
15
16
|
if (explicitPath) {
|
|
16
17
|
if (existsSync(explicitPath)) {
|
|
@@ -64,8 +65,10 @@ function isAlreadyProtected(server) {
|
|
|
64
65
|
}
|
|
65
66
|
return false;
|
|
66
67
|
}
|
|
67
|
-
function wrapServer(server, policy) {
|
|
68
|
-
const
|
|
68
|
+
function wrapServer(server, policy, apiKey) {
|
|
69
|
+
const env = { ...server.env ?? {} };
|
|
70
|
+
env.SOLONGATE_API_KEY = apiKey;
|
|
71
|
+
return {
|
|
69
72
|
command: "npx",
|
|
70
73
|
args: [
|
|
71
74
|
"-y",
|
|
@@ -76,12 +79,9 @@ function wrapServer(server, policy) {
|
|
|
76
79
|
"--",
|
|
77
80
|
server.command,
|
|
78
81
|
...server.args ?? []
|
|
79
|
-
]
|
|
82
|
+
],
|
|
83
|
+
env
|
|
80
84
|
};
|
|
81
|
-
if (server.env && Object.keys(server.env).length > 0) {
|
|
82
|
-
result.env = { ...server.env };
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
85
85
|
}
|
|
86
86
|
async function prompt(question) {
|
|
87
87
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -493,6 +493,7 @@ async function main() {
|
|
|
493
493
|
console.log("");
|
|
494
494
|
console.log(` ${_c.dim}${_c.italic}Init Setup${_c.reset}`);
|
|
495
495
|
console.log("");
|
|
496
|
+
await sleep(400);
|
|
496
497
|
const configInfo = findConfigFile(options.configPath, true);
|
|
497
498
|
if (!configInfo) {
|
|
498
499
|
console.log(" No MCP config found and could not create one.");
|
|
@@ -517,6 +518,7 @@ async function main() {
|
|
|
517
518
|
console.log(" No MCP servers found in config.");
|
|
518
519
|
process.exit(1);
|
|
519
520
|
}
|
|
521
|
+
await sleep(300);
|
|
520
522
|
console.log(` Found ${serverNames.length} MCP server(s):`);
|
|
521
523
|
console.log("");
|
|
522
524
|
const toProtect = [];
|
|
@@ -524,6 +526,7 @@ async function main() {
|
|
|
524
526
|
const skipped = [];
|
|
525
527
|
for (const name of serverNames) {
|
|
526
528
|
const server = config.mcpServers[name];
|
|
529
|
+
await sleep(200);
|
|
527
530
|
if (isAlreadyProtected(server)) {
|
|
528
531
|
alreadyProtected.push(name);
|
|
529
532
|
console.log(` [protected] ${name}`);
|
|
@@ -557,6 +560,7 @@ async function main() {
|
|
|
557
560
|
process.exit(0);
|
|
558
561
|
}
|
|
559
562
|
console.log("");
|
|
563
|
+
await sleep(300);
|
|
560
564
|
ensureEnvFile();
|
|
561
565
|
console.log("");
|
|
562
566
|
let apiKey = options.apiKey || process.env.SOLONGATE_API_KEY || "";
|
|
@@ -586,14 +590,17 @@ async function main() {
|
|
|
586
590
|
console.log(" Invalid API key format. Must start with sg_live_ or sg_test_");
|
|
587
591
|
process.exit(1);
|
|
588
592
|
}
|
|
593
|
+
await sleep(300);
|
|
589
594
|
console.log(` Policy: ${options.policy}`);
|
|
595
|
+
await sleep(150);
|
|
590
596
|
console.log(` API Key: ${apiKey.slice(0, 12)}...${apiKey.slice(-4)}`);
|
|
597
|
+
await sleep(150);
|
|
591
598
|
console.log(` Protecting: ${toProtect.join(", ")}`);
|
|
592
599
|
console.log("");
|
|
593
600
|
const newConfig = { mcpServers: {} };
|
|
594
601
|
for (const name of serverNames) {
|
|
595
602
|
if (toProtect.includes(name)) {
|
|
596
|
-
newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy);
|
|
603
|
+
newConfig.mcpServers[name] = wrapServer(config.mcpServers[name], options.policy, apiKey);
|
|
597
604
|
} else {
|
|
598
605
|
newConfig.mcpServers[name] = config.mcpServers[name];
|
|
599
606
|
}
|
|
@@ -605,6 +612,7 @@ async function main() {
|
|
|
605
612
|
console.log(JSON.stringify(newConfig, null, 2));
|
|
606
613
|
process.exit(0);
|
|
607
614
|
}
|
|
615
|
+
await sleep(400);
|
|
608
616
|
if (!configInfo.created && !existsSync(backupPath)) {
|
|
609
617
|
copyFileSync(configInfo.path, backupPath);
|
|
610
618
|
console.log(` Backup: ${backupPath}`);
|
|
@@ -616,22 +624,29 @@ async function main() {
|
|
|
616
624
|
} else {
|
|
617
625
|
writeFileSync(configInfo.path, JSON.stringify(newConfig, null, 2) + "\n");
|
|
618
626
|
}
|
|
627
|
+
await sleep(300);
|
|
619
628
|
console.log(" Config updated!");
|
|
620
629
|
console.log("");
|
|
630
|
+
await sleep(500);
|
|
621
631
|
installClaudeCodeHooks(apiKey);
|
|
622
632
|
console.log("");
|
|
633
|
+
await sleep(400);
|
|
623
634
|
console.log(" \u2500\u2500 Summary \u2500\u2500");
|
|
624
635
|
console.log("");
|
|
625
636
|
for (const name of toProtect) {
|
|
637
|
+
await sleep(200);
|
|
626
638
|
console.log(` \u2713 ${name} \u2014 protected (${options.policy})`);
|
|
627
639
|
}
|
|
628
640
|
for (const name of alreadyProtected) {
|
|
641
|
+
await sleep(200);
|
|
629
642
|
console.log(` \u25CF ${name} \u2014 already protected`);
|
|
630
643
|
}
|
|
631
644
|
for (const name of skipped) {
|
|
645
|
+
await sleep(200);
|
|
632
646
|
console.log(` \u25CB ${name} \u2014 skipped`);
|
|
633
647
|
}
|
|
634
648
|
console.log("");
|
|
649
|
+
await sleep(500);
|
|
635
650
|
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");
|
|
636
651
|
console.log(" \u2502 Setup complete! \u2502");
|
|
637
652
|
console.log(" \u2502 \u2502");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
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": {
|