@alfe.ai/ctrader-mcp 0.3.6 → 0.3.7
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/server.js +27 -9
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -591,23 +591,41 @@ var CTraderError = class extends Error {
|
|
|
591
591
|
* execution events for other sessions, …).
|
|
592
592
|
*/
|
|
593
593
|
const LISTENABLE_EVENTS = new Set([PayloadType.OA_DEPTH_EVENT, PayloadType.OA_SPOT_EVENT]);
|
|
594
|
-
|
|
594
|
+
/**
|
|
595
|
+
* Halved from 10s so the read-idle watchdog can detect a wedged socket before
|
|
596
|
+
* `REQUEST_TIMEOUT_MS` fires, while still tolerating two consecutive missed
|
|
597
|
+
* echoes (see `READ_IDLE_TIMEOUT_MS`). cTrader expects a heartbeat at least
|
|
598
|
+
* every 10s and drops an idle connection at ~30s, so 5s is well within
|
|
599
|
+
* protocol expectations. Heartbeats are protocol keepalives, not part of the
|
|
600
|
+
* historical-data payload class that gets rate limited.
|
|
601
|
+
*/
|
|
602
|
+
const HEARTBEAT_INTERVAL_MS = 5e3;
|
|
595
603
|
const REQUEST_TIMEOUT_MS = 2e4;
|
|
596
604
|
const RECONNECT_BASE_MS = 1e3;
|
|
597
605
|
const RECONNECT_MAX_MS = 3e4;
|
|
598
606
|
const MAX_PENDING_REQUESTS = 256;
|
|
599
607
|
/**
|
|
600
|
-
* Read-idle watchdog: cTrader echoes our
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
* heartbeat echo doesn't false-positive.
|
|
608
|
+
* Read-idle watchdog: cTrader echoes our heartbeats and pushes its own traffic,
|
|
609
|
+
* so a *healthy* socket is never silent for long. If NO inbound byte arrives
|
|
610
|
+
* for this long we treat the socket as silently half-dead (a TCP half-open with
|
|
611
|
+
* no FIN — the OS never fires `close`, so `handleDrop` never runs and every
|
|
612
|
+
* request would otherwise time out indefinitely) and force a reconnect. Set to
|
|
613
|
+
* 3× the heartbeat interval so two dropped heartbeat echoes don't false-positive.
|
|
607
614
|
*/
|
|
608
615
|
const READ_IDLE_TIMEOUT_MS = 3 * HEARTBEAT_INTERVAL_MS;
|
|
609
616
|
/** How often the watchdog checks the read-idle clock. */
|
|
610
|
-
const WATCHDOG_INTERVAL_MS = HEARTBEAT_INTERVAL_MS;
|
|
617
|
+
const WATCHDOG_INTERVAL_MS = HEARTBEAT_INTERVAL_MS / 2;
|
|
618
|
+
/**
|
|
619
|
+
* Detection must beat the request timeout, or the watchdog is useless to the
|
|
620
|
+
* caller that trips it: a wedged socket surfaces an ambiguous `REQUEST_TIMEOUT`
|
|
621
|
+
* (indistinguishable from a slow server) instead of the fast, honest,
|
|
622
|
+
* retryable `CONNECTION_DROPPED` the reconnect path exists to produce.
|
|
623
|
+
*
|
|
624
|
+
* That was the shipped state — 30s idle + 10s poll = up to 40s to detect, vs a
|
|
625
|
+
* 20s request timeout — so the 0.3.1 watchdog never spared the first caller.
|
|
626
|
+
* Worst-case detection is READ_IDLE_TIMEOUT_MS + WATCHDOG_INTERVAL_MS.
|
|
627
|
+
*/
|
|
628
|
+
if (READ_IDLE_TIMEOUT_MS + WATCHDOG_INTERVAL_MS >= REQUEST_TIMEOUT_MS) throw new Error(`ctrader-mcp timing misconfigured: read-idle detection (${String(READ_IDLE_TIMEOUT_MS + WATCHDOG_INTERVAL_MS)}ms) must be faster than REQUEST_TIMEOUT_MS (${String(REQUEST_TIMEOUT_MS)}ms).`);
|
|
611
629
|
function log$1(msg) {
|
|
612
630
|
process.stderr.write(`[ctrader-mcp] ${msg}\n`);
|
|
613
631
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/ctrader-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "cTrader MCP server — full trading (market/limit/stop/stop-limit orders, trailing stops), Level 2 depth, live quotes, trade history, PnL & margin over the cTrader Open API (protobuf/TLS)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/server.js",
|