@intutic/mcp-governance-proxy 1.9.0 → 1.10.1
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/README.md +28 -0
- package/dist/anomaly/detectors.d.ts +129 -0
- package/dist/anomaly/detectors.d.ts.map +1 -0
- package/dist/anomaly/detectors.js +368 -0
- package/dist/anomaly/detectors.js.map +1 -0
- package/dist/anomaly/index.d.ts +52 -0
- package/dist/anomaly/index.d.ts.map +1 -0
- package/dist/anomaly/index.js +71 -0
- package/dist/anomaly/index.js.map +1 -0
- package/dist/config.d.ts +107 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +129 -6
- package/dist/config.js.map +1 -1
- package/dist/daemon/healthMonitor.d.ts.map +1 -1
- package/dist/daemon/healthMonitor.js +45 -46
- package/dist/daemon/healthMonitor.js.map +1 -1
- package/dist/daemon/index.d.ts +15 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +78 -9
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/instrumentation.d.ts +20 -0
- package/dist/daemon/instrumentation.d.ts.map +1 -0
- package/dist/daemon/instrumentation.js +61 -0
- package/dist/daemon/instrumentation.js.map +1 -0
- package/dist/daemon/policyCache.d.ts +83 -0
- package/dist/daemon/policyCache.d.ts.map +1 -1
- package/dist/daemon/policyCache.js +280 -11
- package/dist/daemon/policyCache.js.map +1 -1
- package/dist/daemon/statusReporter.d.ts +12 -0
- package/dist/daemon/statusReporter.d.ts.map +1 -0
- package/dist/daemon/statusReporter.js +130 -0
- package/dist/daemon/statusReporter.js.map +1 -0
- package/dist/daemon/telemetryBatcher.d.ts +3 -1
- package/dist/daemon/telemetryBatcher.d.ts.map +1 -1
- package/dist/daemon/telemetryBatcher.js +56 -13
- package/dist/daemon/telemetryBatcher.js.map +1 -1
- package/dist/daemonClient.d.ts +1 -1
- package/dist/daemonClient.d.ts.map +1 -1
- package/dist/daemonClient.js +0 -2
- package/dist/daemonClient.js.map +1 -1
- package/dist/dlp.d.ts +19 -0
- package/dist/dlp.d.ts.map +1 -1
- package/dist/dlp.js +95 -18
- package/dist/dlp.js.map +1 -1
- package/dist/emitter.d.ts +40 -2
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +27 -5
- package/dist/emitter.js.map +1 -1
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/injection.d.ts +46 -0
- package/dist/injection.d.ts.map +1 -0
- package/dist/injection.js +147 -0
- package/dist/injection.js.map +1 -0
- package/dist/interceptor.d.ts +131 -1
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/interceptor.js +301 -5
- package/dist/interceptor.js.map +1 -1
- package/dist/policy.d.ts +110 -2
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +206 -5
- package/dist/policy.js.map +1 -1
- package/dist/proxy.d.ts +205 -0
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +572 -65
- package/dist/proxy.js.map +1 -1
- package/dist/remoteBridge.d.ts +51 -0
- package/dist/remoteBridge.d.ts.map +1 -0
- package/dist/remoteBridge.js +182 -0
- package/dist/remoteBridge.js.map +1 -0
- package/dist/session.d.ts +158 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +206 -0
- package/dist/session.js.map +1 -0
- package/dist/sessionScope.d.ts +51 -0
- package/dist/sessionScope.d.ts.map +1 -0
- package/dist/sessionScope.js +94 -0
- package/dist/sessionScope.js.map +1 -0
- package/dist/sessionStore.d.ts +69 -0
- package/dist/sessionStore.d.ts.map +1 -0
- package/dist/sessionStore.js +143 -0
- package/dist/sessionStore.js.map +1 -0
- package/dist/tofu.d.ts +112 -0
- package/dist/tofu.d.ts.map +1 -0
- package/dist/tofu.js +180 -0
- package/dist/tofu.js.map +1 -0
- package/dist/toolPoison.d.ts +32 -0
- package/dist/toolPoison.d.ts.map +1 -0
- package/dist/toolPoison.js +81 -0
- package/dist/toolPoison.js.map +1 -0
- package/dist/valkeyErrors.d.ts +17 -0
- package/dist/valkeyErrors.d.ts.map +1 -0
- package/dist/valkeyErrors.js +24 -0
- package/dist/valkeyErrors.js.map +1 -0
- package/dist/wasm/context.d.ts +57 -0
- package/dist/wasm/context.d.ts.map +1 -0
- package/dist/wasm/context.js +59 -0
- package/dist/wasm/context.js.map +1 -0
- package/dist/wasm/hostImports.d.ts +43 -0
- package/dist/wasm/hostImports.d.ts.map +1 -0
- package/dist/wasm/hostImports.js +158 -0
- package/dist/wasm/hostImports.js.map +1 -0
- package/dist/wasm/loader.d.ts +95 -0
- package/dist/wasm/loader.d.ts.map +1 -0
- package/dist/wasm/loader.js +198 -0
- package/dist/wasm/loader.js.map +1 -0
- package/dist/wasm/referencedFiles.d.ts +115 -0
- package/dist/wasm/referencedFiles.d.ts.map +1 -0
- package/dist/wasm/referencedFiles.js +366 -0
- package/dist/wasm/referencedFiles.js.map +1 -0
- package/dist/wasm/runner.d.ts +91 -0
- package/dist/wasm/runner.d.ts.map +1 -0
- package/dist/wasm/runner.js +308 -0
- package/dist/wasm/runner.js.map +1 -0
- package/dist/wasm/watch.d.ts +5 -0
- package/dist/wasm/watch.d.ts.map +1 -0
- package/dist/wasm/watch.js +54 -0
- package/dist/wasm/watch.js.map +1 -0
- package/dist/wasm/worker.d.ts +39 -0
- package/dist/wasm/worker.d.ts.map +1 -0
- package/dist/wasm/worker.js +245 -0
- package/dist/wasm/worker.js.map +1 -0
- package/package.json +14 -4
|
@@ -13,6 +13,7 @@ import fs from 'node:fs';
|
|
|
13
13
|
import path from 'node:path';
|
|
14
14
|
import os from 'node:os';
|
|
15
15
|
import { Redis } from 'ioredis';
|
|
16
|
+
import { describeConnectionError } from '../valkeyErrors.js';
|
|
16
17
|
import { createLogger } from '@intutic/logger';
|
|
17
18
|
const logger = createLogger('mcp-proxy.telemetryBatcher');
|
|
18
19
|
const CP_URL = process.env['CONTROL_PLANE_URL'] ?? 'http://localhost:3001';
|
|
@@ -26,7 +27,7 @@ const valkey = new Redis(VALKEY_URL, {
|
|
|
26
27
|
maxRetriesPerRequest: 3,
|
|
27
28
|
});
|
|
28
29
|
valkey.on('error', (err) => {
|
|
29
|
-
logger.warn({ err: err
|
|
30
|
+
logger.warn({ err: describeConnectionError(err) }, 'telemetryBatcher Valkey connection error');
|
|
30
31
|
});
|
|
31
32
|
const daemonId = process.pid.toString();
|
|
32
33
|
const ring = [];
|
|
@@ -38,16 +39,31 @@ export function enqueueEvent(event) {
|
|
|
38
39
|
ring.shift();
|
|
39
40
|
ring.push(event);
|
|
40
41
|
}
|
|
42
|
+
/** Events awaiting the next flush. Reported upstream by the status reporter. */
|
|
43
|
+
export function pendingCount() {
|
|
44
|
+
return ring.length;
|
|
45
|
+
}
|
|
41
46
|
async function flush() {
|
|
42
47
|
if (isFlushing || ring.length === 0)
|
|
43
48
|
return;
|
|
44
49
|
isFlushing = true;
|
|
45
|
-
|
|
50
|
+
try {
|
|
51
|
+
await flushBatch(ring.splice(0, ring.length));
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
// Held in a finally because `isFlushing` is a latch, not a flag: the one
|
|
55
|
+
// path that can still throw past the handlers below is `new URL(CP_URL)`
|
|
56
|
+
// on a CONTROL_PLANE_URL with no scheme, and leaving the latch set there
|
|
57
|
+
// would silently retire the flush timer for the life of the daemon.
|
|
58
|
+
isFlushing = false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function flushBatch(batch) {
|
|
46
62
|
const body = JSON.stringify({ events: batch });
|
|
47
63
|
const url = new URL('/api/v1/hook-events', CP_URL);
|
|
48
64
|
const isHttps = url.protocol === 'https:';
|
|
49
65
|
const lib = isHttps ? https : http;
|
|
50
|
-
const tryUpload = (
|
|
66
|
+
const tryUpload = () => new Promise((resolve, reject) => {
|
|
51
67
|
const req = lib.request({ hostname: url.hostname, port: url.port, path: url.pathname, method: 'POST',
|
|
52
68
|
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body),
|
|
53
69
|
'Authorization': `Bearer ${DAEMON_API_KEY}` } }, (res) => {
|
|
@@ -65,7 +81,7 @@ async function flush() {
|
|
|
65
81
|
let success = false;
|
|
66
82
|
for (let i = 0; i < 3; i++) {
|
|
67
83
|
try {
|
|
68
|
-
await tryUpload(
|
|
84
|
+
await tryUpload();
|
|
69
85
|
success = true;
|
|
70
86
|
break;
|
|
71
87
|
}
|
|
@@ -82,11 +98,16 @@ async function flush() {
|
|
|
82
98
|
logger.warn({ count: batch.length }, 'telemetry.flush_failed_buffered_to_valkey');
|
|
83
99
|
}
|
|
84
100
|
catch (valkeyErr) {
|
|
85
|
-
// Fallback: local disk buffer
|
|
101
|
+
// Fallback: local disk buffer. The Valkey failure is reported on the
|
|
102
|
+
// disk-fallback line rather than dropped — it is the reason this branch
|
|
103
|
+
// ran at all, and without it the log says only "wrote to disk".
|
|
104
|
+
const valkeyError = valkeyErr instanceof Error
|
|
105
|
+
? describeConnectionError(valkeyErr)
|
|
106
|
+
: String(valkeyErr);
|
|
86
107
|
try {
|
|
87
108
|
fs.mkdirSync(path.dirname(DISK_BUFFER), { recursive: true, mode: 0o700 });
|
|
88
109
|
fs.appendFileSync(DISK_BUFFER, batch.map(e => JSON.stringify(e)).join('\n') + '\n', { mode: 0o600 });
|
|
89
|
-
logger.warn({ count: batch.length }, 'telemetry.flush_failed_buffered_to_disk');
|
|
110
|
+
logger.warn({ valkeyError, count: batch.length }, 'telemetry.flush_failed_buffered_to_disk');
|
|
90
111
|
}
|
|
91
112
|
catch (diskErr) {
|
|
92
113
|
logger.error({ diskErr, count: batch.length }, 'telemetry.disk_buffer_failed');
|
|
@@ -96,7 +117,6 @@ async function flush() {
|
|
|
96
117
|
else {
|
|
97
118
|
logger.debug({ count: batch.length }, 'telemetry.flushed');
|
|
98
119
|
}
|
|
99
|
-
isFlushing = false;
|
|
100
120
|
}
|
|
101
121
|
/** Drains any Valkey or disk buffer from a previous crash, then starts the flush timer. */
|
|
102
122
|
export function startBatcher() {
|
|
@@ -108,7 +128,12 @@ export function startBatcher() {
|
|
|
108
128
|
try {
|
|
109
129
|
enqueueEvent(JSON.parse(line));
|
|
110
130
|
}
|
|
111
|
-
catch {
|
|
131
|
+
catch {
|
|
132
|
+
// Unparseable buffer entry (truncated by a crash mid-rpush, or
|
|
133
|
+
// written by an older event schema). Drop the single bad line rather
|
|
134
|
+
// than lose the rest of the recovered batch — telemetry is
|
|
135
|
+
// best-effort and the buffer is deleted below regardless.
|
|
136
|
+
}
|
|
112
137
|
}
|
|
113
138
|
await valkey.del(key);
|
|
114
139
|
logger.info({ count: lines.length }, 'telemetry.valkey_buffer_drained');
|
|
@@ -122,22 +147,40 @@ export function startBatcher() {
|
|
|
122
147
|
try {
|
|
123
148
|
enqueueEvent(JSON.parse(line));
|
|
124
149
|
}
|
|
125
|
-
catch {
|
|
150
|
+
catch {
|
|
151
|
+
// Unparseable NDJSON line — the last record is routinely truncated
|
|
152
|
+
// when the daemon was killed mid-append. Drop the bad line and keep
|
|
153
|
+
// draining the rest of the file.
|
|
154
|
+
}
|
|
126
155
|
}
|
|
127
156
|
fs.unlinkSync(DISK_BUFFER);
|
|
128
157
|
logger.info({ count: lines.length }, 'telemetry.disk_buffer_drained');
|
|
129
158
|
}
|
|
130
159
|
}
|
|
131
|
-
catch {
|
|
132
|
-
|
|
160
|
+
catch (err) {
|
|
161
|
+
// The buffer file vanished between existsSync and readFileSync, or is
|
|
162
|
+
// unreadable, or the unlink failed. Startup must not fail over recovery of
|
|
163
|
+
// best-effort telemetry, so the daemon carries on either way. Note the
|
|
164
|
+
// unlink case leaves the file behind, so those events are re-enqueued (and
|
|
165
|
+
// re-delivered) on the next start; duplicate hook events are tolerable,
|
|
166
|
+
// blocking daemon startup is not.
|
|
167
|
+
logger.warn({ err }, 'telemetry.disk_buffer_drain_failed');
|
|
168
|
+
}
|
|
169
|
+
flushTimer = setInterval(() => {
|
|
170
|
+
// Nothing awaits this tick, so an escaping rejection is an unhandled one
|
|
171
|
+
// every FLUSH_MS. Telemetry is best-effort; log and keep the timer alive.
|
|
172
|
+
void flush().catch((err) => logger.error({ err }, 'telemetry.flush_failed'));
|
|
173
|
+
}, FLUSH_MS);
|
|
133
174
|
flushTimer.unref();
|
|
134
175
|
}
|
|
135
|
-
/** Flushes remaining events and stops the timer. */
|
|
176
|
+
/** Flushes remaining events and stops the timer. Never rejects. */
|
|
136
177
|
export async function stopBatcher() {
|
|
137
178
|
if (flushTimer) {
|
|
138
179
|
clearInterval(flushTimer);
|
|
139
180
|
flushTimer = null;
|
|
140
181
|
}
|
|
141
|
-
|
|
182
|
+
// Shutdown must not be blocked by a final flush that throws: the caller is a
|
|
183
|
+
// signal handler that has to reach process.exit().
|
|
184
|
+
await flush().catch((err) => logger.error({ err }, 'telemetry.final_flush_failed'));
|
|
142
185
|
}
|
|
143
186
|
//# sourceMappingURL=telemetryBatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetryBatcher.js","sourceRoot":"","sources":["../../src/daemon/telemetryBatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,IAAI,MAAO,WAAW,CAAA;AAC7B,OAAO,EAAE,MAAS,SAAS,CAAA;AAC3B,OAAO,IAAI,MAAO,WAAW,CAAA;AAC7B,OAAO,EAAE,MAAS,SAAS,CAAA;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,MAAM,GAAG,YAAY,CAAC,4BAA4B,CAAC,CAAA;AAEzD,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAiB,uBAAuB,CAAA;AAChG,MAAM,cAAc,GAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAmB,EAAE,CAAA;AAC3E,MAAM,QAAQ,GAAU,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAA;AAC5F,MAAM,aAAa,GAAK,GAAG,CAAA;AAC3B,MAAM,WAAW,GAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,yBAAyB,CAAC,CAAA;AAEtF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,wBAAwB,CAAA;AACpG,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE;IACnC,WAAW,EAAE,IAAI;IACjB,oBAAoB,EAAE,CAAC;CACxB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"telemetryBatcher.js","sourceRoot":"","sources":["../../src/daemon/telemetryBatcher.ts"],"names":[],"mappings":"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"}
|
package/dist/daemonClient.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sends a JSON-RPC request to the mcp-daemon Unix domain socket.
|
|
3
3
|
*/
|
|
4
|
-
export declare function callDaemonSocket(method: string, params: Record<string, unknown>): Promise<
|
|
4
|
+
export declare function callDaemonSocket<T = unknown>(method: string, params: Record<string, unknown>): Promise<T>;
|
|
5
5
|
//# sourceMappingURL=daemonClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemonClient.d.ts","sourceRoot":"","sources":["../src/daemonClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"daemonClient.d.ts","sourceRoot":"","sources":["../src/daemonClient.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,CAAC,CAAC,CAiDZ"}
|
package/dist/daemonClient.js
CHANGED
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
import * as net from 'node:net';
|
|
8
8
|
import * as path from 'node:path';
|
|
9
9
|
import * as os from 'node:os';
|
|
10
|
-
import { createStderrLogger as createLogger } from './stderrLog.js';
|
|
11
|
-
const log = createLogger('mcp-proxy-daemon-client');
|
|
12
10
|
function getSocketPath() {
|
|
13
11
|
return process.env['MCP_DAEMON_SOCKET'] ??
|
|
14
12
|
path.join(os.homedir(), '.intutic', 'mcp-proxy.sock');
|
package/dist/daemonClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemonClient.js","sourceRoot":"","sources":["../src/daemonClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"daemonClient.js","sourceRoot":"","sources":["../src/daemonClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAE7B,SAAS,aAAa;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAA;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,MAA+B;IAE/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAA;QACpD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QAE1B,IAAI,MAAM,GAAG,EAAE,CAAA;QACf,MAAM,GAAG,GAAG;YACV,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;YACtE,MAAM;YACN,MAAM;SACP,CAAA;QAED,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;QAC1C,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAClC,MAAM,IAAI,KAAK,CAAA;YACf,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAChC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAA;gBAC7B,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,CAAC;wBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;wBAC5B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;4BACd,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;wBACtC,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;wBACrB,CAAC;oBACH,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,CAAC,GAAG,CAAC,CAAA;oBACb,CAAC;4BAAS,CAAC;wBACT,MAAM,CAAC,GAAG,EAAE,CAAA;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,MAAM,CAAC,GAAG,CAAC,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,aAAa;QACb,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE;YAC3B,MAAM,CAAC,OAAO,EAAE,CAAA;YAChB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/dlp.d.ts
CHANGED
|
@@ -15,6 +15,25 @@ export interface DlpScanResult {
|
|
|
15
15
|
hasFinding: boolean;
|
|
16
16
|
findings: DlpFinding[];
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Replace the dynamic pattern set from control-plane regex sources.
|
|
20
|
+
* Invalid sources are dropped loudly by count — a pattern that does not
|
|
21
|
+
* compile enforces nothing, and silence there is how it stays broken.
|
|
22
|
+
* Returns the number dropped so the caller can log it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setDynamicPatterns(sources: readonly string[]): number;
|
|
25
|
+
/**
|
|
26
|
+
* Redact every redactable-pattern match in a string.
|
|
27
|
+
*
|
|
28
|
+
* Used on the RESPONSE direction (tool results, resource reads), where the
|
|
29
|
+
* action already happened and blocking protects nothing — redaction keeps the
|
|
30
|
+
* secret out of the agent's context, which is the only thing still at stake.
|
|
31
|
+
* Command patterns are skipped by design; see DLP_PATTERNS.
|
|
32
|
+
*/
|
|
33
|
+
export declare function redactText(text: string): {
|
|
34
|
+
redacted: string;
|
|
35
|
+
findings: DlpFinding[];
|
|
36
|
+
};
|
|
18
37
|
/**
|
|
19
38
|
* Scan tool arguments for DLP findings.
|
|
20
39
|
*
|
package/dist/dlp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dlp.d.ts","sourceRoot":"","sources":["../src/dlp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAA;CACvB;
|
|
1
|
+
{"version":3,"file":"dlp.d.ts","sourceRoot":"","sources":["../src/dlp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAA;CACvB;AAqDD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAgBrE;AAMD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,CAYrF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,CAe/D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,MAAM,CAGnE"}
|
package/dist/dlp.js
CHANGED
|
@@ -8,29 +8,103 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
/**
|
|
11
|
-
* Compiled DLP patterns.
|
|
11
|
+
* Compiled DLP patterns.
|
|
12
|
+
*
|
|
13
|
+
* `redactable` separates VALUE patterns (a credential-shaped string that can
|
|
14
|
+
* be replaced with a placeholder wherever it appears) from COMMAND patterns
|
|
15
|
+
* (a destructive instruction, meaningful only as a reason to refuse an
|
|
16
|
+
* input). The distinction exists for the response direction: redacting
|
|
17
|
+
* "DROP TABLE" out of a tool RESULT would rewrite data the tool legitimately
|
|
18
|
+
* returned (a schema dump mentions DROP TABLE), while redacting a key out of
|
|
19
|
+
* a result protects the agent's context without changing what the result
|
|
20
|
+
* means. Command patterns therefore never apply to results.
|
|
12
21
|
*/
|
|
13
22
|
const DLP_PATTERNS = [
|
|
14
23
|
// API keys / tokens
|
|
15
|
-
{ regex: /sk-[A-Za-z0-9]{20,}/, description: 'OpenAI API key pattern' },
|
|
16
|
-
{ regex: /sk-ant-[A-Za-z0-9\-_]{20,}/, description: 'Anthropic API key pattern' },
|
|
17
|
-
{ regex: /AIza[A-Za-z0-9\-_]{35}/, description: 'Google API key pattern' },
|
|
18
|
-
{ regex: /ghp_[A-Za-z0-9]{36}/, description: 'GitHub personal access token' },
|
|
19
|
-
{ regex: /ghs_[A-Za-z0-9]{36}/, description: 'GitHub server token' },
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
{ regex: /sk-[A-Za-z0-9]{20,}/, description: 'OpenAI API key pattern', redactable: true },
|
|
25
|
+
{ regex: /sk-ant-[A-Za-z0-9\-_]{20,}/, description: 'Anthropic API key pattern', redactable: true },
|
|
26
|
+
{ regex: /AIza[A-Za-z0-9\-_]{35}/, description: 'Google API key pattern', redactable: true },
|
|
27
|
+
{ regex: /ghp_[A-Za-z0-9]{36}/, description: 'GitHub personal access token', redactable: true },
|
|
28
|
+
{ regex: /ghs_[A-Za-z0-9]{36}/, description: 'GitHub server token', redactable: true },
|
|
29
|
+
// `-` is last in these classes, where it is already a literal — the escape
|
|
30
|
+
// was a no-op. It stays a class member either way; see the Slack cases in
|
|
31
|
+
// __tests__/dlp.test.ts, which pin the hyphen-spanning token shape.
|
|
32
|
+
{ regex: /xoxb-[A-Za-z0-9-]{50,}/, description: 'Slack bot token', redactable: true },
|
|
33
|
+
{ regex: /xoxp-[A-Za-z0-9-]{50,}/, description: 'Slack user token', redactable: true },
|
|
34
|
+
{ regex: /AKIA[A-Z0-9]{16}/, description: 'AWS Access Key ID', redactable: true },
|
|
35
|
+
// PII. The Rust proxy's dlp.rs has carried an SSN pattern from the start;
|
|
36
|
+
// this scanner had none, so a tool result carrying one streamed into the
|
|
37
|
+
// agent's context unremarked. Same shape dlp.rs uses: grouped digits only —
|
|
38
|
+
// a bare 9-digit run matches phone numbers and IDs far too often.
|
|
39
|
+
{ regex: /\b\d{3}-\d{2}-\d{4}\b/, description: 'US Social Security Number', redactable: true },
|
|
23
40
|
// High-entropy strings that look like secrets (≥40 chars of hex or base64)
|
|
24
|
-
{ regex: /[0-9a-f]{40,}/, description: 'High-entropy hex string (possible secret)' },
|
|
25
|
-
// Destructive shell patterns in Bash/command arguments
|
|
26
|
-
{ regex: /rm\s+-rf?\s+\//, description: 'Destructive rm -rf / command' },
|
|
27
|
-
{ regex: /DROP\s+TABLE/i, description: 'SQL DROP TABLE statement' },
|
|
28
|
-
{ regex: /DROP\s+DATABASE/i, description: 'SQL DROP DATABASE statement' },
|
|
29
|
-
{ regex: /TRUNCATE\s+TABLE/i, description: 'SQL TRUNCATE TABLE statement' },
|
|
41
|
+
{ regex: /[0-9a-f]{40,}/, description: 'High-entropy hex string (possible secret)', redactable: true },
|
|
42
|
+
// Destructive shell patterns in Bash/command arguments — input-only.
|
|
43
|
+
{ regex: /rm\s+-rf?\s+\//, description: 'Destructive rm -rf / command', redactable: false },
|
|
44
|
+
{ regex: /DROP\s+TABLE/i, description: 'SQL DROP TABLE statement', redactable: false },
|
|
45
|
+
{ regex: /DROP\s+DATABASE/i, description: 'SQL DROP DATABASE statement', redactable: false },
|
|
46
|
+
{ regex: /TRUNCATE\s+TABLE/i, description: 'SQL TRUNCATE TABLE statement', redactable: false },
|
|
30
47
|
// Private key material
|
|
31
|
-
{ regex: /-----BEGIN\s+(RSA\s+)?PRIVATE KEY-----/, description: 'PEM private key material' },
|
|
32
|
-
{ regex: /-----BEGIN\s+EC\s+PRIVATE KEY-----/, description: 'EC private key material' },
|
|
48
|
+
{ regex: /-----BEGIN\s+(RSA\s+)?PRIVATE KEY-----/, description: 'PEM private key material', redactable: true },
|
|
49
|
+
{ regex: /-----BEGIN\s+EC\s+PRIVATE KEY-----/, description: 'EC private key material', redactable: true },
|
|
33
50
|
];
|
|
51
|
+
/**
|
|
52
|
+
* Control-plane-supplied patterns, compiled. The daemon has fetched and
|
|
53
|
+
* cached `dlpPatterns` since the policy cache existed, and this scanner never
|
|
54
|
+
* read them — a workspace's custom patterns were a setting wired to nothing.
|
|
55
|
+
* The hardcoded floor above stays regardless: an unreachable control plane
|
|
56
|
+
* must degrade to the floor, never to no scanning.
|
|
57
|
+
*/
|
|
58
|
+
let dynamicPatterns = [];
|
|
59
|
+
/**
|
|
60
|
+
* Replace the dynamic pattern set from control-plane regex sources.
|
|
61
|
+
* Invalid sources are dropped loudly by count — a pattern that does not
|
|
62
|
+
* compile enforces nothing, and silence there is how it stays broken.
|
|
63
|
+
* Returns the number dropped so the caller can log it.
|
|
64
|
+
*/
|
|
65
|
+
export function setDynamicPatterns(sources) {
|
|
66
|
+
const compiled = [];
|
|
67
|
+
let dropped = 0;
|
|
68
|
+
for (const src of sources) {
|
|
69
|
+
try {
|
|
70
|
+
compiled.push({
|
|
71
|
+
regex: new RegExp(src),
|
|
72
|
+
description: `Workspace DLP pattern: ${src}`,
|
|
73
|
+
redactable: true,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
dropped += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
dynamicPatterns = compiled;
|
|
81
|
+
return dropped;
|
|
82
|
+
}
|
|
83
|
+
function allPatterns() {
|
|
84
|
+
return dynamicPatterns.length ? [...DLP_PATTERNS, ...dynamicPatterns] : DLP_PATTERNS;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Redact every redactable-pattern match in a string.
|
|
88
|
+
*
|
|
89
|
+
* Used on the RESPONSE direction (tool results, resource reads), where the
|
|
90
|
+
* action already happened and blocking protects nothing — redaction keeps the
|
|
91
|
+
* secret out of the agent's context, which is the only thing still at stake.
|
|
92
|
+
* Command patterns are skipped by design; see DLP_PATTERNS.
|
|
93
|
+
*/
|
|
94
|
+
export function redactText(text) {
|
|
95
|
+
const findings = [];
|
|
96
|
+
let redacted = text;
|
|
97
|
+
for (const { regex, description, redactable } of allPatterns()) {
|
|
98
|
+
if (!redactable)
|
|
99
|
+
continue;
|
|
100
|
+
const global = new RegExp(regex.source, regex.flags.includes('g') ? regex.flags : regex.flags + 'g');
|
|
101
|
+
if (global.test(redacted)) {
|
|
102
|
+
findings.push({ pattern: regex.source, description });
|
|
103
|
+
redacted = redacted.replace(global, '[REDACTED_SECRET]');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return { redacted, findings };
|
|
107
|
+
}
|
|
34
108
|
/**
|
|
35
109
|
* Scan tool arguments for DLP findings.
|
|
36
110
|
*
|
|
@@ -41,7 +115,10 @@ export function scanToolInput(toolInput) {
|
|
|
41
115
|
// Serialize to string for pattern matching
|
|
42
116
|
const serialized = JSON.stringify(toolInput ?? {});
|
|
43
117
|
const findings = [];
|
|
44
|
-
|
|
118
|
+
// The full set — floor plus workspace patterns — on the input direction too:
|
|
119
|
+
// a workspace pattern that blocked results but not the input that exfiltrates
|
|
120
|
+
// them would be scanning the wrong side.
|
|
121
|
+
for (const { regex, description } of allPatterns()) {
|
|
45
122
|
if (regex.test(serialized)) {
|
|
46
123
|
findings.push({ pattern: regex.source, description });
|
|
47
124
|
}
|
package/dist/dlp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dlp.js","sourceRoot":"","sources":["../src/dlp.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH
|
|
1
|
+
{"version":3,"file":"dlp.js","sourceRoot":"","sources":["../src/dlp.ts"],"names":[],"mappings":"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"}
|
package/dist/emitter.d.ts
CHANGED
|
@@ -8,7 +8,38 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
|
-
export type EventKind = 'tool_allowed' | 'tool_blocked' | 'tool_redacted'
|
|
11
|
+
export type EventKind = 'tool_allowed' | 'tool_blocked' | 'tool_redacted'
|
|
12
|
+
/**
|
|
13
|
+
* A `warn` SOP rule matched and the call was allowed (LLD #71): the same
|
|
14
|
+
* event the harness gates log for a warn-severity rule, carrying the rule
|
|
15
|
+
* id as `[<id>]` in `reason`, so a SHADOW guardrail seen through this
|
|
16
|
+
* proxy counts toward its evidence like one seen through a gate.
|
|
17
|
+
*/
|
|
18
|
+
| 'tool_flagged'
|
|
19
|
+
/**
|
|
20
|
+
* Server-level TOFU pin mismatch (tofu.ts) — a server's `tools/list`
|
|
21
|
+
* response no longer matches the fingerprint pinned on first contact. Sent
|
|
22
|
+
* with `toolName` carrying the SERVER name (there is no single tool
|
|
23
|
+
* involved), the same "reuse toolName as the identifier of whatever this
|
|
24
|
+
* event is about" shape `tool_blocked`/`tool_allowed` already use.
|
|
25
|
+
*/
|
|
26
|
+
| 'mcp_server_definition_changed'
|
|
27
|
+
/**
|
|
28
|
+
* A prompt-injection pattern fired (injection.ts), on any of the three
|
|
29
|
+
* scanned surfaces (`tool_result`/`tool_description`/`tool_input`). Always
|
|
30
|
+
* emitted regardless of `mcpInjectionAction` — warn mode reports and
|
|
31
|
+
* allows, block mode reports and additionally emits `tool_blocked` (see
|
|
32
|
+
* interceptor.ts / proxy.ts) so existing consumers keyed on `tool_blocked`
|
|
33
|
+
* are not blind to this new block reason.
|
|
34
|
+
*/
|
|
35
|
+
| 'injection_detected'
|
|
36
|
+
/**
|
|
37
|
+
* A Phase-2 anomaly detector (anomaly/detectors.ts) fired against the
|
|
38
|
+
* session's tool-call sequence. Emitted on Steer (allow) and on Reask/Kill
|
|
39
|
+
* (block) alike — a Reask/Kill firing ALSO emits `tool_blocked`, the same
|
|
40
|
+
* "existing consumers key on it" rule `injection_detected` follows.
|
|
41
|
+
*/
|
|
42
|
+
| 'anomaly_detected';
|
|
12
43
|
export interface GovernanceEvent {
|
|
13
44
|
incidentId: string;
|
|
14
45
|
kind: EventKind;
|
|
@@ -17,6 +48,13 @@ export interface GovernanceEvent {
|
|
|
17
48
|
workspaceId: string;
|
|
18
49
|
harnessType: string;
|
|
19
50
|
reason?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Set only by `injection_detected`/`anomaly_detected` today — the
|
|
53
|
+
* escalation-rule mirror `injection.ts`'s `injectionSeverity` (Phase 1) and
|
|
54
|
+
* the per-detector disposition mapping (Phase 2) compute. Absent on every
|
|
55
|
+
* other event kind, matching how `reason` is already optional here.
|
|
56
|
+
*/
|
|
57
|
+
severity?: string;
|
|
20
58
|
timestamp: string;
|
|
21
59
|
}
|
|
22
60
|
export declare class GovernanceEmitter {
|
|
@@ -26,7 +64,7 @@ export declare class GovernanceEmitter {
|
|
|
26
64
|
private readonly workspaceId;
|
|
27
65
|
private readonly mcpProxyMode;
|
|
28
66
|
constructor(controlPlaneUrl: string, apiKey: string, eventsFilePath: string, workspaceId: string, mcpProxyMode?: string);
|
|
29
|
-
emit(kind: EventKind, toolName: string, toolInput: unknown, reason?: string): void;
|
|
67
|
+
emit(kind: EventKind, toolName: string, toolInput: unknown, reason?: string, severity?: string): void;
|
|
30
68
|
private runDualPath;
|
|
31
69
|
private postToControlPlane;
|
|
32
70
|
private appendToFile;
|
package/dist/emitter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,MAAM,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,cAAc,GACd,eAAe;AACjB;;;;;GAKG;GACD,cAAc;AAChB;;;;;;GAMG;GACD,+BAA+B;AACjC;;;;;;;GAOG;GACD,oBAAoB;AACtB;;;;;GAKG;GACD,kBAAkB,CAAA;AAEtB,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAJZ,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAsB;IAGvD,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAuCrG,OAAO,CAAC,WAAW;YAYL,kBAAkB;YA4BlB,YAAY;CAM3B"}
|
package/dist/emitter.js
CHANGED
|
@@ -29,7 +29,7 @@ export class GovernanceEmitter {
|
|
|
29
29
|
this.workspaceId = workspaceId;
|
|
30
30
|
this.mcpProxyMode = mcpProxyMode;
|
|
31
31
|
}
|
|
32
|
-
emit(kind, toolName, toolInput, reason) {
|
|
32
|
+
emit(kind, toolName, toolInput, reason, severity) {
|
|
33
33
|
const event = {
|
|
34
34
|
incidentId: node_crypto.randomUUID(),
|
|
35
35
|
kind,
|
|
@@ -38,16 +38,21 @@ export class GovernanceEmitter {
|
|
|
38
38
|
workspaceId: this.workspaceId,
|
|
39
39
|
harnessType: 'mcp-governance-proxy',
|
|
40
40
|
reason,
|
|
41
|
+
severity,
|
|
41
42
|
timestamp: new Date().toISOString(),
|
|
42
43
|
};
|
|
43
44
|
if (this.mcpProxyMode === 'daemon') {
|
|
44
45
|
const eventPayload = {
|
|
45
|
-
|
|
46
|
+
// `tool_redacted` was declared in EventKind and collapsed to
|
|
47
|
+
// `tool_allowed` here since the type existed — a redaction the audit
|
|
48
|
+
// trail recorded as a plain allow. The kind passes through as itself.
|
|
49
|
+
event: kind,
|
|
46
50
|
toolName,
|
|
47
51
|
workspaceId: this.workspaceId,
|
|
48
52
|
harnessType: 'mcp-governance-proxy',
|
|
49
53
|
timestamp: event.timestamp,
|
|
50
54
|
reason,
|
|
55
|
+
severity,
|
|
51
56
|
toolInput,
|
|
52
57
|
};
|
|
53
58
|
callDaemonSocket('telemetry.enqueue', eventPayload).then(() => {
|
|
@@ -74,18 +79,26 @@ export class GovernanceEmitter {
|
|
|
74
79
|
const payload = JSON.stringify({
|
|
75
80
|
events: [
|
|
76
81
|
{
|
|
77
|
-
|
|
82
|
+
// Same collapse as the daemon path had: the kind IS the event.
|
|
83
|
+
event: event.kind,
|
|
78
84
|
toolName: event.toolName,
|
|
79
85
|
toolInput: event.toolInput,
|
|
80
86
|
workspaceId: event.workspaceId,
|
|
81
87
|
harnessType: event.harnessType,
|
|
82
88
|
incidentId: event.incidentId,
|
|
83
89
|
reason: event.reason,
|
|
90
|
+
severity: event.severity,
|
|
84
91
|
timestamp: event.timestamp,
|
|
85
92
|
},
|
|
86
93
|
],
|
|
87
94
|
});
|
|
88
|
-
|
|
95
|
+
// POST /api/v1/hook-events — the batch governance-event ingest whose
|
|
96
|
+
// BatchHookEventsSchema this payload already matches exactly. Path A used
|
|
97
|
+
// to post to /api/v1/telemetry/enqueue, an endpoint that never existed in
|
|
98
|
+
// the control plane; because httpPost resolved on any response, every
|
|
99
|
+
// tool_allowed/tool_blocked event 404'd silently and the 'Path A failed'
|
|
100
|
+
// warning never fired.
|
|
101
|
+
const url = `${this.controlPlaneUrl}/api/v1/hook-events`;
|
|
89
102
|
await httpPost(url, this.apiKey, payload);
|
|
90
103
|
}
|
|
91
104
|
async appendToFile(event) {
|
|
@@ -110,7 +123,16 @@ function httpPost(url, apiKey, body) {
|
|
|
110
123
|
}, (res) => {
|
|
111
124
|
// Drain response body to free socket
|
|
112
125
|
res.resume();
|
|
113
|
-
res.on('end',
|
|
126
|
+
res.on('end', () => {
|
|
127
|
+
// Reject on error statuses so a wrong or removed endpoint surfaces as
|
|
128
|
+
// a caller-visible failure instead of silently succeeding.
|
|
129
|
+
const status = res.statusCode ?? 0;
|
|
130
|
+
if (status >= 400) {
|
|
131
|
+
reject(new Error(`HTTP POST ${url} returned ${status}`));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
resolve();
|
|
135
|
+
});
|
|
114
136
|
});
|
|
115
137
|
req.on('error', reject);
|
|
116
138
|
req.on('timeout', () => { req.destroy(); reject(new Error('HTTP POST timed out')); });
|
package/dist/emitter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,UAAU,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AACtC,OAAO,KAAK,WAAW,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEpD,MAAM,GAAG,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { loadConfig } from './config.js';
|
|
24
24
|
import { McpGovernanceProxy } from './proxy.js';
|
|
25
|
+
import { runRemoteProxy } from './remoteBridge.js';
|
|
25
26
|
import { createStderrLogger as createLogger } from './stderrLog.js';
|
|
26
27
|
const log = createLogger('mcp-proxy-main');
|
|
27
28
|
async function main() {
|
|
@@ -34,9 +35,19 @@ async function main() {
|
|
|
34
35
|
process.stderr.write(`[intutic-mcp-proxy] Configuration error: ${err.message}\n`);
|
|
35
36
|
process.exit(1);
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
// Remote (HTTP/SSE) bridge mode, from `--remote-url` — see remoteBridge.ts.
|
|
39
|
+
// Shares the SAME proxy_fatal/exit(1) catch below as stdio proxy mode
|
|
40
|
+
// rather than a second error surface, so a remote connect failure and a
|
|
41
|
+
// "spawned stdio command doesn't exist" failure look identical to whatever
|
|
42
|
+
// is watching this process's stderr/exit code.
|
|
38
43
|
try {
|
|
39
|
-
|
|
44
|
+
if (config.remoteUrl !== undefined) {
|
|
45
|
+
await runRemoteProxy(config);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const proxy = new McpGovernanceProxy(config);
|
|
49
|
+
await proxy.run();
|
|
50
|
+
}
|
|
40
51
|
}
|
|
41
52
|
catch (err) {
|
|
42
53
|
log.error({ action: 'proxy_fatal', err: err.message }, 'Proxy exited with error');
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEnE,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAA;AAE1C,KAAK,UAAU,IAAI;IACjB,IAAI,MAAM,CAAA;IACV,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iCAAiC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA6C,GAAa,CAAC,OAAO,IAAI,CAAC,CAAA;QAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,kBAAkB,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEnE,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAA;AAE1C,KAAK,UAAU,IAAI;IACjB,IAAI,MAAM,CAAA;IACV,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iCAAiC;QACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA6C,GAAa,CAAC,OAAO,IAAI,CAAC,CAAA;QAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,4EAA4E;IAC5E,sEAAsE;IACtE,wEAAwE;IACxE,2EAA2E;IAC3E,+CAA+C;IAC/C,IAAI,CAAC;QACH,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACnC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAA;QAC9B,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;YAC5C,MAAM,KAAK,CAAC,GAAG,EAAE,CAAA;QACnB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,EAAG,GAAa,CAAC,OAAO,EAAE,EAAE,yBAAyB,CAAC,CAAA;QAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|