e-arveldaja-mcp 0.12.2 → 0.12.3
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/CHANGELOG.md +5 -0
- package/dist/progress.d.ts.map +1 -1
- package/dist/progress.js +32 -0
- package/dist/progress.js.map +1 -1
- package/package.json +1 -1
- package/server.json +9 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.12.3] - 2026-04-26
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Long-running tools crashed the Claude Code MCP transport with "Received a progress notification for an unknown token"** — call sites in `camt-import`, `bank-reconciliation`, `receipt-inbox`, `wise-import`, `analyze-unconfirmed`, `lightyear-investments`, and `api/base-resource` invoked `reportProgress` once per item across loops of 50–69+ entries. Each emit was awaited but landed in the OS stdio buffer; on slow clients the response was matched and the progressToken handler cleared *before* the trailing notifications were drained, and Claude Code treats any "unknown token" progress notification as a fatal transport error (closes the stdio pipe; the user must reconnect via `/mcp`). `reportProgress` now (a) throttles to at most one notification per 100 ms within an invocation, (b) skips the trailing `progress >= total` emit since the response itself signals completion, and (c) honors a `EARVELDAJA_DISABLE_PROGRESS=1` env-var kill switch for environments still affected. Throttle state is per-invocation (WeakMap keyed by the SDK's tool extra), so concurrent tool calls and back-to-back invocations never share a window.
|
|
9
|
+
|
|
5
10
|
## [0.12.2] - 2026-04-26
|
|
6
11
|
|
|
7
12
|
### Fixed
|
package/dist/progress.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,eAAO,MAAM,gBAAgB,8BAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,eAAO,MAAM,gBAAgB,8BAAqC,CAAC;AAyBnE;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BpF"}
|
package/dist/progress.js
CHANGED
|
@@ -1,16 +1,48 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
export const toolExtraStorage = new AsyncLocalStorage();
|
|
3
|
+
/**
|
|
4
|
+
* Minimum interval between emitted progress notifications within a single
|
|
5
|
+
* tool invocation. Tight per-item loops (50 CAMT entries, 69 reconcile rows,
|
|
6
|
+
* etc.) would otherwise flood the stdio transport. Any notification that
|
|
7
|
+
* arrives at the client *after* the tool's response is matched gets dropped
|
|
8
|
+
* with "Received a progress notification for an unknown token" — and on
|
|
9
|
+
* Claude Code that drop is fatal: the transport is closed and the server
|
|
10
|
+
* must be reconnected. Throttling cuts the volume and shrinks the race
|
|
11
|
+
* window; the trailing 100% emit is also skipped because the response itself
|
|
12
|
+
* already signals completion.
|
|
13
|
+
*
|
|
14
|
+
* Set EARVELDAJA_DISABLE_PROGRESS=1 to disable progress entirely on clients
|
|
15
|
+
* that still mishandle late-arriving events.
|
|
16
|
+
*/
|
|
17
|
+
const PROGRESS_THROTTLE_MS = 100;
|
|
18
|
+
const lastEmitByExtra = new WeakMap();
|
|
19
|
+
function progressDisabled() {
|
|
20
|
+
const v = process.env.EARVELDAJA_DISABLE_PROGRESS;
|
|
21
|
+
return v === "1" || v === "true";
|
|
22
|
+
}
|
|
3
23
|
/**
|
|
4
24
|
* Report progress for long-running operations.
|
|
5
25
|
* No-op if the client didn't supply a progress token.
|
|
6
26
|
*/
|
|
7
27
|
export async function reportProgress(progress, total) {
|
|
28
|
+
if (progressDisabled())
|
|
29
|
+
return;
|
|
8
30
|
const extra = toolExtraStorage.getStore();
|
|
9
31
|
if (!extra)
|
|
10
32
|
return;
|
|
11
33
|
const progressToken = extra?._meta?.progressToken;
|
|
12
34
|
if (progressToken === undefined)
|
|
13
35
|
return;
|
|
36
|
+
// Skip the trailing 100% notification: the response signals completion,
|
|
37
|
+
// and the final emit is the most likely to lose the race against it.
|
|
38
|
+
if (total !== undefined && progress >= total)
|
|
39
|
+
return;
|
|
40
|
+
// Throttle within an invocation: at most one notification per window.
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
const last = lastEmitByExtra.get(extra) ?? 0;
|
|
43
|
+
if (now - last < PROGRESS_THROTTLE_MS)
|
|
44
|
+
return;
|
|
45
|
+
lastEmitByExtra.set(extra, now);
|
|
14
46
|
try {
|
|
15
47
|
await extra.sendNotification({
|
|
16
48
|
method: "notifications/progress",
|
package/dist/progress.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,iBAAiB,EAAa,CAAC;AAEnE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,KAAc;IACnE,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC;IAC1C,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,aAAa,GAAG,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC;IAClD,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,iBAAiB,EAAa,CAAC;AAEnE;;;;;;;;;;;;;GAaG;AACH,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,MAAM,eAAe,GAAG,IAAI,OAAO,EAAqB,CAAC;AAEzD,SAAS,gBAAgB;IACvB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;IAClD,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,MAAM,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,KAAc;IACnE,IAAI,gBAAgB,EAAE;QAAE,OAAO;IAC/B,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC;IAC1C,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,aAAa,GAAG,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC;IAClD,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO;IAExC,wEAAwE;IACxE,qEAAqE;IACrE,IAAI,KAAK,KAAK,SAAS,IAAI,QAAQ,IAAI,KAAK;QAAE,OAAO;IAErD,sEAAsE;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,GAAG,GAAG,IAAI,GAAG,oBAAoB;QAAE,OAAO;IAC9C,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,gBAAgB,CAAC;YAC3B,MAAM,EAAE,wBAAwB;YAChC,MAAM,EAAE;gBACN,aAAa;gBACb,QAAQ;gBACR,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC;aACtC;SACF,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;IAC7C,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/iseppo/e-arveldaja-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.12.
|
|
9
|
+
"version": "0.12.3",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "e-arveldaja-mcp",
|
|
14
|
-
"version": "0.12.
|
|
14
|
+
"version": "0.12.3",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
|
@@ -51,6 +51,13 @@
|
|
|
51
51
|
"isRequired": false,
|
|
52
52
|
"isSecret": false,
|
|
53
53
|
"format": "string"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "EARVELDAJA_DISABLE_PROGRESS",
|
|
57
|
+
"description": "Set to \"1\" or \"true\" to disable MCP progress notifications. Workaround for clients that close the stdio transport when a progress notification arrives after the matching response has been processed.",
|
|
58
|
+
"isRequired": false,
|
|
59
|
+
"isSecret": false,
|
|
60
|
+
"format": "string"
|
|
54
61
|
}
|
|
55
62
|
]
|
|
56
63
|
}
|