fixparser-plugin-mcp 9.1.7-67ba45e9 → 9.1.7-70682ed6

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.
@@ -35,51 +35,9 @@ __export(MCPLocal_exports, {
35
35
  module.exports = __toCommonJS(MCPLocal_exports);
36
36
  var import_server = require("@modelcontextprotocol/sdk/server/index.js");
37
37
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
38
+ var import_fixparser3 = require("fixparser");
38
39
  var import_zod = require("zod");
39
40
 
40
- // src/MCPBase.ts
41
- var MCPBase = class {
42
- /**
43
- * Optional logger instance for diagnostics and output.
44
- * @protected
45
- */
46
- logger;
47
- /**
48
- * FIXParser instance, set during plugin register().
49
- * @protected
50
- */
51
- parser;
52
- /**
53
- * Called when server is setup and listening.
54
- * @protected
55
- */
56
- onReady = void 0;
57
- /**
58
- * Map to store verified orders before execution
59
- * @protected
60
- */
61
- verifiedOrders = /* @__PURE__ */ new Map();
62
- /**
63
- * Map to store pending market data requests
64
- * @protected
65
- */
66
- pendingRequests = /* @__PURE__ */ new Map();
67
- /**
68
- * Map to store market data prices
69
- * @protected
70
- */
71
- marketDataPrices = /* @__PURE__ */ new Map();
72
- /**
73
- * Maximum number of price history entries to keep per symbol
74
- * @protected
75
- */
76
- MAX_PRICE_HISTORY = 1e5;
77
- constructor({ logger, onReady }) {
78
- this.logger = logger;
79
- this.onReady = onReady;
80
- }
81
- };
82
-
83
41
  // src/schemas/schemas.ts
84
42
  var toolSchemas = {
85
43
  parse: {
@@ -163,7 +121,7 @@ var toolSchemas = {
163
121
  }
164
122
  },
165
123
  executeOrder: {
166
- description: "Executes a verified order. verifyOrder must be called before executeOrder.",
124
+ description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
167
125
  schema: {
168
126
  type: "object",
169
127
  properties: {
@@ -316,63 +274,10 @@ var import_quickchart_js = __toESM(require("quickchart-js"), 1);
316
274
  var createMarketDataRequestHandler = (parser, pendingRequests) => {
317
275
  return async (args) => {
318
276
  try {
319
- parser.logger.log({
320
- level: "info",
321
- message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
322
- });
323
277
  const response = new Promise((resolve) => {
324
278
  pendingRequests.set(args.mdReqID, resolve);
325
- parser.logger.log({
326
- level: "info",
327
- message: `Registered callback for market data request ID: ${args.mdReqID}`
328
- });
329
279
  });
330
- const entryTypes = args.mdEntryTypes || [
331
- import_fixparser.MDEntryType.Bid,
332
- import_fixparser.MDEntryType.Offer,
333
- import_fixparser.MDEntryType.Trade,
334
- import_fixparser.MDEntryType.IndexValue,
335
- import_fixparser.MDEntryType.OpeningPrice,
336
- import_fixparser.MDEntryType.ClosingPrice,
337
- import_fixparser.MDEntryType.SettlementPrice,
338
- import_fixparser.MDEntryType.TradingSessionHighPrice,
339
- import_fixparser.MDEntryType.TradingSessionLowPrice,
340
- import_fixparser.MDEntryType.VWAP,
341
- import_fixparser.MDEntryType.Imbalance,
342
- import_fixparser.MDEntryType.TradeVolume,
343
- import_fixparser.MDEntryType.OpenInterest,
344
- import_fixparser.MDEntryType.CompositeUnderlyingPrice,
345
- import_fixparser.MDEntryType.SimulatedSellPrice,
346
- import_fixparser.MDEntryType.SimulatedBuyPrice,
347
- import_fixparser.MDEntryType.MarginRate,
348
- import_fixparser.MDEntryType.MidPrice,
349
- import_fixparser.MDEntryType.EmptyBook,
350
- import_fixparser.MDEntryType.SettleHighPrice,
351
- import_fixparser.MDEntryType.SettleLowPrice,
352
- import_fixparser.MDEntryType.PriorSettlePrice,
353
- import_fixparser.MDEntryType.SessionHighBid,
354
- import_fixparser.MDEntryType.SessionLowOffer,
355
- import_fixparser.MDEntryType.EarlyPrices,
356
- import_fixparser.MDEntryType.AuctionClearingPrice,
357
- import_fixparser.MDEntryType.SwapValueFactor,
358
- import_fixparser.MDEntryType.DailyValueAdjustmentForLongPositions,
359
- import_fixparser.MDEntryType.CumulativeValueAdjustmentForLongPositions,
360
- import_fixparser.MDEntryType.DailyValueAdjustmentForShortPositions,
361
- import_fixparser.MDEntryType.CumulativeValueAdjustmentForShortPositions,
362
- import_fixparser.MDEntryType.FixingPrice,
363
- import_fixparser.MDEntryType.CashRate,
364
- import_fixparser.MDEntryType.RecoveryRate,
365
- import_fixparser.MDEntryType.RecoveryRateForLong,
366
- import_fixparser.MDEntryType.RecoveryRateForShort,
367
- import_fixparser.MDEntryType.MarketBid,
368
- import_fixparser.MDEntryType.MarketOffer,
369
- import_fixparser.MDEntryType.ShortSaleMinPrice,
370
- import_fixparser.MDEntryType.PreviousClosingPrice,
371
- import_fixparser.MDEntryType.ThresholdLimitPriceBanding,
372
- import_fixparser.MDEntryType.DailyFinancingValue,
373
- import_fixparser.MDEntryType.AccruedFinancingValue,
374
- import_fixparser.MDEntryType.TWAP
375
- ];
280
+ const entryTypes = args.mdEntryTypes || [import_fixparser.MDEntryType.Bid, import_fixparser.MDEntryType.Offer, import_fixparser.MDEntryType.TradeVolume];
376
281
  const messageFields = [
377
282
  new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
378
283
  new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
@@ -394,10 +299,6 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
394
299
  });
395
300
  const mdr = parser.createMessage(...messageFields);
396
301
  if (!parser.connected) {
397
- parser.logger.log({
398
- level: "error",
399
- message: "Not connected. Cannot send market data request."
400
- });
401
302
  return {
402
303
  content: [
403
304
  {
@@ -409,16 +310,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
409
310
  isError: true
410
311
  };
411
312
  }
412
- parser.logger.log({
413
- level: "info",
414
- message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
415
- });
416
313
  parser.send(mdr);
417
314
  const fixData = await response;
418
- parser.logger.log({
419
- level: "info",
420
- message: `Received market data response for request ID: ${args.mdReqID}`
421
- });
422
315
  return {
423
316
  content: [
424
317
  {
@@ -459,17 +352,13 @@ var createGetStockGraphHandler = (marketDataPrices) => {
459
352
  };
460
353
  }
461
354
  const chart = new import_quickchart_js.default();
462
- chart.setWidth(1200);
463
- chart.setHeight(600);
464
- chart.setBackgroundColor("transparent");
355
+ chart.setWidth(600);
356
+ chart.setHeight(300);
465
357
  const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
466
358
  const bidData = priceHistory.map((point) => point.bid);
467
359
  const offerData = priceHistory.map((point) => point.offer);
468
360
  const spreadData = priceHistory.map((point) => point.spread);
469
361
  const volumeData = priceHistory.map((point) => point.volume);
470
- const tradeData = priceHistory.map((point) => point.trade);
471
- const vwapData = priceHistory.map((point) => point.vwap);
472
- const twapData = priceHistory.map((point) => point.twap);
473
362
  const config = {
474
363
  type: "line",
475
364
  data: {
@@ -499,30 +388,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
499
388
  fill: false,
500
389
  tension: 0.4
501
390
  },
502
- {
503
- label: "Trade",
504
- data: tradeData,
505
- borderColor: "#ffc107",
506
- backgroundColor: "rgba(255, 193, 7, 0.1)",
507
- fill: false,
508
- tension: 0.4
509
- },
510
- {
511
- label: "VWAP",
512
- data: vwapData,
513
- borderColor: "#17a2b8",
514
- backgroundColor: "rgba(23, 162, 184, 0.1)",
515
- fill: false,
516
- tension: 0.4
517
- },
518
- {
519
- label: "TWAP",
520
- data: twapData,
521
- borderColor: "#6610f2",
522
- backgroundColor: "rgba(102, 16, 242, 0.1)",
523
- fill: false,
524
- tension: 0.4
525
- },
526
391
  {
527
392
  label: "Volume",
528
393
  data: volumeData,
@@ -550,16 +415,18 @@ var createGetStockGraphHandler = (marketDataPrices) => {
550
415
  };
551
416
  chart.setConfig(config);
552
417
  const imageBuffer = await chart.toBinary();
553
- const base64 = imageBuffer.toString("base64");
418
+ const base64Image = imageBuffer.toString("base64");
554
419
  return {
555
420
  content: [
556
421
  {
557
- type: "resource",
558
- resource: {
559
- uri: "resource://graph",
560
- mimeType: "image/png",
561
- blob: base64
562
- }
422
+ type: "image",
423
+ image: {
424
+ source: {
425
+ data: `data:image/png;base64,${base64Image}`
426
+ }
427
+ },
428
+ uri: "getStockGraph",
429
+ mimeType: "image/png"
563
430
  }
564
431
  ]
565
432
  };
@@ -568,7 +435,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
568
435
  content: [
569
436
  {
570
437
  type: "text",
571
- text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
438
+ text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
572
439
  uri: "getStockGraph"
573
440
  }
574
441
  ],
@@ -606,48 +473,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
606
473
  bid: point.bid,
607
474
  offer: point.offer,
608
475
  spread: point.spread,
609
- volume: point.volume,
610
- trade: point.trade,
611
- indexValue: point.indexValue,
612
- openingPrice: point.openingPrice,
613
- closingPrice: point.closingPrice,
614
- settlementPrice: point.settlementPrice,
615
- tradingSessionHighPrice: point.tradingSessionHighPrice,
616
- tradingSessionLowPrice: point.tradingSessionLowPrice,
617
- vwap: point.vwap,
618
- imbalance: point.imbalance,
619
- openInterest: point.openInterest,
620
- compositeUnderlyingPrice: point.compositeUnderlyingPrice,
621
- simulatedSellPrice: point.simulatedSellPrice,
622
- simulatedBuyPrice: point.simulatedBuyPrice,
623
- marginRate: point.marginRate,
624
- midPrice: point.midPrice,
625
- emptyBook: point.emptyBook,
626
- settleHighPrice: point.settleHighPrice,
627
- settleLowPrice: point.settleLowPrice,
628
- priorSettlePrice: point.priorSettlePrice,
629
- sessionHighBid: point.sessionHighBid,
630
- sessionLowOffer: point.sessionLowOffer,
631
- earlyPrices: point.earlyPrices,
632
- auctionClearingPrice: point.auctionClearingPrice,
633
- swapValueFactor: point.swapValueFactor,
634
- dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
635
- cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
636
- dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
637
- cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
638
- fixingPrice: point.fixingPrice,
639
- cashRate: point.cashRate,
640
- recoveryRate: point.recoveryRate,
641
- recoveryRateForLong: point.recoveryRateForLong,
642
- recoveryRateForShort: point.recoveryRateForShort,
643
- marketBid: point.marketBid,
644
- marketOffer: point.marketOffer,
645
- shortSaleMinPrice: point.shortSaleMinPrice,
646
- previousClosingPrice: point.previousClosingPrice,
647
- thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
648
- dailyFinancingValue: point.dailyFinancingValue,
649
- accruedFinancingValue: point.accruedFinancingValue,
650
- twap: point.twap
476
+ volume: point.volume
651
477
  }))
652
478
  },
653
479
  null,
@@ -662,7 +488,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
662
488
  content: [
663
489
  {
664
490
  type: "text",
665
- text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
491
+ text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
666
492
  uri: "getStockPriceHistory"
667
493
  }
668
494
  ],
@@ -770,7 +596,7 @@ Parameters verified:
770
596
  - Symbol: ${args.symbol}
771
597
  - TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
772
598
 
773
- To execute this order, call the executeOrder tool with these exact same parameters. Important: The user has to explicitly confirm before executeOrder is called!`,
599
+ To execute this order, call the executeOrder tool with these exact same parameters.`,
774
600
  uri: "verifyOrder"
775
601
  }
776
602
  ]
@@ -969,290 +795,9 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
969
795
  getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
970
796
  });
971
797
 
972
- // src/utils/messageHandler.ts
973
- var import_fixparser3 = require("fixparser");
974
- function getEnumValue(enumObj, name) {
975
- return enumObj[name] || name;
976
- }
977
- function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
978
- parser.logger.log({
979
- level: "info",
980
- message: `MCP Server received message: ${message.messageType}: ${message.description}`
981
- });
982
- const msgType = message.messageType;
983
- if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
984
- 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
- const enumValue = getEnumValue(import_fixparser3.MDEntryType, entryType);
1054
- switch (enumValue) {
1055
- case import_fixparser3.MDEntryType.Bid:
1056
- data.bid = price;
1057
- break;
1058
- case import_fixparser3.MDEntryType.Offer:
1059
- data.offer = price;
1060
- break;
1061
- case import_fixparser3.MDEntryType.Trade:
1062
- data.trade = price;
1063
- break;
1064
- case import_fixparser3.MDEntryType.IndexValue:
1065
- data.indexValue = price;
1066
- break;
1067
- case import_fixparser3.MDEntryType.OpeningPrice:
1068
- data.openingPrice = price;
1069
- break;
1070
- case import_fixparser3.MDEntryType.ClosingPrice:
1071
- data.closingPrice = price;
1072
- break;
1073
- case import_fixparser3.MDEntryType.SettlementPrice:
1074
- data.settlementPrice = price;
1075
- break;
1076
- case import_fixparser3.MDEntryType.TradingSessionHighPrice:
1077
- data.tradingSessionHighPrice = price;
1078
- break;
1079
- case import_fixparser3.MDEntryType.TradingSessionLowPrice:
1080
- data.tradingSessionLowPrice = price;
1081
- break;
1082
- case import_fixparser3.MDEntryType.VWAP:
1083
- data.vwap = price;
1084
- break;
1085
- case import_fixparser3.MDEntryType.Imbalance:
1086
- data.imbalance = size;
1087
- break;
1088
- case import_fixparser3.MDEntryType.TradeVolume:
1089
- data.volume = size;
1090
- break;
1091
- case import_fixparser3.MDEntryType.OpenInterest:
1092
- data.openInterest = size;
1093
- break;
1094
- case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
1095
- data.compositeUnderlyingPrice = price;
1096
- break;
1097
- case import_fixparser3.MDEntryType.SimulatedSellPrice:
1098
- data.simulatedSellPrice = price;
1099
- break;
1100
- case import_fixparser3.MDEntryType.SimulatedBuyPrice:
1101
- data.simulatedBuyPrice = price;
1102
- break;
1103
- case import_fixparser3.MDEntryType.MarginRate:
1104
- data.marginRate = price;
1105
- break;
1106
- case import_fixparser3.MDEntryType.MidPrice:
1107
- data.midPrice = price;
1108
- break;
1109
- case import_fixparser3.MDEntryType.EmptyBook:
1110
- data.emptyBook = 1;
1111
- break;
1112
- case import_fixparser3.MDEntryType.SettleHighPrice:
1113
- data.settleHighPrice = price;
1114
- break;
1115
- case import_fixparser3.MDEntryType.SettleLowPrice:
1116
- data.settleLowPrice = price;
1117
- break;
1118
- case import_fixparser3.MDEntryType.PriorSettlePrice:
1119
- data.priorSettlePrice = price;
1120
- break;
1121
- case import_fixparser3.MDEntryType.SessionHighBid:
1122
- data.sessionHighBid = price;
1123
- break;
1124
- case import_fixparser3.MDEntryType.SessionLowOffer:
1125
- data.sessionLowOffer = price;
1126
- break;
1127
- case import_fixparser3.MDEntryType.EarlyPrices:
1128
- data.earlyPrices = price;
1129
- break;
1130
- case import_fixparser3.MDEntryType.AuctionClearingPrice:
1131
- data.auctionClearingPrice = price;
1132
- break;
1133
- case import_fixparser3.MDEntryType.SwapValueFactor:
1134
- data.swapValueFactor = price;
1135
- break;
1136
- case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
1137
- data.dailyValueAdjustmentForLongPositions = price;
1138
- break;
1139
- case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
1140
- data.cumulativeValueAdjustmentForLongPositions = price;
1141
- break;
1142
- case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
1143
- data.dailyValueAdjustmentForShortPositions = price;
1144
- break;
1145
- case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
1146
- data.cumulativeValueAdjustmentForShortPositions = price;
1147
- break;
1148
- case import_fixparser3.MDEntryType.FixingPrice:
1149
- data.fixingPrice = price;
1150
- break;
1151
- case import_fixparser3.MDEntryType.CashRate:
1152
- data.cashRate = price;
1153
- break;
1154
- case import_fixparser3.MDEntryType.RecoveryRate:
1155
- data.recoveryRate = price;
1156
- break;
1157
- case import_fixparser3.MDEntryType.RecoveryRateForLong:
1158
- data.recoveryRateForLong = price;
1159
- break;
1160
- case import_fixparser3.MDEntryType.RecoveryRateForShort:
1161
- data.recoveryRateForShort = price;
1162
- break;
1163
- case import_fixparser3.MDEntryType.MarketBid:
1164
- data.marketBid = price;
1165
- break;
1166
- case import_fixparser3.MDEntryType.MarketOffer:
1167
- data.marketOffer = price;
1168
- break;
1169
- case import_fixparser3.MDEntryType.ShortSaleMinPrice:
1170
- data.shortSaleMinPrice = price;
1171
- break;
1172
- case import_fixparser3.MDEntryType.PreviousClosingPrice:
1173
- data.previousClosingPrice = price;
1174
- break;
1175
- case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
1176
- data.thresholdLimitPriceBanding = price;
1177
- break;
1178
- case import_fixparser3.MDEntryType.DailyFinancingValue:
1179
- data.dailyFinancingValue = price;
1180
- break;
1181
- case import_fixparser3.MDEntryType.AccruedFinancingValue:
1182
- data.accruedFinancingValue = price;
1183
- break;
1184
- case import_fixparser3.MDEntryType.TWAP:
1185
- data.twap = price;
1186
- break;
1187
- }
1188
- }
1189
- data.spread = data.offer - data.bid;
1190
- console.log(">>>>>>>>>>>>>>>>>>>>", data);
1191
- if (!marketDataPrices.has(symbol)) {
1192
- parser.logger.log({
1193
- level: "info",
1194
- message: `Creating new price history array for symbol: ${symbol}`
1195
- });
1196
- marketDataPrices.set(symbol, []);
1197
- }
1198
- const prices = marketDataPrices.get(symbol);
1199
- prices.push(data);
1200
- parser.logger.log({
1201
- level: "info",
1202
- message: `Updated price history for ${symbol}. Current size: ${prices.length}`
1203
- });
1204
- if (prices.length > maxPriceHistory) {
1205
- prices.splice(0, prices.length - maxPriceHistory);
1206
- parser.logger.log({
1207
- level: "info",
1208
- message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
1209
- });
1210
- }
1211
- onPriceUpdate?.(symbol, data);
1212
- const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
1213
- if (mdReqID) {
1214
- const callback = pendingRequests.get(mdReqID);
1215
- if (callback) {
1216
- callback(message);
1217
- pendingRequests.delete(mdReqID);
1218
- parser.logger.log({
1219
- level: "info",
1220
- message: `Resolved market data request for ID: ${mdReqID}`
1221
- });
1222
- }
1223
- }
1224
- } else if (msgType === import_fixparser3.Messages.ExecutionReport) {
1225
- const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
1226
- const callback = pendingRequests.get(reqId);
1227
- if (callback) {
1228
- callback(message);
1229
- pendingRequests.delete(reqId);
1230
- }
1231
- }
1232
- }
1233
-
1234
798
  // src/MCPLocal.ts
1235
- var MCPLocal = class extends MCPBase {
1236
- /**
1237
- * Map to store verified orders before execution
1238
- * @private
1239
- */
1240
- verifiedOrders = /* @__PURE__ */ new Map();
1241
- /**
1242
- * Map to store pending requests and their callbacks
1243
- * @private
1244
- */
1245
- pendingRequests = /* @__PURE__ */ new Map();
1246
- /**
1247
- * Map to store market data prices for each symbol
1248
- * @private
1249
- */
1250
- marketDataPrices = /* @__PURE__ */ new Map();
1251
- /**
1252
- * Maximum number of price history entries to keep per symbol
1253
- * @private
1254
- */
1255
- MAX_PRICE_HISTORY = 1e5;
799
+ var MCPLocal = class {
800
+ parser;
1256
801
  server = new import_server.Server(
1257
802
  {
1258
803
  name: "fixparser",
@@ -1274,13 +819,90 @@ var MCPLocal = class extends MCPBase {
1274
819
  }
1275
820
  );
1276
821
  transport = new import_stdio.StdioServerTransport();
822
+ onReady = void 0;
823
+ pendingRequests = /* @__PURE__ */ new Map();
824
+ verifiedOrders = /* @__PURE__ */ new Map();
825
+ marketDataPrices = /* @__PURE__ */ new Map();
826
+ MAX_PRICE_HISTORY = 1e5;
827
+ // Maximum number of price points to store per symbol
1277
828
  constructor({ logger, onReady }) {
1278
- super({ logger, onReady });
829
+ if (onReady) this.onReady = onReady;
1279
830
  }
1280
831
  async register(parser) {
1281
832
  this.parser = parser;
1282
833
  this.parser.addOnMessageCallback((message) => {
1283
- handleMessage(message, this.parser, this.pendingRequests, this.marketDataPrices, this.MAX_PRICE_HISTORY);
834
+ this.parser?.logger.log({
835
+ level: "info",
836
+ message: `MCP Server received message: ${message.messageType}: ${message.description}`
837
+ });
838
+ const msgType = message.messageType;
839
+ if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.ExecutionReport || msgType === import_fixparser3.Messages.Reject || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
840
+ this.parser?.logger.log({
841
+ level: "info",
842
+ message: `MCP Server handling message type: ${msgType}`
843
+ });
844
+ let id;
845
+ if (msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh || msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
846
+ const symbol = message.getField(import_fixparser3.Fields.Symbol);
847
+ const entryType = message.getField(import_fixparser3.Fields.MDEntryType);
848
+ const price = message.getField(import_fixparser3.Fields.MDEntryPx);
849
+ const size = message.getField(import_fixparser3.Fields.MDEntrySize);
850
+ const timestamp = message.getField(import_fixparser3.Fields.MDEntryTime)?.value || Date.now();
851
+ if (symbol?.value && price?.value) {
852
+ const symbolStr = String(symbol.value);
853
+ const priceNum = Number(price.value);
854
+ const sizeNum = size?.value ? Number(size.value) : 0;
855
+ const priceHistory = this.marketDataPrices.get(symbolStr) || [];
856
+ const lastEntry = priceHistory[priceHistory.length - 1] || {
857
+ timestamp: 0,
858
+ bid: 0,
859
+ offer: 0,
860
+ spread: 0,
861
+ volume: 0
862
+ };
863
+ const newEntry = {
864
+ timestamp: Number(timestamp),
865
+ bid: entryType?.value === import_fixparser3.MDEntryType.Bid ? priceNum : lastEntry.bid,
866
+ offer: entryType?.value === import_fixparser3.MDEntryType.Offer ? priceNum : lastEntry.offer,
867
+ spread: entryType?.value === import_fixparser3.MDEntryType.Offer ? priceNum - lastEntry.bid : entryType?.value === import_fixparser3.MDEntryType.Bid ? lastEntry.offer - priceNum : lastEntry.spread,
868
+ volume: entryType?.value === import_fixparser3.MDEntryType.TradeVolume ? sizeNum : lastEntry.volume
869
+ };
870
+ priceHistory.push(newEntry);
871
+ if (priceHistory.length > this.MAX_PRICE_HISTORY) {
872
+ priceHistory.shift();
873
+ }
874
+ this.marketDataPrices.set(symbolStr, priceHistory);
875
+ this.parser?.logger.log({
876
+ level: "info",
877
+ message: `MCP Server added ${symbol}: ${JSON.stringify(newEntry)}`
878
+ });
879
+ this.server.notification({
880
+ method: "priceUpdate",
881
+ params: {
882
+ symbol: symbolStr,
883
+ ...newEntry
884
+ }
885
+ });
886
+ }
887
+ }
888
+ if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
889
+ const mdReqID = message.getField(import_fixparser3.Fields.MDReqID);
890
+ if (mdReqID) id = String(mdReqID.value);
891
+ } else if (msgType === import_fixparser3.Messages.ExecutionReport) {
892
+ const clOrdID = message.getField(import_fixparser3.Fields.ClOrdID);
893
+ if (clOrdID) id = String(clOrdID.value);
894
+ } else if (msgType === import_fixparser3.Messages.Reject) {
895
+ const refSeqNum = message.getField(import_fixparser3.Fields.RefSeqNum);
896
+ if (refSeqNum) id = String(refSeqNum.value);
897
+ }
898
+ if (id) {
899
+ const callback = this.pendingRequests.get(id);
900
+ if (callback) {
901
+ callback(message);
902
+ this.pendingRequests.delete(id);
903
+ }
904
+ }
905
+ }
1284
906
  });
1285
907
  this.addWorkflows();
1286
908
  await this.server.connect(this.transport);
@@ -1295,15 +917,18 @@ var MCPLocal = class extends MCPBase {
1295
917
  if (!this.server) {
1296
918
  return;
1297
919
  }
1298
- this.server.setRequestHandler(import_zod.z.object({ method: import_zod.z.literal("tools/list") }), async () => {
1299
- return {
1300
- tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
1301
- name,
1302
- description,
1303
- inputSchema: schema
1304
- }))
1305
- };
1306
- });
920
+ this.server.setRequestHandler(
921
+ import_zod.z.object({ method: import_zod.z.literal("tools/list") }),
922
+ async (request, extra) => {
923
+ return {
924
+ tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
925
+ name,
926
+ description,
927
+ inputSchema: schema
928
+ }))
929
+ };
930
+ }
931
+ );
1307
932
  this.server.setRequestHandler(
1308
933
  import_zod.z.object({
1309
934
  method: import_zod.z.literal("tools/call"),
@@ -1315,7 +940,7 @@ var MCPLocal = class extends MCPBase {
1315
940
  }).optional()
1316
941
  })
1317
942
  }),
1318
- async (request) => {
943
+ async (request, extra) => {
1319
944
  const { name, arguments: args } = request.params;
1320
945
  const toolHandlers = createToolHandlers(
1321
946
  this.parser,