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