fixparser-plugin-mcp 9.1.7-620b3399 → 9.1.7-63c797c5

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.",
169
+ description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
170
170
  schema: {
171
171
  type: "object",
172
172
  properties: {
@@ -319,63 +319,10 @@ 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
- });
326
322
  const response = new Promise((resolve) => {
327
323
  pendingRequests.set(args.mdReqID, resolve);
328
- parser.logger.log({
329
- level: "info",
330
- message: `Registered callback for market data request ID: ${args.mdReqID}`
331
- });
332
324
  });
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
- ];
325
+ const entryTypes = args.mdEntryTypes || [import_fixparser.MDEntryType.Bid, import_fixparser.MDEntryType.Offer, import_fixparser.MDEntryType.TradeVolume];
379
326
  const messageFields = [
380
327
  new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
381
328
  new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
@@ -397,10 +344,6 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
397
344
  });
398
345
  const mdr = parser.createMessage(...messageFields);
399
346
  if (!parser.connected) {
400
- parser.logger.log({
401
- level: "error",
402
- message: "Not connected. Cannot send market data request."
403
- });
404
347
  return {
405
348
  content: [
406
349
  {
@@ -412,16 +355,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
412
355
  isError: true
413
356
  };
414
357
  }
415
- parser.logger.log({
416
- level: "info",
417
- message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
418
- });
419
358
  parser.send(mdr);
420
359
  const fixData = await response;
421
- parser.logger.log({
422
- level: "info",
423
- message: `Received market data response for request ID: ${args.mdReqID}`
424
- });
425
360
  return {
426
361
  content: [
427
362
  {
@@ -470,9 +405,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
470
405
  const offerData = priceHistory.map((point) => point.offer);
471
406
  const spreadData = priceHistory.map((point) => point.spread);
472
407
  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);
476
408
  const config = {
477
409
  type: "line",
478
410
  data: {
@@ -502,30 +434,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
502
434
  fill: false,
503
435
  tension: 0.4
504
436
  },
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
- },
529
437
  {
530
438
  label: "Volume",
531
439
  data: volumeData,
@@ -571,7 +479,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
571
479
  content: [
572
480
  {
573
481
  type: "text",
574
- text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
482
+ text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
575
483
  uri: "getStockGraph"
576
484
  }
577
485
  ],
@@ -609,48 +517,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
609
517
  bid: point.bid,
610
518
  offer: point.offer,
611
519
  spread: point.spread,
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
520
+ volume: point.volume
654
521
  }))
655
522
  },
656
523
  null,
@@ -665,7 +532,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
665
532
  content: [
666
533
  {
667
534
  type: "text",
668
- text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
535
+ text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
669
536
  uri: "getStockPriceHistory"
670
537
  }
671
538
  ],
@@ -773,7 +640,7 @@ Parameters verified:
773
640
  - Symbol: ${args.symbol}
774
641
  - TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
775
642
 
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!`,
643
+ To execute this order, call the executeOrder tool with these exact same parameters.`,
777
644
  uri: "verifyOrder"
778
645
  }
779
646
  ]
@@ -980,245 +847,46 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
980
847
  message: `MCP Server received message: ${message.messageType}: ${message.description}`
981
848
  });
982
849
  const msgType = message.messageType;
983
- if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
850
+ if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
984
851
  const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
985
- parser.logger.log({
986
- level: "info",
987
- message: `Processing market data for symbol: ${symbol}`
988
- });
989
- const fixJson = message.toFIXJSON();
990
- const entries = fixJson.Body?.NoMDEntries || [];
991
- parser.logger.log({
992
- level: "info",
993
- message: `Found ${entries.length} market data entries`
994
- });
995
- const data = {
996
- timestamp: Date.now(),
997
- bid: 0,
998
- offer: 0,
999
- spread: 0,
1000
- volume: 0,
1001
- trade: 0,
1002
- indexValue: 0,
1003
- openingPrice: 0,
1004
- closingPrice: 0,
1005
- settlementPrice: 0,
1006
- tradingSessionHighPrice: 0,
1007
- tradingSessionLowPrice: 0,
1008
- vwap: 0,
1009
- imbalance: 0,
1010
- openInterest: 0,
1011
- compositeUnderlyingPrice: 0,
1012
- simulatedSellPrice: 0,
1013
- simulatedBuyPrice: 0,
1014
- marginRate: 0,
1015
- midPrice: 0,
1016
- emptyBook: 0,
1017
- settleHighPrice: 0,
1018
- settleLowPrice: 0,
1019
- priorSettlePrice: 0,
1020
- sessionHighBid: 0,
1021
- sessionLowOffer: 0,
1022
- earlyPrices: 0,
1023
- auctionClearingPrice: 0,
1024
- swapValueFactor: 0,
1025
- dailyValueAdjustmentForLongPositions: 0,
1026
- cumulativeValueAdjustmentForLongPositions: 0,
1027
- dailyValueAdjustmentForShortPositions: 0,
1028
- cumulativeValueAdjustmentForShortPositions: 0,
1029
- fixingPrice: 0,
1030
- cashRate: 0,
1031
- recoveryRate: 0,
1032
- recoveryRateForLong: 0,
1033
- recoveryRateForShort: 0,
1034
- marketBid: 0,
1035
- marketOffer: 0,
1036
- shortSaleMinPrice: 0,
1037
- previousClosingPrice: 0,
1038
- thresholdLimitPriceBanding: 0,
1039
- dailyFinancingValue: 0,
1040
- accruedFinancingValue: 0,
1041
- twap: 0
1042
- };
1043
- for (const entry of entries) {
1044
- const entryType = entry.MDEntryType;
1045
- const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
1046
- const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
1047
- if (entryType === import_fixparser3.MDEntryType.Bid || entryType === import_fixparser3.MDEntryType.Offer || entryType === import_fixparser3.MDEntryType.TradeVolume) {
1048
- parser.logger.log({
1049
- level: "info",
1050
- message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
1051
- });
1052
- }
1053
- switch (entryType) {
1054
- case import_fixparser3.MDEntryType.Bid:
1055
- data.bid = price;
1056
- break;
1057
- case import_fixparser3.MDEntryType.Offer:
1058
- data.offer = price;
1059
- break;
1060
- case import_fixparser3.MDEntryType.Trade:
1061
- data.trade = price;
1062
- break;
1063
- case import_fixparser3.MDEntryType.IndexValue:
1064
- data.indexValue = price;
1065
- break;
1066
- case import_fixparser3.MDEntryType.OpeningPrice:
1067
- data.openingPrice = price;
1068
- break;
1069
- case import_fixparser3.MDEntryType.ClosingPrice:
1070
- data.closingPrice = price;
1071
- break;
1072
- case import_fixparser3.MDEntryType.SettlementPrice:
1073
- data.settlementPrice = price;
1074
- break;
1075
- case import_fixparser3.MDEntryType.TradingSessionHighPrice:
1076
- data.tradingSessionHighPrice = price;
1077
- break;
1078
- case import_fixparser3.MDEntryType.TradingSessionLowPrice:
1079
- data.tradingSessionLowPrice = price;
1080
- break;
1081
- case import_fixparser3.MDEntryType.VWAP:
1082
- data.vwap = price;
1083
- break;
1084
- case import_fixparser3.MDEntryType.Imbalance:
1085
- data.imbalance = size;
1086
- break;
1087
- case import_fixparser3.MDEntryType.TradeVolume:
1088
- data.volume = size;
1089
- break;
1090
- case import_fixparser3.MDEntryType.OpenInterest:
1091
- data.openInterest = size;
1092
- break;
1093
- case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
1094
- data.compositeUnderlyingPrice = price;
1095
- break;
1096
- case import_fixparser3.MDEntryType.SimulatedSellPrice:
1097
- data.simulatedSellPrice = price;
1098
- break;
1099
- case import_fixparser3.MDEntryType.SimulatedBuyPrice:
1100
- data.simulatedBuyPrice = price;
1101
- break;
1102
- case import_fixparser3.MDEntryType.MarginRate:
1103
- data.marginRate = price;
1104
- break;
1105
- case import_fixparser3.MDEntryType.MidPrice:
1106
- data.midPrice = price;
1107
- break;
1108
- case import_fixparser3.MDEntryType.EmptyBook:
1109
- data.emptyBook = 1;
1110
- break;
1111
- case import_fixparser3.MDEntryType.SettleHighPrice:
1112
- data.settleHighPrice = price;
1113
- break;
1114
- case import_fixparser3.MDEntryType.SettleLowPrice:
1115
- data.settleLowPrice = price;
1116
- break;
1117
- case import_fixparser3.MDEntryType.PriorSettlePrice:
1118
- data.priorSettlePrice = price;
1119
- break;
1120
- case import_fixparser3.MDEntryType.SessionHighBid:
1121
- data.sessionHighBid = price;
1122
- break;
1123
- case import_fixparser3.MDEntryType.SessionLowOffer:
1124
- data.sessionLowOffer = price;
1125
- break;
1126
- case import_fixparser3.MDEntryType.EarlyPrices:
1127
- data.earlyPrices = price;
1128
- break;
1129
- case import_fixparser3.MDEntryType.AuctionClearingPrice:
1130
- data.auctionClearingPrice = price;
1131
- break;
1132
- case import_fixparser3.MDEntryType.SwapValueFactor:
1133
- data.swapValueFactor = price;
1134
- break;
1135
- case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
1136
- data.dailyValueAdjustmentForLongPositions = price;
1137
- break;
1138
- case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
1139
- data.cumulativeValueAdjustmentForLongPositions = price;
1140
- break;
1141
- case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
1142
- data.dailyValueAdjustmentForShortPositions = price;
1143
- break;
1144
- case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
1145
- data.cumulativeValueAdjustmentForShortPositions = price;
1146
- break;
1147
- case import_fixparser3.MDEntryType.FixingPrice:
1148
- data.fixingPrice = price;
1149
- break;
1150
- case import_fixparser3.MDEntryType.CashRate:
1151
- data.cashRate = price;
1152
- break;
1153
- case import_fixparser3.MDEntryType.RecoveryRate:
1154
- data.recoveryRate = price;
1155
- break;
1156
- case import_fixparser3.MDEntryType.RecoveryRateForLong:
1157
- data.recoveryRateForLong = price;
1158
- break;
1159
- case import_fixparser3.MDEntryType.RecoveryRateForShort:
1160
- data.recoveryRateForShort = price;
1161
- break;
1162
- case import_fixparser3.MDEntryType.MarketBid:
1163
- data.marketBid = price;
1164
- break;
1165
- case import_fixparser3.MDEntryType.MarketOffer:
1166
- data.marketOffer = price;
1167
- break;
1168
- case import_fixparser3.MDEntryType.ShortSaleMinPrice:
1169
- data.shortSaleMinPrice = price;
1170
- break;
1171
- case import_fixparser3.MDEntryType.PreviousClosingPrice:
1172
- data.previousClosingPrice = price;
1173
- break;
1174
- case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
1175
- data.thresholdLimitPriceBanding = price;
1176
- break;
1177
- case import_fixparser3.MDEntryType.DailyFinancingValue:
1178
- data.dailyFinancingValue = price;
1179
- break;
1180
- case import_fixparser3.MDEntryType.AccruedFinancingValue:
1181
- data.accruedFinancingValue = price;
1182
- break;
1183
- case import_fixparser3.MDEntryType.TWAP:
1184
- data.twap = price;
1185
- break;
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;
1186
870
  }
1187
871
  }
1188
- data.spread = data.offer - data.bid;
872
+ const spread = offer - bid;
873
+ const timestamp = Date.now();
874
+ const data = {
875
+ timestamp,
876
+ bid,
877
+ offer,
878
+ spread,
879
+ volume
880
+ };
1189
881
  if (!marketDataPrices.has(symbol)) {
1190
- parser.logger.log({
1191
- level: "info",
1192
- message: `Creating new price history array for symbol: ${symbol}`
1193
- });
1194
882
  marketDataPrices.set(symbol, []);
1195
883
  }
1196
884
  const prices = marketDataPrices.get(symbol);
1197
885
  prices.push(data);
1198
- parser.logger.log({
1199
- level: "info",
1200
- message: `Updated price history for ${symbol}. Current size: ${prices.length}`
1201
- });
1202
886
  if (prices.length > maxPriceHistory) {
1203
887
  prices.splice(0, prices.length - maxPriceHistory);
1204
- parser.logger.log({
1205
- level: "info",
1206
- message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
1207
- });
1208
888
  }
1209
889
  onPriceUpdate?.(symbol, data);
1210
- const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
1211
- if (mdReqID) {
1212
- const callback = pendingRequests.get(mdReqID);
1213
- if (callback) {
1214
- callback(message);
1215
- pendingRequests.delete(mdReqID);
1216
- parser.logger.log({
1217
- level: "info",
1218
- message: `Resolved market data request for ID: ${mdReqID}`
1219
- });
1220
- }
1221
- }
1222
890
  } else if (msgType === import_fixparser3.Messages.ExecutionReport) {
1223
891
  const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
1224
892
  const callback = pendingRequests.get(reqId);
@@ -1231,39 +899,6 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
1231
899
 
1232
900
  // src/MCPRemote.ts
1233
901
  var transports = {};
1234
- function jsonSchemaToZod(schema) {
1235
- if (schema.type === "object") {
1236
- const shape = {};
1237
- for (const [key, prop] of Object.entries(schema.properties || {})) {
1238
- const propSchema = prop;
1239
- if (propSchema.type === "string") {
1240
- if (propSchema.enum) {
1241
- shape[key] = import_zod.z.enum(propSchema.enum);
1242
- } else {
1243
- shape[key] = import_zod.z.string();
1244
- }
1245
- } else if (propSchema.type === "number") {
1246
- shape[key] = import_zod.z.number();
1247
- } else if (propSchema.type === "boolean") {
1248
- shape[key] = import_zod.z.boolean();
1249
- } else if (propSchema.type === "array") {
1250
- if (propSchema.items.type === "string") {
1251
- shape[key] = import_zod.z.array(import_zod.z.string());
1252
- } else if (propSchema.items.type === "number") {
1253
- shape[key] = import_zod.z.array(import_zod.z.number());
1254
- } else if (propSchema.items.type === "boolean") {
1255
- shape[key] = import_zod.z.array(import_zod.z.boolean());
1256
- } else {
1257
- shape[key] = import_zod.z.array(import_zod.z.any());
1258
- }
1259
- } else {
1260
- shape[key] = import_zod.z.any();
1261
- }
1262
- }
1263
- return shape;
1264
- }
1265
- return {};
1266
- }
1267
902
  var MCPRemote = class extends MCPBase {
1268
903
  /**
1269
904
  * Port number the server will listen on.
@@ -1306,7 +941,7 @@ var MCPRemote = class extends MCPBase {
1306
941
  */
1307
942
  marketDataPrices = /* @__PURE__ */ new Map();
1308
943
  /**
1309
- * Maximum number of price history entries to keep per symbol
944
+ * Maximum number of price points to store per symbol
1310
945
  * @private
1311
946
  */
1312
947
  MAX_PRICE_HISTORY = 1e5;
@@ -1328,22 +963,55 @@ var MCPRemote = class extends MCPBase {
1328
963
  this.parser,
1329
964
  this.pendingRequests,
1330
965
  this.marketDataPrices,
1331
- this.MAX_PRICE_HISTORY
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
+ }
1332
991
  );
1333
- this.logger?.log({
1334
- level: "info",
1335
- message: `Market Data Prices TEST: ${JSON.stringify(this.marketDataPrices)}`
1336
- });
1337
992
  }
1338
993
  });
1339
994
  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
+ });
1340
1000
  if (!req.url || !req.method) {
1001
+ this.logger?.log({
1002
+ level: "error",
1003
+ message: "Invalid request: missing URL or method"
1004
+ });
1341
1005
  res.writeHead(400);
1342
1006
  res.end("Bad Request");
1343
1007
  return;
1344
1008
  }
1345
1009
  if (req.url === "/mcp") {
1346
1010
  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
+ });
1347
1015
  if (req.method === "POST") {
1348
1016
  const bodyChunks = [];
1349
1017
  req.on("data", (chunk) => {
@@ -1354,23 +1022,47 @@ var MCPRemote = class extends MCPBase {
1354
1022
  const body = Buffer.concat(bodyChunks).toString();
1355
1023
  try {
1356
1024
  parsed = JSON.parse(body);
1025
+ this.logger?.log({
1026
+ level: "info",
1027
+ message: `Parsed request body: ${JSON.stringify(parsed)}`
1028
+ });
1357
1029
  } catch (err) {
1030
+ this.logger?.log({
1031
+ level: "error",
1032
+ message: `Failed to parse JSON body: ${err}`
1033
+ });
1358
1034
  res.writeHead(400);
1359
1035
  res.end(JSON.stringify({ error: "Invalid JSON" }));
1360
1036
  return;
1361
1037
  }
1362
1038
  let transport;
1363
1039
  if (sessionId && transports[sessionId]) {
1040
+ this.logger?.log({
1041
+ level: "info",
1042
+ message: `Using existing transport for session: ${sessionId}`
1043
+ });
1364
1044
  transport = transports[sessionId];
1365
1045
  } 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
+ });
1366
1050
  transport = new import_streamableHttp.StreamableHTTPServerTransport({
1367
1051
  sessionIdGenerator: () => (0, import_node_crypto.randomUUID)(),
1368
1052
  onsessioninitialized: (sessionId2) => {
1053
+ this.logger?.log({
1054
+ level: "info",
1055
+ message: `New session initialized: ${sessionId2}`
1056
+ });
1369
1057
  transports[sessionId2] = transport;
1370
1058
  }
1371
1059
  });
1372
1060
  transport.onclose = () => {
1373
1061
  if (transport.sessionId) {
1062
+ this.logger?.log({
1063
+ level: "info",
1064
+ message: `Session closed: ${transport.sessionId}`
1065
+ });
1374
1066
  delete transports[transport.sessionId];
1375
1067
  }
1376
1068
  };
@@ -1381,6 +1073,10 @@ var MCPRemote = class extends MCPBase {
1381
1073
  this.setupTools();
1382
1074
  await this.mcpServer.connect(transport);
1383
1075
  } else {
1076
+ this.logger?.log({
1077
+ level: "error",
1078
+ message: "Invalid request: No valid session ID provided"
1079
+ });
1384
1080
  res.writeHead(400, { "Content-Type": "application/json" });
1385
1081
  res.end(
1386
1082
  JSON.stringify({
@@ -1396,6 +1092,10 @@ var MCPRemote = class extends MCPBase {
1396
1092
  }
1397
1093
  try {
1398
1094
  await transport.handleRequest(req, res, parsed);
1095
+ this.logger?.log({
1096
+ level: "info",
1097
+ message: "Request handled successfully"
1098
+ });
1399
1099
  } catch (error) {
1400
1100
  this.logger?.log({
1401
1101
  level: "error",
@@ -1406,6 +1106,10 @@ var MCPRemote = class extends MCPBase {
1406
1106
  });
1407
1107
  } else if (req.method === "GET" || req.method === "DELETE") {
1408
1108
  if (!sessionId || !transports[sessionId]) {
1109
+ this.logger?.log({
1110
+ level: "error",
1111
+ message: `Invalid session ID for ${req.method} request: ${sessionId}`
1112
+ });
1409
1113
  res.writeHead(400);
1410
1114
  res.end("Invalid or missing session ID");
1411
1115
  return;
@@ -1413,6 +1117,10 @@ var MCPRemote = class extends MCPBase {
1413
1117
  const transport = transports[sessionId];
1414
1118
  try {
1415
1119
  await transport.handleRequest(req, res);
1120
+ this.logger?.log({
1121
+ level: "info",
1122
+ message: `${req.method} request handled successfully for session: ${sessionId}`
1123
+ });
1416
1124
  } catch (error) {
1417
1125
  this.logger?.log({
1418
1126
  level: "error",
@@ -1429,6 +1137,10 @@ var MCPRemote = class extends MCPBase {
1429
1137
  res.end("Method Not Allowed");
1430
1138
  }
1431
1139
  } else {
1140
+ this.logger?.log({
1141
+ level: "error",
1142
+ message: `Not found: ${req.url}`
1143
+ });
1432
1144
  res.writeHead(404);
1433
1145
  res.end("Not Found");
1434
1146
  }
@@ -1458,40 +1170,69 @@ var MCPRemote = class extends MCPBase {
1458
1170
  });
1459
1171
  return;
1460
1172
  }
1461
- const toolHandlers = createToolHandlers(
1462
- this.parser,
1463
- this.verifiedOrders,
1464
- this.pendingRequests,
1465
- this.marketDataPrices
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
1195
  );
1467
- Object.entries(toolSchemas).forEach(([name, { description, schema }]) => {
1468
- this.mcpServer?.registerTool(
1469
- name,
1470
- {
1471
- description,
1472
- inputSchema: jsonSchemaToZod(schema)
1473
- },
1474
- async (args) => {
1475
- const handler = toolHandlers[name];
1476
- if (!handler) {
1477
- return {
1478
- content: [
1479
- {
1480
- type: "text",
1481
- text: `Tool not found: ${name}`
1482
- }
1483
- ],
1484
- isError: true
1485
- };
1486
- }
1487
- const result = await handler(args);
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) {
1488
1218
  return {
1489
- content: result.content,
1490
- isError: result.isError
1219
+ content: [
1220
+ {
1221
+ type: "text",
1222
+ text: `Tool not found: ${name}`,
1223
+ uri: name
1224
+ }
1225
+ ],
1226
+ isError: true
1491
1227
  };
1492
1228
  }
1493
- );
1494
- });
1229
+ const result = await handler(args);
1230
+ return {
1231
+ content: result.content,
1232
+ isError: result.isError
1233
+ };
1234
+ }
1235
+ );
1495
1236
  }
1496
1237
  };
1497
1238
  // Annotate the CommonJS export names for ESM import in node: