@solongate/proxy 0.1.23 → 0.1.25
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/create.js +8 -6
- package/dist/index.js +105 -6
- package/package.json +1 -1
package/dist/create.js
CHANGED
|
@@ -205,13 +205,15 @@ await server.connect(transport);
|
|
|
205
205
|
console.log('');
|
|
206
206
|
console.log('${name} is running (stdio mode)');
|
|
207
207
|
console.log('');
|
|
208
|
-
console.log('
|
|
209
|
-
console.log('
|
|
208
|
+
console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
|
|
209
|
+
console.log('You need an MCP client to connect:');
|
|
210
210
|
console.log('');
|
|
211
|
-
console.log('
|
|
212
|
-
console.log('
|
|
213
|
-
console.log('
|
|
214
|
-
console.log('
|
|
211
|
+
console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
|
|
212
|
+
console.log(' Claude Desktop Add to Settings > MCP Servers');
|
|
213
|
+
console.log(' Cursor Open this folder, .mcp.json is auto-detected');
|
|
214
|
+
console.log(' Windsurf Open this folder, .mcp.json is auto-detected');
|
|
215
|
+
console.log(' Cline VS Code extension, add server in settings');
|
|
216
|
+
console.log(' Zed Add to settings.json under mcp_servers');
|
|
215
217
|
console.log('');
|
|
216
218
|
console.log('Press Ctrl+C to stop.');
|
|
217
219
|
`
|
package/dist/index.js
CHANGED
|
@@ -917,13 +917,15 @@ await server.connect(transport);
|
|
|
917
917
|
console.log('');
|
|
918
918
|
console.log('${name} is running (stdio mode)');
|
|
919
919
|
console.log('');
|
|
920
|
-
console.log('
|
|
921
|
-
console.log('
|
|
920
|
+
console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
|
|
921
|
+
console.log('You need an MCP client to connect:');
|
|
922
922
|
console.log('');
|
|
923
|
-
console.log('
|
|
924
|
-
console.log('
|
|
925
|
-
console.log('
|
|
926
|
-
console.log('
|
|
923
|
+
console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
|
|
924
|
+
console.log(' Claude Desktop Add to Settings > MCP Servers');
|
|
925
|
+
console.log(' Cursor Open this folder, .mcp.json is auto-detected');
|
|
926
|
+
console.log(' Windsurf Open this folder, .mcp.json is auto-detected');
|
|
927
|
+
console.log(' Cline VS Code extension, add server in settings');
|
|
928
|
+
console.log(' Zed Add to settings.json under mcp_servers');
|
|
927
929
|
console.log('');
|
|
928
930
|
console.log('Press Ctrl+C to stop.');
|
|
929
931
|
`
|
|
@@ -3082,6 +3084,7 @@ var SolonGate = class {
|
|
|
3082
3084
|
});
|
|
3083
3085
|
if (!options.policySet && !config.policySet && apiKey.startsWith("sg_live_")) {
|
|
3084
3086
|
this.fetchCloudPolicyOnce();
|
|
3087
|
+
this.startPolicyPolling();
|
|
3085
3088
|
}
|
|
3086
3089
|
this.tokenIssuer = config.tokenSecret ? new TokenIssuer({
|
|
3087
3090
|
secret: config.tokenSecret,
|
|
@@ -3151,6 +3154,40 @@ var SolonGate = class {
|
|
|
3151
3154
|
}).catch(() => {
|
|
3152
3155
|
});
|
|
3153
3156
|
}
|
|
3157
|
+
/**
|
|
3158
|
+
* Poll for policy updates from dashboard every 60 seconds.
|
|
3159
|
+
*/
|
|
3160
|
+
startPolicyPolling() {
|
|
3161
|
+
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
3162
|
+
let currentVersion = 0;
|
|
3163
|
+
setInterval(async () => {
|
|
3164
|
+
try {
|
|
3165
|
+
const res = await fetch(`${apiUrl}/api/v1/policies/default`, {
|
|
3166
|
+
headers: { "Authorization": `Bearer ${this.apiKey}` },
|
|
3167
|
+
signal: AbortSignal.timeout(1e4)
|
|
3168
|
+
});
|
|
3169
|
+
if (!res.ok) return;
|
|
3170
|
+
const data = await res.json();
|
|
3171
|
+
const version = Number(data._version ?? 0);
|
|
3172
|
+
const rulesCount = Array.isArray(data.rules) ? data.rules.length : 0;
|
|
3173
|
+
if (version !== currentVersion && version > 0) {
|
|
3174
|
+
const policySet = {
|
|
3175
|
+
id: String(data.id ?? "cloud"),
|
|
3176
|
+
name: String(data.name ?? "Cloud Policy"),
|
|
3177
|
+
description: String(data.description ?? ""),
|
|
3178
|
+
version,
|
|
3179
|
+
rules: data.rules ?? [],
|
|
3180
|
+
createdAt: String(data._created_at ?? ""),
|
|
3181
|
+
updatedAt: ""
|
|
3182
|
+
};
|
|
3183
|
+
this.policyEngine.loadPolicySet(policySet);
|
|
3184
|
+
currentVersion = version;
|
|
3185
|
+
console.warn(`[SolonGate] Policy updated from dashboard: ${policySet.name} v${version} (${rulesCount} rules)`);
|
|
3186
|
+
}
|
|
3187
|
+
} catch {
|
|
3188
|
+
}
|
|
3189
|
+
}, 6e4);
|
|
3190
|
+
}
|
|
3154
3191
|
/**
|
|
3155
3192
|
* Send audit log to SolonGate Cloud API (fire-and-forget).
|
|
3156
3193
|
*/
|
|
@@ -3325,6 +3362,7 @@ var SolonGateProxy = class {
|
|
|
3325
3362
|
}
|
|
3326
3363
|
}
|
|
3327
3364
|
}
|
|
3365
|
+
this.gate.loadPolicy(this.config.policy);
|
|
3328
3366
|
log(`Policy: ${this.config.policy.name} (${this.config.policy.rules.length} rules)`);
|
|
3329
3367
|
const transport = this.config.upstream.transport ?? "stdio";
|
|
3330
3368
|
if (transport === "stdio") {
|
|
@@ -3334,8 +3372,10 @@ var SolonGateProxy = class {
|
|
|
3334
3372
|
}
|
|
3335
3373
|
await this.connectUpstream();
|
|
3336
3374
|
await this.discoverTools();
|
|
3375
|
+
this.registerToolsToCloud();
|
|
3337
3376
|
this.createServer();
|
|
3338
3377
|
await this.serve();
|
|
3378
|
+
this.startPolicyPolling();
|
|
3339
3379
|
}
|
|
3340
3380
|
/**
|
|
3341
3381
|
* Connect to the upstream MCP server.
|
|
@@ -3495,6 +3535,65 @@ var SolonGateProxy = class {
|
|
|
3495
3535
|
});
|
|
3496
3536
|
});
|
|
3497
3537
|
}
|
|
3538
|
+
/**
|
|
3539
|
+
* Register discovered tools to the SolonGate Cloud API.
|
|
3540
|
+
* This makes tools visible on the Dashboard (/tools page).
|
|
3541
|
+
*/
|
|
3542
|
+
registerToolsToCloud() {
|
|
3543
|
+
if (!this.config.apiKey || this.config.apiKey.startsWith("sg_test_")) return;
|
|
3544
|
+
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
3545
|
+
for (const tool of this.upstreamTools) {
|
|
3546
|
+
fetch(`${apiUrl}/api/v1/tools`, {
|
|
3547
|
+
method: "POST",
|
|
3548
|
+
headers: {
|
|
3549
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
3550
|
+
"Content-Type": "application/json"
|
|
3551
|
+
},
|
|
3552
|
+
body: JSON.stringify({
|
|
3553
|
+
name: tool.name,
|
|
3554
|
+
description: tool.description ?? "",
|
|
3555
|
+
input_schema: tool.inputSchema,
|
|
3556
|
+
permissions: this.guessPermissions(tool.name),
|
|
3557
|
+
enabled: true
|
|
3558
|
+
})
|
|
3559
|
+
}).catch(() => {
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3562
|
+
log(`Registered ${this.upstreamTools.length} tools to dashboard`);
|
|
3563
|
+
}
|
|
3564
|
+
/**
|
|
3565
|
+
* Guess tool permissions from tool name.
|
|
3566
|
+
*/
|
|
3567
|
+
guessPermissions(toolName) {
|
|
3568
|
+
const name = toolName.toLowerCase();
|
|
3569
|
+
if (name.includes("exec") || name.includes("shell") || name.includes("run") || name.includes("eval")) {
|
|
3570
|
+
return ["EXECUTE"];
|
|
3571
|
+
}
|
|
3572
|
+
if (name.includes("write") || name.includes("create") || name.includes("delete") || name.includes("update") || name.includes("set")) {
|
|
3573
|
+
return ["WRITE"];
|
|
3574
|
+
}
|
|
3575
|
+
return ["READ"];
|
|
3576
|
+
}
|
|
3577
|
+
/**
|
|
3578
|
+
* Poll for policy updates from dashboard every 60 seconds.
|
|
3579
|
+
* When user changes policy in dashboard, proxy picks it up automatically.
|
|
3580
|
+
*/
|
|
3581
|
+
startPolicyPolling() {
|
|
3582
|
+
if (!this.config.apiKey || this.config.apiKey.startsWith("sg_test_")) return;
|
|
3583
|
+
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
3584
|
+
const POLL_INTERVAL = 6e4;
|
|
3585
|
+
setInterval(async () => {
|
|
3586
|
+
try {
|
|
3587
|
+
const newPolicy = await fetchCloudPolicy(this.config.apiKey, apiUrl);
|
|
3588
|
+
if (newPolicy.version !== this.config.policy.version || newPolicy.rules.length !== this.config.policy.rules.length) {
|
|
3589
|
+
this.config.policy = newPolicy;
|
|
3590
|
+
this.gate.loadPolicy(newPolicy);
|
|
3591
|
+
log(`Policy updated from dashboard: ${newPolicy.name} v${newPolicy.version} (${newPolicy.rules.length} rules)`);
|
|
3592
|
+
}
|
|
3593
|
+
} catch {
|
|
3594
|
+
}
|
|
3595
|
+
}, POLL_INTERVAL);
|
|
3596
|
+
}
|
|
3498
3597
|
/**
|
|
3499
3598
|
* Start serving downstream.
|
|
3500
3599
|
* If --port is set, serves via StreamableHTTP on that port.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "MCP security proxy \u00e2\u20ac\u201d protect any MCP server with policies, input validation, rate limiting, and audit logging. Zero code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|