fixparser-plugin-mcp 9.1.7-bfafe1e3 → 9.1.7-c213f7c6

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.
@@ -1,9 +1,51 @@
1
1
  // src/MCPLocal.ts
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { Fields as Fields3, MDEntryType as MDEntryType2, Messages as Messages3 } from "fixparser";
5
4
  import { z } from "zod";
6
5
 
6
+ // src/MCPBase.ts
7
+ var MCPBase = class {
8
+ /**
9
+ * Optional logger instance for diagnostics and output.
10
+ * @protected
11
+ */
12
+ logger;
13
+ /**
14
+ * FIXParser instance, set during plugin register().
15
+ * @protected
16
+ */
17
+ parser;
18
+ /**
19
+ * Called when server is setup and listening.
20
+ * @protected
21
+ */
22
+ onReady = void 0;
23
+ /**
24
+ * Map to store verified orders before execution
25
+ * @protected
26
+ */
27
+ verifiedOrders = /* @__PURE__ */ new Map();
28
+ /**
29
+ * Map to store pending market data requests
30
+ * @protected
31
+ */
32
+ pendingRequests = /* @__PURE__ */ new Map();
33
+ /**
34
+ * Map to store market data prices
35
+ * @protected
36
+ */
37
+ marketDataPrices = /* @__PURE__ */ new Map();
38
+ /**
39
+ * Maximum number of price history entries to keep per symbol
40
+ * @protected
41
+ */
42
+ MAX_PRICE_HISTORY = 1e5;
43
+ constructor({ logger, onReady }) {
44
+ this.logger = logger;
45
+ this.onReady = onReady;
46
+ }
47
+ };
48
+
7
49
  // src/schemas/schemas.ts
8
50
  var toolSchemas = {
9
51
  parse: {
@@ -87,7 +129,7 @@ var toolSchemas = {
87
129
  }
88
130
  },
89
131
  executeOrder: {
90
- description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
132
+ description: "Executes a verified order. verifyOrder must be called before executeOrder.",
91
133
  schema: {
92
134
  type: "object",
93
135
  properties: {
@@ -243,7 +285,52 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
243
285
  const response = new Promise((resolve) => {
244
286
  pendingRequests.set(args.mdReqID, resolve);
245
287
  });
246
- const entryTypes = args.mdEntryTypes || [MDEntryType.Bid, MDEntryType.Offer, MDEntryType.TradeVolume];
288
+ const entryTypes = args.mdEntryTypes || [
289
+ MDEntryType.Bid,
290
+ MDEntryType.Offer,
291
+ MDEntryType.Trade,
292
+ MDEntryType.IndexValue,
293
+ MDEntryType.OpeningPrice,
294
+ MDEntryType.ClosingPrice,
295
+ MDEntryType.SettlementPrice,
296
+ MDEntryType.TradingSessionHighPrice,
297
+ MDEntryType.TradingSessionLowPrice,
298
+ MDEntryType.VWAP,
299
+ MDEntryType.Imbalance,
300
+ MDEntryType.TradeVolume,
301
+ MDEntryType.OpenInterest,
302
+ MDEntryType.CompositeUnderlyingPrice,
303
+ MDEntryType.SimulatedSellPrice,
304
+ MDEntryType.SimulatedBuyPrice,
305
+ MDEntryType.MarginRate,
306
+ MDEntryType.MidPrice,
307
+ MDEntryType.EmptyBook,
308
+ MDEntryType.SettleHighPrice,
309
+ MDEntryType.SettleLowPrice,
310
+ MDEntryType.PriorSettlePrice,
311
+ MDEntryType.SessionHighBid,
312
+ MDEntryType.SessionLowOffer,
313
+ MDEntryType.EarlyPrices,
314
+ MDEntryType.AuctionClearingPrice,
315
+ MDEntryType.SwapValueFactor,
316
+ MDEntryType.DailyValueAdjustmentForLongPositions,
317
+ MDEntryType.CumulativeValueAdjustmentForLongPositions,
318
+ MDEntryType.DailyValueAdjustmentForShortPositions,
319
+ MDEntryType.CumulativeValueAdjustmentForShortPositions,
320
+ MDEntryType.FixingPrice,
321
+ MDEntryType.CashRate,
322
+ MDEntryType.RecoveryRate,
323
+ MDEntryType.RecoveryRateForLong,
324
+ MDEntryType.RecoveryRateForShort,
325
+ MDEntryType.MarketBid,
326
+ MDEntryType.MarketOffer,
327
+ MDEntryType.ShortSaleMinPrice,
328
+ MDEntryType.PreviousClosingPrice,
329
+ MDEntryType.ThresholdLimitPriceBanding,
330
+ MDEntryType.DailyFinancingValue,
331
+ MDEntryType.AccruedFinancingValue,
332
+ MDEntryType.TWAP
333
+ ];
247
334
  const messageFields = [
248
335
  new Field(Fields.MsgType, Messages.MarketDataRequest),
249
336
  new Field(Fields.SenderCompID, parser.sender),
@@ -318,14 +405,18 @@ var createGetStockGraphHandler = (marketDataPrices) => {
318
405
  };
319
406
  }
320
407
  const chart = new QuickChart();
321
- chart.setWidth(600);
322
- chart.setHeight(300);
408
+ chart.setWidth(1200);
409
+ chart.setHeight(600);
410
+ chart.setBackgroundColor("transparent");
323
411
  const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
324
412
  const bidData = priceHistory.map((point) => point.bid);
325
413
  const offerData = priceHistory.map((point) => point.offer);
326
414
  const spreadData = priceHistory.map((point) => point.spread);
327
415
  const volumeData = priceHistory.map((point) => point.volume);
328
- chart.setConfig({
416
+ const tradeData = priceHistory.map((point) => point.trade);
417
+ const vwapData = priceHistory.map((point) => point.vwap);
418
+ const twapData = priceHistory.map((point) => point.twap);
419
+ const config = {
329
420
  type: "line",
330
421
  data: {
331
422
  labels,
@@ -354,69 +445,67 @@ var createGetStockGraphHandler = (marketDataPrices) => {
354
445
  fill: false,
355
446
  tension: 0.4
356
447
  },
448
+ {
449
+ label: "Trade",
450
+ data: tradeData,
451
+ borderColor: "#ffc107",
452
+ backgroundColor: "rgba(255, 193, 7, 0.1)",
453
+ fill: false,
454
+ tension: 0.4
455
+ },
456
+ {
457
+ label: "VWAP",
458
+ data: vwapData,
459
+ borderColor: "#17a2b8",
460
+ backgroundColor: "rgba(23, 162, 184, 0.1)",
461
+ fill: false,
462
+ tension: 0.4
463
+ },
464
+ {
465
+ label: "TWAP",
466
+ data: twapData,
467
+ borderColor: "#6610f2",
468
+ backgroundColor: "rgba(102, 16, 242, 0.1)",
469
+ fill: false,
470
+ tension: 0.4
471
+ },
357
472
  {
358
473
  label: "Volume",
359
474
  data: volumeData,
360
475
  borderColor: "#007bff",
361
476
  backgroundColor: "rgba(0, 123, 255, 0.1)",
362
477
  fill: true,
363
- tension: 0.4,
364
- yAxisID: "volume"
478
+ tension: 0.4
365
479
  }
366
480
  ]
367
481
  },
368
482
  options: {
483
+ responsive: true,
369
484
  plugins: {
370
485
  title: {
371
486
  display: true,
372
- text: `${symbol} Market Data`,
373
- font: {
374
- size: 16,
375
- weight: "bold"
376
- }
377
- },
378
- legend: {
379
- display: true
487
+ text: `${symbol} Market Data`
380
488
  }
381
489
  },
382
490
  scales: {
383
491
  y: {
384
- beginAtZero: false,
385
- grid: {
386
- color: "#e9ecef"
387
- }
388
- },
389
- volume: {
390
- position: "right",
391
- beginAtZero: true,
392
- grid: {
393
- display: false
394
- }
395
- },
396
- x: {
397
- grid: {
398
- display: false
399
- }
492
+ beginAtZero: false
400
493
  }
401
494
  }
402
495
  }
403
- });
496
+ };
497
+ chart.setConfig(config);
404
498
  const imageBuffer = await chart.toBinary();
405
- const base64Image = imageBuffer.toString("base64");
406
- console.log("-------------------------------------------");
407
- console.log("b64", base64Image);
408
- console.log("-------------------------------------------");
499
+ const base64 = imageBuffer.toString("base64");
409
500
  return {
410
501
  content: [
411
502
  {
412
- type: "image",
413
- image: {
414
- source: {
415
- data: base64Image
416
- }
417
- },
418
- uri: "getStockGraph",
419
- mimeType: "image/png"
503
+ type: "resource",
504
+ resource: {
505
+ uri: "resource://graph",
506
+ mimeType: "image/png",
507
+ blob: base64
508
+ }
420
509
  }
421
510
  ]
422
511
  };
@@ -425,7 +514,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
425
514
  content: [
426
515
  {
427
516
  type: "text",
428
- text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
517
+ text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
429
518
  uri: "getStockGraph"
430
519
  }
431
520
  ],
@@ -463,7 +552,48 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
463
552
  bid: point.bid,
464
553
  offer: point.offer,
465
554
  spread: point.spread,
466
- volume: point.volume
555
+ volume: point.volume,
556
+ trade: point.trade,
557
+ indexValue: point.indexValue,
558
+ openingPrice: point.openingPrice,
559
+ closingPrice: point.closingPrice,
560
+ settlementPrice: point.settlementPrice,
561
+ tradingSessionHighPrice: point.tradingSessionHighPrice,
562
+ tradingSessionLowPrice: point.tradingSessionLowPrice,
563
+ vwap: point.vwap,
564
+ imbalance: point.imbalance,
565
+ openInterest: point.openInterest,
566
+ compositeUnderlyingPrice: point.compositeUnderlyingPrice,
567
+ simulatedSellPrice: point.simulatedSellPrice,
568
+ simulatedBuyPrice: point.simulatedBuyPrice,
569
+ marginRate: point.marginRate,
570
+ midPrice: point.midPrice,
571
+ emptyBook: point.emptyBook,
572
+ settleHighPrice: point.settleHighPrice,
573
+ settleLowPrice: point.settleLowPrice,
574
+ priorSettlePrice: point.priorSettlePrice,
575
+ sessionHighBid: point.sessionHighBid,
576
+ sessionLowOffer: point.sessionLowOffer,
577
+ earlyPrices: point.earlyPrices,
578
+ auctionClearingPrice: point.auctionClearingPrice,
579
+ swapValueFactor: point.swapValueFactor,
580
+ dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
581
+ cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
582
+ dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
583
+ cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
584
+ fixingPrice: point.fixingPrice,
585
+ cashRate: point.cashRate,
586
+ recoveryRate: point.recoveryRate,
587
+ recoveryRateForLong: point.recoveryRateForLong,
588
+ recoveryRateForShort: point.recoveryRateForShort,
589
+ marketBid: point.marketBid,
590
+ marketOffer: point.marketOffer,
591
+ shortSaleMinPrice: point.shortSaleMinPrice,
592
+ previousClosingPrice: point.previousClosingPrice,
593
+ thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
594
+ dailyFinancingValue: point.dailyFinancingValue,
595
+ accruedFinancingValue: point.accruedFinancingValue,
596
+ twap: point.twap
467
597
  }))
468
598
  },
469
599
  null,
@@ -478,7 +608,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
478
608
  content: [
479
609
  {
480
610
  type: "text",
481
- text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
611
+ text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
482
612
  uri: "getStockPriceHistory"
483
613
  }
484
614
  ],
@@ -586,7 +716,7 @@ Parameters verified:
586
716
  - Symbol: ${args.symbol}
587
717
  - TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
588
718
 
589
- To execute this order, call the executeOrder tool with these exact same parameters.`,
719
+ To execute this order, call the executeOrder tool with these exact same parameters. Important: The user has to explicitly confirm before executeOrder is called!`,
590
720
  uri: "verifyOrder"
591
721
  }
592
722
  ]
@@ -785,9 +915,261 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
785
915
  getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
786
916
  });
787
917
 
918
+ // src/utils/messageHandler.ts
919
+ import { Fields as Fields3, MDEntryType as MDEntryType2, Messages as Messages3 } from "fixparser";
920
+ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
921
+ parser.logger.log({
922
+ level: "info",
923
+ message: `MCP Server received message: ${message.messageType}: ${message.description}`
924
+ });
925
+ const msgType = message.messageType;
926
+ if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.MarketDataIncrementalRefresh) {
927
+ const symbol = message.getField(Fields3.Symbol)?.value;
928
+ const fixJson = message.toFIXJSON();
929
+ const entries = fixJson.Body?.NoMDEntries || [];
930
+ const data = {
931
+ timestamp: Date.now(),
932
+ bid: 0,
933
+ offer: 0,
934
+ spread: 0,
935
+ volume: 0,
936
+ trade: 0,
937
+ indexValue: 0,
938
+ openingPrice: 0,
939
+ closingPrice: 0,
940
+ settlementPrice: 0,
941
+ tradingSessionHighPrice: 0,
942
+ tradingSessionLowPrice: 0,
943
+ vwap: 0,
944
+ imbalance: 0,
945
+ openInterest: 0,
946
+ compositeUnderlyingPrice: 0,
947
+ simulatedSellPrice: 0,
948
+ simulatedBuyPrice: 0,
949
+ marginRate: 0,
950
+ midPrice: 0,
951
+ emptyBook: 0,
952
+ settleHighPrice: 0,
953
+ settleLowPrice: 0,
954
+ priorSettlePrice: 0,
955
+ sessionHighBid: 0,
956
+ sessionLowOffer: 0,
957
+ earlyPrices: 0,
958
+ auctionClearingPrice: 0,
959
+ swapValueFactor: 0,
960
+ dailyValueAdjustmentForLongPositions: 0,
961
+ cumulativeValueAdjustmentForLongPositions: 0,
962
+ dailyValueAdjustmentForShortPositions: 0,
963
+ cumulativeValueAdjustmentForShortPositions: 0,
964
+ fixingPrice: 0,
965
+ cashRate: 0,
966
+ recoveryRate: 0,
967
+ recoveryRateForLong: 0,
968
+ recoveryRateForShort: 0,
969
+ marketBid: 0,
970
+ marketOffer: 0,
971
+ shortSaleMinPrice: 0,
972
+ previousClosingPrice: 0,
973
+ thresholdLimitPriceBanding: 0,
974
+ dailyFinancingValue: 0,
975
+ accruedFinancingValue: 0,
976
+ twap: 0
977
+ };
978
+ for (const entry of entries) {
979
+ const entryType = entry.MDEntryType;
980
+ const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
981
+ const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
982
+ if (entryType === MDEntryType2.Bid || entryType === MDEntryType2.Offer || entryType === MDEntryType2.TradeVolume) {
983
+ parser.logger.log({
984
+ level: "info",
985
+ message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
986
+ });
987
+ }
988
+ switch (entryType) {
989
+ case MDEntryType2.Bid:
990
+ data.bid = price;
991
+ break;
992
+ case MDEntryType2.Offer:
993
+ data.offer = price;
994
+ break;
995
+ case MDEntryType2.Trade:
996
+ data.trade = price;
997
+ break;
998
+ case MDEntryType2.IndexValue:
999
+ data.indexValue = price;
1000
+ break;
1001
+ case MDEntryType2.OpeningPrice:
1002
+ data.openingPrice = price;
1003
+ break;
1004
+ case MDEntryType2.ClosingPrice:
1005
+ data.closingPrice = price;
1006
+ break;
1007
+ case MDEntryType2.SettlementPrice:
1008
+ data.settlementPrice = price;
1009
+ break;
1010
+ case MDEntryType2.TradingSessionHighPrice:
1011
+ data.tradingSessionHighPrice = price;
1012
+ break;
1013
+ case MDEntryType2.TradingSessionLowPrice:
1014
+ data.tradingSessionLowPrice = price;
1015
+ break;
1016
+ case MDEntryType2.VWAP:
1017
+ data.vwap = price;
1018
+ break;
1019
+ case MDEntryType2.Imbalance:
1020
+ data.imbalance = size;
1021
+ break;
1022
+ case MDEntryType2.TradeVolume:
1023
+ data.volume = size;
1024
+ break;
1025
+ case MDEntryType2.OpenInterest:
1026
+ data.openInterest = size;
1027
+ break;
1028
+ case MDEntryType2.CompositeUnderlyingPrice:
1029
+ data.compositeUnderlyingPrice = price;
1030
+ break;
1031
+ case MDEntryType2.SimulatedSellPrice:
1032
+ data.simulatedSellPrice = price;
1033
+ break;
1034
+ case MDEntryType2.SimulatedBuyPrice:
1035
+ data.simulatedBuyPrice = price;
1036
+ break;
1037
+ case MDEntryType2.MarginRate:
1038
+ data.marginRate = price;
1039
+ break;
1040
+ case MDEntryType2.MidPrice:
1041
+ data.midPrice = price;
1042
+ break;
1043
+ case MDEntryType2.EmptyBook:
1044
+ data.emptyBook = 1;
1045
+ break;
1046
+ case MDEntryType2.SettleHighPrice:
1047
+ data.settleHighPrice = price;
1048
+ break;
1049
+ case MDEntryType2.SettleLowPrice:
1050
+ data.settleLowPrice = price;
1051
+ break;
1052
+ case MDEntryType2.PriorSettlePrice:
1053
+ data.priorSettlePrice = price;
1054
+ break;
1055
+ case MDEntryType2.SessionHighBid:
1056
+ data.sessionHighBid = price;
1057
+ break;
1058
+ case MDEntryType2.SessionLowOffer:
1059
+ data.sessionLowOffer = price;
1060
+ break;
1061
+ case MDEntryType2.EarlyPrices:
1062
+ data.earlyPrices = price;
1063
+ break;
1064
+ case MDEntryType2.AuctionClearingPrice:
1065
+ data.auctionClearingPrice = price;
1066
+ break;
1067
+ case MDEntryType2.SwapValueFactor:
1068
+ data.swapValueFactor = price;
1069
+ break;
1070
+ case MDEntryType2.DailyValueAdjustmentForLongPositions:
1071
+ data.dailyValueAdjustmentForLongPositions = price;
1072
+ break;
1073
+ case MDEntryType2.CumulativeValueAdjustmentForLongPositions:
1074
+ data.cumulativeValueAdjustmentForLongPositions = price;
1075
+ break;
1076
+ case MDEntryType2.DailyValueAdjustmentForShortPositions:
1077
+ data.dailyValueAdjustmentForShortPositions = price;
1078
+ break;
1079
+ case MDEntryType2.CumulativeValueAdjustmentForShortPositions:
1080
+ data.cumulativeValueAdjustmentForShortPositions = price;
1081
+ break;
1082
+ case MDEntryType2.FixingPrice:
1083
+ data.fixingPrice = price;
1084
+ break;
1085
+ case MDEntryType2.CashRate:
1086
+ data.cashRate = price;
1087
+ break;
1088
+ case MDEntryType2.RecoveryRate:
1089
+ data.recoveryRate = price;
1090
+ break;
1091
+ case MDEntryType2.RecoveryRateForLong:
1092
+ data.recoveryRateForLong = price;
1093
+ break;
1094
+ case MDEntryType2.RecoveryRateForShort:
1095
+ data.recoveryRateForShort = price;
1096
+ break;
1097
+ case MDEntryType2.MarketBid:
1098
+ data.marketBid = price;
1099
+ break;
1100
+ case MDEntryType2.MarketOffer:
1101
+ data.marketOffer = price;
1102
+ break;
1103
+ case MDEntryType2.ShortSaleMinPrice:
1104
+ data.shortSaleMinPrice = price;
1105
+ break;
1106
+ case MDEntryType2.PreviousClosingPrice:
1107
+ data.previousClosingPrice = price;
1108
+ break;
1109
+ case MDEntryType2.ThresholdLimitPriceBanding:
1110
+ data.thresholdLimitPriceBanding = price;
1111
+ break;
1112
+ case MDEntryType2.DailyFinancingValue:
1113
+ data.dailyFinancingValue = price;
1114
+ break;
1115
+ case MDEntryType2.AccruedFinancingValue:
1116
+ data.accruedFinancingValue = price;
1117
+ break;
1118
+ case MDEntryType2.TWAP:
1119
+ data.twap = price;
1120
+ break;
1121
+ }
1122
+ }
1123
+ data.spread = data.offer - data.bid;
1124
+ if (!marketDataPrices.has(symbol)) {
1125
+ marketDataPrices.set(symbol, []);
1126
+ }
1127
+ const prices = marketDataPrices.get(symbol);
1128
+ prices.push(data);
1129
+ if (prices.length > maxPriceHistory) {
1130
+ prices.splice(0, prices.length - maxPriceHistory);
1131
+ }
1132
+ onPriceUpdate?.(symbol, data);
1133
+ const mdReqID = message.getField(Fields3.MDReqID)?.value;
1134
+ if (mdReqID) {
1135
+ const callback = pendingRequests.get(mdReqID);
1136
+ if (callback) {
1137
+ callback(message);
1138
+ pendingRequests.delete(mdReqID);
1139
+ }
1140
+ }
1141
+ } else if (msgType === Messages3.ExecutionReport) {
1142
+ const reqId = message.getField(Fields3.ClOrdID)?.value;
1143
+ const callback = pendingRequests.get(reqId);
1144
+ if (callback) {
1145
+ callback(message);
1146
+ pendingRequests.delete(reqId);
1147
+ }
1148
+ }
1149
+ }
1150
+
788
1151
  // src/MCPLocal.ts
789
- var MCPLocal = class {
790
- parser;
1152
+ var MCPLocal = class extends MCPBase {
1153
+ /**
1154
+ * Map to store verified orders before execution
1155
+ * @private
1156
+ */
1157
+ verifiedOrders = /* @__PURE__ */ new Map();
1158
+ /**
1159
+ * Map to store pending requests and their callbacks
1160
+ * @private
1161
+ */
1162
+ pendingRequests = /* @__PURE__ */ new Map();
1163
+ /**
1164
+ * Map to store market data prices for each symbol
1165
+ * @private
1166
+ */
1167
+ marketDataPrices = /* @__PURE__ */ new Map();
1168
+ /**
1169
+ * Maximum number of price history entries to keep per symbol
1170
+ * @private
1171
+ */
1172
+ MAX_PRICE_HISTORY = 1e5;
791
1173
  server = new Server(
792
1174
  {
793
1175
  name: "fixparser",
@@ -809,90 +1191,13 @@ var MCPLocal = class {
809
1191
  }
810
1192
  );
811
1193
  transport = new StdioServerTransport();
812
- onReady = void 0;
813
- pendingRequests = /* @__PURE__ */ new Map();
814
- verifiedOrders = /* @__PURE__ */ new Map();
815
- marketDataPrices = /* @__PURE__ */ new Map();
816
- MAX_PRICE_HISTORY = 1e5;
817
- // Maximum number of price points to store per symbol
818
1194
  constructor({ logger, onReady }) {
819
- if (onReady) this.onReady = onReady;
1195
+ super({ logger, onReady });
820
1196
  }
821
1197
  async register(parser) {
822
1198
  this.parser = parser;
823
1199
  this.parser.addOnMessageCallback((message) => {
824
- this.parser?.logger.log({
825
- level: "info",
826
- message: `MCP Server received message: ${message.messageType}: ${message.description}`
827
- });
828
- const msgType = message.messageType;
829
- if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.ExecutionReport || msgType === Messages3.Reject || msgType === Messages3.MarketDataIncrementalRefresh) {
830
- this.parser?.logger.log({
831
- level: "info",
832
- message: `MCP Server handling message type: ${msgType}`
833
- });
834
- let id;
835
- if (msgType === Messages3.MarketDataIncrementalRefresh || msgType === Messages3.MarketDataSnapshotFullRefresh) {
836
- const symbol = message.getField(Fields3.Symbol);
837
- const entryType = message.getField(Fields3.MDEntryType);
838
- const price = message.getField(Fields3.MDEntryPx);
839
- const size = message.getField(Fields3.MDEntrySize);
840
- const timestamp = message.getField(Fields3.MDEntryTime)?.value || Date.now();
841
- if (symbol?.value && price?.value) {
842
- const symbolStr = String(symbol.value);
843
- const priceNum = Number(price.value);
844
- const sizeNum = size?.value ? Number(size.value) : 0;
845
- const priceHistory = this.marketDataPrices.get(symbolStr) || [];
846
- const lastEntry = priceHistory[priceHistory.length - 1] || {
847
- timestamp: 0,
848
- bid: 0,
849
- offer: 0,
850
- spread: 0,
851
- volume: 0
852
- };
853
- const newEntry = {
854
- timestamp: Number(timestamp),
855
- bid: entryType?.value === MDEntryType2.Bid ? priceNum : lastEntry.bid,
856
- offer: entryType?.value === MDEntryType2.Offer ? priceNum : lastEntry.offer,
857
- spread: entryType?.value === MDEntryType2.Offer ? priceNum - lastEntry.bid : entryType?.value === MDEntryType2.Bid ? lastEntry.offer - priceNum : lastEntry.spread,
858
- volume: entryType?.value === MDEntryType2.TradeVolume ? sizeNum : lastEntry.volume
859
- };
860
- priceHistory.push(newEntry);
861
- if (priceHistory.length > this.MAX_PRICE_HISTORY) {
862
- priceHistory.shift();
863
- }
864
- this.marketDataPrices.set(symbolStr, priceHistory);
865
- this.parser?.logger.log({
866
- level: "info",
867
- message: `MCP Server added ${symbol}: ${JSON.stringify(newEntry)}`
868
- });
869
- this.server.notification({
870
- method: "priceUpdate",
871
- params: {
872
- symbol: symbolStr,
873
- ...newEntry
874
- }
875
- });
876
- }
877
- }
878
- if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
879
- const mdReqID = message.getField(Fields3.MDReqID);
880
- if (mdReqID) id = String(mdReqID.value);
881
- } else if (msgType === Messages3.ExecutionReport) {
882
- const clOrdID = message.getField(Fields3.ClOrdID);
883
- if (clOrdID) id = String(clOrdID.value);
884
- } else if (msgType === Messages3.Reject) {
885
- const refSeqNum = message.getField(Fields3.RefSeqNum);
886
- if (refSeqNum) id = String(refSeqNum.value);
887
- }
888
- if (id) {
889
- const callback = this.pendingRequests.get(id);
890
- if (callback) {
891
- callback(message);
892
- this.pendingRequests.delete(id);
893
- }
894
- }
895
- }
1200
+ handleMessage(message, this.parser, this.pendingRequests, this.marketDataPrices, this.MAX_PRICE_HISTORY);
896
1201
  });
897
1202
  this.addWorkflows();
898
1203
  await this.server.connect(this.transport);
@@ -907,18 +1212,15 @@ var MCPLocal = class {
907
1212
  if (!this.server) {
908
1213
  return;
909
1214
  }
910
- this.server.setRequestHandler(
911
- z.object({ method: z.literal("tools/list") }),
912
- async (request, extra) => {
913
- return {
914
- tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
915
- name,
916
- description,
917
- inputSchema: schema
918
- }))
919
- };
920
- }
921
- );
1215
+ this.server.setRequestHandler(z.object({ method: z.literal("tools/list") }), async () => {
1216
+ return {
1217
+ tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
1218
+ name,
1219
+ description,
1220
+ inputSchema: schema
1221
+ }))
1222
+ };
1223
+ });
922
1224
  this.server.setRequestHandler(
923
1225
  z.object({
924
1226
  method: z.literal("tools/call"),
@@ -930,7 +1232,7 @@ var MCPLocal = class {
930
1232
  }).optional()
931
1233
  })
932
1234
  }),
933
- async (request, extra) => {
1235
+ async (request) => {
934
1236
  const { name, arguments: args } = request.params;
935
1237
  const toolHandlers = createToolHandlers(
936
1238
  this.parser,