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.
@@ -129,7 +129,7 @@ var toolSchemas = {
129
129
  }
130
130
  },
131
131
  executeOrder: {
132
- description: "Executes a verified order. verifyOrder must be called before executeOrder.",
132
+ description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
133
133
  schema: {
134
134
  type: "object",
135
135
  properties: {
@@ -282,63 +282,10 @@ import QuickChart from "quickchart-js";
282
282
  var createMarketDataRequestHandler = (parser, pendingRequests) => {
283
283
  return async (args) => {
284
284
  try {
285
- parser.logger.log({
286
- level: "info",
287
- message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
288
- });
289
285
  const response = new Promise((resolve) => {
290
286
  pendingRequests.set(args.mdReqID, resolve);
291
- parser.logger.log({
292
- level: "info",
293
- message: `Registered callback for market data request ID: ${args.mdReqID}`
294
- });
295
287
  });
296
- const entryTypes = args.mdEntryTypes || [
297
- MDEntryType.Bid,
298
- MDEntryType.Offer,
299
- MDEntryType.Trade,
300
- MDEntryType.IndexValue,
301
- MDEntryType.OpeningPrice,
302
- MDEntryType.ClosingPrice,
303
- MDEntryType.SettlementPrice,
304
- MDEntryType.TradingSessionHighPrice,
305
- MDEntryType.TradingSessionLowPrice,
306
- MDEntryType.VWAP,
307
- MDEntryType.Imbalance,
308
- MDEntryType.TradeVolume,
309
- MDEntryType.OpenInterest,
310
- MDEntryType.CompositeUnderlyingPrice,
311
- MDEntryType.SimulatedSellPrice,
312
- MDEntryType.SimulatedBuyPrice,
313
- MDEntryType.MarginRate,
314
- MDEntryType.MidPrice,
315
- MDEntryType.EmptyBook,
316
- MDEntryType.SettleHighPrice,
317
- MDEntryType.SettleLowPrice,
318
- MDEntryType.PriorSettlePrice,
319
- MDEntryType.SessionHighBid,
320
- MDEntryType.SessionLowOffer,
321
- MDEntryType.EarlyPrices,
322
- MDEntryType.AuctionClearingPrice,
323
- MDEntryType.SwapValueFactor,
324
- MDEntryType.DailyValueAdjustmentForLongPositions,
325
- MDEntryType.CumulativeValueAdjustmentForLongPositions,
326
- MDEntryType.DailyValueAdjustmentForShortPositions,
327
- MDEntryType.CumulativeValueAdjustmentForShortPositions,
328
- MDEntryType.FixingPrice,
329
- MDEntryType.CashRate,
330
- MDEntryType.RecoveryRate,
331
- MDEntryType.RecoveryRateForLong,
332
- MDEntryType.RecoveryRateForShort,
333
- MDEntryType.MarketBid,
334
- MDEntryType.MarketOffer,
335
- MDEntryType.ShortSaleMinPrice,
336
- MDEntryType.PreviousClosingPrice,
337
- MDEntryType.ThresholdLimitPriceBanding,
338
- MDEntryType.DailyFinancingValue,
339
- MDEntryType.AccruedFinancingValue,
340
- MDEntryType.TWAP
341
- ];
288
+ const entryTypes = args.mdEntryTypes || [MDEntryType.Bid, MDEntryType.Offer, MDEntryType.TradeVolume];
342
289
  const messageFields = [
343
290
  new Field(Fields.MsgType, Messages.MarketDataRequest),
344
291
  new Field(Fields.SenderCompID, parser.sender),
@@ -360,10 +307,6 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
360
307
  });
361
308
  const mdr = parser.createMessage(...messageFields);
362
309
  if (!parser.connected) {
363
- parser.logger.log({
364
- level: "error",
365
- message: "Not connected. Cannot send market data request."
366
- });
367
310
  return {
368
311
  content: [
369
312
  {
@@ -375,16 +318,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
375
318
  isError: true
376
319
  };
377
320
  }
378
- parser.logger.log({
379
- level: "info",
380
- message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
381
- });
382
321
  parser.send(mdr);
383
322
  const fixData = await response;
384
- parser.logger.log({
385
- level: "info",
386
- message: `Received market data response for request ID: ${args.mdReqID}`
387
- });
388
323
  return {
389
324
  content: [
390
325
  {
@@ -433,9 +368,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
433
368
  const offerData = priceHistory.map((point) => point.offer);
434
369
  const spreadData = priceHistory.map((point) => point.spread);
435
370
  const volumeData = priceHistory.map((point) => point.volume);
436
- const tradeData = priceHistory.map((point) => point.trade);
437
- const vwapData = priceHistory.map((point) => point.vwap);
438
- const twapData = priceHistory.map((point) => point.twap);
439
371
  const config = {
440
372
  type: "line",
441
373
  data: {
@@ -465,30 +397,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
465
397
  fill: false,
466
398
  tension: 0.4
467
399
  },
468
- {
469
- label: "Trade",
470
- data: tradeData,
471
- borderColor: "#ffc107",
472
- backgroundColor: "rgba(255, 193, 7, 0.1)",
473
- fill: false,
474
- tension: 0.4
475
- },
476
- {
477
- label: "VWAP",
478
- data: vwapData,
479
- borderColor: "#17a2b8",
480
- backgroundColor: "rgba(23, 162, 184, 0.1)",
481
- fill: false,
482
- tension: 0.4
483
- },
484
- {
485
- label: "TWAP",
486
- data: twapData,
487
- borderColor: "#6610f2",
488
- backgroundColor: "rgba(102, 16, 242, 0.1)",
489
- fill: false,
490
- tension: 0.4
491
- },
492
400
  {
493
401
  label: "Volume",
494
402
  data: volumeData,
@@ -534,7 +442,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
534
442
  content: [
535
443
  {
536
444
  type: "text",
537
- text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
445
+ text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
538
446
  uri: "getStockGraph"
539
447
  }
540
448
  ],
@@ -572,48 +480,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
572
480
  bid: point.bid,
573
481
  offer: point.offer,
574
482
  spread: point.spread,
575
- volume: point.volume,
576
- trade: point.trade,
577
- indexValue: point.indexValue,
578
- openingPrice: point.openingPrice,
579
- closingPrice: point.closingPrice,
580
- settlementPrice: point.settlementPrice,
581
- tradingSessionHighPrice: point.tradingSessionHighPrice,
582
- tradingSessionLowPrice: point.tradingSessionLowPrice,
583
- vwap: point.vwap,
584
- imbalance: point.imbalance,
585
- openInterest: point.openInterest,
586
- compositeUnderlyingPrice: point.compositeUnderlyingPrice,
587
- simulatedSellPrice: point.simulatedSellPrice,
588
- simulatedBuyPrice: point.simulatedBuyPrice,
589
- marginRate: point.marginRate,
590
- midPrice: point.midPrice,
591
- emptyBook: point.emptyBook,
592
- settleHighPrice: point.settleHighPrice,
593
- settleLowPrice: point.settleLowPrice,
594
- priorSettlePrice: point.priorSettlePrice,
595
- sessionHighBid: point.sessionHighBid,
596
- sessionLowOffer: point.sessionLowOffer,
597
- earlyPrices: point.earlyPrices,
598
- auctionClearingPrice: point.auctionClearingPrice,
599
- swapValueFactor: point.swapValueFactor,
600
- dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
601
- cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
602
- dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
603
- cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
604
- fixingPrice: point.fixingPrice,
605
- cashRate: point.cashRate,
606
- recoveryRate: point.recoveryRate,
607
- recoveryRateForLong: point.recoveryRateForLong,
608
- recoveryRateForShort: point.recoveryRateForShort,
609
- marketBid: point.marketBid,
610
- marketOffer: point.marketOffer,
611
- shortSaleMinPrice: point.shortSaleMinPrice,
612
- previousClosingPrice: point.previousClosingPrice,
613
- thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
614
- dailyFinancingValue: point.dailyFinancingValue,
615
- accruedFinancingValue: point.accruedFinancingValue,
616
- twap: point.twap
483
+ volume: point.volume
617
484
  }))
618
485
  },
619
486
  null,
@@ -628,7 +495,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
628
495
  content: [
629
496
  {
630
497
  type: "text",
631
- text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
498
+ text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
632
499
  uri: "getStockPriceHistory"
633
500
  }
634
501
  ],
@@ -736,7 +603,7 @@ Parameters verified:
736
603
  - Symbol: ${args.symbol}
737
604
  - TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
738
605
 
739
- To execute this order, call the executeOrder tool with these exact same parameters. Important: The user has to explicitly confirm before executeOrder is called!`,
606
+ To execute this order, call the executeOrder tool with these exact same parameters.`,
740
607
  uri: "verifyOrder"
741
608
  }
742
609
  ]
@@ -943,245 +810,46 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
943
810
  message: `MCP Server received message: ${message.messageType}: ${message.description}`
944
811
  });
945
812
  const msgType = message.messageType;
946
- if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.MarketDataIncrementalRefresh) {
813
+ if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
947
814
  const symbol = message.getField(Fields3.Symbol)?.value;
948
- parser.logger.log({
949
- level: "info",
950
- message: `Processing market data for symbol: ${symbol}`
951
- });
952
- const fixJson = message.toFIXJSON();
953
- const entries = fixJson.Body?.NoMDEntries || [];
954
- parser.logger.log({
955
- level: "info",
956
- message: `Found ${entries.length} market data entries`
957
- });
958
- const data = {
959
- timestamp: Date.now(),
960
- bid: 0,
961
- offer: 0,
962
- spread: 0,
963
- volume: 0,
964
- trade: 0,
965
- indexValue: 0,
966
- openingPrice: 0,
967
- closingPrice: 0,
968
- settlementPrice: 0,
969
- tradingSessionHighPrice: 0,
970
- tradingSessionLowPrice: 0,
971
- vwap: 0,
972
- imbalance: 0,
973
- openInterest: 0,
974
- compositeUnderlyingPrice: 0,
975
- simulatedSellPrice: 0,
976
- simulatedBuyPrice: 0,
977
- marginRate: 0,
978
- midPrice: 0,
979
- emptyBook: 0,
980
- settleHighPrice: 0,
981
- settleLowPrice: 0,
982
- priorSettlePrice: 0,
983
- sessionHighBid: 0,
984
- sessionLowOffer: 0,
985
- earlyPrices: 0,
986
- auctionClearingPrice: 0,
987
- swapValueFactor: 0,
988
- dailyValueAdjustmentForLongPositions: 0,
989
- cumulativeValueAdjustmentForLongPositions: 0,
990
- dailyValueAdjustmentForShortPositions: 0,
991
- cumulativeValueAdjustmentForShortPositions: 0,
992
- fixingPrice: 0,
993
- cashRate: 0,
994
- recoveryRate: 0,
995
- recoveryRateForLong: 0,
996
- recoveryRateForShort: 0,
997
- marketBid: 0,
998
- marketOffer: 0,
999
- shortSaleMinPrice: 0,
1000
- previousClosingPrice: 0,
1001
- thresholdLimitPriceBanding: 0,
1002
- dailyFinancingValue: 0,
1003
- accruedFinancingValue: 0,
1004
- twap: 0
1005
- };
1006
- for (const entry of entries) {
1007
- const entryType = entry.MDEntryType;
1008
- const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
1009
- const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
1010
- if (entryType === MDEntryType2.Bid || entryType === MDEntryType2.Offer || entryType === MDEntryType2.TradeVolume) {
1011
- parser.logger.log({
1012
- level: "info",
1013
- message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
1014
- });
1015
- }
1016
- switch (entryType) {
1017
- case MDEntryType2.Bid:
1018
- data.bid = price;
1019
- break;
1020
- case MDEntryType2.Offer:
1021
- data.offer = price;
1022
- break;
1023
- case MDEntryType2.Trade:
1024
- data.trade = price;
1025
- break;
1026
- case MDEntryType2.IndexValue:
1027
- data.indexValue = price;
1028
- break;
1029
- case MDEntryType2.OpeningPrice:
1030
- data.openingPrice = price;
1031
- break;
1032
- case MDEntryType2.ClosingPrice:
1033
- data.closingPrice = price;
1034
- break;
1035
- case MDEntryType2.SettlementPrice:
1036
- data.settlementPrice = price;
1037
- break;
1038
- case MDEntryType2.TradingSessionHighPrice:
1039
- data.tradingSessionHighPrice = price;
1040
- break;
1041
- case MDEntryType2.TradingSessionLowPrice:
1042
- data.tradingSessionLowPrice = price;
1043
- break;
1044
- case MDEntryType2.VWAP:
1045
- data.vwap = price;
1046
- break;
1047
- case MDEntryType2.Imbalance:
1048
- data.imbalance = size;
1049
- break;
1050
- case MDEntryType2.TradeVolume:
1051
- data.volume = size;
1052
- break;
1053
- case MDEntryType2.OpenInterest:
1054
- data.openInterest = size;
1055
- break;
1056
- case MDEntryType2.CompositeUnderlyingPrice:
1057
- data.compositeUnderlyingPrice = price;
1058
- break;
1059
- case MDEntryType2.SimulatedSellPrice:
1060
- data.simulatedSellPrice = price;
1061
- break;
1062
- case MDEntryType2.SimulatedBuyPrice:
1063
- data.simulatedBuyPrice = price;
1064
- break;
1065
- case MDEntryType2.MarginRate:
1066
- data.marginRate = price;
1067
- break;
1068
- case MDEntryType2.MidPrice:
1069
- data.midPrice = price;
1070
- break;
1071
- case MDEntryType2.EmptyBook:
1072
- data.emptyBook = 1;
1073
- break;
1074
- case MDEntryType2.SettleHighPrice:
1075
- data.settleHighPrice = price;
1076
- break;
1077
- case MDEntryType2.SettleLowPrice:
1078
- data.settleLowPrice = price;
1079
- break;
1080
- case MDEntryType2.PriorSettlePrice:
1081
- data.priorSettlePrice = price;
1082
- break;
1083
- case MDEntryType2.SessionHighBid:
1084
- data.sessionHighBid = price;
1085
- break;
1086
- case MDEntryType2.SessionLowOffer:
1087
- data.sessionLowOffer = price;
1088
- break;
1089
- case MDEntryType2.EarlyPrices:
1090
- data.earlyPrices = price;
1091
- break;
1092
- case MDEntryType2.AuctionClearingPrice:
1093
- data.auctionClearingPrice = price;
1094
- break;
1095
- case MDEntryType2.SwapValueFactor:
1096
- data.swapValueFactor = price;
1097
- break;
1098
- case MDEntryType2.DailyValueAdjustmentForLongPositions:
1099
- data.dailyValueAdjustmentForLongPositions = price;
1100
- break;
1101
- case MDEntryType2.CumulativeValueAdjustmentForLongPositions:
1102
- data.cumulativeValueAdjustmentForLongPositions = price;
1103
- break;
1104
- case MDEntryType2.DailyValueAdjustmentForShortPositions:
1105
- data.dailyValueAdjustmentForShortPositions = price;
1106
- break;
1107
- case MDEntryType2.CumulativeValueAdjustmentForShortPositions:
1108
- data.cumulativeValueAdjustmentForShortPositions = price;
1109
- break;
1110
- case MDEntryType2.FixingPrice:
1111
- data.fixingPrice = price;
1112
- break;
1113
- case MDEntryType2.CashRate:
1114
- data.cashRate = price;
1115
- break;
1116
- case MDEntryType2.RecoveryRate:
1117
- data.recoveryRate = price;
1118
- break;
1119
- case MDEntryType2.RecoveryRateForLong:
1120
- data.recoveryRateForLong = price;
1121
- break;
1122
- case MDEntryType2.RecoveryRateForShort:
1123
- data.recoveryRateForShort = price;
1124
- break;
1125
- case MDEntryType2.MarketBid:
1126
- data.marketBid = price;
1127
- break;
1128
- case MDEntryType2.MarketOffer:
1129
- data.marketOffer = price;
1130
- break;
1131
- case MDEntryType2.ShortSaleMinPrice:
1132
- data.shortSaleMinPrice = price;
1133
- break;
1134
- case MDEntryType2.PreviousClosingPrice:
1135
- data.previousClosingPrice = price;
1136
- break;
1137
- case MDEntryType2.ThresholdLimitPriceBanding:
1138
- data.thresholdLimitPriceBanding = price;
1139
- break;
1140
- case MDEntryType2.DailyFinancingValue:
1141
- data.dailyFinancingValue = price;
1142
- break;
1143
- case MDEntryType2.AccruedFinancingValue:
1144
- data.accruedFinancingValue = price;
1145
- break;
1146
- case MDEntryType2.TWAP:
1147
- data.twap = price;
1148
- break;
815
+ const entries = message.getField(Fields3.NoMDEntries)?.value;
816
+ let bid = 0;
817
+ let offer = 0;
818
+ let volume = 0;
819
+ const entryTypes = message.getFields(Fields3.MDEntryType);
820
+ const entryPrices = message.getFields(Fields3.MDEntryPx);
821
+ const entrySizes = message.getFields(Fields3.MDEntrySize);
822
+ if (entryTypes && entryPrices && entrySizes) {
823
+ for (let i = 0; i < entries; i++) {
824
+ const entryType = entryTypes[i]?.value;
825
+ const entryPrice = Number.parseFloat(entryPrices[i]?.value);
826
+ const entrySize = Number.parseFloat(entrySizes[i]?.value);
827
+ if (entryType === MDEntryType2.Bid) {
828
+ bid = entryPrice;
829
+ } else if (entryType === MDEntryType2.Offer) {
830
+ offer = entryPrice;
831
+ }
832
+ volume += entrySize;
1149
833
  }
1150
834
  }
1151
- data.spread = data.offer - data.bid;
835
+ const spread = offer - bid;
836
+ const timestamp = Date.now();
837
+ const data = {
838
+ timestamp,
839
+ bid,
840
+ offer,
841
+ spread,
842
+ volume
843
+ };
1152
844
  if (!marketDataPrices.has(symbol)) {
1153
- parser.logger.log({
1154
- level: "info",
1155
- message: `Creating new price history array for symbol: ${symbol}`
1156
- });
1157
845
  marketDataPrices.set(symbol, []);
1158
846
  }
1159
847
  const prices = marketDataPrices.get(symbol);
1160
848
  prices.push(data);
1161
- parser.logger.log({
1162
- level: "info",
1163
- message: `Updated price history for ${symbol}. Current size: ${prices.length}`
1164
- });
1165
849
  if (prices.length > maxPriceHistory) {
1166
850
  prices.splice(0, prices.length - maxPriceHistory);
1167
- parser.logger.log({
1168
- level: "info",
1169
- message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
1170
- });
1171
851
  }
1172
852
  onPriceUpdate?.(symbol, data);
1173
- const mdReqID = message.getField(Fields3.MDReqID)?.value;
1174
- if (mdReqID) {
1175
- const callback = pendingRequests.get(mdReqID);
1176
- if (callback) {
1177
- callback(message);
1178
- pendingRequests.delete(mdReqID);
1179
- parser.logger.log({
1180
- level: "info",
1181
- message: `Resolved market data request for ID: ${mdReqID}`
1182
- });
1183
- }
1184
- }
1185
853
  } else if (msgType === Messages3.ExecutionReport) {
1186
854
  const reqId = message.getField(Fields3.ClOrdID)?.value;
1187
855
  const callback = pendingRequests.get(reqId);
@@ -1210,7 +878,7 @@ var MCPLocal = class extends MCPBase {
1210
878
  */
1211
879
  marketDataPrices = /* @__PURE__ */ new Map();
1212
880
  /**
1213
- * Maximum number of price history entries to keep per symbol
881
+ * Maximum number of price points to store per symbol
1214
882
  * @private
1215
883
  */
1216
884
  MAX_PRICE_HISTORY = 1e5;
@@ -1319,39 +987,6 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
1319
987
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
1320
988
  import { z as z2 } from "zod";
1321
989
  var transports = {};
1322
- function jsonSchemaToZod(schema) {
1323
- if (schema.type === "object") {
1324
- const shape = {};
1325
- for (const [key, prop] of Object.entries(schema.properties || {})) {
1326
- const propSchema = prop;
1327
- if (propSchema.type === "string") {
1328
- if (propSchema.enum) {
1329
- shape[key] = z2.enum(propSchema.enum);
1330
- } else {
1331
- shape[key] = z2.string();
1332
- }
1333
- } else if (propSchema.type === "number") {
1334
- shape[key] = z2.number();
1335
- } else if (propSchema.type === "boolean") {
1336
- shape[key] = z2.boolean();
1337
- } else if (propSchema.type === "array") {
1338
- if (propSchema.items.type === "string") {
1339
- shape[key] = z2.array(z2.string());
1340
- } else if (propSchema.items.type === "number") {
1341
- shape[key] = z2.array(z2.number());
1342
- } else if (propSchema.items.type === "boolean") {
1343
- shape[key] = z2.array(z2.boolean());
1344
- } else {
1345
- shape[key] = z2.array(z2.any());
1346
- }
1347
- } else {
1348
- shape[key] = z2.any();
1349
- }
1350
- }
1351
- return shape;
1352
- }
1353
- return {};
1354
- }
1355
990
  var MCPRemote = class extends MCPBase {
1356
991
  /**
1357
992
  * Port number the server will listen on.
@@ -1394,7 +1029,7 @@ var MCPRemote = class extends MCPBase {
1394
1029
  */
1395
1030
  marketDataPrices = /* @__PURE__ */ new Map();
1396
1031
  /**
1397
- * Maximum number of price history entries to keep per symbol
1032
+ * Maximum number of price points to store per symbol
1398
1033
  * @private
1399
1034
  */
1400
1035
  MAX_PRICE_HISTORY = 1e5;
@@ -1416,22 +1051,55 @@ var MCPRemote = class extends MCPBase {
1416
1051
  this.parser,
1417
1052
  this.pendingRequests,
1418
1053
  this.marketDataPrices,
1419
- this.MAX_PRICE_HISTORY
1054
+ this.MAX_PRICE_HISTORY,
1055
+ (symbol, data) => {
1056
+ this.mcpServer?.tool(
1057
+ "priceUpdate",
1058
+ {
1059
+ description: "Price update notification",
1060
+ schema: z2.object({
1061
+ symbol: z2.string(),
1062
+ timestamp: z2.number(),
1063
+ bid: z2.number(),
1064
+ offer: z2.number(),
1065
+ spread: z2.number(),
1066
+ volume: z2.number()
1067
+ })
1068
+ },
1069
+ () => ({
1070
+ content: [
1071
+ {
1072
+ type: "text",
1073
+ text: JSON.stringify({ symbol, ...data })
1074
+ }
1075
+ ]
1076
+ })
1077
+ );
1078
+ }
1420
1079
  );
1421
- this.logger?.log({
1422
- level: "info",
1423
- message: `Market Data Prices TEST: ${JSON.stringify(this.marketDataPrices)}`
1424
- });
1425
1080
  }
1426
1081
  });
1427
1082
  this.httpServer = createServer(async (req, res) => {
1083
+ console.log(req.headers);
1084
+ this.logger?.log({
1085
+ level: "info",
1086
+ message: `Incoming request: ${req.method} ${req.url}`
1087
+ });
1428
1088
  if (!req.url || !req.method) {
1089
+ this.logger?.log({
1090
+ level: "error",
1091
+ message: "Invalid request: missing URL or method"
1092
+ });
1429
1093
  res.writeHead(400);
1430
1094
  res.end("Bad Request");
1431
1095
  return;
1432
1096
  }
1433
1097
  if (req.url === "/mcp") {
1434
1098
  const sessionId = req.headers["mcp-session-id"];
1099
+ this.logger?.log({
1100
+ level: "info",
1101
+ message: `MCP request received. Session ID: ${sessionId || "none"}, headers: ${req.headers}`
1102
+ });
1435
1103
  if (req.method === "POST") {
1436
1104
  const bodyChunks = [];
1437
1105
  req.on("data", (chunk) => {
@@ -1442,23 +1110,47 @@ var MCPRemote = class extends MCPBase {
1442
1110
  const body = Buffer.concat(bodyChunks).toString();
1443
1111
  try {
1444
1112
  parsed = JSON.parse(body);
1113
+ this.logger?.log({
1114
+ level: "info",
1115
+ message: `Parsed request body: ${JSON.stringify(parsed)}`
1116
+ });
1445
1117
  } catch (err) {
1118
+ this.logger?.log({
1119
+ level: "error",
1120
+ message: `Failed to parse JSON body: ${err}`
1121
+ });
1446
1122
  res.writeHead(400);
1447
1123
  res.end(JSON.stringify({ error: "Invalid JSON" }));
1448
1124
  return;
1449
1125
  }
1450
1126
  let transport;
1451
1127
  if (sessionId && transports[sessionId]) {
1128
+ this.logger?.log({
1129
+ level: "info",
1130
+ message: `Using existing transport for session: ${sessionId}`
1131
+ });
1452
1132
  transport = transports[sessionId];
1453
1133
  } else if (!sessionId && req.method === "POST" && isInitializeRequest(parsed)) {
1134
+ this.logger?.log({
1135
+ level: "info",
1136
+ message: "Creating new transport for initialization request"
1137
+ });
1454
1138
  transport = new StreamableHTTPServerTransport({
1455
1139
  sessionIdGenerator: () => randomUUID(),
1456
1140
  onsessioninitialized: (sessionId2) => {
1141
+ this.logger?.log({
1142
+ level: "info",
1143
+ message: `New session initialized: ${sessionId2}`
1144
+ });
1457
1145
  transports[sessionId2] = transport;
1458
1146
  }
1459
1147
  });
1460
1148
  transport.onclose = () => {
1461
1149
  if (transport.sessionId) {
1150
+ this.logger?.log({
1151
+ level: "info",
1152
+ message: `Session closed: ${transport.sessionId}`
1153
+ });
1462
1154
  delete transports[transport.sessionId];
1463
1155
  }
1464
1156
  };
@@ -1469,6 +1161,10 @@ var MCPRemote = class extends MCPBase {
1469
1161
  this.setupTools();
1470
1162
  await this.mcpServer.connect(transport);
1471
1163
  } else {
1164
+ this.logger?.log({
1165
+ level: "error",
1166
+ message: "Invalid request: No valid session ID provided"
1167
+ });
1472
1168
  res.writeHead(400, { "Content-Type": "application/json" });
1473
1169
  res.end(
1474
1170
  JSON.stringify({
@@ -1484,6 +1180,10 @@ var MCPRemote = class extends MCPBase {
1484
1180
  }
1485
1181
  try {
1486
1182
  await transport.handleRequest(req, res, parsed);
1183
+ this.logger?.log({
1184
+ level: "info",
1185
+ message: "Request handled successfully"
1186
+ });
1487
1187
  } catch (error) {
1488
1188
  this.logger?.log({
1489
1189
  level: "error",
@@ -1494,6 +1194,10 @@ var MCPRemote = class extends MCPBase {
1494
1194
  });
1495
1195
  } else if (req.method === "GET" || req.method === "DELETE") {
1496
1196
  if (!sessionId || !transports[sessionId]) {
1197
+ this.logger?.log({
1198
+ level: "error",
1199
+ message: `Invalid session ID for ${req.method} request: ${sessionId}`
1200
+ });
1497
1201
  res.writeHead(400);
1498
1202
  res.end("Invalid or missing session ID");
1499
1203
  return;
@@ -1501,6 +1205,10 @@ var MCPRemote = class extends MCPBase {
1501
1205
  const transport = transports[sessionId];
1502
1206
  try {
1503
1207
  await transport.handleRequest(req, res);
1208
+ this.logger?.log({
1209
+ level: "info",
1210
+ message: `${req.method} request handled successfully for session: ${sessionId}`
1211
+ });
1504
1212
  } catch (error) {
1505
1213
  this.logger?.log({
1506
1214
  level: "error",
@@ -1517,6 +1225,10 @@ var MCPRemote = class extends MCPBase {
1517
1225
  res.end("Method Not Allowed");
1518
1226
  }
1519
1227
  } else {
1228
+ this.logger?.log({
1229
+ level: "error",
1230
+ message: `Not found: ${req.url}`
1231
+ });
1520
1232
  res.writeHead(404);
1521
1233
  res.end("Not Found");
1522
1234
  }
@@ -1546,40 +1258,69 @@ var MCPRemote = class extends MCPBase {
1546
1258
  });
1547
1259
  return;
1548
1260
  }
1549
- const toolHandlers = createToolHandlers(
1550
- this.parser,
1551
- this.verifiedOrders,
1552
- this.pendingRequests,
1553
- this.marketDataPrices
1261
+ this.mcpServer.tool(
1262
+ "tools/list",
1263
+ {
1264
+ description: "List available tools",
1265
+ schema: z2.object({})
1266
+ },
1267
+ async () => {
1268
+ return {
1269
+ content: [
1270
+ {
1271
+ type: "text",
1272
+ text: JSON.stringify(
1273
+ Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
1274
+ name,
1275
+ description,
1276
+ inputSchema: schema
1277
+ }))
1278
+ )
1279
+ }
1280
+ ]
1281
+ };
1282
+ }
1554
1283
  );
1555
- Object.entries(toolSchemas).forEach(([name, { description, schema }]) => {
1556
- this.mcpServer?.registerTool(
1557
- name,
1558
- {
1559
- description,
1560
- inputSchema: jsonSchemaToZod(schema)
1561
- },
1562
- async (args) => {
1563
- const handler = toolHandlers[name];
1564
- if (!handler) {
1565
- return {
1566
- content: [
1567
- {
1568
- type: "text",
1569
- text: `Tool not found: ${name}`
1570
- }
1571
- ],
1572
- isError: true
1573
- };
1574
- }
1575
- const result = await handler(args);
1284
+ this.mcpServer.tool(
1285
+ "tools/call",
1286
+ {
1287
+ description: "Call a tool",
1288
+ schema: z2.object({
1289
+ name: z2.string(),
1290
+ arguments: z2.any(),
1291
+ _meta: z2.object({
1292
+ progressToken: z2.number()
1293
+ }).optional()
1294
+ })
1295
+ },
1296
+ async (request) => {
1297
+ const { name, arguments: args } = request;
1298
+ const toolHandlers = createToolHandlers(
1299
+ this.parser,
1300
+ this.verifiedOrders,
1301
+ this.pendingRequests,
1302
+ this.marketDataPrices
1303
+ );
1304
+ const handler = toolHandlers[name];
1305
+ if (!handler) {
1576
1306
  return {
1577
- content: result.content,
1578
- isError: result.isError
1307
+ content: [
1308
+ {
1309
+ type: "text",
1310
+ text: `Tool not found: ${name}`,
1311
+ uri: name
1312
+ }
1313
+ ],
1314
+ isError: true
1579
1315
  };
1580
1316
  }
1581
- );
1582
- });
1317
+ const result = await handler(args);
1318
+ return {
1319
+ content: result.content,
1320
+ isError: result.isError
1321
+ };
1322
+ }
1323
+ );
1583
1324
  }
1584
1325
  };
1585
1326
  export {