@solongate/proxy 0.28.6 → 0.28.8
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 +115 -49
- package/dist/init.js +115 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -672,15 +672,29 @@ function installHooks(selectedTools = []) {
|
|
|
672
672
|
unlockProtectedDirs();
|
|
673
673
|
const hooksDir = resolve3(".solongate", "hooks");
|
|
674
674
|
mkdirSync2(hooksDir, { recursive: true });
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
675
|
+
const hookFiles = ["guard.mjs", "audit.mjs", "stop.mjs"];
|
|
676
|
+
let hooksUpdated = 0;
|
|
677
|
+
let hooksSkipped = 0;
|
|
678
|
+
for (const filename of hookFiles) {
|
|
679
|
+
const hookPath = join(hooksDir, filename);
|
|
680
|
+
const latest = readHookScript(filename);
|
|
681
|
+
let needsWrite = true;
|
|
682
|
+
if (existsSync4(hookPath)) {
|
|
683
|
+
const current = readFileSync4(hookPath, "utf-8");
|
|
684
|
+
if (current === latest) {
|
|
685
|
+
needsWrite = false;
|
|
686
|
+
hooksSkipped++;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
if (needsWrite) {
|
|
690
|
+
writeFileSync2(hookPath, latest);
|
|
691
|
+
hooksUpdated++;
|
|
692
|
+
console.log(` ${existsSync4(hookPath) ? "Updated" : "Created"} ${hookPath}`);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
if (hooksSkipped > 0 && hooksUpdated === 0) {
|
|
696
|
+
console.log(` Hook files already up to date`);
|
|
697
|
+
}
|
|
684
698
|
const allClients = [
|
|
685
699
|
{ name: "Claude Code", dir: ".claude", key: "claude", agentId: "claude-code", agentName: "Claude Code" },
|
|
686
700
|
{ name: "Cursor", dir: ".cursor", key: "cursor", agentId: "cursor", agentName: "Cursor" },
|
|
@@ -691,6 +705,7 @@ function installHooks(selectedTools = []) {
|
|
|
691
705
|
];
|
|
692
706
|
const clients = selectedTools.length > 0 ? allClients.filter((c3) => selectedTools.includes(c3.key)) : allClients;
|
|
693
707
|
const activatedNames = [];
|
|
708
|
+
const skippedNames = [];
|
|
694
709
|
for (const client of clients) {
|
|
695
710
|
const clientDir = resolve3(client.dir);
|
|
696
711
|
mkdirSync2(clientDir, { recursive: true });
|
|
@@ -715,18 +730,31 @@ function installHooks(selectedTools = []) {
|
|
|
715
730
|
} catch {
|
|
716
731
|
}
|
|
717
732
|
const merged = { ...existing, hooks: hookSettings };
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
733
|
+
const mergedStr = JSON.stringify(merged, null, 2) + "\n";
|
|
734
|
+
const existingStr = existsSync4(settingsPath) ? readFileSync4(settingsPath, "utf-8") : "";
|
|
735
|
+
if (mergedStr === existingStr) {
|
|
736
|
+
skippedNames.push(client.name);
|
|
737
|
+
} else {
|
|
738
|
+
writeFileSync2(settingsPath, mergedStr);
|
|
739
|
+
console.log(` ${existingStr ? "Updated" : "Created"} ${settingsPath}`);
|
|
740
|
+
activatedNames.push(client.name);
|
|
741
|
+
}
|
|
721
742
|
}
|
|
722
743
|
console.log("");
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
744
|
+
if (activatedNames.length > 0) {
|
|
745
|
+
console.log(" Hooks installed:");
|
|
746
|
+
console.log(" guard.mjs \u2192 blocks policy-violating calls (pre-execution)");
|
|
747
|
+
console.log(" audit.mjs \u2192 logs all calls to dashboard (post-execution)");
|
|
748
|
+
console.log(" stop.mjs \u2192 tracks text-only responses (no tool calls)");
|
|
749
|
+
console.log(` Activated for: ${activatedNames.join(", ")}`);
|
|
750
|
+
}
|
|
751
|
+
if (skippedNames.length > 0) {
|
|
752
|
+
console.log(` Already configured: ${skippedNames.join(", ")}`);
|
|
753
|
+
}
|
|
728
754
|
}
|
|
729
755
|
function ensureEnvFile() {
|
|
756
|
+
let envChanged = false;
|
|
757
|
+
let gitignoreChanged = false;
|
|
730
758
|
const envPath = resolve3(".env");
|
|
731
759
|
if (!existsSync4(envPath)) {
|
|
732
760
|
const envContent = `# SolonGate Configuration
|
|
@@ -742,28 +770,50 @@ GROQ_API_KEY=gsk_your_groq_key_here
|
|
|
742
770
|
writeFileSync2(envPath, envContent);
|
|
743
771
|
console.log(` Created .env`);
|
|
744
772
|
console.log(` \u2192 Set your API key in .env (get one at https://dashboard.solongate.com)`);
|
|
745
|
-
|
|
773
|
+
envChanged = true;
|
|
774
|
+
} else {
|
|
775
|
+
const existingEnv = readFileSync4(envPath, "utf-8");
|
|
776
|
+
if (!existingEnv.includes("SOLONGATE_API_KEY")) {
|
|
777
|
+
const separator = existingEnv.endsWith("\n") ? "" : "\n";
|
|
778
|
+
const appendContent = `${separator}
|
|
779
|
+
# SolonGate API key \u2014 get one at https://dashboard.solongate.com
|
|
780
|
+
SOLONGATE_API_KEY=sg_live_your_key_here
|
|
781
|
+
`;
|
|
782
|
+
writeFileSync2(envPath, existingEnv + appendContent);
|
|
783
|
+
console.log(` Updated .env (added SOLONGATE_API_KEY)`);
|
|
784
|
+
console.log(` \u2192 Set your API key in .env (get one at https://dashboard.solongate.com)`);
|
|
785
|
+
envChanged = true;
|
|
786
|
+
}
|
|
746
787
|
}
|
|
747
788
|
const gitignorePath = resolve3(".gitignore");
|
|
789
|
+
const requiredEntries = [
|
|
790
|
+
{ pattern: ".env", lines: ".env\n.env.local" },
|
|
791
|
+
{ pattern: ".mcp.json", lines: ".mcp.json" },
|
|
792
|
+
{ pattern: ".solongate", lines: ".solongate/" }
|
|
793
|
+
];
|
|
748
794
|
if (existsSync4(gitignorePath)) {
|
|
749
795
|
let gitignore = readFileSync4(gitignorePath, "utf-8");
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
gitignore = gitignore.trimEnd() + "\n.mcp.json\n";
|
|
757
|
-
updated = true;
|
|
796
|
+
const added = [];
|
|
797
|
+
for (const entry of requiredEntries) {
|
|
798
|
+
if (!gitignore.includes(entry.pattern)) {
|
|
799
|
+
gitignore = gitignore.trimEnd() + "\n" + entry.lines + "\n";
|
|
800
|
+
added.push(entry.pattern);
|
|
801
|
+
}
|
|
758
802
|
}
|
|
759
|
-
if (
|
|
803
|
+
if (added.length > 0) {
|
|
760
804
|
writeFileSync2(gitignorePath, gitignore);
|
|
761
|
-
console.log(` Updated .gitignore (added .
|
|
805
|
+
console.log(` Updated .gitignore (added ${added.join(", ")})`);
|
|
806
|
+
gitignoreChanged = true;
|
|
762
807
|
}
|
|
763
808
|
} else {
|
|
764
|
-
writeFileSync2(gitignorePath, ".env\n.env.local\n.mcp.json\nnode_modules/\n");
|
|
765
|
-
console.log(` Created .gitignore (with .env
|
|
809
|
+
writeFileSync2(gitignorePath, ".env\n.env.local\n.mcp.json\n.solongate/\nnode_modules/\n");
|
|
810
|
+
console.log(` Created .gitignore (with .env, .mcp.json, .solongate/ excluded)`);
|
|
811
|
+
gitignoreChanged = true;
|
|
812
|
+
}
|
|
813
|
+
if (!envChanged && !gitignoreChanged) {
|
|
814
|
+
console.log(` .env and .gitignore already up to date`);
|
|
766
815
|
}
|
|
816
|
+
return { envChanged, gitignoreChanged };
|
|
767
817
|
}
|
|
768
818
|
async function main() {
|
|
769
819
|
const options = parseInitArgs(process.argv);
|
|
@@ -924,21 +974,28 @@ async function main() {
|
|
|
924
974
|
newConfig.mcpServers[name] = config.mcpServers[name];
|
|
925
975
|
}
|
|
926
976
|
}
|
|
927
|
-
|
|
977
|
+
const currentContent = readFileSync4(configInfo.path, "utf-8");
|
|
978
|
+
let newContent;
|
|
928
979
|
if (configInfo.type === "claude-desktop") {
|
|
929
|
-
const original = JSON.parse(
|
|
980
|
+
const original = JSON.parse(currentContent);
|
|
930
981
|
original.mcpServers = newConfig.mcpServers;
|
|
931
|
-
|
|
982
|
+
newContent = JSON.stringify(original, null, 2) + "\n";
|
|
932
983
|
} else {
|
|
933
|
-
|
|
984
|
+
newContent = JSON.stringify(newConfig, null, 2) + "\n";
|
|
985
|
+
}
|
|
986
|
+
await sleep(400);
|
|
987
|
+
if (newContent === currentContent) {
|
|
988
|
+
console.log(" Config already up to date");
|
|
989
|
+
} else {
|
|
990
|
+
writeFileSync2(configInfo.path, newContent);
|
|
991
|
+
console.log(" Config updated!");
|
|
934
992
|
}
|
|
935
|
-
await sleep(300);
|
|
936
|
-
console.log(" Config updated!");
|
|
937
993
|
console.log("");
|
|
938
994
|
await sleep(500);
|
|
939
995
|
installHooks(options.tools);
|
|
940
996
|
console.log("");
|
|
941
997
|
await sleep(400);
|
|
998
|
+
const allUpToDate = toProtect.length === 0 && alreadyProtected.length === serverNames.length;
|
|
942
999
|
console.log(" \u2500\u2500 Summary \u2500\u2500");
|
|
943
1000
|
console.log("");
|
|
944
1001
|
for (const name of toProtect) {
|
|
@@ -955,19 +1012,28 @@ async function main() {
|
|
|
955
1012
|
}
|
|
956
1013
|
console.log("");
|
|
957
1014
|
await sleep(500);
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1015
|
+
if (allUpToDate) {
|
|
1016
|
+
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");
|
|
1017
|
+
console.log(" \u2502 Everything is already up to date! \u2502");
|
|
1018
|
+
console.log(" \u2502 \u2502");
|
|
1019
|
+
console.log(" \u2502 All MCP servers protected, hooks configured. \u2502");
|
|
1020
|
+
console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
|
|
1021
|
+
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");
|
|
1022
|
+
} else {
|
|
1023
|
+
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");
|
|
1024
|
+
console.log(" \u2502 Setup complete! \u2502");
|
|
1025
|
+
console.log(" \u2502 \u2502");
|
|
1026
|
+
console.log(" \u2502 MCP servers \u2192 Protected via proxy \u2502");
|
|
1027
|
+
console.log(" \u2502 AI tools \u2192 Guarded via hooks \u2502");
|
|
1028
|
+
console.log(" \u2502 Claude, Cursor, Gemini, Antigravity, \u2502");
|
|
1029
|
+
console.log(" \u2502 OpenClaw, Perplexity \u2502");
|
|
1030
|
+
console.log(" \u2502 API key \u2192 Set in .env \u2502");
|
|
1031
|
+
console.log(" \u2502 \u2502");
|
|
1032
|
+
console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
|
|
1033
|
+
console.log(" \u2502 \u2502");
|
|
1034
|
+
console.log(" \u2502 Restart your MCP client to apply changes. \u2502");
|
|
1035
|
+
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");
|
|
1036
|
+
}
|
|
971
1037
|
console.log("");
|
|
972
1038
|
}
|
|
973
1039
|
var SEARCH_PATHS, CLAUDE_DESKTOP_PATHS, sleep, __dirname, HOOKS_DIR;
|
package/dist/init.js
CHANGED
|
@@ -255,15 +255,29 @@ function installHooks(selectedTools = []) {
|
|
|
255
255
|
unlockProtectedDirs();
|
|
256
256
|
const hooksDir = resolve(".solongate", "hooks");
|
|
257
257
|
mkdirSync(hooksDir, { recursive: true });
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
258
|
+
const hookFiles = ["guard.mjs", "audit.mjs", "stop.mjs"];
|
|
259
|
+
let hooksUpdated = 0;
|
|
260
|
+
let hooksSkipped = 0;
|
|
261
|
+
for (const filename of hookFiles) {
|
|
262
|
+
const hookPath = join(hooksDir, filename);
|
|
263
|
+
const latest = readHookScript(filename);
|
|
264
|
+
let needsWrite = true;
|
|
265
|
+
if (existsSync(hookPath)) {
|
|
266
|
+
const current = readFileSync(hookPath, "utf-8");
|
|
267
|
+
if (current === latest) {
|
|
268
|
+
needsWrite = false;
|
|
269
|
+
hooksSkipped++;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (needsWrite) {
|
|
273
|
+
writeFileSync(hookPath, latest);
|
|
274
|
+
hooksUpdated++;
|
|
275
|
+
console.log(` ${existsSync(hookPath) ? "Updated" : "Created"} ${hookPath}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (hooksSkipped > 0 && hooksUpdated === 0) {
|
|
279
|
+
console.log(` Hook files already up to date`);
|
|
280
|
+
}
|
|
267
281
|
const allClients = [
|
|
268
282
|
{ name: "Claude Code", dir: ".claude", key: "claude", agentId: "claude-code", agentName: "Claude Code" },
|
|
269
283
|
{ name: "Cursor", dir: ".cursor", key: "cursor", agentId: "cursor", agentName: "Cursor" },
|
|
@@ -274,6 +288,7 @@ function installHooks(selectedTools = []) {
|
|
|
274
288
|
];
|
|
275
289
|
const clients = selectedTools.length > 0 ? allClients.filter((c2) => selectedTools.includes(c2.key)) : allClients;
|
|
276
290
|
const activatedNames = [];
|
|
291
|
+
const skippedNames = [];
|
|
277
292
|
for (const client of clients) {
|
|
278
293
|
const clientDir = resolve(client.dir);
|
|
279
294
|
mkdirSync(clientDir, { recursive: true });
|
|
@@ -298,18 +313,31 @@ function installHooks(selectedTools = []) {
|
|
|
298
313
|
} catch {
|
|
299
314
|
}
|
|
300
315
|
const merged = { ...existing, hooks: hookSettings };
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
316
|
+
const mergedStr = JSON.stringify(merged, null, 2) + "\n";
|
|
317
|
+
const existingStr = existsSync(settingsPath) ? readFileSync(settingsPath, "utf-8") : "";
|
|
318
|
+
if (mergedStr === existingStr) {
|
|
319
|
+
skippedNames.push(client.name);
|
|
320
|
+
} else {
|
|
321
|
+
writeFileSync(settingsPath, mergedStr);
|
|
322
|
+
console.log(` ${existingStr ? "Updated" : "Created"} ${settingsPath}`);
|
|
323
|
+
activatedNames.push(client.name);
|
|
324
|
+
}
|
|
304
325
|
}
|
|
305
326
|
console.log("");
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
327
|
+
if (activatedNames.length > 0) {
|
|
328
|
+
console.log(" Hooks installed:");
|
|
329
|
+
console.log(" guard.mjs \u2192 blocks policy-violating calls (pre-execution)");
|
|
330
|
+
console.log(" audit.mjs \u2192 logs all calls to dashboard (post-execution)");
|
|
331
|
+
console.log(" stop.mjs \u2192 tracks text-only responses (no tool calls)");
|
|
332
|
+
console.log(` Activated for: ${activatedNames.join(", ")}`);
|
|
333
|
+
}
|
|
334
|
+
if (skippedNames.length > 0) {
|
|
335
|
+
console.log(` Already configured: ${skippedNames.join(", ")}`);
|
|
336
|
+
}
|
|
311
337
|
}
|
|
312
338
|
function ensureEnvFile() {
|
|
339
|
+
let envChanged = false;
|
|
340
|
+
let gitignoreChanged = false;
|
|
313
341
|
const envPath = resolve(".env");
|
|
314
342
|
if (!existsSync(envPath)) {
|
|
315
343
|
const envContent = `# SolonGate Configuration
|
|
@@ -325,28 +353,50 @@ GROQ_API_KEY=gsk_your_groq_key_here
|
|
|
325
353
|
writeFileSync(envPath, envContent);
|
|
326
354
|
console.log(` Created .env`);
|
|
327
355
|
console.log(` \u2192 Set your API key in .env (get one at https://dashboard.solongate.com)`);
|
|
328
|
-
|
|
356
|
+
envChanged = true;
|
|
357
|
+
} else {
|
|
358
|
+
const existingEnv = readFileSync(envPath, "utf-8");
|
|
359
|
+
if (!existingEnv.includes("SOLONGATE_API_KEY")) {
|
|
360
|
+
const separator = existingEnv.endsWith("\n") ? "" : "\n";
|
|
361
|
+
const appendContent = `${separator}
|
|
362
|
+
# SolonGate API key \u2014 get one at https://dashboard.solongate.com
|
|
363
|
+
SOLONGATE_API_KEY=sg_live_your_key_here
|
|
364
|
+
`;
|
|
365
|
+
writeFileSync(envPath, existingEnv + appendContent);
|
|
366
|
+
console.log(` Updated .env (added SOLONGATE_API_KEY)`);
|
|
367
|
+
console.log(` \u2192 Set your API key in .env (get one at https://dashboard.solongate.com)`);
|
|
368
|
+
envChanged = true;
|
|
369
|
+
}
|
|
329
370
|
}
|
|
330
371
|
const gitignorePath = resolve(".gitignore");
|
|
372
|
+
const requiredEntries = [
|
|
373
|
+
{ pattern: ".env", lines: ".env\n.env.local" },
|
|
374
|
+
{ pattern: ".mcp.json", lines: ".mcp.json" },
|
|
375
|
+
{ pattern: ".solongate", lines: ".solongate/" }
|
|
376
|
+
];
|
|
331
377
|
if (existsSync(gitignorePath)) {
|
|
332
378
|
let gitignore = readFileSync(gitignorePath, "utf-8");
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
gitignore = gitignore.trimEnd() + "\n.mcp.json\n";
|
|
340
|
-
updated = true;
|
|
379
|
+
const added = [];
|
|
380
|
+
for (const entry of requiredEntries) {
|
|
381
|
+
if (!gitignore.includes(entry.pattern)) {
|
|
382
|
+
gitignore = gitignore.trimEnd() + "\n" + entry.lines + "\n";
|
|
383
|
+
added.push(entry.pattern);
|
|
384
|
+
}
|
|
341
385
|
}
|
|
342
|
-
if (
|
|
386
|
+
if (added.length > 0) {
|
|
343
387
|
writeFileSync(gitignorePath, gitignore);
|
|
344
|
-
console.log(` Updated .gitignore (added .
|
|
388
|
+
console.log(` Updated .gitignore (added ${added.join(", ")})`);
|
|
389
|
+
gitignoreChanged = true;
|
|
345
390
|
}
|
|
346
391
|
} else {
|
|
347
|
-
writeFileSync(gitignorePath, ".env\n.env.local\n.mcp.json\nnode_modules/\n");
|
|
348
|
-
console.log(` Created .gitignore (with .env
|
|
392
|
+
writeFileSync(gitignorePath, ".env\n.env.local\n.mcp.json\n.solongate/\nnode_modules/\n");
|
|
393
|
+
console.log(` Created .gitignore (with .env, .mcp.json, .solongate/ excluded)`);
|
|
394
|
+
gitignoreChanged = true;
|
|
395
|
+
}
|
|
396
|
+
if (!envChanged && !gitignoreChanged) {
|
|
397
|
+
console.log(` .env and .gitignore already up to date`);
|
|
349
398
|
}
|
|
399
|
+
return { envChanged, gitignoreChanged };
|
|
350
400
|
}
|
|
351
401
|
async function main() {
|
|
352
402
|
const options = parseInitArgs(process.argv);
|
|
@@ -507,21 +557,28 @@ async function main() {
|
|
|
507
557
|
newConfig.mcpServers[name] = config.mcpServers[name];
|
|
508
558
|
}
|
|
509
559
|
}
|
|
510
|
-
|
|
560
|
+
const currentContent = readFileSync(configInfo.path, "utf-8");
|
|
561
|
+
let newContent;
|
|
511
562
|
if (configInfo.type === "claude-desktop") {
|
|
512
|
-
const original = JSON.parse(
|
|
563
|
+
const original = JSON.parse(currentContent);
|
|
513
564
|
original.mcpServers = newConfig.mcpServers;
|
|
514
|
-
|
|
565
|
+
newContent = JSON.stringify(original, null, 2) + "\n";
|
|
515
566
|
} else {
|
|
516
|
-
|
|
567
|
+
newContent = JSON.stringify(newConfig, null, 2) + "\n";
|
|
568
|
+
}
|
|
569
|
+
await sleep(400);
|
|
570
|
+
if (newContent === currentContent) {
|
|
571
|
+
console.log(" Config already up to date");
|
|
572
|
+
} else {
|
|
573
|
+
writeFileSync(configInfo.path, newContent);
|
|
574
|
+
console.log(" Config updated!");
|
|
517
575
|
}
|
|
518
|
-
await sleep(300);
|
|
519
|
-
console.log(" Config updated!");
|
|
520
576
|
console.log("");
|
|
521
577
|
await sleep(500);
|
|
522
578
|
installHooks(options.tools);
|
|
523
579
|
console.log("");
|
|
524
580
|
await sleep(400);
|
|
581
|
+
const allUpToDate = toProtect.length === 0 && alreadyProtected.length === serverNames.length;
|
|
525
582
|
console.log(" \u2500\u2500 Summary \u2500\u2500");
|
|
526
583
|
console.log("");
|
|
527
584
|
for (const name of toProtect) {
|
|
@@ -538,19 +595,28 @@ async function main() {
|
|
|
538
595
|
}
|
|
539
596
|
console.log("");
|
|
540
597
|
await sleep(500);
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
598
|
+
if (allUpToDate) {
|
|
599
|
+
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");
|
|
600
|
+
console.log(" \u2502 Everything is already up to date! \u2502");
|
|
601
|
+
console.log(" \u2502 \u2502");
|
|
602
|
+
console.log(" \u2502 All MCP servers protected, hooks configured. \u2502");
|
|
603
|
+
console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
|
|
604
|
+
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");
|
|
605
|
+
} else {
|
|
606
|
+
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");
|
|
607
|
+
console.log(" \u2502 Setup complete! \u2502");
|
|
608
|
+
console.log(" \u2502 \u2502");
|
|
609
|
+
console.log(" \u2502 MCP servers \u2192 Protected via proxy \u2502");
|
|
610
|
+
console.log(" \u2502 AI tools \u2192 Guarded via hooks \u2502");
|
|
611
|
+
console.log(" \u2502 Claude, Cursor, Gemini, Antigravity, \u2502");
|
|
612
|
+
console.log(" \u2502 OpenClaw, Perplexity \u2502");
|
|
613
|
+
console.log(" \u2502 API key \u2192 Set in .env \u2502");
|
|
614
|
+
console.log(" \u2502 \u2502");
|
|
615
|
+
console.log(" \u2502 View logs: https://dashboard.solongate.com \u2502");
|
|
616
|
+
console.log(" \u2502 \u2502");
|
|
617
|
+
console.log(" \u2502 Restart your MCP client to apply changes. \u2502");
|
|
618
|
+
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");
|
|
619
|
+
}
|
|
554
620
|
console.log("");
|
|
555
621
|
}
|
|
556
622
|
main().catch((err) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.8",
|
|
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": {
|