@solongate/proxy 0.82.21 → 0.82.22

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 CHANGED
@@ -3398,12 +3398,12 @@ ${ctx.indent}`;
3398
3398
  for (const {
3399
3399
  format,
3400
3400
  test,
3401
- resolve: resolve9
3401
+ resolve: resolve7
3402
3402
  } of tags) {
3403
3403
  if (test) {
3404
3404
  const match = str.match(test);
3405
3405
  if (match) {
3406
- let res = resolve9.apply(null, match);
3406
+ let res = resolve7.apply(null, match);
3407
3407
  if (!(res instanceof Scalar)) res = new Scalar(res);
3408
3408
  if (format) res.format = format;
3409
3409
  return res;
@@ -6507,18 +6507,6 @@ var init_src = __esm({
6507
6507
  });
6508
6508
 
6509
6509
  // src/cli-utils.ts
6510
- function log3(msg) {
6511
- process.stderr.write(msg + "\n");
6512
- }
6513
- function printBanner(subtitle) {
6514
- log3("");
6515
- for (let i = 0; i < BANNER_FULL.length; i++) {
6516
- log3(`${c.bold}${BANNER_COLORS[i]}${BANNER_FULL[i]}${c.reset}`);
6517
- }
6518
- log3("");
6519
- log3(` ${c.dim}${c.italic}${subtitle}${c.reset}`);
6520
- log3("");
6521
- }
6522
6510
  var c, BANNER_FULL, BANNER_COLORS;
6523
6511
  var init_cli_utils = __esm({
6524
6512
  "src/cli-utils.ts"() {
@@ -6622,9 +6610,9 @@ async function fetchLatest() {
6622
6610
  function spawnGlobalInstall(version) {
6623
6611
  try {
6624
6612
  mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
6625
- const log5 = openSync(LOG_FILE, "a");
6613
+ const log4 = openSync(LOG_FILE, "a");
6626
6614
  const p = spawn("npm", ["install", "-g", `${PKG}@${version}`], {
6627
- stdio: ["ignore", log5, log5],
6615
+ stdio: ["ignore", log4, log4],
6628
6616
  detached: true,
6629
6617
  windowsHide: true,
6630
6618
  shell: process.platform === "win32"
@@ -6638,7 +6626,7 @@ function spawnGlobalInstall(version) {
6638
6626
  }
6639
6627
  }
6640
6628
  function runGlobalInstall(version) {
6641
- return new Promise((resolve9) => {
6629
+ return new Promise((resolve7) => {
6642
6630
  try {
6643
6631
  mkdirSync3(join4(homedir2(), ".solongate"), { recursive: true });
6644
6632
  execFile(
@@ -6653,11 +6641,11 @@ ${stderr}
6653
6641
  `, { flag: "a" });
6654
6642
  } catch {
6655
6643
  }
6656
- resolve9(!err2);
6644
+ resolve7(!err2);
6657
6645
  }
6658
6646
  );
6659
6647
  } catch {
6660
- resolve9(false);
6648
+ resolve7(false);
6661
6649
  }
6662
6650
  });
6663
6651
  }
@@ -6772,11 +6760,11 @@ function startLogsServerDaemon() {
6772
6760
  }
6773
6761
  try {
6774
6762
  mkdirSync4(DIR, { recursive: true });
6775
- const log5 = openSync2(LOG_FILE2, "a");
6763
+ const log4 = openSync2(LOG_FILE2, "a");
6776
6764
  const cli = join5(dirname2(fileURLToPath2(import.meta.url)), "index.js");
6777
6765
  const p = spawn2(process.execPath, [cli, "logs-server"], {
6778
6766
  detached: true,
6779
- stdio: ["ignore", log5, log5],
6767
+ stdio: ["ignore", log4, log4],
6780
6768
  windowsHide: true
6781
6769
  });
6782
6770
  p.on("error", () => {
@@ -7854,7 +7842,7 @@ function LivePanel({ active: active2 }) {
7854
7842
  const [localBuf, setLocalBuf] = useState2([]);
7855
7843
  const [localOn, setLocalOn] = useState2(null);
7856
7844
  const [ring, setRing] = useState2(null);
7857
- const [log5, setLog] = useState2([]);
7845
+ const [log4, setLog] = useState2([]);
7858
7846
  const [filter, setFilter] = useState2("all");
7859
7847
  const [signal, setSignal] = useState2("none");
7860
7848
  const [search, setSearch] = useState2("");
@@ -8698,7 +8686,7 @@ function LivePanel({ active: active2 }) {
8698
8686
  ] }),
8699
8687
  /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", width: colW, overflow: "hidden", children: [
8700
8688
  /* @__PURE__ */ jsx2(PaneTitle, { label: "EVENT LOG", extra: "system heartbeat", width: colW }),
8701
- log5.slice(-(colH - 1)).map((l, i) => /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8689
+ log4.slice(-(colH - 1)).map((l, i) => /* @__PURE__ */ jsxs2(Text2, { wrap: "truncate", children: [
8702
8690
  /* @__PURE__ */ jsxs2(Text2, { color: theme.dim, children: [
8703
8691
  hhmmss(l.ts),
8704
8692
  " "
@@ -12605,644 +12593,16 @@ var init_logs_server = __esm({
12605
12593
  }
12606
12594
  });
12607
12595
 
12608
- // src/inject.ts
12609
- var inject_exports = {};
12610
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync7, copyFileSync } from "fs";
12611
- import { resolve as resolve6 } from "path";
12612
- import { execSync } from "child_process";
12613
- function parseInjectArgs(argv) {
12614
- const args = argv.slice(2);
12615
- const opts = {
12616
- dryRun: false,
12617
- restore: false,
12618
- skipInstall: false
12619
- };
12620
- for (let i = 0; i < args.length; i++) {
12621
- switch (args[i]) {
12622
- case "--file":
12623
- opts.file = args[++i];
12624
- break;
12625
- case "--dry-run":
12626
- opts.dryRun = true;
12627
- break;
12628
- case "--restore":
12629
- opts.restore = true;
12630
- break;
12631
- case "--skip-install":
12632
- opts.skipInstall = true;
12633
- break;
12634
- case "--help":
12635
- case "-h":
12636
- printHelp();
12637
- process.exit(0);
12638
- }
12639
- }
12640
- return opts;
12641
- }
12642
- function printHelp() {
12643
- log3(`
12644
- SolonGate Inject \u2014 Add security to your MCP server in seconds
12645
-
12646
- USAGE
12647
- npx @solongate/proxy inject [options]
12648
-
12649
- OPTIONS
12650
- --file <path> Entry file to modify (default: auto-detect)
12651
- --dry-run Preview changes without writing
12652
- --restore Restore original file from backup
12653
- --skip-install Don't install SDK package
12654
- -h, --help Show this help message
12655
-
12656
- EXAMPLES
12657
- npx @solongate/proxy inject # Auto-detect and inject
12658
- npx @solongate/proxy inject --file src/main.ts # Specify entry file
12659
- npx @solongate/proxy inject --dry-run # Preview changes
12660
- npx @solongate/proxy inject --restore # Undo injection
12661
-
12662
- WHAT IT DOES
12663
- Replaces McpServer with SecureMcpServer (2 lines changed)
12664
- All tool() calls are automatically protected by SolonGate.
12665
- `);
12666
- }
12667
- function detectProject() {
12668
- if (!existsSync7(resolve6("package.json"))) return false;
12669
- try {
12670
- const pkg = JSON.parse(readFileSync12(resolve6("package.json"), "utf-8"));
12671
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
12672
- return !!(allDeps["@modelcontextprotocol/sdk"] || allDeps["@modelcontextprotocol/server"]);
12673
- } catch {
12674
- return false;
12675
- }
12676
- }
12677
- function findTsEntryFile() {
12678
- try {
12679
- const pkg = JSON.parse(readFileSync12(resolve6("package.json"), "utf-8"));
12680
- if (pkg.bin) {
12681
- const binPath = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin)[0];
12682
- if (typeof binPath === "string") {
12683
- const srcPath = binPath.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
12684
- if (existsSync7(resolve6(srcPath))) return resolve6(srcPath);
12685
- if (existsSync7(resolve6(binPath))) return resolve6(binPath);
12686
- }
12687
- }
12688
- if (pkg.main) {
12689
- const srcPath = pkg.main.replace(/^\.\/dist\//, "./src/").replace(/\.js$/, ".ts");
12690
- if (existsSync7(resolve6(srcPath))) return resolve6(srcPath);
12691
- }
12692
- } catch {
12693
- }
12694
- const candidates = [
12695
- "src/index.ts",
12696
- "src/server.ts",
12697
- "src/main.ts",
12698
- "index.ts",
12699
- "server.ts",
12700
- "main.ts"
12701
- ];
12702
- for (const c2 of candidates) {
12703
- const full = resolve6(c2);
12704
- if (existsSync7(full)) {
12705
- try {
12706
- const content = readFileSync12(full, "utf-8");
12707
- if (content.includes("McpServer") || content.includes("McpServer")) {
12708
- return full;
12709
- }
12710
- } catch {
12711
- }
12712
- }
12713
- }
12714
- for (const c2 of candidates) {
12715
- if (existsSync7(resolve6(c2))) return resolve6(c2);
12716
- }
12717
- return null;
12718
- }
12719
- function detectPackageManager() {
12720
- if (existsSync7(resolve6("pnpm-lock.yaml"))) return "pnpm";
12721
- if (existsSync7(resolve6("yarn.lock"))) return "yarn";
12722
- return "npm";
12723
- }
12724
- function installSdk() {
12725
- try {
12726
- const pkg = JSON.parse(readFileSync12(resolve6("package.json"), "utf-8"));
12727
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
12728
- if (allDeps["@solongate/proxy"]) {
12729
- log3(" @solongate/proxy already installed");
12730
- return true;
12731
- }
12732
- } catch {
12733
- }
12734
- const pm = detectPackageManager();
12735
- const cmd = pm === "yarn" ? "yarn add @solongate/proxy" : `${pm} install @solongate/proxy`;
12736
- log3(` Installing @solongate/proxy via ${pm}...`);
12737
- try {
12738
- execSync(cmd, { stdio: "pipe", cwd: process.cwd() });
12739
- return true;
12740
- } catch (err2) {
12741
- log3(` Failed to install: ${err2 instanceof Error ? err2.message : String(err2)}`);
12742
- log3(" You can install manually: npm install @solongate/proxy");
12743
- return false;
12744
- }
12745
- }
12746
- function injectTypeScript(filePath) {
12747
- const original = readFileSync12(filePath, "utf-8");
12748
- const changes = [];
12749
- let modified = original;
12750
- if (modified.includes("SecureMcpServer")) {
12751
- return { file: filePath, changes: ["Already injected \u2014 skipping"], original, modified };
12752
- }
12753
- const mcpImportPatterns = [
12754
- // Solo import: import { McpServer } from '...'
12755
- /import\s*\{\s*McpServer\s*\}\s*from\s*['"][^'"]+['"]/,
12756
- // Import with others: import { McpServer, ... } from '...'
12757
- /import\s*\{[^}]*McpServer[^}]*\}\s*from\s*['"][^'"]+['"]/
12758
- ];
12759
- let importReplaced = false;
12760
- for (const pattern of mcpImportPatterns) {
12761
- const match = modified.match(pattern);
12762
- if (match) {
12763
- const importLine = match[0];
12764
- const namedImports = importLine.match(/\{([^}]+)\}/)?.[1] ?? "";
12765
- const importNames = namedImports.split(",").map((s) => s.trim()).filter(Boolean);
12766
- if (importNames.length === 1 && importNames[0] === "McpServer") {
12767
- modified = modified.replace(
12768
- importLine,
12769
- `import { SecureMcpServer } from '@solongate/proxy'`
12770
- );
12771
- changes.push("Replaced McpServer import with SecureMcpServer from @solongate/proxy");
12772
- } else {
12773
- const otherImports = importNames.filter((n) => n !== "McpServer");
12774
- const fromModule = importLine.match(/from\s*['"]([^'"]+)['"]/)?.[1] ?? "";
12775
- modified = modified.replace(
12776
- importLine,
12777
- `import { ${otherImports.join(", ")} } from '${fromModule}';
12778
- import { SecureMcpServer } from '@solongate/proxy'`
12779
- );
12780
- changes.push("Removed McpServer from existing import, added SecureMcpServer import from @solongate/proxy");
12781
- }
12782
- importReplaced = true;
12783
- break;
12784
- }
12785
- }
12786
- if (!importReplaced) {
12787
- const insertPos = findImportInsertPosition(modified);
12788
- modified = modified.slice(0, insertPos) + `import { SecureMcpServer } from '@solongate/proxy';
12789
- ` + modified.slice(insertPos);
12790
- changes.push("Added SecureMcpServer import from @solongate/proxy");
12791
- }
12792
- const constructorPattern = /new\s+McpServer\s*\(/g;
12793
- const constructorCount = (modified.match(constructorPattern) || []).length;
12794
- if (constructorCount > 0) {
12795
- modified = modified.replace(constructorPattern, "new SecureMcpServer(");
12796
- changes.push(`Replaced ${constructorCount} McpServer constructor(s) with SecureMcpServer`);
12797
- }
12798
- return { file: filePath, changes, original, modified };
12799
- }
12800
- function findImportInsertPosition(content) {
12801
- let pos = 0;
12802
- if (content.startsWith("#!")) {
12803
- pos = content.indexOf("\n") + 1;
12804
- }
12805
- const lines = content.slice(pos).split("\n");
12806
- let offset = pos;
12807
- for (const line of lines) {
12808
- const trimmed = line.trim();
12809
- if (trimmed === "" || trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*") || trimmed.startsWith("*/")) {
12810
- offset += line.length + 1;
12811
- } else {
12812
- break;
12813
- }
12814
- }
12815
- const importRegex = /^import\s+.+$/gm;
12816
- let lastImportEnd = offset;
12817
- let importMatch;
12818
- while ((importMatch = importRegex.exec(content)) !== null) {
12819
- lastImportEnd = importMatch.index + importMatch[0].length + 1;
12820
- }
12821
- return lastImportEnd > offset ? lastImportEnd : offset;
12822
- }
12823
- function showDiff(result) {
12824
- if (result.original === result.modified) {
12825
- log3(" No changes needed.");
12826
- return;
12827
- }
12828
- const origLines = result.original.split("\n");
12829
- const modLines = result.modified.split("\n");
12830
- log3("");
12831
- log3(` File: ${result.file}`);
12832
- log3(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
12833
- const maxLines = Math.max(origLines.length, modLines.length);
12834
- let diffCount = 0;
12835
- for (let i = 0; i < maxLines; i++) {
12836
- const orig = origLines[i];
12837
- const mod = modLines[i];
12838
- if (orig !== mod) {
12839
- if (diffCount < 30) {
12840
- if (orig !== void 0) log3(` - ${orig}`);
12841
- if (mod !== void 0) log3(` + ${mod}`);
12842
- }
12843
- diffCount++;
12844
- }
12845
- }
12846
- if (diffCount > 30) {
12847
- log3(` ... and ${diffCount - 30} more line changes`);
12848
- }
12849
- log3("");
12850
- }
12851
- async function main() {
12852
- const opts = parseInjectArgs(process.argv);
12853
- printBanner("Inject SDK");
12854
- if (!detectProject()) {
12855
- log3(" Could not detect a TypeScript MCP server project.");
12856
- log3(" Make sure you are in a project directory with:");
12857
- log3(" package.json + @modelcontextprotocol/sdk in dependencies");
12858
- log3("");
12859
- log3(" To create a new MCP server: npx @solongate/proxy create <name>");
12860
- process.exit(1);
12861
- }
12862
- log3(" Language: TypeScript");
12863
- const entryFile = opts.file ? resolve6(opts.file) : findTsEntryFile();
12864
- if (!entryFile || !existsSync7(entryFile)) {
12865
- log3(` Could not find entry file.${opts.file ? ` File not found: ${opts.file}` : ""}`);
12866
- log3("");
12867
- log3(" Specify it manually: --file <path>");
12868
- log3("");
12869
- log3(" Common entry points:");
12870
- log3(" src/index.ts, src/server.ts, index.ts");
12871
- process.exit(1);
12872
- }
12873
- log3(` Entry: ${entryFile}`);
12874
- log3("");
12875
- const backupPath = entryFile + ".solongate-backup";
12876
- if (opts.restore) {
12877
- if (!existsSync7(backupPath)) {
12878
- log3(" No backup found. Nothing to restore.");
12879
- process.exit(1);
12880
- }
12881
- copyFileSync(backupPath, entryFile);
12882
- log3(` Restored original file from backup.`);
12883
- log3(` Backup: ${backupPath}`);
12884
- process.exit(0);
12885
- }
12886
- if (!opts.skipInstall && !opts.dryRun) {
12887
- installSdk();
12888
- log3("");
12889
- }
12890
- const result = injectTypeScript(entryFile);
12891
- log3(` Changes (${result.changes.length}):`);
12892
- for (const change of result.changes) {
12893
- log3(` - ${change}`);
12894
- }
12895
- if (result.changes.length === 1 && result.changes[0].includes("Already injected")) {
12896
- log3("");
12897
- log3(" Your MCP server is already protected by SolonGate!");
12898
- process.exit(0);
12899
- }
12900
- if (result.original === result.modified) {
12901
- log3("");
12902
- log3(" No changes were made. The file may not contain recognizable MCP patterns.");
12903
- log3(" See docs: https://solongate.com/docs/integration");
12904
- process.exit(0);
12905
- }
12906
- if (opts.dryRun) {
12907
- log3("");
12908
- log3(" --- DRY RUN (no changes written) ---");
12909
- showDiff(result);
12910
- log3(" To apply: npx @solongate/proxy inject");
12911
- process.exit(0);
12912
- }
12913
- if (!existsSync7(backupPath)) {
12914
- copyFileSync(entryFile, backupPath);
12915
- log3("");
12916
- log3(` Backup: ${backupPath}`);
12917
- }
12918
- writeFileSync10(entryFile, result.modified);
12919
- log3("");
12920
- log3(" \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\u2510");
12921
- log3(" \u2502 SolonGate SDK injected successfully! \u2502");
12922
- log3(" \u2502 \u2502");
12923
- log3(" \u2502 McpServer \u2192 SecureMcpServer \u2502");
12924
- log3(" \u2502 All tool() calls are now auto-protected. \u2502");
12925
- log3(" \u2502 \u2502");
12926
- log3(" \u2502 Set your API key: \u2502");
12927
- log3(" \u2502 export SOLONGATE_API_KEY=sg_live_xxx \u2502");
12928
- log3(" \u2502 \u2502");
12929
- log3(" \u2502 To undo: \u2502");
12930
- log3(" \u2502 npx @solongate/proxy inject --restore \u2502");
12931
- log3(" \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\u2518");
12932
- log3("");
12933
- }
12934
- var init_inject = __esm({
12935
- "src/inject.ts"() {
12936
- "use strict";
12937
- init_cli_utils();
12938
- main().catch((err2) => {
12939
- log3(`Fatal: ${err2 instanceof Error ? err2.message : String(err2)}`);
12940
- process.exit(1);
12941
- });
12942
- }
12943
- });
12944
-
12945
- // src/create.ts
12946
- var create_exports = {};
12947
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync8 } from "fs";
12948
- import { resolve as resolve7, join as join16 } from "path";
12949
- import { execSync as execSync2 } from "child_process";
12950
- function withSpinner(message, fn) {
12951
- const frames = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
12952
- let i = 0;
12953
- const id = setInterval(() => {
12954
- const color = i % 2 === 0 ? c.blue3 : c.blue5;
12955
- process.stderr.write(`\r ${color}${frames[i++ % frames.length]}${c.reset} ${c.dim}${message}${c.reset}`);
12956
- }, 80);
12957
- try {
12958
- const result = fn();
12959
- clearInterval(id);
12960
- process.stderr.write(`\r ${c.green}\u2713${c.reset} ${message}${" ".repeat(20)}
12961
- `);
12962
- return result;
12963
- } catch (err2) {
12964
- clearInterval(id);
12965
- process.stderr.write(`\r ${c.red}\u2717${c.reset} ${message} \u2014 failed${" ".repeat(10)}
12966
- `);
12967
- throw err2;
12968
- }
12969
- }
12970
- function parseCreateArgs(argv) {
12971
- const args = argv.slice(2);
12972
- const opts = {
12973
- name: "",
12974
- policy: "",
12975
- noInstall: false
12976
- };
12977
- for (let i = 0; i < args.length; i++) {
12978
- switch (args[i]) {
12979
- case "--policy":
12980
- opts.policy = args[++i];
12981
- break;
12982
- case "--no-install":
12983
- opts.noInstall = true;
12984
- break;
12985
- case "--help":
12986
- case "-h":
12987
- printHelp2();
12988
- process.exit(0);
12989
- break;
12990
- default:
12991
- if (!args[i].startsWith("-") && !opts.name) {
12992
- opts.name = args[i];
12993
- }
12994
- }
12995
- }
12996
- if (!opts.name) {
12997
- log3("");
12998
- log3(" Error: Project name required.");
12999
- log3("");
13000
- log3(" Usage: npx @solongate/proxy create <name>");
13001
- log3("");
13002
- log3(" Examples:");
13003
- log3(" npx @solongate/proxy create my-mcp-server");
13004
- log3(" npx @solongate/proxy create weather-api");
13005
- process.exit(1);
13006
- }
13007
- return opts;
13008
- }
13009
- function printHelp2() {
13010
- log3(`
13011
- SolonGate Create \u2014 Scaffold a secure MCP server in seconds
13012
-
13013
- USAGE
13014
- npx @solongate/proxy create <name> [options]
13015
-
13016
- OPTIONS
13017
- --policy <file> Policy JSON file (default: cloud-managed)
13018
- --no-install Skip dependency installation
13019
- -h, --help Show this help message
13020
-
13021
- EXAMPLES
13022
- npx @solongate/proxy create my-server
13023
- npx @solongate/proxy create db-tools --policy ./policy.json
13024
- `);
13025
- }
13026
- function createProject(dir, name, _policy) {
13027
- writeFileSync11(
13028
- join16(dir, "package.json"),
13029
- JSON.stringify(
13030
- {
13031
- name,
13032
- version: "0.1.0",
13033
- type: "module",
13034
- private: true,
13035
- bin: { [name]: "./dist/index.js" },
13036
- scripts: {
13037
- build: "tsup src/index.ts --format esm",
13038
- dev: "tsx --env-file=.env src/index.ts",
13039
- start: "node --env-file=.env dist/index.js"
13040
- },
13041
- dependencies: {
13042
- "@modelcontextprotocol/sdk": "^1.26.0",
13043
- "@solongate/proxy": "latest",
13044
- zod: "^3.25.0"
13045
- },
13046
- devDependencies: {
13047
- "@types/node": "^22.0.0",
13048
- tsup: "^8.3.0",
13049
- tsx: "^4.19.0",
13050
- typescript: "^5.7.0"
13051
- }
13052
- },
13053
- null,
13054
- 2
13055
- ) + "\n"
13056
- );
13057
- writeFileSync11(
13058
- join16(dir, "tsconfig.json"),
13059
- JSON.stringify(
13060
- {
13061
- compilerOptions: {
13062
- target: "ES2022",
13063
- module: "ESNext",
13064
- moduleResolution: "bundler",
13065
- esModuleInterop: true,
13066
- strict: true,
13067
- outDir: "dist",
13068
- rootDir: "src",
13069
- declaration: true,
13070
- skipLibCheck: true
13071
- },
13072
- include: ["src"]
13073
- },
13074
- null,
13075
- 2
13076
- ) + "\n"
13077
- );
13078
- mkdirSync10(join16(dir, "src"), { recursive: true });
13079
- writeFileSync11(
13080
- join16(dir, "src", "index.ts"),
13081
- `#!/usr/bin/env node
13082
-
13083
- console.log = (...args: unknown[]) => {
13084
- process.stderr.write(args.map(String).join(' ') + '\\n');
13085
- };
13086
-
13087
- import { SecureMcpServer } from '@solongate/proxy';
13088
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13089
- import { z } from 'zod';
13090
-
13091
- // Policy is managed from the SolonGate Dashboard (https://solongate.com)
13092
- // No local policySet needed \u2014 it's fetched from the cloud via your API key.
13093
- const server = new SecureMcpServer(
13094
- { name: '${name}', version: '0.1.0' },
13095
- );
13096
-
13097
- server.tool(
13098
- 'hello',
13099
- 'Say hello to someone',
13100
- { name: z.string().describe('Name of the person to greet') },
13101
- async ({ name }: { name: string }) => ({
13102
- content: [{ type: 'text', text: \`Hello, \${name}! Welcome to ${name}.\` }],
13103
- }),
13104
- );
13105
-
13106
- const transport = new StdioServerTransport();
13107
- await server.connect(transport);
13108
- console.log('');
13109
- console.log('${name} is running (stdio mode)');
13110
- console.log('');
13111
- console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
13112
- console.log('You need an MCP client to connect:');
13113
- console.log('');
13114
- console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
13115
- console.log(' Antigravity .agents/mcp_config.json (or ~/.gemini/config/mcp_config.json)');
13116
- console.log(' OpenClaw Uses openclaw.plugin.json config');
13117
- console.log('');
13118
- console.log('Press Ctrl+C to stop.');
13119
- `
13120
- );
13121
- writeFileSync11(
13122
- join16(dir, ".mcp.json"),
13123
- JSON.stringify(
13124
- {
13125
- mcpServers: {
13126
- [name]: {
13127
- command: "node",
13128
- args: ["dist/index.js"],
13129
- env: {
13130
- SOLONGATE_API_KEY: "sg_live_YOUR_KEY_HERE"
13131
- }
13132
- }
13133
- }
13134
- },
13135
- null,
13136
- 2
13137
- ) + "\n"
13138
- );
13139
- writeFileSync11(
13140
- join16(dir, ".env"),
13141
- `SOLONGATE_API_KEY=sg_live_YOUR_KEY_HERE
13142
- `
13143
- );
13144
- writeFileSync11(
13145
- join16(dir, ".gitignore"),
13146
- `node_modules/
13147
- dist/
13148
- *.solongate-backup
13149
- .env
13150
- .env.local
13151
- .mcp.json
13152
- `
13153
- );
13154
- }
13155
- async function main2() {
13156
- const opts = parseCreateArgs(process.argv);
13157
- const dir = resolve7(opts.name);
13158
- printBanner("Create MCP Server");
13159
- if (existsSync8(dir)) {
13160
- log3(` ${c.red}Error:${c.reset} Directory "${opts.name}" already exists.`);
13161
- process.exit(1);
13162
- }
13163
- withSpinner(`Setting up ${opts.name}...`, () => {
13164
- mkdirSync10(dir, { recursive: true });
13165
- createProject(dir, opts.name, opts.policy);
13166
- });
13167
- if (!opts.noInstall) {
13168
- withSpinner("Installing dependencies...", () => {
13169
- execSync2("npm install", { cwd: dir, stdio: "pipe" });
13170
- });
13171
- }
13172
- log3("");
13173
- const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
13174
- const W = 52;
13175
- const hr = "\u2500".repeat(W + 2);
13176
- const bLine = (text) => {
13177
- const visible = stripAnsi(text);
13178
- const padding = W - visible.length;
13179
- log3(` ${c.dim}\u2502${c.reset} ${text}${" ".repeat(Math.max(0, padding))} ${c.dim}\u2502${c.reset}`);
13180
- };
13181
- const bEmpty = () => log3(` ${c.dim}\u2502${c.reset} ${" ".repeat(W)} ${c.dim}\u2502${c.reset}`);
13182
- log3(` ${c.dim}\u256D${hr}\u256E${c.reset}`);
13183
- log3(` ${c.dim}\u2502${c.reset} ${c.green}${c.bold}\u2714 MCP Server created successfully!${c.reset}${" ".repeat(W - 35)} ${c.dim}\u2502${c.reset}`);
13184
- log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
13185
- bEmpty();
13186
- bLine(`${c.yellow}Next steps:${c.reset}`);
13187
- bEmpty();
13188
- bLine(` ${c.cyan}$${c.reset} cd ${c.bold}${opts.name}${c.reset}`);
13189
- bLine(` ${c.cyan}$${c.reset} npm run build`);
13190
- bLine(` ${c.cyan}$${c.reset} npm run dev ${c.dim}# dev mode${c.reset}`);
13191
- bLine(` ${c.cyan}$${c.reset} npm start ${c.dim}# production${c.reset}`);
13192
- bEmpty();
13193
- log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
13194
- bEmpty();
13195
- bLine(`${c.yellow}Set your API key:${c.reset}`);
13196
- bEmpty();
13197
- bLine(` ${c.cyan}$${c.reset} export SOLONGATE_API_KEY=${c.blue3}sg_live_xxx${c.reset}`);
13198
- bEmpty();
13199
- bLine(`${c.dim}https://dashboard.solongate.com/api-keys/${c.reset}`);
13200
- bEmpty();
13201
- log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
13202
- bEmpty();
13203
- bLine(`${c.yellow}Use with any MCP server:${c.reset}`);
13204
- bEmpty();
13205
- bLine(` ${c.cyan}$${c.reset} solongate-proxy -- npx @modelcontextprotocol/server-filesystem .`);
13206
- bLine(` ${c.cyan}$${c.reset} solongate-proxy -- npx @playwright/mcp@latest`);
13207
- bLine(` ${c.dim}Wraps any MCP server or AI tool with SolonGate protection${c.reset}`);
13208
- bEmpty();
13209
- log3(` ${c.dim}\u251C${hr}\u2524${c.reset}`);
13210
- bEmpty();
13211
- bLine(`${c.yellow}Use with Claude Code / MCP client:${c.reset}`);
13212
- bEmpty();
13213
- bLine(` ${c.dim}1.${c.reset} Replace ${c.blue3}sg_live_YOUR_KEY_HERE${c.reset} in .mcp.json`);
13214
- bLine(` ${c.dim}2.${c.reset} Open this folder in your MCP client`);
13215
- bLine(` ${c.dim}3.${c.reset} .mcp.json is auto-detected on startup`);
13216
- bEmpty();
13217
- bLine(`${c.yellow}Direct test (without MCP client):${c.reset}`);
13218
- bEmpty();
13219
- bLine(` ${c.dim}1.${c.reset} Replace ${c.blue3}sg_live_YOUR_KEY_HERE${c.reset} in .env`);
13220
- bLine(` ${c.dim}2.${c.reset} ${c.cyan}$${c.reset} npm run build && npm start`);
13221
- bEmpty();
13222
- log3(` ${c.dim}\u2570${hr}\u256F${c.reset}`);
13223
- log3("");
13224
- }
13225
- var init_create = __esm({
13226
- "src/create.ts"() {
13227
- "use strict";
13228
- init_cli_utils();
13229
- main2().catch((err2) => {
13230
- log3(`Fatal: ${err2 instanceof Error ? err2.message : String(err2)}`);
13231
- process.exit(1);
13232
- });
13233
- }
13234
- });
13235
-
13236
12596
  // src/pull-push.ts
13237
12597
  var pull_push_exports = {};
13238
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync12, existsSync as existsSync9 } from "fs";
13239
- import { resolve as resolve8 } from "path";
12598
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync7 } from "fs";
12599
+ import { resolve as resolve6 } from "path";
13240
12600
  function loadEnv() {
13241
12601
  if (process.env.SOLONGATE_API_KEY) return;
13242
- const envPath = resolve8(".env");
13243
- if (!existsSync9(envPath)) return;
12602
+ const envPath = resolve6(".env");
12603
+ if (!existsSync7(envPath)) return;
13244
12604
  try {
13245
- const content = readFileSync13(envPath, "utf-8");
12605
+ const content = readFileSync12(envPath, "utf-8");
13246
12606
  for (const line of content.split("\n")) {
13247
12607
  const trimmed = line.trim();
13248
12608
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -13284,20 +12644,20 @@ function parseCliArgs() {
13284
12644
  }
13285
12645
  }
13286
12646
  if (!apiKey) {
13287
- log4(red2("ERROR: API key not found."));
13288
- log4("");
13289
- log4("Set it in .env file:");
13290
- log4(" SOLONGATE_API_KEY=sg_live_...");
13291
- log4("");
13292
- log4("Or pass via environment:");
13293
- log4(` SOLONGATE_API_KEY=sg_live_... solongate-proxy ${command}`);
12647
+ log3(red2("ERROR: API key not found."));
12648
+ log3("");
12649
+ log3("Set it in .env file:");
12650
+ log3(" SOLONGATE_API_KEY=sg_live_...");
12651
+ log3("");
12652
+ log3("Or pass via environment:");
12653
+ log3(` SOLONGATE_API_KEY=sg_live_... solongate-proxy ${command}`);
13294
12654
  process.exit(1);
13295
12655
  }
13296
12656
  if (!apiKey.startsWith("sg_live_")) {
13297
- log4(red2("ERROR: Pull/push/list requires a live API key (sg_live_...)."));
12657
+ log3(red2("ERROR: Pull/push/list requires a live API key (sg_live_...)."));
13298
12658
  process.exit(1);
13299
12659
  }
13300
- return { command, apiKey, file: resolve8(file), policyId };
12660
+ return { command, apiKey, file: resolve6(file), policyId };
13301
12661
  }
13302
12662
  async function listPolicies(apiKey) {
13303
12663
  const res = await fetch(`${API_URL}/api/v1/policies`, {
@@ -13310,18 +12670,18 @@ async function listPolicies(apiKey) {
13310
12670
  async function list5(apiKey, policyId) {
13311
12671
  const policies = await listPolicies(apiKey);
13312
12672
  if (policies.length === 0) {
13313
- log4(yellow2("No policies found. Create one in the dashboard first."));
13314
- log4(dim2(" https://dashboard.solongate.com/policies"));
12673
+ log3(yellow2("No policies found. Create one in the dashboard first."));
12674
+ log3(dim2(" https://dashboard.solongate.com/policies"));
13315
12675
  return;
13316
12676
  }
13317
12677
  if (policyId) {
13318
12678
  const match = policies.find((p) => p.id === policyId);
13319
12679
  if (!match) {
13320
- log4(red2(`Policy not found: ${policyId}`));
13321
- log4("");
13322
- log4("Available policies:");
12680
+ log3(red2(`Policy not found: ${policyId}`));
12681
+ log3("");
12682
+ log3("Available policies:");
13323
12683
  for (const p of policies) {
13324
- log4(` ${dim2("\u2022")} ${p.id}`);
12684
+ log3(` ${dim2("\u2022")} ${p.id}`);
13325
12685
  }
13326
12686
  process.exit(1);
13327
12687
  }
@@ -13329,10 +12689,10 @@ async function list5(apiKey, policyId) {
13329
12689
  printPolicyDetail(full);
13330
12690
  return;
13331
12691
  }
13332
- log4("");
13333
- log4(bold2(` Policies (${policies.length})`));
13334
- log4(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
13335
- log4("");
12692
+ log3("");
12693
+ log3(bold2(` Policies (${policies.length})`));
12694
+ log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
12695
+ log3("");
13336
12696
  const fullPolicies = await Promise.all(
13337
12697
  policies.map(
13338
12698
  (p) => fetchCloudPolicy(apiKey, API_URL, p.id).then((full) => ({ policy: p, rules: full.rules })).catch(() => ({ policy: p, rules: [] }))
@@ -13341,136 +12701,136 @@ async function list5(apiKey, policyId) {
13341
12701
  for (const { policy, rules } of fullPolicies) {
13342
12702
  printPolicySummary(policy, [...rules]);
13343
12703
  }
13344
- log4(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
13345
- log4("");
13346
- log4(` ${dim2("View details:")} solongate-proxy list --policy-id <ID>`);
13347
- log4(` ${dim2("Pull policy:")} solongate-proxy pull --policy-id <ID>`);
13348
- log4(` ${dim2("Push policy:")} solongate-proxy push --policy-id <ID>`);
13349
- log4("");
12704
+ log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
12705
+ log3("");
12706
+ log3(` ${dim2("View details:")} solongate-proxy list --policy-id <ID>`);
12707
+ log3(` ${dim2("Pull policy:")} solongate-proxy pull --policy-id <ID>`);
12708
+ log3(` ${dim2("Push policy:")} solongate-proxy push --policy-id <ID>`);
12709
+ log3("");
13350
12710
  }
13351
12711
  function printPolicySummary(p, rules) {
13352
12712
  const ruleCount = rules.length;
13353
12713
  const allowCount = rules.filter((r) => r.effect === "ALLOW").length;
13354
12714
  const denyCount = rules.filter((r) => r.effect === "DENY").length;
13355
- log4(` ${cyan2(p.id)}`);
13356
- log4(` ${bold2(p.name)} ${dim2(`v${p.version ?? "?"}`)}`);
13357
- log4(` ${dim2("Rules:")} ${ruleCount} ${green2(`${allowCount} ALLOW`)} ${red2(`${denyCount} DENY`)}`);
12715
+ log3(` ${cyan2(p.id)}`);
12716
+ log3(` ${bold2(p.name)} ${dim2(`v${p.version ?? "?"}`)}`);
12717
+ log3(` ${dim2("Rules:")} ${ruleCount} ${green2(`${allowCount} ALLOW`)} ${red2(`${denyCount} DENY`)}`);
13358
12718
  if (p.created_at) {
13359
- log4(` ${dim2("Updated:")} ${new Date(p.created_at).toLocaleString()}`);
12719
+ log3(` ${dim2("Updated:")} ${new Date(p.created_at).toLocaleString()}`);
13360
12720
  }
13361
- log4("");
12721
+ log3("");
13362
12722
  }
13363
12723
  function printPolicyDetail(policy) {
13364
- log4("");
13365
- log4(bold2(` ${policy.name}`));
13366
- log4(` ${dim2("ID:")} ${cyan2(policy.id)} ${dim2("Version:")} ${policy.version} ${dim2("Rules:")} ${policy.rules.length}`);
13367
- log4("");
12724
+ log3("");
12725
+ log3(bold2(` ${policy.name}`));
12726
+ log3(` ${dim2("ID:")} ${cyan2(policy.id)} ${dim2("Version:")} ${policy.version} ${dim2("Rules:")} ${policy.rules.length}`);
12727
+ log3("");
13368
12728
  if (policy.rules.length === 0) {
13369
- log4(yellow2(" No rules defined."));
13370
- log4("");
12729
+ log3(yellow2(" No rules defined."));
12730
+ log3("");
13371
12731
  return;
13372
12732
  }
13373
- log4(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
12733
+ log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
13374
12734
  for (const rule of policy.rules) {
13375
12735
  const effectColor = rule.effect === "ALLOW" ? green2 : red2;
13376
- log4("");
13377
- log4(` ${effectColor(rule.effect.padEnd(5))} ${bold2(rule.toolPattern)} ${dim2(`P:${rule.priority}`)}`);
12736
+ log3("");
12737
+ log3(` ${effectColor(rule.effect.padEnd(5))} ${bold2(rule.toolPattern)} ${dim2(`P:${rule.priority}`)}`);
13378
12738
  if (rule.description) {
13379
- log4(` ${dim2(rule.description)}`);
12739
+ log3(` ${dim2(rule.description)}`);
13380
12740
  }
13381
- log4(` ${dim2(`${rule.permission} trust:${rule.minimumTrustLevel || "UNTRUSTED"}`)}`);
12741
+ log3(` ${dim2(`${rule.permission} trust:${rule.minimumTrustLevel || "UNTRUSTED"}`)}`);
13382
12742
  if (rule.pathConstraints) {
13383
12743
  const pc = rule.pathConstraints;
13384
- if (pc.rootDirectory) log4(` ${magenta("ROOT")} ${pc.rootDirectory}`);
13385
- if (pc.allowed?.length) log4(` ${green2("PATHS")} ${pc.allowed.join(", ")}`);
13386
- if (pc.denied?.length) log4(` ${red2("DENY")} ${pc.denied.join(", ")}`);
12744
+ if (pc.rootDirectory) log3(` ${magenta("ROOT")} ${pc.rootDirectory}`);
12745
+ if (pc.allowed?.length) log3(` ${green2("PATHS")} ${pc.allowed.join(", ")}`);
12746
+ if (pc.denied?.length) log3(` ${red2("DENY")} ${pc.denied.join(", ")}`);
13387
12747
  }
13388
12748
  if (rule.commandConstraints) {
13389
12749
  const cc = rule.commandConstraints;
13390
- if (cc.allowed?.length) log4(` ${green2("CMDS")} ${cc.allowed.join(", ")}`);
13391
- if (cc.denied?.length) log4(` ${red2("DENY")} ${cc.denied.join(", ")}`);
12750
+ if (cc.allowed?.length) log3(` ${green2("CMDS")} ${cc.allowed.join(", ")}`);
12751
+ if (cc.denied?.length) log3(` ${red2("DENY")} ${cc.denied.join(", ")}`);
13392
12752
  }
13393
12753
  if (rule.filenameConstraints) {
13394
12754
  const fc = rule.filenameConstraints;
13395
- if (fc.allowed?.length) log4(` ${green2("FILES")} ${fc.allowed.join(", ")}`);
13396
- if (fc.denied?.length) log4(` ${red2("DENY")} ${fc.denied.join(", ")}`);
12755
+ if (fc.allowed?.length) log3(` ${green2("FILES")} ${fc.allowed.join(", ")}`);
12756
+ if (fc.denied?.length) log3(` ${red2("DENY")} ${fc.denied.join(", ")}`);
13397
12757
  }
13398
12758
  if (rule.urlConstraints) {
13399
12759
  const uc = rule.urlConstraints;
13400
- if (uc.allowed?.length) log4(` ${green2("URLS")} ${uc.allowed.join(", ")}`);
13401
- if (uc.denied?.length) log4(` ${red2("DENY")} ${uc.denied.join(", ")}`);
12760
+ if (uc.allowed?.length) log3(` ${green2("URLS")} ${uc.allowed.join(", ")}`);
12761
+ if (uc.denied?.length) log3(` ${red2("DENY")} ${uc.denied.join(", ")}`);
13402
12762
  }
13403
12763
  }
13404
- log4("");
13405
- log4(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
13406
- log4("");
12764
+ log3("");
12765
+ log3(dim2(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
12766
+ log3("");
13407
12767
  }
13408
12768
  async function pull(apiKey, file, policyId) {
13409
12769
  if (!policyId) {
13410
12770
  const policies = await listPolicies(apiKey);
13411
12771
  if (policies.length === 0) {
13412
- log4(red2("No policies found. Create one in the dashboard first."));
12772
+ log3(red2("No policies found. Create one in the dashboard first."));
13413
12773
  process.exit(1);
13414
12774
  }
13415
12775
  if (policies.length === 1) {
13416
12776
  policyId = policies[0].id;
13417
- log4(dim2(`Auto-selecting only policy: ${policyId}`));
12777
+ log3(dim2(`Auto-selecting only policy: ${policyId}`));
13418
12778
  } else {
13419
- log4(yellow2(`Found ${policies.length} policies:`));
13420
- log4("");
12779
+ log3(yellow2(`Found ${policies.length} policies:`));
12780
+ log3("");
13421
12781
  for (const p of policies) {
13422
- log4(` ${cyan2(p.id)} ${p.name} ${dim2(`v${p.version ?? "?"}`)}`);
12782
+ log3(` ${cyan2(p.id)} ${p.name} ${dim2(`v${p.version ?? "?"}`)}`);
13423
12783
  }
13424
- log4("");
13425
- log4("Use --policy-id <ID> to specify which one to pull.");
12784
+ log3("");
12785
+ log3("Use --policy-id <ID> to specify which one to pull.");
13426
12786
  process.exit(1);
13427
12787
  }
13428
12788
  }
13429
- log4(`Pulling ${cyan2(policyId)} from dashboard...`);
12789
+ log3(`Pulling ${cyan2(policyId)} from dashboard...`);
13430
12790
  const policy = await fetchCloudPolicy(apiKey, API_URL, policyId);
13431
12791
  const { id: _id, ...policyWithoutId } = policy;
13432
12792
  const json = JSON.stringify(policyWithoutId, null, 2) + "\n";
13433
- writeFileSync12(file, json, "utf-8");
13434
- log4("");
13435
- log4(green2(" Saved to: ") + file);
13436
- log4(` ${dim2("Name:")} ${policy.name}`);
13437
- log4(` ${dim2("Version:")} ${policy.version}`);
13438
- log4(` ${dim2("Rules:")} ${policy.rules.length}`);
13439
- log4("");
13440
- log4(dim2("The policy file does not contain an ID."));
13441
- log4(dim2("Use --policy-id to specify the target when pushing/pulling."));
13442
- log4("");
12793
+ writeFileSync10(file, json, "utf-8");
12794
+ log3("");
12795
+ log3(green2(" Saved to: ") + file);
12796
+ log3(` ${dim2("Name:")} ${policy.name}`);
12797
+ log3(` ${dim2("Version:")} ${policy.version}`);
12798
+ log3(` ${dim2("Rules:")} ${policy.rules.length}`);
12799
+ log3("");
12800
+ log3(dim2("The policy file does not contain an ID."));
12801
+ log3(dim2("Use --policy-id to specify the target when pushing/pulling."));
12802
+ log3("");
13443
12803
  }
13444
12804
  async function push(apiKey, file, policyId) {
13445
- if (!existsSync9(file)) {
13446
- log4(red2(`ERROR: File not found: ${file}`));
12805
+ if (!existsSync7(file)) {
12806
+ log3(red2(`ERROR: File not found: ${file}`));
13447
12807
  process.exit(1);
13448
12808
  }
13449
12809
  if (!policyId) {
13450
- log4(red2("ERROR: --policy-id is required for push."));
13451
- log4("");
13452
- log4("This determines which cloud policy to update.");
13453
- log4("");
13454
- log4("Usage:");
13455
- log4(" solongate-proxy push --policy-id my-policy");
13456
- log4(" solongate-proxy push --policy-id my-policy --file custom.json");
13457
- log4("");
13458
- log4("List your policies:");
13459
- log4(" solongate-proxy list");
12810
+ log3(red2("ERROR: --policy-id is required for push."));
12811
+ log3("");
12812
+ log3("This determines which cloud policy to update.");
12813
+ log3("");
12814
+ log3("Usage:");
12815
+ log3(" solongate-proxy push --policy-id my-policy");
12816
+ log3(" solongate-proxy push --policy-id my-policy --file custom.json");
12817
+ log3("");
12818
+ log3("List your policies:");
12819
+ log3(" solongate-proxy list");
13460
12820
  process.exit(1);
13461
12821
  }
13462
- const content = readFileSync13(file, "utf-8");
12822
+ const content = readFileSync12(file, "utf-8");
13463
12823
  let policy;
13464
12824
  try {
13465
12825
  policy = JSON.parse(content);
13466
12826
  } catch {
13467
- log4(red2(`ERROR: Invalid JSON in ${file}`));
12827
+ log3(red2(`ERROR: Invalid JSON in ${file}`));
13468
12828
  process.exit(1);
13469
12829
  }
13470
- log4(`Pushing to ${cyan2(policyId)}...`);
13471
- log4(` ${dim2("File:")} ${file}`);
13472
- log4(` ${dim2("Name:")} ${policy.name || "Unnamed"}`);
13473
- log4(` ${dim2("Rules:")} ${(policy.rules || []).length}`);
12830
+ log3(`Pushing to ${cyan2(policyId)}...`);
12831
+ log3(` ${dim2("File:")} ${file}`);
12832
+ log3(` ${dim2("Name:")} ${policy.name || "Unnamed"}`);
12833
+ log3(` ${dim2("Rules:")} ${(policy.rules || []).length}`);
13474
12834
  const checkRes = await fetch(`${API_URL}/api/v1/policies/${policyId}`, {
13475
12835
  headers: { "Authorization": `Bearer ${apiKey}` }
13476
12836
  });
@@ -13492,17 +12852,17 @@ async function push(apiKey, file, policyId) {
13492
12852
  });
13493
12853
  if (!res.ok) {
13494
12854
  const body = await res.text().catch(() => "");
13495
- log4(red2(`ERROR: Push failed (${res.status}): ${body}`));
12855
+ log3(red2(`ERROR: Push failed (${res.status}): ${body}`));
13496
12856
  process.exit(1);
13497
12857
  }
13498
12858
  const data = await res.json();
13499
- log4("");
13500
- log4(green2(` Pushed to cloud: v${data._version ?? "created"}`));
13501
- log4(` ${dim2("Policy ID:")} ${policyId}`);
13502
- log4(` ${dim2("Method:")} ${method === "PUT" ? "Updated existing" : "Created new"}`);
13503
- log4("");
12859
+ log3("");
12860
+ log3(green2(` Pushed to cloud: v${data._version ?? "created"}`));
12861
+ log3(` ${dim2("Policy ID:")} ${policyId}`);
12862
+ log3(` ${dim2("Method:")} ${method === "PUT" ? "Updated existing" : "Created new"}`);
12863
+ log3("");
13504
12864
  }
13505
- async function main3() {
12865
+ async function main() {
13506
12866
  const { command, apiKey, file, policyId } = parseCliArgs();
13507
12867
  try {
13508
12868
  if (command === "pull") {
@@ -13512,32 +12872,32 @@ async function main3() {
13512
12872
  } else if (command === "list" || command === "ls") {
13513
12873
  await list5(apiKey, policyId);
13514
12874
  } else {
13515
- log4(red2(`Unknown command: ${command}`));
13516
- log4("");
13517
- log4(bold2("Usage:"));
13518
- log4(" solongate-proxy list List all policies");
13519
- log4(" solongate-proxy list --policy-id <ID> Show policy details");
13520
- log4(" solongate-proxy pull --policy-id <ID> Pull policy to local file");
13521
- log4(" solongate-proxy push --policy-id <ID> Push local file to cloud");
13522
- log4("");
13523
- log4(bold2("Flags:"));
13524
- log4(" --policy-id, --id <ID> Cloud policy ID (required for push)");
13525
- log4(" --file, -f <path> Local file path (default: policy.json)");
13526
- log4(" --api-key <key> API key (or set SOLONGATE_API_KEY)");
13527
- log4("");
12875
+ log3(red2(`Unknown command: ${command}`));
12876
+ log3("");
12877
+ log3(bold2("Usage:"));
12878
+ log3(" solongate-proxy list List all policies");
12879
+ log3(" solongate-proxy list --policy-id <ID> Show policy details");
12880
+ log3(" solongate-proxy pull --policy-id <ID> Pull policy to local file");
12881
+ log3(" solongate-proxy push --policy-id <ID> Push local file to cloud");
12882
+ log3("");
12883
+ log3(bold2("Flags:"));
12884
+ log3(" --policy-id, --id <ID> Cloud policy ID (required for push)");
12885
+ log3(" --file, -f <path> Local file path (default: policy.json)");
12886
+ log3(" --api-key <key> API key (or set SOLONGATE_API_KEY)");
12887
+ log3("");
13528
12888
  process.exit(1);
13529
12889
  }
13530
12890
  } catch (err2) {
13531
- log4(red2(`ERROR: ${err2 instanceof Error ? err2.message : String(err2)}`));
12891
+ log3(red2(`ERROR: ${err2 instanceof Error ? err2.message : String(err2)}`));
13532
12892
  process.exit(1);
13533
12893
  }
13534
12894
  }
13535
- var log4, dim2, bold2, green2, red2, yellow2, cyan2, magenta, API_URL;
12895
+ var log3, dim2, bold2, green2, red2, yellow2, cyan2, magenta, API_URL;
13536
12896
  var init_pull_push = __esm({
13537
12897
  "src/pull-push.ts"() {
13538
12898
  "use strict";
13539
12899
  init_config();
13540
- log4 = (...args) => process.stderr.write(`${args.map(String).join(" ")}
12900
+ log3 = (...args) => process.stderr.write(`${args.map(String).join(" ")}
13541
12901
  `);
13542
12902
  dim2 = (s) => `\x1B[2m${s}\x1B[0m`;
13543
12903
  bold2 = (s) => `\x1B[1m${s}\x1B[0m`;
@@ -13547,15 +12907,15 @@ var init_pull_push = __esm({
13547
12907
  cyan2 = (s) => `\x1B[36m${s}\x1B[0m`;
13548
12908
  magenta = (s) => `\x1B[35m${s}\x1B[0m`;
13549
12909
  API_URL = "https://api.solongate.com";
13550
- main3();
12910
+ main();
13551
12911
  }
13552
12912
  });
13553
12913
 
13554
12914
  // src/index.ts
13555
12915
  init_config();
13556
- import { readFileSync as readFileSync14 } from "fs";
12916
+ import { readFileSync as readFileSync13 } from "fs";
13557
12917
  import { fileURLToPath as fileURLToPath4 } from "url";
13558
- import { dirname as dirname4, join as join17 } from "path";
12918
+ import { dirname as dirname4, join as join16 } from "path";
13559
12919
 
13560
12920
  // src/proxy.ts
13561
12921
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -15979,7 +15339,7 @@ var Mutex = class {
15979
15339
  this.locked = true;
15980
15340
  return;
15981
15341
  }
15982
- return new Promise((resolve9, reject) => {
15342
+ return new Promise((resolve7, reject) => {
15983
15343
  const timer = setTimeout(() => {
15984
15344
  const idx = this.queue.indexOf(onReady);
15985
15345
  if (idx !== -1) this.queue.splice(idx, 1);
@@ -15987,7 +15347,7 @@ var Mutex = class {
15987
15347
  }, timeoutMs);
15988
15348
  const onReady = () => {
15989
15349
  clearTimeout(timer);
15990
- resolve9();
15350
+ resolve7();
15991
15351
  };
15992
15352
  this.queue.push(onReady);
15993
15353
  });
@@ -16578,7 +15938,7 @@ ${msg.content.text}`;
16578
15938
 
16579
15939
  // src/index.ts
16580
15940
  init_cli_utils();
16581
- var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["create", "inject", "pull", "push", "list", "ls", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "stats", "audit", "agents", "agent", "doctor", "watch", "alerts", "webhooks", "dataroom"]);
15941
+ var CLI_SUBCOMMANDS = /* @__PURE__ */ new Set(["pull", "push", "list", "ls", "logs-server", "local-logs", "policy", "ratelimit", "dlp", "stats", "audit", "agents", "agent", "doctor", "watch", "alerts", "webhooks", "dataroom"]);
16582
15942
  var CLI_INFO_ARGS = /* @__PURE__ */ new Set(["login", "help", "--help", "-h", "--version", "-v", "version"]);
16583
15943
  var IS_HUMAN_CLI = process.argv.length <= 2 || CLI_SUBCOMMANDS.has(process.argv[2] ?? "") || CLI_INFO_ARGS.has(process.argv[2] ?? "");
16584
15944
  if (!IS_HUMAN_CLI) {
@@ -16597,8 +15957,8 @@ if (!IS_HUMAN_CLI) {
16597
15957
  }
16598
15958
  var PKG_VERSION = (() => {
16599
15959
  try {
16600
- const p = join17(dirname4(fileURLToPath4(import.meta.url)), "..", "package.json");
16601
- return JSON.parse(readFileSync14(p, "utf-8")).version || "unknown";
15960
+ const p = join16(dirname4(fileURLToPath4(import.meta.url)), "..", "package.json");
15961
+ return JSON.parse(readFileSync13(p, "utf-8")).version || "unknown";
16602
15962
  } catch {
16603
15963
  return "unknown";
16604
15964
  }
@@ -16617,7 +15977,7 @@ function printWelcome() {
16617
15977
  console.log(` ${c.dim}Manage it at ${c.reset}${c.cyan}https://dashboard.solongate.com${c.reset}`);
16618
15978
  console.log("");
16619
15979
  }
16620
- function printHelp3() {
15980
+ function printHelp() {
16621
15981
  const W = 46;
16622
15982
  const head = (t) => console.log(`
16623
15983
  ${c.bold}${t}${c.reset}`);
@@ -16640,7 +16000,6 @@ function printHelp3() {
16640
16000
  head("Setup & status");
16641
16001
  cmd("solongate", "open the dataroom UI (login, policies, audit, settings)");
16642
16002
  cmd("doctor [--json]", "health check: login, policy, guard, local logs");
16643
- cmd("create", "scaffold a guarded MCP server in this folder");
16644
16003
  cmd("logs-server", "serve local audit logs to the dashboard");
16645
16004
  head("Policies");
16646
16005
  cmd("policy list", "list all policies");
@@ -16687,10 +16046,10 @@ function printHelp3() {
16687
16046
  console.log(` ${c.dim}Details for a command: ${c.reset}${c.cyan}solongate <command> help${c.reset}${c.dim} \xB7 Dashboard: ${c.reset}${c.cyan}https://dashboard.solongate.com${c.reset}`);
16688
16047
  console.log("");
16689
16048
  }
16690
- async function main4() {
16049
+ async function main2() {
16691
16050
  const subcommand = process.argv[2];
16692
16051
  if (subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
16693
- printHelp3();
16052
+ printHelp();
16694
16053
  return;
16695
16054
  }
16696
16055
  if (subcommand === "--version" || subcommand === "-v" || subcommand === "version") {
@@ -16740,16 +16099,6 @@ async function main4() {
16740
16099
  await runLogsServer2();
16741
16100
  return;
16742
16101
  }
16743
- if (subcommand === "inject") {
16744
- process.argv.splice(2, 1);
16745
- await Promise.resolve().then(() => (init_inject(), inject_exports));
16746
- return;
16747
- }
16748
- if (subcommand === "create") {
16749
- process.argv.splice(2, 1);
16750
- await Promise.resolve().then(() => (init_create(), create_exports));
16751
- return;
16752
- }
16753
16102
  if (subcommand === "pull" || subcommand === "push" || subcommand === "list" || subcommand === "ls") {
16754
16103
  await Promise.resolve().then(() => (init_pull_push(), pull_push_exports));
16755
16104
  return;
@@ -16776,4 +16125,4 @@ async function main4() {
16776
16125
  process.exit(1);
16777
16126
  }
16778
16127
  }
16779
- main4();
16128
+ main2();