fixparser-plugin-mcp 9.1.7-63c797c5 → 9.1.7-67ba45e9

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.
@@ -166,7 +166,7 @@ var toolSchemas = {
166
166
  }
167
167
  },
168
168
  executeOrder: {
169
- description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
169
+ description: "Executes a verified order. verifyOrder must be called before executeOrder.",
170
170
  schema: {
171
171
  type: "object",
172
172
  properties: {
@@ -319,10 +319,63 @@ var import_quickchart_js = __toESM(require("quickchart-js"), 1);
319
319
  var createMarketDataRequestHandler = (parser, pendingRequests) => {
320
320
  return async (args) => {
321
321
  try {
322
+ parser.logger.log({
323
+ level: "info",
324
+ message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
325
+ });
322
326
  const response = new Promise((resolve) => {
323
327
  pendingRequests.set(args.mdReqID, resolve);
328
+ parser.logger.log({
329
+ level: "info",
330
+ message: `Registered callback for market data request ID: ${args.mdReqID}`
331
+ });
324
332
  });
325
- const entryTypes = args.mdEntryTypes || [import_fixparser.MDEntryType.Bid, import_fixparser.MDEntryType.Offer, import_fixparser.MDEntryType.TradeVolume];
333
+ const entryTypes = args.mdEntryTypes || [
334
+ import_fixparser.MDEntryType.Bid,
335
+ import_fixparser.MDEntryType.Offer,
336
+ import_fixparser.MDEntryType.Trade,
337
+ import_fixparser.MDEntryType.IndexValue,
338
+ import_fixparser.MDEntryType.OpeningPrice,
339
+ import_fixparser.MDEntryType.ClosingPrice,
340
+ import_fixparser.MDEntryType.SettlementPrice,
341
+ import_fixparser.MDEntryType.TradingSessionHighPrice,
342
+ import_fixparser.MDEntryType.TradingSessionLowPrice,
343
+ import_fixparser.MDEntryType.VWAP,
344
+ import_fixparser.MDEntryType.Imbalance,
345
+ import_fixparser.MDEntryType.TradeVolume,
346
+ import_fixparser.MDEntryType.OpenInterest,
347
+ import_fixparser.MDEntryType.CompositeUnderlyingPrice,
348
+ import_fixparser.MDEntryType.SimulatedSellPrice,
349
+ import_fixparser.MDEntryType.SimulatedBuyPrice,
350
+ import_fixparser.MDEntryType.MarginRate,
351
+ import_fixparser.MDEntryType.MidPrice,
352
+ import_fixparser.MDEntryType.EmptyBook,
353
+ import_fixparser.MDEntryType.SettleHighPrice,
354
+ import_fixparser.MDEntryType.SettleLowPrice,
355
+ import_fixparser.MDEntryType.PriorSettlePrice,
356
+ import_fixparser.MDEntryType.SessionHighBid,
357
+ import_fixparser.MDEntryType.SessionLowOffer,
358
+ import_fixparser.MDEntryType.EarlyPrices,
359
+ import_fixparser.MDEntryType.AuctionClearingPrice,
360
+ import_fixparser.MDEntryType.SwapValueFactor,
361
+ import_fixparser.MDEntryType.DailyValueAdjustmentForLongPositions,
362
+ import_fixparser.MDEntryType.CumulativeValueAdjustmentForLongPositions,
363
+ import_fixparser.MDEntryType.DailyValueAdjustmentForShortPositions,
364
+ import_fixparser.MDEntryType.CumulativeValueAdjustmentForShortPositions,
365
+ import_fixparser.MDEntryType.FixingPrice,
366
+ import_fixparser.MDEntryType.CashRate,
367
+ import_fixparser.MDEntryType.RecoveryRate,
368
+ import_fixparser.MDEntryType.RecoveryRateForLong,
369
+ import_fixparser.MDEntryType.RecoveryRateForShort,
370
+ import_fixparser.MDEntryType.MarketBid,
371
+ import_fixparser.MDEntryType.MarketOffer,
372
+ import_fixparser.MDEntryType.ShortSaleMinPrice,
373
+ import_fixparser.MDEntryType.PreviousClosingPrice,
374
+ import_fixparser.MDEntryType.ThresholdLimitPriceBanding,
375
+ import_fixparser.MDEntryType.DailyFinancingValue,
376
+ import_fixparser.MDEntryType.AccruedFinancingValue,
377
+ import_fixparser.MDEntryType.TWAP
378
+ ];
326
379
  const messageFields = [
327
380
  new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
328
381
  new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
@@ -344,6 +397,10 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
344
397
  });
345
398
  const mdr = parser.createMessage(...messageFields);
346
399
  if (!parser.connected) {
400
+ parser.logger.log({
401
+ level: "error",
402
+ message: "Not connected. Cannot send market data request."
403
+ });
347
404
  return {
348
405
  content: [
349
406
  {
@@ -355,8 +412,16 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
355
412
  isError: true
356
413
  };
357
414
  }
415
+ parser.logger.log({
416
+ level: "info",
417
+ message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
418
+ });
358
419
  parser.send(mdr);
359
420
  const fixData = await response;
421
+ parser.logger.log({
422
+ level: "info",
423
+ message: `Received market data response for request ID: ${args.mdReqID}`
424
+ });
360
425
  return {
361
426
  content: [
362
427
  {
@@ -405,6 +470,9 @@ var createGetStockGraphHandler = (marketDataPrices) => {
405
470
  const offerData = priceHistory.map((point) => point.offer);
406
471
  const spreadData = priceHistory.map((point) => point.spread);
407
472
  const volumeData = priceHistory.map((point) => point.volume);
473
+ const tradeData = priceHistory.map((point) => point.trade);
474
+ const vwapData = priceHistory.map((point) => point.vwap);
475
+ const twapData = priceHistory.map((point) => point.twap);
408
476
  const config = {
409
477
  type: "line",
410
478
  data: {
@@ -434,6 +502,30 @@ var createGetStockGraphHandler = (marketDataPrices) => {
434
502
  fill: false,
435
503
  tension: 0.4
436
504
  },
505
+ {
506
+ label: "Trade",
507
+ data: tradeData,
508
+ borderColor: "#ffc107",
509
+ backgroundColor: "rgba(255, 193, 7, 0.1)",
510
+ fill: false,
511
+ tension: 0.4
512
+ },
513
+ {
514
+ label: "VWAP",
515
+ data: vwapData,
516
+ borderColor: "#17a2b8",
517
+ backgroundColor: "rgba(23, 162, 184, 0.1)",
518
+ fill: false,
519
+ tension: 0.4
520
+ },
521
+ {
522
+ label: "TWAP",
523
+ data: twapData,
524
+ borderColor: "#6610f2",
525
+ backgroundColor: "rgba(102, 16, 242, 0.1)",
526
+ fill: false,
527
+ tension: 0.4
528
+ },
437
529
  {
438
530
  label: "Volume",
439
531
  data: volumeData,
@@ -479,7 +571,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
479
571
  content: [
480
572
  {
481
573
  type: "text",
482
- text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
574
+ text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
483
575
  uri: "getStockGraph"
484
576
  }
485
577
  ],
@@ -517,7 +609,48 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
517
609
  bid: point.bid,
518
610
  offer: point.offer,
519
611
  spread: point.spread,
520
- volume: point.volume
612
+ volume: point.volume,
613
+ trade: point.trade,
614
+ indexValue: point.indexValue,
615
+ openingPrice: point.openingPrice,
616
+ closingPrice: point.closingPrice,
617
+ settlementPrice: point.settlementPrice,
618
+ tradingSessionHighPrice: point.tradingSessionHighPrice,
619
+ tradingSessionLowPrice: point.tradingSessionLowPrice,
620
+ vwap: point.vwap,
621
+ imbalance: point.imbalance,
622
+ openInterest: point.openInterest,
623
+ compositeUnderlyingPrice: point.compositeUnderlyingPrice,
624
+ simulatedSellPrice: point.simulatedSellPrice,
625
+ simulatedBuyPrice: point.simulatedBuyPrice,
626
+ marginRate: point.marginRate,
627
+ midPrice: point.midPrice,
628
+ emptyBook: point.emptyBook,
629
+ settleHighPrice: point.settleHighPrice,
630
+ settleLowPrice: point.settleLowPrice,
631
+ priorSettlePrice: point.priorSettlePrice,
632
+ sessionHighBid: point.sessionHighBid,
633
+ sessionLowOffer: point.sessionLowOffer,
634
+ earlyPrices: point.earlyPrices,
635
+ auctionClearingPrice: point.auctionClearingPrice,
636
+ swapValueFactor: point.swapValueFactor,
637
+ dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
638
+ cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
639
+ dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
640
+ cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
641
+ fixingPrice: point.fixingPrice,
642
+ cashRate: point.cashRate,
643
+ recoveryRate: point.recoveryRate,
644
+ recoveryRateForLong: point.recoveryRateForLong,
645
+ recoveryRateForShort: point.recoveryRateForShort,
646
+ marketBid: point.marketBid,
647
+ marketOffer: point.marketOffer,
648
+ shortSaleMinPrice: point.shortSaleMinPrice,
649
+ previousClosingPrice: point.previousClosingPrice,
650
+ thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
651
+ dailyFinancingValue: point.dailyFinancingValue,
652
+ accruedFinancingValue: point.accruedFinancingValue,
653
+ twap: point.twap
521
654
  }))
522
655
  },
523
656
  null,
@@ -532,7 +665,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
532
665
  content: [
533
666
  {
534
667
  type: "text",
535
- text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
668
+ text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
536
669
  uri: "getStockPriceHistory"
537
670
  }
538
671
  ],
@@ -640,7 +773,7 @@ Parameters verified:
640
773
  - Symbol: ${args.symbol}
641
774
  - TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
642
775
 
643
- To execute this order, call the executeOrder tool with these exact same parameters.`,
776
+ To execute this order, call the executeOrder tool with these exact same parameters. Important: The user has to explicitly confirm before executeOrder is called!`,
644
777
  uri: "verifyOrder"
645
778
  }
646
779
  ]
@@ -841,52 +974,256 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
841
974
 
842
975
  // src/utils/messageHandler.ts
843
976
  var import_fixparser3 = require("fixparser");
977
+ function getEnumValue(enumObj, name) {
978
+ return enumObj[name] || name;
979
+ }
844
980
  function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
845
981
  parser.logger.log({
846
982
  level: "info",
847
983
  message: `MCP Server received message: ${message.messageType}: ${message.description}`
848
984
  });
849
985
  const msgType = message.messageType;
850
- if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
986
+ if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
851
987
  const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
852
- const entries = message.getField(import_fixparser3.Fields.NoMDEntries)?.value;
853
- let bid = 0;
854
- let offer = 0;
855
- let volume = 0;
856
- const entryTypes = message.getFields(import_fixparser3.Fields.MDEntryType);
857
- const entryPrices = message.getFields(import_fixparser3.Fields.MDEntryPx);
858
- const entrySizes = message.getFields(import_fixparser3.Fields.MDEntrySize);
859
- if (entryTypes && entryPrices && entrySizes) {
860
- for (let i = 0; i < entries; i++) {
861
- const entryType = entryTypes[i]?.value;
862
- const entryPrice = Number.parseFloat(entryPrices[i]?.value);
863
- const entrySize = Number.parseFloat(entrySizes[i]?.value);
864
- if (entryType === import_fixparser3.MDEntryType.Bid) {
865
- bid = entryPrice;
866
- } else if (entryType === import_fixparser3.MDEntryType.Offer) {
867
- offer = entryPrice;
868
- }
869
- volume += entrySize;
870
- }
871
- }
872
- const spread = offer - bid;
873
- const timestamp = Date.now();
988
+ parser.logger.log({
989
+ level: "info",
990
+ message: `Processing market data for symbol: ${symbol}`
991
+ });
992
+ const fixJson = message.toFIXJSON();
993
+ const entries = fixJson.Body?.NoMDEntries || [];
994
+ parser.logger.log({
995
+ level: "info",
996
+ message: `Found ${entries.length} market data entries`
997
+ });
874
998
  const data = {
875
- timestamp,
876
- bid,
877
- offer,
878
- spread,
879
- volume
999
+ timestamp: Date.now(),
1000
+ bid: 0,
1001
+ offer: 0,
1002
+ spread: 0,
1003
+ volume: 0,
1004
+ trade: 0,
1005
+ indexValue: 0,
1006
+ openingPrice: 0,
1007
+ closingPrice: 0,
1008
+ settlementPrice: 0,
1009
+ tradingSessionHighPrice: 0,
1010
+ tradingSessionLowPrice: 0,
1011
+ vwap: 0,
1012
+ imbalance: 0,
1013
+ openInterest: 0,
1014
+ compositeUnderlyingPrice: 0,
1015
+ simulatedSellPrice: 0,
1016
+ simulatedBuyPrice: 0,
1017
+ marginRate: 0,
1018
+ midPrice: 0,
1019
+ emptyBook: 0,
1020
+ settleHighPrice: 0,
1021
+ settleLowPrice: 0,
1022
+ priorSettlePrice: 0,
1023
+ sessionHighBid: 0,
1024
+ sessionLowOffer: 0,
1025
+ earlyPrices: 0,
1026
+ auctionClearingPrice: 0,
1027
+ swapValueFactor: 0,
1028
+ dailyValueAdjustmentForLongPositions: 0,
1029
+ cumulativeValueAdjustmentForLongPositions: 0,
1030
+ dailyValueAdjustmentForShortPositions: 0,
1031
+ cumulativeValueAdjustmentForShortPositions: 0,
1032
+ fixingPrice: 0,
1033
+ cashRate: 0,
1034
+ recoveryRate: 0,
1035
+ recoveryRateForLong: 0,
1036
+ recoveryRateForShort: 0,
1037
+ marketBid: 0,
1038
+ marketOffer: 0,
1039
+ shortSaleMinPrice: 0,
1040
+ previousClosingPrice: 0,
1041
+ thresholdLimitPriceBanding: 0,
1042
+ dailyFinancingValue: 0,
1043
+ accruedFinancingValue: 0,
1044
+ twap: 0
880
1045
  };
1046
+ for (const entry of entries) {
1047
+ const entryType = entry.MDEntryType;
1048
+ const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
1049
+ const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
1050
+ if (entryType === import_fixparser3.MDEntryType.Bid || entryType === import_fixparser3.MDEntryType.Offer || entryType === import_fixparser3.MDEntryType.TradeVolume) {
1051
+ parser.logger.log({
1052
+ level: "info",
1053
+ message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
1054
+ });
1055
+ }
1056
+ const enumValue = getEnumValue(import_fixparser3.MDEntryType, entryType);
1057
+ switch (enumValue) {
1058
+ case import_fixparser3.MDEntryType.Bid:
1059
+ data.bid = price;
1060
+ break;
1061
+ case import_fixparser3.MDEntryType.Offer:
1062
+ data.offer = price;
1063
+ break;
1064
+ case import_fixparser3.MDEntryType.Trade:
1065
+ data.trade = price;
1066
+ break;
1067
+ case import_fixparser3.MDEntryType.IndexValue:
1068
+ data.indexValue = price;
1069
+ break;
1070
+ case import_fixparser3.MDEntryType.OpeningPrice:
1071
+ data.openingPrice = price;
1072
+ break;
1073
+ case import_fixparser3.MDEntryType.ClosingPrice:
1074
+ data.closingPrice = price;
1075
+ break;
1076
+ case import_fixparser3.MDEntryType.SettlementPrice:
1077
+ data.settlementPrice = price;
1078
+ break;
1079
+ case import_fixparser3.MDEntryType.TradingSessionHighPrice:
1080
+ data.tradingSessionHighPrice = price;
1081
+ break;
1082
+ case import_fixparser3.MDEntryType.TradingSessionLowPrice:
1083
+ data.tradingSessionLowPrice = price;
1084
+ break;
1085
+ case import_fixparser3.MDEntryType.VWAP:
1086
+ data.vwap = price;
1087
+ break;
1088
+ case import_fixparser3.MDEntryType.Imbalance:
1089
+ data.imbalance = size;
1090
+ break;
1091
+ case import_fixparser3.MDEntryType.TradeVolume:
1092
+ data.volume = size;
1093
+ break;
1094
+ case import_fixparser3.MDEntryType.OpenInterest:
1095
+ data.openInterest = size;
1096
+ break;
1097
+ case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
1098
+ data.compositeUnderlyingPrice = price;
1099
+ break;
1100
+ case import_fixparser3.MDEntryType.SimulatedSellPrice:
1101
+ data.simulatedSellPrice = price;
1102
+ break;
1103
+ case import_fixparser3.MDEntryType.SimulatedBuyPrice:
1104
+ data.simulatedBuyPrice = price;
1105
+ break;
1106
+ case import_fixparser3.MDEntryType.MarginRate:
1107
+ data.marginRate = price;
1108
+ break;
1109
+ case import_fixparser3.MDEntryType.MidPrice:
1110
+ data.midPrice = price;
1111
+ break;
1112
+ case import_fixparser3.MDEntryType.EmptyBook:
1113
+ data.emptyBook = 1;
1114
+ break;
1115
+ case import_fixparser3.MDEntryType.SettleHighPrice:
1116
+ data.settleHighPrice = price;
1117
+ break;
1118
+ case import_fixparser3.MDEntryType.SettleLowPrice:
1119
+ data.settleLowPrice = price;
1120
+ break;
1121
+ case import_fixparser3.MDEntryType.PriorSettlePrice:
1122
+ data.priorSettlePrice = price;
1123
+ break;
1124
+ case import_fixparser3.MDEntryType.SessionHighBid:
1125
+ data.sessionHighBid = price;
1126
+ break;
1127
+ case import_fixparser3.MDEntryType.SessionLowOffer:
1128
+ data.sessionLowOffer = price;
1129
+ break;
1130
+ case import_fixparser3.MDEntryType.EarlyPrices:
1131
+ data.earlyPrices = price;
1132
+ break;
1133
+ case import_fixparser3.MDEntryType.AuctionClearingPrice:
1134
+ data.auctionClearingPrice = price;
1135
+ break;
1136
+ case import_fixparser3.MDEntryType.SwapValueFactor:
1137
+ data.swapValueFactor = price;
1138
+ break;
1139
+ case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
1140
+ data.dailyValueAdjustmentForLongPositions = price;
1141
+ break;
1142
+ case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
1143
+ data.cumulativeValueAdjustmentForLongPositions = price;
1144
+ break;
1145
+ case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
1146
+ data.dailyValueAdjustmentForShortPositions = price;
1147
+ break;
1148
+ case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
1149
+ data.cumulativeValueAdjustmentForShortPositions = price;
1150
+ break;
1151
+ case import_fixparser3.MDEntryType.FixingPrice:
1152
+ data.fixingPrice = price;
1153
+ break;
1154
+ case import_fixparser3.MDEntryType.CashRate:
1155
+ data.cashRate = price;
1156
+ break;
1157
+ case import_fixparser3.MDEntryType.RecoveryRate:
1158
+ data.recoveryRate = price;
1159
+ break;
1160
+ case import_fixparser3.MDEntryType.RecoveryRateForLong:
1161
+ data.recoveryRateForLong = price;
1162
+ break;
1163
+ case import_fixparser3.MDEntryType.RecoveryRateForShort:
1164
+ data.recoveryRateForShort = price;
1165
+ break;
1166
+ case import_fixparser3.MDEntryType.MarketBid:
1167
+ data.marketBid = price;
1168
+ break;
1169
+ case import_fixparser3.MDEntryType.MarketOffer:
1170
+ data.marketOffer = price;
1171
+ break;
1172
+ case import_fixparser3.MDEntryType.ShortSaleMinPrice:
1173
+ data.shortSaleMinPrice = price;
1174
+ break;
1175
+ case import_fixparser3.MDEntryType.PreviousClosingPrice:
1176
+ data.previousClosingPrice = price;
1177
+ break;
1178
+ case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
1179
+ data.thresholdLimitPriceBanding = price;
1180
+ break;
1181
+ case import_fixparser3.MDEntryType.DailyFinancingValue:
1182
+ data.dailyFinancingValue = price;
1183
+ break;
1184
+ case import_fixparser3.MDEntryType.AccruedFinancingValue:
1185
+ data.accruedFinancingValue = price;
1186
+ break;
1187
+ case import_fixparser3.MDEntryType.TWAP:
1188
+ data.twap = price;
1189
+ break;
1190
+ }
1191
+ }
1192
+ data.spread = data.offer - data.bid;
1193
+ console.log(">>>>>>>>>>>>>>>>>>>>", data);
881
1194
  if (!marketDataPrices.has(symbol)) {
1195
+ parser.logger.log({
1196
+ level: "info",
1197
+ message: `Creating new price history array for symbol: ${symbol}`
1198
+ });
882
1199
  marketDataPrices.set(symbol, []);
883
1200
  }
884
1201
  const prices = marketDataPrices.get(symbol);
885
1202
  prices.push(data);
1203
+ parser.logger.log({
1204
+ level: "info",
1205
+ message: `Updated price history for ${symbol}. Current size: ${prices.length}`
1206
+ });
886
1207
  if (prices.length > maxPriceHistory) {
887
1208
  prices.splice(0, prices.length - maxPriceHistory);
1209
+ parser.logger.log({
1210
+ level: "info",
1211
+ message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
1212
+ });
888
1213
  }
889
1214
  onPriceUpdate?.(symbol, data);
1215
+ const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
1216
+ if (mdReqID) {
1217
+ const callback = pendingRequests.get(mdReqID);
1218
+ if (callback) {
1219
+ callback(message);
1220
+ pendingRequests.delete(mdReqID);
1221
+ parser.logger.log({
1222
+ level: "info",
1223
+ message: `Resolved market data request for ID: ${mdReqID}`
1224
+ });
1225
+ }
1226
+ }
890
1227
  } else if (msgType === import_fixparser3.Messages.ExecutionReport) {
891
1228
  const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
892
1229
  const callback = pendingRequests.get(reqId);
@@ -915,7 +1252,7 @@ var MCPLocal = class extends MCPBase {
915
1252
  */
916
1253
  marketDataPrices = /* @__PURE__ */ new Map();
917
1254
  /**
918
- * Maximum number of price points to store per symbol
1255
+ * Maximum number of price history entries to keep per symbol
919
1256
  * @private
920
1257
  */
921
1258
  MAX_PRICE_HISTORY = 1e5;
@@ -1024,6 +1361,39 @@ var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamable
1024
1361
  var import_types = require("@modelcontextprotocol/sdk/types.js");
1025
1362
  var import_zod2 = require("zod");
1026
1363
  var transports = {};
1364
+ function jsonSchemaToZod(schema) {
1365
+ if (schema.type === "object") {
1366
+ const shape = {};
1367
+ for (const [key, prop] of Object.entries(schema.properties || {})) {
1368
+ const propSchema = prop;
1369
+ if (propSchema.type === "string") {
1370
+ if (propSchema.enum) {
1371
+ shape[key] = import_zod2.z.enum(propSchema.enum);
1372
+ } else {
1373
+ shape[key] = import_zod2.z.string();
1374
+ }
1375
+ } else if (propSchema.type === "number") {
1376
+ shape[key] = import_zod2.z.number();
1377
+ } else if (propSchema.type === "boolean") {
1378
+ shape[key] = import_zod2.z.boolean();
1379
+ } else if (propSchema.type === "array") {
1380
+ if (propSchema.items.type === "string") {
1381
+ shape[key] = import_zod2.z.array(import_zod2.z.string());
1382
+ } else if (propSchema.items.type === "number") {
1383
+ shape[key] = import_zod2.z.array(import_zod2.z.number());
1384
+ } else if (propSchema.items.type === "boolean") {
1385
+ shape[key] = import_zod2.z.array(import_zod2.z.boolean());
1386
+ } else {
1387
+ shape[key] = import_zod2.z.array(import_zod2.z.any());
1388
+ }
1389
+ } else {
1390
+ shape[key] = import_zod2.z.any();
1391
+ }
1392
+ }
1393
+ return shape;
1394
+ }
1395
+ return {};
1396
+ }
1027
1397
  var MCPRemote = class extends MCPBase {
1028
1398
  /**
1029
1399
  * Port number the server will listen on.
@@ -1066,7 +1436,7 @@ var MCPRemote = class extends MCPBase {
1066
1436
  */
1067
1437
  marketDataPrices = /* @__PURE__ */ new Map();
1068
1438
  /**
1069
- * Maximum number of price points to store per symbol
1439
+ * Maximum number of price history entries to keep per symbol
1070
1440
  * @private
1071
1441
  */
1072
1442
  MAX_PRICE_HISTORY = 1e5;
@@ -1088,55 +1458,22 @@ var MCPRemote = class extends MCPBase {
1088
1458
  this.parser,
1089
1459
  this.pendingRequests,
1090
1460
  this.marketDataPrices,
1091
- this.MAX_PRICE_HISTORY,
1092
- (symbol, data) => {
1093
- this.mcpServer?.tool(
1094
- "priceUpdate",
1095
- {
1096
- description: "Price update notification",
1097
- schema: import_zod2.z.object({
1098
- symbol: import_zod2.z.string(),
1099
- timestamp: import_zod2.z.number(),
1100
- bid: import_zod2.z.number(),
1101
- offer: import_zod2.z.number(),
1102
- spread: import_zod2.z.number(),
1103
- volume: import_zod2.z.number()
1104
- })
1105
- },
1106
- () => ({
1107
- content: [
1108
- {
1109
- type: "text",
1110
- text: JSON.stringify({ symbol, ...data })
1111
- }
1112
- ]
1113
- })
1114
- );
1115
- }
1461
+ this.MAX_PRICE_HISTORY
1116
1462
  );
1463
+ this.logger?.log({
1464
+ level: "info",
1465
+ message: `Market Data Prices TEST: ${JSON.stringify(this.marketDataPrices)}`
1466
+ });
1117
1467
  }
1118
1468
  });
1119
1469
  this.httpServer = (0, import_node_http.createServer)(async (req, res) => {
1120
- console.log(req.headers);
1121
- this.logger?.log({
1122
- level: "info",
1123
- message: `Incoming request: ${req.method} ${req.url}`
1124
- });
1125
1470
  if (!req.url || !req.method) {
1126
- this.logger?.log({
1127
- level: "error",
1128
- message: "Invalid request: missing URL or method"
1129
- });
1130
1471
  res.writeHead(400);
1131
1472
  res.end("Bad Request");
1132
1473
  return;
1133
1474
  }
1134
1475
  if (req.url === "/mcp") {
1135
1476
  const sessionId = req.headers["mcp-session-id"];
1136
- this.logger?.log({
1137
- level: "info",
1138
- message: `MCP request received. Session ID: ${sessionId || "none"}, headers: ${req.headers}`
1139
- });
1140
1477
  if (req.method === "POST") {
1141
1478
  const bodyChunks = [];
1142
1479
  req.on("data", (chunk) => {
@@ -1147,47 +1484,23 @@ var MCPRemote = class extends MCPBase {
1147
1484
  const body = Buffer.concat(bodyChunks).toString();
1148
1485
  try {
1149
1486
  parsed = JSON.parse(body);
1150
- this.logger?.log({
1151
- level: "info",
1152
- message: `Parsed request body: ${JSON.stringify(parsed)}`
1153
- });
1154
1487
  } catch (err) {
1155
- this.logger?.log({
1156
- level: "error",
1157
- message: `Failed to parse JSON body: ${err}`
1158
- });
1159
1488
  res.writeHead(400);
1160
1489
  res.end(JSON.stringify({ error: "Invalid JSON" }));
1161
1490
  return;
1162
1491
  }
1163
1492
  let transport;
1164
1493
  if (sessionId && transports[sessionId]) {
1165
- this.logger?.log({
1166
- level: "info",
1167
- message: `Using existing transport for session: ${sessionId}`
1168
- });
1169
1494
  transport = transports[sessionId];
1170
1495
  } else if (!sessionId && req.method === "POST" && (0, import_types.isInitializeRequest)(parsed)) {
1171
- this.logger?.log({
1172
- level: "info",
1173
- message: "Creating new transport for initialization request"
1174
- });
1175
1496
  transport = new import_streamableHttp.StreamableHTTPServerTransport({
1176
1497
  sessionIdGenerator: () => (0, import_node_crypto.randomUUID)(),
1177
1498
  onsessioninitialized: (sessionId2) => {
1178
- this.logger?.log({
1179
- level: "info",
1180
- message: `New session initialized: ${sessionId2}`
1181
- });
1182
1499
  transports[sessionId2] = transport;
1183
1500
  }
1184
1501
  });
1185
1502
  transport.onclose = () => {
1186
1503
  if (transport.sessionId) {
1187
- this.logger?.log({
1188
- level: "info",
1189
- message: `Session closed: ${transport.sessionId}`
1190
- });
1191
1504
  delete transports[transport.sessionId];
1192
1505
  }
1193
1506
  };
@@ -1198,10 +1511,6 @@ var MCPRemote = class extends MCPBase {
1198
1511
  this.setupTools();
1199
1512
  await this.mcpServer.connect(transport);
1200
1513
  } else {
1201
- this.logger?.log({
1202
- level: "error",
1203
- message: "Invalid request: No valid session ID provided"
1204
- });
1205
1514
  res.writeHead(400, { "Content-Type": "application/json" });
1206
1515
  res.end(
1207
1516
  JSON.stringify({
@@ -1217,10 +1526,6 @@ var MCPRemote = class extends MCPBase {
1217
1526
  }
1218
1527
  try {
1219
1528
  await transport.handleRequest(req, res, parsed);
1220
- this.logger?.log({
1221
- level: "info",
1222
- message: "Request handled successfully"
1223
- });
1224
1529
  } catch (error) {
1225
1530
  this.logger?.log({
1226
1531
  level: "error",
@@ -1231,10 +1536,6 @@ var MCPRemote = class extends MCPBase {
1231
1536
  });
1232
1537
  } else if (req.method === "GET" || req.method === "DELETE") {
1233
1538
  if (!sessionId || !transports[sessionId]) {
1234
- this.logger?.log({
1235
- level: "error",
1236
- message: `Invalid session ID for ${req.method} request: ${sessionId}`
1237
- });
1238
1539
  res.writeHead(400);
1239
1540
  res.end("Invalid or missing session ID");
1240
1541
  return;
@@ -1242,10 +1543,6 @@ var MCPRemote = class extends MCPBase {
1242
1543
  const transport = transports[sessionId];
1243
1544
  try {
1244
1545
  await transport.handleRequest(req, res);
1245
- this.logger?.log({
1246
- level: "info",
1247
- message: `${req.method} request handled successfully for session: ${sessionId}`
1248
- });
1249
1546
  } catch (error) {
1250
1547
  this.logger?.log({
1251
1548
  level: "error",
@@ -1262,10 +1559,6 @@ var MCPRemote = class extends MCPBase {
1262
1559
  res.end("Method Not Allowed");
1263
1560
  }
1264
1561
  } else {
1265
- this.logger?.log({
1266
- level: "error",
1267
- message: `Not found: ${req.url}`
1268
- });
1269
1562
  res.writeHead(404);
1270
1563
  res.end("Not Found");
1271
1564
  }
@@ -1295,69 +1588,40 @@ var MCPRemote = class extends MCPBase {
1295
1588
  });
1296
1589
  return;
1297
1590
  }
1298
- this.mcpServer.tool(
1299
- "tools/list",
1300
- {
1301
- description: "List available tools",
1302
- schema: import_zod2.z.object({})
1303
- },
1304
- async () => {
1305
- return {
1306
- content: [
1307
- {
1308
- type: "text",
1309
- text: JSON.stringify(
1310
- Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
1311
- name,
1312
- description,
1313
- inputSchema: schema
1314
- }))
1315
- )
1316
- }
1317
- ]
1318
- };
1319
- }
1591
+ const toolHandlers = createToolHandlers(
1592
+ this.parser,
1593
+ this.verifiedOrders,
1594
+ this.pendingRequests,
1595
+ this.marketDataPrices
1320
1596
  );
1321
- this.mcpServer.tool(
1322
- "tools/call",
1323
- {
1324
- description: "Call a tool",
1325
- schema: import_zod2.z.object({
1326
- name: import_zod2.z.string(),
1327
- arguments: import_zod2.z.any(),
1328
- _meta: import_zod2.z.object({
1329
- progressToken: import_zod2.z.number()
1330
- }).optional()
1331
- })
1332
- },
1333
- async (request) => {
1334
- const { name, arguments: args } = request;
1335
- const toolHandlers = createToolHandlers(
1336
- this.parser,
1337
- this.verifiedOrders,
1338
- this.pendingRequests,
1339
- this.marketDataPrices
1340
- );
1341
- const handler = toolHandlers[name];
1342
- if (!handler) {
1597
+ Object.entries(toolSchemas).forEach(([name, { description, schema }]) => {
1598
+ this.mcpServer?.registerTool(
1599
+ name,
1600
+ {
1601
+ description,
1602
+ inputSchema: jsonSchemaToZod(schema)
1603
+ },
1604
+ async (args) => {
1605
+ const handler = toolHandlers[name];
1606
+ if (!handler) {
1607
+ return {
1608
+ content: [
1609
+ {
1610
+ type: "text",
1611
+ text: `Tool not found: ${name}`
1612
+ }
1613
+ ],
1614
+ isError: true
1615
+ };
1616
+ }
1617
+ const result = await handler(args);
1343
1618
  return {
1344
- content: [
1345
- {
1346
- type: "text",
1347
- text: `Tool not found: ${name}`,
1348
- uri: name
1349
- }
1350
- ],
1351
- isError: true
1619
+ content: result.content,
1620
+ isError: result.isError
1352
1621
  };
1353
1622
  }
1354
- const result = await handler(args);
1355
- return {
1356
- content: result.content,
1357
- isError: result.isError
1358
- };
1359
- }
1360
- );
1623
+ );
1624
+ });
1361
1625
  }
1362
1626
  };
1363
1627
  // Annotate the CommonJS export names for ESM import in node: