@mattral/collector 1.0.0 → 1.1.0

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 ADDED
@@ -0,0 +1,32 @@
1
+ # @mattral/collector
2
+
3
+ Health checking and traffic-observing proxy collectors for MCP servers —
4
+ the data-collection layer of [mcp-reliable](https://www.npmjs.com/package/mcp-reliable).
5
+
6
+ ```bash
7
+ npm install @mattral/collector
8
+ ```
9
+
10
+ ## What's in it
11
+
12
+ - **`HealthChecker`** — periodic reachability + latency checks against a
13
+ registered server (`initialize` handshake + `tools/list`), with a
14
+ configurable connection timeout.
15
+ - **`StdioProxyCollector`** — sits transparently between a real MCP client
16
+ and a real stdio server, forwarding every message unmodified while
17
+ recording each execution and running drift detection (schema,
18
+ output-shape, statistical/latency) against real traffic.
19
+ - **`extractOutputPayload`** / **`extractErrorMessage`** — correctly
20
+ unwrap MCP's `content` block convention to get at a tool's actual output
21
+ or error text, instead of the transport-level envelope around it.
22
+
23
+ ## Learn more
24
+
25
+ See the [mcp-reliable GitHub repo](https://github.com/Mattral/mcp-reliable),
26
+ particularly `docs/architecture.md` for how health checks and the proxy
27
+ each observe a server differently, and `docs/decisions/` for the
28
+ reasoning behind the extraction helpers above.
29
+
30
+ ## License
31
+
32
+ MIT
@@ -0,0 +1,28 @@
1
+ import type { JsonRpcMessage } from "./json-rpc-framer.js";
2
+ /**
3
+ * Extracts a human-readable error message from a raw MCP `tools/call`
4
+ * response, for both kinds of failure the protocol allows:
5
+ *
6
+ * - **Protocol-level failures**: the JSON-RPC response has an `error`
7
+ * object (e.g. a malformed request, a transport-level failure). Its
8
+ * `.message` is already the right text — nothing to unwrap.
9
+ * - **Tool-level failures**: the JSON-RPC response is a normal `result`
10
+ * with `isError: true`, and the actual, tool-specific error description
11
+ * lives in `result.content` as ordinary text blocks — this is the MCP
12
+ * spec's convention for a tool reporting its *own* failure without it
13
+ * being treated as a transport-level protocol error (this project's own
14
+ * reference server's `flaky` tool does exactly this).
15
+ *
16
+ * Before this function existed, every tool-level failure's real error
17
+ * text was discarded in favor of one generic placeholder string,
18
+ * regardless of what the tool actually said — the same underlying mistake
19
+ * as the pre-`extractOutputPayload` output-shape bug (see
20
+ * docs/decisions/0015-statistical-drift-detection.md): treating MCP's
21
+ * `content` array as opaque instead of reading what's actually inside it.
22
+ * See docs/decisions/0016-error-classification.md.
23
+ *
24
+ * Falls back to a generic placeholder only when there's truly no error
25
+ * object and no text content to describe the failure at all.
26
+ */
27
+ export declare function extractErrorMessage(message: JsonRpcMessage): string;
28
+ //# sourceMappingURL=error-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-message.d.ts","sourceRoot":"","sources":["../src/error-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAkBnE"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Extracts a human-readable error message from a raw MCP `tools/call`
3
+ * response, for both kinds of failure the protocol allows:
4
+ *
5
+ * - **Protocol-level failures**: the JSON-RPC response has an `error`
6
+ * object (e.g. a malformed request, a transport-level failure). Its
7
+ * `.message` is already the right text — nothing to unwrap.
8
+ * - **Tool-level failures**: the JSON-RPC response is a normal `result`
9
+ * with `isError: true`, and the actual, tool-specific error description
10
+ * lives in `result.content` as ordinary text blocks — this is the MCP
11
+ * spec's convention for a tool reporting its *own* failure without it
12
+ * being treated as a transport-level protocol error (this project's own
13
+ * reference server's `flaky` tool does exactly this).
14
+ *
15
+ * Before this function existed, every tool-level failure's real error
16
+ * text was discarded in favor of one generic placeholder string,
17
+ * regardless of what the tool actually said — the same underlying mistake
18
+ * as the pre-`extractOutputPayload` output-shape bug (see
19
+ * docs/decisions/0015-statistical-drift-detection.md): treating MCP's
20
+ * `content` array as opaque instead of reading what's actually inside it.
21
+ * See docs/decisions/0016-error-classification.md.
22
+ *
23
+ * Falls back to a generic placeholder only when there's truly no error
24
+ * object and no text content to describe the failure at all.
25
+ */
26
+ export function extractErrorMessage(message) {
27
+ if (message.error?.message)
28
+ return message.error.message;
29
+ const content = message.result?.content;
30
+ if (Array.isArray(content)) {
31
+ const texts = content
32
+ .filter((block) => typeof block === "object" &&
33
+ block !== null &&
34
+ block.type === "text" &&
35
+ typeof block.text === "string")
36
+ .map((block) => block.text);
37
+ if (texts.length > 0)
38
+ return texts.join(" ");
39
+ }
40
+ return "Tool call returned isError: true, with no error text or content to describe why.";
41
+ }
42
+ //# sourceMappingURL=error-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-message.js","sourceRoot":"","sources":["../src/error-message.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAuB;IACzD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IAEzD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,OAAO;aAClB,MAAM,CACL,CAAC,KAAK,EAA2C,EAAE,CACjD,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACb,KAA4B,CAAC,IAAI,KAAK,MAAM;YAC7C,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ,CACzD;aACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,kFAAkF,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Extracts the "meaningful" structured payload from a raw MCP
3
+ * `tools/call` result, for output-shape drift detection to actually be
4
+ * useful against it.
5
+ *
6
+ * Naively hashing `result.content` itself is close to useless for the
7
+ * extremely common case where a tool returns its real structured data as
8
+ * JSON text inside a single content block — `content: [{ type: "text",
9
+ * text: "{...}" }]` has the exact same `[{type, text}]` shape whether the
10
+ * embedded JSON is `{"message": "..."}` or `{"echoed": "...", "respondedAt":
11
+ * "..."}`. A structural hash of the wrapper alone would never notice the
12
+ * tool's actual output changed underneath it — this is exactly what this
13
+ * project's own reference server does (see
14
+ * `examples/reference-mcp-server/src/index.ts`), and what a great many
15
+ * real-world MCP tools do too, for any tool that doesn't declare a formal
16
+ * `outputSchema`. This function unwraps that, so what gets fingerprinted
17
+ * is the real payload, not MCP's transport-level envelope around it.
18
+ *
19
+ * Precedence:
20
+ * 1. `structuredContent`, if the tool declared an output schema and the
21
+ * SDK populated it — already a real object, nothing to unwrap.
22
+ * 2. A single text content block that parses as JSON — the common
23
+ * "structured data serialized as text" convention.
24
+ * 3. Otherwise, the raw `content` array as-is — still useful: catches a
25
+ * tool switching between text/image/resource blocks, or adding/
26
+ * removing blocks, even without parseable JSON inside them.
27
+ * 4. If there's no `content` or `structuredContent` at all, the raw
28
+ * result object, matching how this was computed before this function
29
+ * existed (see docs/decisions/0015-statistical-drift-detection.md).
30
+ */
31
+ export declare function extractOutputPayload(result: unknown): unknown;
32
+ //# sourceMappingURL=output-payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-payload.d.ts","sourceRoot":"","sources":["../src/output-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAsB7D"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Extracts the "meaningful" structured payload from a raw MCP
3
+ * `tools/call` result, for output-shape drift detection to actually be
4
+ * useful against it.
5
+ *
6
+ * Naively hashing `result.content` itself is close to useless for the
7
+ * extremely common case where a tool returns its real structured data as
8
+ * JSON text inside a single content block — `content: [{ type: "text",
9
+ * text: "{...}" }]` has the exact same `[{type, text}]` shape whether the
10
+ * embedded JSON is `{"message": "..."}` or `{"echoed": "...", "respondedAt":
11
+ * "..."}`. A structural hash of the wrapper alone would never notice the
12
+ * tool's actual output changed underneath it — this is exactly what this
13
+ * project's own reference server does (see
14
+ * `examples/reference-mcp-server/src/index.ts`), and what a great many
15
+ * real-world MCP tools do too, for any tool that doesn't declare a formal
16
+ * `outputSchema`. This function unwraps that, so what gets fingerprinted
17
+ * is the real payload, not MCP's transport-level envelope around it.
18
+ *
19
+ * Precedence:
20
+ * 1. `structuredContent`, if the tool declared an output schema and the
21
+ * SDK populated it — already a real object, nothing to unwrap.
22
+ * 2. A single text content block that parses as JSON — the common
23
+ * "structured data serialized as text" convention.
24
+ * 3. Otherwise, the raw `content` array as-is — still useful: catches a
25
+ * tool switching between text/image/resource blocks, or adding/
26
+ * removing blocks, even without parseable JSON inside them.
27
+ * 4. If there's no `content` or `structuredContent` at all, the raw
28
+ * result object, matching how this was computed before this function
29
+ * existed (see docs/decisions/0015-statistical-drift-detection.md).
30
+ */
31
+ export function extractOutputPayload(result) {
32
+ if (result === null || typeof result !== "object")
33
+ return result;
34
+ const r = result;
35
+ if (r.structuredContent !== undefined)
36
+ return r.structuredContent;
37
+ if (Array.isArray(r.content)) {
38
+ if (r.content.length === 1) {
39
+ const block = r.content[0];
40
+ if (block?.type === "text" && typeof block.text === "string") {
41
+ try {
42
+ return JSON.parse(block.text);
43
+ }
44
+ catch {
45
+ // Not JSON - a genuine plain-text result. Fall through to
46
+ // hashing the content array itself.
47
+ }
48
+ }
49
+ }
50
+ return r.content;
51
+ }
52
+ return result;
53
+ }
54
+ //# sourceMappingURL=output-payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-payload.js","sourceRoot":"","sources":["../src/output-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAClD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IACjE,MAAM,CAAC,GAAG,MAA4D,CAAC;IAEvE,IAAI,CAAC,CAAC,iBAAiB,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC,iBAAiB,CAAC;IAElE,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAqC,CAAC;YAC/D,IAAI,KAAK,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7D,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChC,CAAC;gBAAC,MAAM,CAAC;oBACP,0DAA0D;oBAC1D,oCAAoC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC,OAAO,CAAC;IACnB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -15,6 +15,24 @@ export interface StdioProxyCollectorOptions {
15
15
  input?: NodeJS.ReadableStream;
16
16
  /** Stream carrying traffic TO the real client (defaults to this process's stdout). */
17
17
  output?: NodeJS.WritableStream;
18
+ /**
19
+ * How many executions of the *same tool* to accumulate between
20
+ * window-based drift checks (output-shape and statistical/latency).
21
+ * Unlike schema drift (an O(1) fingerprint compare, checked on every
22
+ * `tools/list`), these compare whole windows of stored executions —
23
+ * running that on literally every single call would mean a store query
24
+ * plus a KS test per call on hot paths. Default 10: frequent enough that
25
+ * drift is caught within a handful of seconds of typical traffic, cheap
26
+ * enough not to matter. See docs/decisions/0015-statistical-drift-detection.md.
27
+ */
28
+ driftCheckIntervalCalls?: number;
29
+ /**
30
+ * Size of each of the two (baseline, recent) windows compared for
31
+ * window-based drift. Default 20, matching `detectLatencyDrift`'s own
32
+ * default `minSampleSize` — there's no point fetching a bigger window
33
+ * than the detector needs.
34
+ */
35
+ driftWindowSize?: number;
18
36
  }
19
37
  /**
20
38
  * A transparent stdio proxy that sits between an MCP client (an agent) and
@@ -33,9 +51,12 @@ export interface StdioProxyCollectorOptions {
33
51
  */
34
52
  export declare class StdioProxyCollector {
35
53
  private readonly options;
54
+ private readonly driftCheckIntervalCalls;
55
+ private readonly driftWindowSize;
36
56
  private child;
37
57
  private readonly pendingCalls;
38
58
  private readonly pendingListRequests;
59
+ private readonly callCountByTool;
39
60
  constructor(options: StdioProxyCollectorOptions);
40
61
  /**
41
62
  * Starts the child process and begins forwarding traffic. Resolves with
@@ -47,6 +68,16 @@ export declare class StdioProxyCollector {
47
68
  private handleDownstreamMessage;
48
69
  private handleUpstreamMessage;
49
70
  private recordCallExecution;
71
+ private recordDrift;
72
+ /**
73
+ * Every `driftCheckIntervalCalls` calls to a given tool, pulls its last
74
+ * two `driftWindowSize`-execution windows and runs the window-based
75
+ * drift detectors (output-shape, latency) against them. Schema drift is
76
+ * handled separately in `recordToolsListResult` — it's a per-fingerprint
77
+ * compare, not a window comparison, so it runs on every `tools/list`
78
+ * instead of being throttled here.
79
+ */
80
+ private maybeCheckWindowDrift;
50
81
  private recordToolsListResult;
51
82
  }
52
83
  //# sourceMappingURL=proxy-collector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-collector.d.ts","sourceRoot":"","sources":["../src/proxy-collector.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,SAAS,EAEf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IAC7C,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;AAoBD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2C;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA8B;gBAEtD,OAAO,EAAE,0BAA0B;IAI/C;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA+CzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,qBAAqB;CAiC9B"}
1
+ {"version":3,"file":"proxy-collector.d.ts","sourceRoot":"","sources":["../src/proxy-collector.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,UAAU,EACf,KAAK,SAAS,EAEf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKzD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IAC7C,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAoBD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2C;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA8B;IAClE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;gBAEjD,OAAO,EAAE,0BAA0B;IAM/C;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA+CzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,WAAW;IAKnB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAsC7B,OAAO,CAAC,qBAAqB;CAgC9B"}
@@ -1,7 +1,9 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { randomUUID } from "node:crypto";
3
- import { computeOutputSignature, computeSchemaFingerprint, detectSchemaDrift } from "@mattral/core";
3
+ import { computeOutputSignature, computeSchemaFingerprint, detectLatencyDrift, detectOutputShapeDrift, detectSchemaDrift } from "@mattral/core";
4
4
  import { JsonRpcFramer } from "./json-rpc-framer.js";
5
+ import { extractErrorMessage } from "./error-message.js";
6
+ import { extractOutputPayload } from "./output-payload.js";
5
7
  function isToolsListResult(value) {
6
8
  return (typeof value === "object" &&
7
9
  value !== null &&
@@ -24,11 +26,16 @@ function isToolsListResult(value) {
24
26
  */
25
27
  export class StdioProxyCollector {
26
28
  options;
29
+ driftCheckIntervalCalls;
30
+ driftWindowSize;
27
31
  child;
28
32
  pendingCalls = new Map();
29
33
  pendingListRequests = new Set();
34
+ callCountByTool = new Map();
30
35
  constructor(options) {
31
36
  this.options = options;
37
+ this.driftCheckIntervalCalls = options.driftCheckIntervalCalls ?? 10;
38
+ this.driftWindowSize = options.driftWindowSize ?? 20;
32
39
  }
33
40
  /**
34
41
  * Starts the child process and begins forwarding traffic. Resolves with
@@ -102,12 +109,11 @@ export class StdioProxyCollector {
102
109
  }
103
110
  }
104
111
  recordCallExecution(pending, message) {
105
- const durationMs = Date.now() - pending.startedAt;
112
+ const now = Date.now();
113
+ const durationMs = now - pending.startedAt;
106
114
  const isError = Boolean(message.error) || Boolean(message.result?.isError);
107
115
  const outputBytes = message.result !== undefined ? Buffer.byteLength(JSON.stringify(message.result), "utf8") : undefined;
108
- const outputSignature = !isError && message.result !== undefined
109
- ? computeOutputSignature(message.result.content ?? message.result)
110
- : undefined;
116
+ const outputSignature = !isError && message.result !== undefined ? computeOutputSignature(extractOutputPayload(message.result)) : undefined;
111
117
  const execution = {
112
118
  id: randomUUID(),
113
119
  serverId: this.options.serverId,
@@ -115,7 +121,7 @@ export class StdioProxyCollector {
115
121
  startedAt: pending.startedAt,
116
122
  durationMs,
117
123
  success: !isError,
118
- errorMessage: isError ? message.error?.message ?? "Tool call returned isError: true" : undefined,
124
+ errorMessage: isError ? extractErrorMessage(message) : undefined,
119
125
  outputSignature,
120
126
  inputBytes: pending.inputBytes,
121
127
  outputBytes,
@@ -123,6 +129,56 @@ export class StdioProxyCollector {
123
129
  };
124
130
  this.options.store.recordExecution(execution);
125
131
  this.options.onExecution?.(execution);
132
+ this.maybeCheckWindowDrift(pending.toolName, now);
133
+ }
134
+ recordDrift(drift) {
135
+ this.options.store.recordDriftEvent(drift);
136
+ this.options.onDrift?.(drift);
137
+ }
138
+ /**
139
+ * Every `driftCheckIntervalCalls` calls to a given tool, pulls its last
140
+ * two `driftWindowSize`-execution windows and runs the window-based
141
+ * drift detectors (output-shape, latency) against them. Schema drift is
142
+ * handled separately in `recordToolsListResult` — it's a per-fingerprint
143
+ * compare, not a window comparison, so it runs on every `tools/list`
144
+ * instead of being throttled here.
145
+ */
146
+ maybeCheckWindowDrift(toolName, now) {
147
+ const count = (this.callCountByTool.get(toolName) ?? 0) + 1;
148
+ this.callCountByTool.set(toolName, count);
149
+ if (count % this.driftCheckIntervalCalls !== 0)
150
+ return;
151
+ const windowSize = this.driftWindowSize;
152
+ // Most-recent-first (see SqliteStore#listExecutions): the first half is
153
+ // the "recent" window, the second half the "baseline" it's compared
154
+ // against.
155
+ const executions = this.options.store.listExecutions({
156
+ serverId: this.options.serverId,
157
+ toolName,
158
+ limit: windowSize * 2
159
+ });
160
+ if (executions.length < windowSize * 2)
161
+ return;
162
+ const recent = executions.slice(0, windowSize);
163
+ const baseline = executions.slice(windowSize, windowSize * 2);
164
+ const shapeDrift = detectOutputShapeDrift({
165
+ serverId: this.options.serverId,
166
+ toolName,
167
+ baseline,
168
+ recent,
169
+ now
170
+ });
171
+ if (shapeDrift)
172
+ this.recordDrift(shapeDrift);
173
+ const latencyDrift = detectLatencyDrift({
174
+ serverId: this.options.serverId,
175
+ toolName,
176
+ baseline,
177
+ recent,
178
+ now
179
+ });
180
+ if (latencyDrift)
181
+ this.recordDrift(latencyDrift);
126
182
  }
127
183
  recordToolsListResult(result) {
128
184
  const now = Date.now();
@@ -139,8 +195,7 @@ export class StdioProxyCollector {
139
195
  now
140
196
  });
141
197
  if (drift) {
142
- this.options.store.recordDriftEvent(drift);
143
- this.options.onDrift?.(drift);
198
+ this.recordDrift(drift);
144
199
  }
145
200
  const toolRecord = {
146
201
  id: existing?.id ?? randomUUID(),
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-collector.js","sourceRoot":"","sources":["../src/proxy-collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy-collector.js","sourceRoot":"","sources":["../src/proxy-collector.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mattral/collector",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Health checking and traffic-observing proxy collectors for MCP servers",
5
5
  "type": "module",
6
6
  "license": "MIT",