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);
@@ -899,6 +1236,39 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
899
1236
 
900
1237
  // src/MCPRemote.ts
901
1238
  var transports = {};
1239
+ function jsonSchemaToZod(schema) {
1240
+ if (schema.type === "object") {
1241
+ const shape = {};
1242
+ for (const [key, prop] of Object.entries(schema.properties || {})) {
1243
+ const propSchema = prop;
1244
+ if (propSchema.type === "string") {
1245
+ if (propSchema.enum) {
1246
+ shape[key] = import_zod.z.enum(propSchema.enum);
1247
+ } else {
1248
+ shape[key] = import_zod.z.string();
1249
+ }
1250
+ } else if (propSchema.type === "number") {
1251
+ shape[key] = import_zod.z.number();
1252
+ } else if (propSchema.type === "boolean") {
1253
+ shape[key] = import_zod.z.boolean();
1254
+ } else if (propSchema.type === "array") {
1255
+ if (propSchema.items.type === "string") {
1256
+ shape[key] = import_zod.z.array(import_zod.z.string());
1257
+ } else if (propSchema.items.type === "number") {
1258
+ shape[key] = import_zod.z.array(import_zod.z.number());
1259
+ } else if (propSchema.items.type === "boolean") {
1260
+ shape[key] = import_zod.z.array(import_zod.z.boolean());
1261
+ } else {
1262
+ shape[key] = import_zod.z.array(import_zod.z.any());
1263
+ }
1264
+ } else {
1265
+ shape[key] = import_zod.z.any();
1266
+ }
1267
+ }
1268
+ return shape;
1269
+ }
1270
+ return {};
1271
+ }
902
1272
  var MCPRemote = class extends MCPBase {
903
1273
  /**
904
1274
  * Port number the server will listen on.
@@ -941,7 +1311,7 @@ var MCPRemote = class extends MCPBase {
941
1311
  */
942
1312
  marketDataPrices = /* @__PURE__ */ new Map();
943
1313
  /**
944
- * Maximum number of price points to store per symbol
1314
+ * Maximum number of price history entries to keep per symbol
945
1315
  * @private
946
1316
  */
947
1317
  MAX_PRICE_HISTORY = 1e5;
@@ -963,55 +1333,22 @@ var MCPRemote = class extends MCPBase {
963
1333
  this.parser,
964
1334
  this.pendingRequests,
965
1335
  this.marketDataPrices,
966
- this.MAX_PRICE_HISTORY,
967
- (symbol, data) => {
968
- this.mcpServer?.tool(
969
- "priceUpdate",
970
- {
971
- description: "Price update notification",
972
- schema: import_zod.z.object({
973
- symbol: import_zod.z.string(),
974
- timestamp: import_zod.z.number(),
975
- bid: import_zod.z.number(),
976
- offer: import_zod.z.number(),
977
- spread: import_zod.z.number(),
978
- volume: import_zod.z.number()
979
- })
980
- },
981
- () => ({
982
- content: [
983
- {
984
- type: "text",
985
- text: JSON.stringify({ symbol, ...data })
986
- }
987
- ]
988
- })
989
- );
990
- }
1336
+ this.MAX_PRICE_HISTORY
991
1337
  );
1338
+ this.logger?.log({
1339
+ level: "info",
1340
+ message: `Market Data Prices TEST: ${JSON.stringify(this.marketDataPrices)}`
1341
+ });
992
1342
  }
993
1343
  });
994
1344
  this.httpServer = (0, import_node_http.createServer)(async (req, res) => {
995
- console.log(req.headers);
996
- this.logger?.log({
997
- level: "info",
998
- message: `Incoming request: ${req.method} ${req.url}`
999
- });
1000
1345
  if (!req.url || !req.method) {
1001
- this.logger?.log({
1002
- level: "error",
1003
- message: "Invalid request: missing URL or method"
1004
- });
1005
1346
  res.writeHead(400);
1006
1347
  res.end("Bad Request");
1007
1348
  return;
1008
1349
  }
1009
1350
  if (req.url === "/mcp") {
1010
1351
  const sessionId = req.headers["mcp-session-id"];
1011
- this.logger?.log({
1012
- level: "info",
1013
- message: `MCP request received. Session ID: ${sessionId || "none"}, headers: ${req.headers}`
1014
- });
1015
1352
  if (req.method === "POST") {
1016
1353
  const bodyChunks = [];
1017
1354
  req.on("data", (chunk) => {
@@ -1022,47 +1359,23 @@ var MCPRemote = class extends MCPBase {
1022
1359
  const body = Buffer.concat(bodyChunks).toString();
1023
1360
  try {
1024
1361
  parsed = JSON.parse(body);
1025
- this.logger?.log({
1026
- level: "info",
1027
- message: `Parsed request body: ${JSON.stringify(parsed)}`
1028
- });
1029
1362
  } catch (err) {
1030
- this.logger?.log({
1031
- level: "error",
1032
- message: `Failed to parse JSON body: ${err}`
1033
- });
1034
1363
  res.writeHead(400);
1035
1364
  res.end(JSON.stringify({ error: "Invalid JSON" }));
1036
1365
  return;
1037
1366
  }
1038
1367
  let transport;
1039
1368
  if (sessionId && transports[sessionId]) {
1040
- this.logger?.log({
1041
- level: "info",
1042
- message: `Using existing transport for session: ${sessionId}`
1043
- });
1044
1369
  transport = transports[sessionId];
1045
1370
  } else if (!sessionId && req.method === "POST" && (0, import_types.isInitializeRequest)(parsed)) {
1046
- this.logger?.log({
1047
- level: "info",
1048
- message: "Creating new transport for initialization request"
1049
- });
1050
1371
  transport = new import_streamableHttp.StreamableHTTPServerTransport({
1051
1372
  sessionIdGenerator: () => (0, import_node_crypto.randomUUID)(),
1052
1373
  onsessioninitialized: (sessionId2) => {
1053
- this.logger?.log({
1054
- level: "info",
1055
- message: `New session initialized: ${sessionId2}`
1056
- });
1057
1374
  transports[sessionId2] = transport;
1058
1375
  }
1059
1376
  });
1060
1377
  transport.onclose = () => {
1061
1378
  if (transport.sessionId) {
1062
- this.logger?.log({
1063
- level: "info",
1064
- message: `Session closed: ${transport.sessionId}`
1065
- });
1066
1379
  delete transports[transport.sessionId];
1067
1380
  }
1068
1381
  };
@@ -1073,10 +1386,6 @@ var MCPRemote = class extends MCPBase {
1073
1386
  this.setupTools();
1074
1387
  await this.mcpServer.connect(transport);
1075
1388
  } else {
1076
- this.logger?.log({
1077
- level: "error",
1078
- message: "Invalid request: No valid session ID provided"
1079
- });
1080
1389
  res.writeHead(400, { "Content-Type": "application/json" });
1081
1390
  res.end(
1082
1391
  JSON.stringify({
@@ -1092,10 +1401,6 @@ var MCPRemote = class extends MCPBase {
1092
1401
  }
1093
1402
  try {
1094
1403
  await transport.handleRequest(req, res, parsed);
1095
- this.logger?.log({
1096
- level: "info",
1097
- message: "Request handled successfully"
1098
- });
1099
1404
  } catch (error) {
1100
1405
  this.logger?.log({
1101
1406
  level: "error",
@@ -1106,10 +1411,6 @@ var MCPRemote = class extends MCPBase {
1106
1411
  });
1107
1412
  } else if (req.method === "GET" || req.method === "DELETE") {
1108
1413
  if (!sessionId || !transports[sessionId]) {
1109
- this.logger?.log({
1110
- level: "error",
1111
- message: `Invalid session ID for ${req.method} request: ${sessionId}`
1112
- });
1113
1414
  res.writeHead(400);
1114
1415
  res.end("Invalid or missing session ID");
1115
1416
  return;
@@ -1117,10 +1418,6 @@ var MCPRemote = class extends MCPBase {
1117
1418
  const transport = transports[sessionId];
1118
1419
  try {
1119
1420
  await transport.handleRequest(req, res);
1120
- this.logger?.log({
1121
- level: "info",
1122
- message: `${req.method} request handled successfully for session: ${sessionId}`
1123
- });
1124
1421
  } catch (error) {
1125
1422
  this.logger?.log({
1126
1423
  level: "error",
@@ -1137,10 +1434,6 @@ var MCPRemote = class extends MCPBase {
1137
1434
  res.end("Method Not Allowed");
1138
1435
  }
1139
1436
  } else {
1140
- this.logger?.log({
1141
- level: "error",
1142
- message: `Not found: ${req.url}`
1143
- });
1144
1437
  res.writeHead(404);
1145
1438
  res.end("Not Found");
1146
1439
  }
@@ -1170,69 +1463,40 @@ var MCPRemote = class extends MCPBase {
1170
1463
  });
1171
1464
  return;
1172
1465
  }
1173
- this.mcpServer.tool(
1174
- "tools/list",
1175
- {
1176
- description: "List available tools",
1177
- schema: import_zod.z.object({})
1178
- },
1179
- async () => {
1180
- return {
1181
- content: [
1182
- {
1183
- type: "text",
1184
- text: JSON.stringify(
1185
- Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
1186
- name,
1187
- description,
1188
- inputSchema: schema
1189
- }))
1190
- )
1191
- }
1192
- ]
1193
- };
1194
- }
1466
+ const toolHandlers = createToolHandlers(
1467
+ this.parser,
1468
+ this.verifiedOrders,
1469
+ this.pendingRequests,
1470
+ this.marketDataPrices
1195
1471
  );
1196
- this.mcpServer.tool(
1197
- "tools/call",
1198
- {
1199
- description: "Call a tool",
1200
- schema: import_zod.z.object({
1201
- name: import_zod.z.string(),
1202
- arguments: import_zod.z.any(),
1203
- _meta: import_zod.z.object({
1204
- progressToken: import_zod.z.number()
1205
- }).optional()
1206
- })
1207
- },
1208
- async (request) => {
1209
- const { name, arguments: args } = request;
1210
- const toolHandlers = createToolHandlers(
1211
- this.parser,
1212
- this.verifiedOrders,
1213
- this.pendingRequests,
1214
- this.marketDataPrices
1215
- );
1216
- const handler = toolHandlers[name];
1217
- if (!handler) {
1472
+ Object.entries(toolSchemas).forEach(([name, { description, schema }]) => {
1473
+ this.mcpServer?.registerTool(
1474
+ name,
1475
+ {
1476
+ description,
1477
+ inputSchema: jsonSchemaToZod(schema)
1478
+ },
1479
+ async (args) => {
1480
+ const handler = toolHandlers[name];
1481
+ if (!handler) {
1482
+ return {
1483
+ content: [
1484
+ {
1485
+ type: "text",
1486
+ text: `Tool not found: ${name}`
1487
+ }
1488
+ ],
1489
+ isError: true
1490
+ };
1491
+ }
1492
+ const result = await handler(args);
1218
1493
  return {
1219
- content: [
1220
- {
1221
- type: "text",
1222
- text: `Tool not found: ${name}`,
1223
- uri: name
1224
- }
1225
- ],
1226
- isError: true
1494
+ content: result.content,
1495
+ isError: result.isError
1227
1496
  };
1228
1497
  }
1229
- const result = await handler(args);
1230
- return {
1231
- content: result.content,
1232
- isError: result.isError
1233
- };
1234
- }
1235
- );
1498
+ );
1499
+ });
1236
1500
  }
1237
1501
  };
1238
1502
  // Annotate the CommonJS export names for ESM import in node: