fixparser-plugin-mcp 9.1.7-63c797c5 → 9.1.7-67ba45e9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/MCPLocal.js +372 -35
- package/build/cjs/MCPLocal.js.map +2 -2
- package/build/cjs/MCPRemote.js +440 -176
- package/build/cjs/MCPRemote.js.map +2 -2
- package/build/cjs/index.js +441 -177
- package/build/cjs/index.js.map +2 -2
- package/build/esm/MCPLocal.mjs +372 -35
- package/build/esm/MCPLocal.mjs.map +2 -2
- package/build/esm/MCPRemote.mjs +440 -176
- package/build/esm/MCPRemote.mjs.map +2 -2
- package/build/esm/index.mjs +441 -177
- package/build/esm/index.mjs.map +2 -2
- package/build-examples/cjs/example_mcp_local.js +7 -7
- package/build-examples/cjs/example_mcp_local.js.map +3 -3
- package/build-examples/cjs/example_mcp_remote.js +7 -7
- package/build-examples/cjs/example_mcp_remote.js.map +3 -3
- package/build-examples/esm/example_mcp_local.mjs +7 -7
- package/build-examples/esm/example_mcp_local.mjs.map +3 -3
- package/build-examples/esm/example_mcp_remote.mjs +7 -7
- package/build-examples/esm/example_mcp_remote.mjs.map +3 -3
- package/package.json +1 -1
- package/types/MCPBase.d.ts +0 -49
- package/types/MCPLocal.d.ts +0 -40
- package/types/MCPRemote.d.ts +0 -66
- package/types/PluginOptions.d.ts +0 -6
- package/types/index.d.ts +0 -3
- package/types/schemas/index.d.ts +0 -15
- package/types/schemas/schemas.d.ts +0 -168
- package/types/tools/index.d.ts +0 -17
- package/types/tools/marketData.d.ts +0 -40
- package/types/tools/order.d.ts +0 -12
- package/types/tools/parse.d.ts +0 -5
- package/types/tools/parseToJSON.d.ts +0 -5
- package/types/utils/messageHandler.d.ts +0 -18
package/build/cjs/MCPRemote.js
CHANGED
|
@@ -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.",
|
|
170
170
|
schema: {
|
|
171
171
|
type: "object",
|
|
172
172
|
properties: {
|
|
@@ -319,10 +319,63 @@ var import_quickchart_js = __toESM(require("quickchart-js"), 1);
|
|
|
319
319
|
var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
320
320
|
return async (args) => {
|
|
321
321
|
try {
|
|
322
|
+
parser.logger.log({
|
|
323
|
+
level: "info",
|
|
324
|
+
message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
|
|
325
|
+
});
|
|
322
326
|
const response = new Promise((resolve) => {
|
|
323
327
|
pendingRequests.set(args.mdReqID, resolve);
|
|
328
|
+
parser.logger.log({
|
|
329
|
+
level: "info",
|
|
330
|
+
message: `Registered callback for market data request ID: ${args.mdReqID}`
|
|
331
|
+
});
|
|
324
332
|
});
|
|
325
|
-
const entryTypes = args.mdEntryTypes || [
|
|
333
|
+
const entryTypes = args.mdEntryTypes || [
|
|
334
|
+
import_fixparser.MDEntryType.Bid,
|
|
335
|
+
import_fixparser.MDEntryType.Offer,
|
|
336
|
+
import_fixparser.MDEntryType.Trade,
|
|
337
|
+
import_fixparser.MDEntryType.IndexValue,
|
|
338
|
+
import_fixparser.MDEntryType.OpeningPrice,
|
|
339
|
+
import_fixparser.MDEntryType.ClosingPrice,
|
|
340
|
+
import_fixparser.MDEntryType.SettlementPrice,
|
|
341
|
+
import_fixparser.MDEntryType.TradingSessionHighPrice,
|
|
342
|
+
import_fixparser.MDEntryType.TradingSessionLowPrice,
|
|
343
|
+
import_fixparser.MDEntryType.VWAP,
|
|
344
|
+
import_fixparser.MDEntryType.Imbalance,
|
|
345
|
+
import_fixparser.MDEntryType.TradeVolume,
|
|
346
|
+
import_fixparser.MDEntryType.OpenInterest,
|
|
347
|
+
import_fixparser.MDEntryType.CompositeUnderlyingPrice,
|
|
348
|
+
import_fixparser.MDEntryType.SimulatedSellPrice,
|
|
349
|
+
import_fixparser.MDEntryType.SimulatedBuyPrice,
|
|
350
|
+
import_fixparser.MDEntryType.MarginRate,
|
|
351
|
+
import_fixparser.MDEntryType.MidPrice,
|
|
352
|
+
import_fixparser.MDEntryType.EmptyBook,
|
|
353
|
+
import_fixparser.MDEntryType.SettleHighPrice,
|
|
354
|
+
import_fixparser.MDEntryType.SettleLowPrice,
|
|
355
|
+
import_fixparser.MDEntryType.PriorSettlePrice,
|
|
356
|
+
import_fixparser.MDEntryType.SessionHighBid,
|
|
357
|
+
import_fixparser.MDEntryType.SessionLowOffer,
|
|
358
|
+
import_fixparser.MDEntryType.EarlyPrices,
|
|
359
|
+
import_fixparser.MDEntryType.AuctionClearingPrice,
|
|
360
|
+
import_fixparser.MDEntryType.SwapValueFactor,
|
|
361
|
+
import_fixparser.MDEntryType.DailyValueAdjustmentForLongPositions,
|
|
362
|
+
import_fixparser.MDEntryType.CumulativeValueAdjustmentForLongPositions,
|
|
363
|
+
import_fixparser.MDEntryType.DailyValueAdjustmentForShortPositions,
|
|
364
|
+
import_fixparser.MDEntryType.CumulativeValueAdjustmentForShortPositions,
|
|
365
|
+
import_fixparser.MDEntryType.FixingPrice,
|
|
366
|
+
import_fixparser.MDEntryType.CashRate,
|
|
367
|
+
import_fixparser.MDEntryType.RecoveryRate,
|
|
368
|
+
import_fixparser.MDEntryType.RecoveryRateForLong,
|
|
369
|
+
import_fixparser.MDEntryType.RecoveryRateForShort,
|
|
370
|
+
import_fixparser.MDEntryType.MarketBid,
|
|
371
|
+
import_fixparser.MDEntryType.MarketOffer,
|
|
372
|
+
import_fixparser.MDEntryType.ShortSaleMinPrice,
|
|
373
|
+
import_fixparser.MDEntryType.PreviousClosingPrice,
|
|
374
|
+
import_fixparser.MDEntryType.ThresholdLimitPriceBanding,
|
|
375
|
+
import_fixparser.MDEntryType.DailyFinancingValue,
|
|
376
|
+
import_fixparser.MDEntryType.AccruedFinancingValue,
|
|
377
|
+
import_fixparser.MDEntryType.TWAP
|
|
378
|
+
];
|
|
326
379
|
const messageFields = [
|
|
327
380
|
new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
|
|
328
381
|
new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
|
|
@@ -344,6 +397,10 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
344
397
|
});
|
|
345
398
|
const mdr = parser.createMessage(...messageFields);
|
|
346
399
|
if (!parser.connected) {
|
|
400
|
+
parser.logger.log({
|
|
401
|
+
level: "error",
|
|
402
|
+
message: "Not connected. Cannot send market data request."
|
|
403
|
+
});
|
|
347
404
|
return {
|
|
348
405
|
content: [
|
|
349
406
|
{
|
|
@@ -355,8 +412,16 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
355
412
|
isError: true
|
|
356
413
|
};
|
|
357
414
|
}
|
|
415
|
+
parser.logger.log({
|
|
416
|
+
level: "info",
|
|
417
|
+
message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
|
|
418
|
+
});
|
|
358
419
|
parser.send(mdr);
|
|
359
420
|
const fixData = await response;
|
|
421
|
+
parser.logger.log({
|
|
422
|
+
level: "info",
|
|
423
|
+
message: `Received market data response for request ID: ${args.mdReqID}`
|
|
424
|
+
});
|
|
360
425
|
return {
|
|
361
426
|
content: [
|
|
362
427
|
{
|
|
@@ -405,6 +470,9 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
405
470
|
const offerData = priceHistory.map((point) => point.offer);
|
|
406
471
|
const spreadData = priceHistory.map((point) => point.spread);
|
|
407
472
|
const volumeData = priceHistory.map((point) => point.volume);
|
|
473
|
+
const tradeData = priceHistory.map((point) => point.trade);
|
|
474
|
+
const vwapData = priceHistory.map((point) => point.vwap);
|
|
475
|
+
const twapData = priceHistory.map((point) => point.twap);
|
|
408
476
|
const config = {
|
|
409
477
|
type: "line",
|
|
410
478
|
data: {
|
|
@@ -434,6 +502,30 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
434
502
|
fill: false,
|
|
435
503
|
tension: 0.4
|
|
436
504
|
},
|
|
505
|
+
{
|
|
506
|
+
label: "Trade",
|
|
507
|
+
data: tradeData,
|
|
508
|
+
borderColor: "#ffc107",
|
|
509
|
+
backgroundColor: "rgba(255, 193, 7, 0.1)",
|
|
510
|
+
fill: false,
|
|
511
|
+
tension: 0.4
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
label: "VWAP",
|
|
515
|
+
data: vwapData,
|
|
516
|
+
borderColor: "#17a2b8",
|
|
517
|
+
backgroundColor: "rgba(23, 162, 184, 0.1)",
|
|
518
|
+
fill: false,
|
|
519
|
+
tension: 0.4
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
label: "TWAP",
|
|
523
|
+
data: twapData,
|
|
524
|
+
borderColor: "#6610f2",
|
|
525
|
+
backgroundColor: "rgba(102, 16, 242, 0.1)",
|
|
526
|
+
fill: false,
|
|
527
|
+
tension: 0.4
|
|
528
|
+
},
|
|
437
529
|
{
|
|
438
530
|
label: "Volume",
|
|
439
531
|
data: volumeData,
|
|
@@ -479,7 +571,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
479
571
|
content: [
|
|
480
572
|
{
|
|
481
573
|
type: "text",
|
|
482
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate
|
|
574
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
|
|
483
575
|
uri: "getStockGraph"
|
|
484
576
|
}
|
|
485
577
|
],
|
|
@@ -517,7 +609,48 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
517
609
|
bid: point.bid,
|
|
518
610
|
offer: point.offer,
|
|
519
611
|
spread: point.spread,
|
|
520
|
-
volume: point.volume
|
|
612
|
+
volume: point.volume,
|
|
613
|
+
trade: point.trade,
|
|
614
|
+
indexValue: point.indexValue,
|
|
615
|
+
openingPrice: point.openingPrice,
|
|
616
|
+
closingPrice: point.closingPrice,
|
|
617
|
+
settlementPrice: point.settlementPrice,
|
|
618
|
+
tradingSessionHighPrice: point.tradingSessionHighPrice,
|
|
619
|
+
tradingSessionLowPrice: point.tradingSessionLowPrice,
|
|
620
|
+
vwap: point.vwap,
|
|
621
|
+
imbalance: point.imbalance,
|
|
622
|
+
openInterest: point.openInterest,
|
|
623
|
+
compositeUnderlyingPrice: point.compositeUnderlyingPrice,
|
|
624
|
+
simulatedSellPrice: point.simulatedSellPrice,
|
|
625
|
+
simulatedBuyPrice: point.simulatedBuyPrice,
|
|
626
|
+
marginRate: point.marginRate,
|
|
627
|
+
midPrice: point.midPrice,
|
|
628
|
+
emptyBook: point.emptyBook,
|
|
629
|
+
settleHighPrice: point.settleHighPrice,
|
|
630
|
+
settleLowPrice: point.settleLowPrice,
|
|
631
|
+
priorSettlePrice: point.priorSettlePrice,
|
|
632
|
+
sessionHighBid: point.sessionHighBid,
|
|
633
|
+
sessionLowOffer: point.sessionLowOffer,
|
|
634
|
+
earlyPrices: point.earlyPrices,
|
|
635
|
+
auctionClearingPrice: point.auctionClearingPrice,
|
|
636
|
+
swapValueFactor: point.swapValueFactor,
|
|
637
|
+
dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
|
|
638
|
+
cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
|
|
639
|
+
dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
|
|
640
|
+
cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
|
|
641
|
+
fixingPrice: point.fixingPrice,
|
|
642
|
+
cashRate: point.cashRate,
|
|
643
|
+
recoveryRate: point.recoveryRate,
|
|
644
|
+
recoveryRateForLong: point.recoveryRateForLong,
|
|
645
|
+
recoveryRateForShort: point.recoveryRateForShort,
|
|
646
|
+
marketBid: point.marketBid,
|
|
647
|
+
marketOffer: point.marketOffer,
|
|
648
|
+
shortSaleMinPrice: point.shortSaleMinPrice,
|
|
649
|
+
previousClosingPrice: point.previousClosingPrice,
|
|
650
|
+
thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
|
|
651
|
+
dailyFinancingValue: point.dailyFinancingValue,
|
|
652
|
+
accruedFinancingValue: point.accruedFinancingValue,
|
|
653
|
+
twap: point.twap
|
|
521
654
|
}))
|
|
522
655
|
},
|
|
523
656
|
null,
|
|
@@ -532,7 +665,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
532
665
|
content: [
|
|
533
666
|
{
|
|
534
667
|
type: "text",
|
|
535
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get
|
|
668
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
536
669
|
uri: "getStockPriceHistory"
|
|
537
670
|
}
|
|
538
671
|
],
|
|
@@ -640,7 +773,7 @@ Parameters verified:
|
|
|
640
773
|
- Symbol: ${args.symbol}
|
|
641
774
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
642
775
|
|
|
643
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
776
|
+
To execute this order, call the executeOrder tool with these exact same parameters. Important: The user has to explicitly confirm before executeOrder is called!`,
|
|
644
777
|
uri: "verifyOrder"
|
|
645
778
|
}
|
|
646
779
|
]
|
|
@@ -841,52 +974,256 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
841
974
|
|
|
842
975
|
// src/utils/messageHandler.ts
|
|
843
976
|
var import_fixparser3 = require("fixparser");
|
|
977
|
+
function getEnumValue(enumObj, name) {
|
|
978
|
+
return enumObj[name] || name;
|
|
979
|
+
}
|
|
844
980
|
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
845
981
|
parser.logger.log({
|
|
846
982
|
level: "info",
|
|
847
983
|
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
848
984
|
});
|
|
849
985
|
const msgType = message.messageType;
|
|
850
|
-
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
986
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
|
|
851
987
|
const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
const
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const entryPrice = Number.parseFloat(entryPrices[i]?.value);
|
|
863
|
-
const entrySize = Number.parseFloat(entrySizes[i]?.value);
|
|
864
|
-
if (entryType === import_fixparser3.MDEntryType.Bid) {
|
|
865
|
-
bid = entryPrice;
|
|
866
|
-
} else if (entryType === import_fixparser3.MDEntryType.Offer) {
|
|
867
|
-
offer = entryPrice;
|
|
868
|
-
}
|
|
869
|
-
volume += entrySize;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
const spread = offer - bid;
|
|
873
|
-
const timestamp = Date.now();
|
|
988
|
+
parser.logger.log({
|
|
989
|
+
level: "info",
|
|
990
|
+
message: `Processing market data for symbol: ${symbol}`
|
|
991
|
+
});
|
|
992
|
+
const fixJson = message.toFIXJSON();
|
|
993
|
+
const entries = fixJson.Body?.NoMDEntries || [];
|
|
994
|
+
parser.logger.log({
|
|
995
|
+
level: "info",
|
|
996
|
+
message: `Found ${entries.length} market data entries`
|
|
997
|
+
});
|
|
874
998
|
const data = {
|
|
875
|
-
timestamp,
|
|
876
|
-
bid,
|
|
877
|
-
offer,
|
|
878
|
-
spread,
|
|
879
|
-
volume
|
|
999
|
+
timestamp: Date.now(),
|
|
1000
|
+
bid: 0,
|
|
1001
|
+
offer: 0,
|
|
1002
|
+
spread: 0,
|
|
1003
|
+
volume: 0,
|
|
1004
|
+
trade: 0,
|
|
1005
|
+
indexValue: 0,
|
|
1006
|
+
openingPrice: 0,
|
|
1007
|
+
closingPrice: 0,
|
|
1008
|
+
settlementPrice: 0,
|
|
1009
|
+
tradingSessionHighPrice: 0,
|
|
1010
|
+
tradingSessionLowPrice: 0,
|
|
1011
|
+
vwap: 0,
|
|
1012
|
+
imbalance: 0,
|
|
1013
|
+
openInterest: 0,
|
|
1014
|
+
compositeUnderlyingPrice: 0,
|
|
1015
|
+
simulatedSellPrice: 0,
|
|
1016
|
+
simulatedBuyPrice: 0,
|
|
1017
|
+
marginRate: 0,
|
|
1018
|
+
midPrice: 0,
|
|
1019
|
+
emptyBook: 0,
|
|
1020
|
+
settleHighPrice: 0,
|
|
1021
|
+
settleLowPrice: 0,
|
|
1022
|
+
priorSettlePrice: 0,
|
|
1023
|
+
sessionHighBid: 0,
|
|
1024
|
+
sessionLowOffer: 0,
|
|
1025
|
+
earlyPrices: 0,
|
|
1026
|
+
auctionClearingPrice: 0,
|
|
1027
|
+
swapValueFactor: 0,
|
|
1028
|
+
dailyValueAdjustmentForLongPositions: 0,
|
|
1029
|
+
cumulativeValueAdjustmentForLongPositions: 0,
|
|
1030
|
+
dailyValueAdjustmentForShortPositions: 0,
|
|
1031
|
+
cumulativeValueAdjustmentForShortPositions: 0,
|
|
1032
|
+
fixingPrice: 0,
|
|
1033
|
+
cashRate: 0,
|
|
1034
|
+
recoveryRate: 0,
|
|
1035
|
+
recoveryRateForLong: 0,
|
|
1036
|
+
recoveryRateForShort: 0,
|
|
1037
|
+
marketBid: 0,
|
|
1038
|
+
marketOffer: 0,
|
|
1039
|
+
shortSaleMinPrice: 0,
|
|
1040
|
+
previousClosingPrice: 0,
|
|
1041
|
+
thresholdLimitPriceBanding: 0,
|
|
1042
|
+
dailyFinancingValue: 0,
|
|
1043
|
+
accruedFinancingValue: 0,
|
|
1044
|
+
twap: 0
|
|
880
1045
|
};
|
|
1046
|
+
for (const entry of entries) {
|
|
1047
|
+
const entryType = entry.MDEntryType;
|
|
1048
|
+
const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
|
|
1049
|
+
const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
|
|
1050
|
+
if (entryType === import_fixparser3.MDEntryType.Bid || entryType === import_fixparser3.MDEntryType.Offer || entryType === import_fixparser3.MDEntryType.TradeVolume) {
|
|
1051
|
+
parser.logger.log({
|
|
1052
|
+
level: "info",
|
|
1053
|
+
message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
const enumValue = getEnumValue(import_fixparser3.MDEntryType, entryType);
|
|
1057
|
+
switch (enumValue) {
|
|
1058
|
+
case import_fixparser3.MDEntryType.Bid:
|
|
1059
|
+
data.bid = price;
|
|
1060
|
+
break;
|
|
1061
|
+
case import_fixparser3.MDEntryType.Offer:
|
|
1062
|
+
data.offer = price;
|
|
1063
|
+
break;
|
|
1064
|
+
case import_fixparser3.MDEntryType.Trade:
|
|
1065
|
+
data.trade = price;
|
|
1066
|
+
break;
|
|
1067
|
+
case import_fixparser3.MDEntryType.IndexValue:
|
|
1068
|
+
data.indexValue = price;
|
|
1069
|
+
break;
|
|
1070
|
+
case import_fixparser3.MDEntryType.OpeningPrice:
|
|
1071
|
+
data.openingPrice = price;
|
|
1072
|
+
break;
|
|
1073
|
+
case import_fixparser3.MDEntryType.ClosingPrice:
|
|
1074
|
+
data.closingPrice = price;
|
|
1075
|
+
break;
|
|
1076
|
+
case import_fixparser3.MDEntryType.SettlementPrice:
|
|
1077
|
+
data.settlementPrice = price;
|
|
1078
|
+
break;
|
|
1079
|
+
case import_fixparser3.MDEntryType.TradingSessionHighPrice:
|
|
1080
|
+
data.tradingSessionHighPrice = price;
|
|
1081
|
+
break;
|
|
1082
|
+
case import_fixparser3.MDEntryType.TradingSessionLowPrice:
|
|
1083
|
+
data.tradingSessionLowPrice = price;
|
|
1084
|
+
break;
|
|
1085
|
+
case import_fixparser3.MDEntryType.VWAP:
|
|
1086
|
+
data.vwap = price;
|
|
1087
|
+
break;
|
|
1088
|
+
case import_fixparser3.MDEntryType.Imbalance:
|
|
1089
|
+
data.imbalance = size;
|
|
1090
|
+
break;
|
|
1091
|
+
case import_fixparser3.MDEntryType.TradeVolume:
|
|
1092
|
+
data.volume = size;
|
|
1093
|
+
break;
|
|
1094
|
+
case import_fixparser3.MDEntryType.OpenInterest:
|
|
1095
|
+
data.openInterest = size;
|
|
1096
|
+
break;
|
|
1097
|
+
case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
|
|
1098
|
+
data.compositeUnderlyingPrice = price;
|
|
1099
|
+
break;
|
|
1100
|
+
case import_fixparser3.MDEntryType.SimulatedSellPrice:
|
|
1101
|
+
data.simulatedSellPrice = price;
|
|
1102
|
+
break;
|
|
1103
|
+
case import_fixparser3.MDEntryType.SimulatedBuyPrice:
|
|
1104
|
+
data.simulatedBuyPrice = price;
|
|
1105
|
+
break;
|
|
1106
|
+
case import_fixparser3.MDEntryType.MarginRate:
|
|
1107
|
+
data.marginRate = price;
|
|
1108
|
+
break;
|
|
1109
|
+
case import_fixparser3.MDEntryType.MidPrice:
|
|
1110
|
+
data.midPrice = price;
|
|
1111
|
+
break;
|
|
1112
|
+
case import_fixparser3.MDEntryType.EmptyBook:
|
|
1113
|
+
data.emptyBook = 1;
|
|
1114
|
+
break;
|
|
1115
|
+
case import_fixparser3.MDEntryType.SettleHighPrice:
|
|
1116
|
+
data.settleHighPrice = price;
|
|
1117
|
+
break;
|
|
1118
|
+
case import_fixparser3.MDEntryType.SettleLowPrice:
|
|
1119
|
+
data.settleLowPrice = price;
|
|
1120
|
+
break;
|
|
1121
|
+
case import_fixparser3.MDEntryType.PriorSettlePrice:
|
|
1122
|
+
data.priorSettlePrice = price;
|
|
1123
|
+
break;
|
|
1124
|
+
case import_fixparser3.MDEntryType.SessionHighBid:
|
|
1125
|
+
data.sessionHighBid = price;
|
|
1126
|
+
break;
|
|
1127
|
+
case import_fixparser3.MDEntryType.SessionLowOffer:
|
|
1128
|
+
data.sessionLowOffer = price;
|
|
1129
|
+
break;
|
|
1130
|
+
case import_fixparser3.MDEntryType.EarlyPrices:
|
|
1131
|
+
data.earlyPrices = price;
|
|
1132
|
+
break;
|
|
1133
|
+
case import_fixparser3.MDEntryType.AuctionClearingPrice:
|
|
1134
|
+
data.auctionClearingPrice = price;
|
|
1135
|
+
break;
|
|
1136
|
+
case import_fixparser3.MDEntryType.SwapValueFactor:
|
|
1137
|
+
data.swapValueFactor = price;
|
|
1138
|
+
break;
|
|
1139
|
+
case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
|
|
1140
|
+
data.dailyValueAdjustmentForLongPositions = price;
|
|
1141
|
+
break;
|
|
1142
|
+
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
|
|
1143
|
+
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1144
|
+
break;
|
|
1145
|
+
case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
|
|
1146
|
+
data.dailyValueAdjustmentForShortPositions = price;
|
|
1147
|
+
break;
|
|
1148
|
+
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
|
|
1149
|
+
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1150
|
+
break;
|
|
1151
|
+
case import_fixparser3.MDEntryType.FixingPrice:
|
|
1152
|
+
data.fixingPrice = price;
|
|
1153
|
+
break;
|
|
1154
|
+
case import_fixparser3.MDEntryType.CashRate:
|
|
1155
|
+
data.cashRate = price;
|
|
1156
|
+
break;
|
|
1157
|
+
case import_fixparser3.MDEntryType.RecoveryRate:
|
|
1158
|
+
data.recoveryRate = price;
|
|
1159
|
+
break;
|
|
1160
|
+
case import_fixparser3.MDEntryType.RecoveryRateForLong:
|
|
1161
|
+
data.recoveryRateForLong = price;
|
|
1162
|
+
break;
|
|
1163
|
+
case import_fixparser3.MDEntryType.RecoveryRateForShort:
|
|
1164
|
+
data.recoveryRateForShort = price;
|
|
1165
|
+
break;
|
|
1166
|
+
case import_fixparser3.MDEntryType.MarketBid:
|
|
1167
|
+
data.marketBid = price;
|
|
1168
|
+
break;
|
|
1169
|
+
case import_fixparser3.MDEntryType.MarketOffer:
|
|
1170
|
+
data.marketOffer = price;
|
|
1171
|
+
break;
|
|
1172
|
+
case import_fixparser3.MDEntryType.ShortSaleMinPrice:
|
|
1173
|
+
data.shortSaleMinPrice = price;
|
|
1174
|
+
break;
|
|
1175
|
+
case import_fixparser3.MDEntryType.PreviousClosingPrice:
|
|
1176
|
+
data.previousClosingPrice = price;
|
|
1177
|
+
break;
|
|
1178
|
+
case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
|
|
1179
|
+
data.thresholdLimitPriceBanding = price;
|
|
1180
|
+
break;
|
|
1181
|
+
case import_fixparser3.MDEntryType.DailyFinancingValue:
|
|
1182
|
+
data.dailyFinancingValue = price;
|
|
1183
|
+
break;
|
|
1184
|
+
case import_fixparser3.MDEntryType.AccruedFinancingValue:
|
|
1185
|
+
data.accruedFinancingValue = price;
|
|
1186
|
+
break;
|
|
1187
|
+
case import_fixparser3.MDEntryType.TWAP:
|
|
1188
|
+
data.twap = price;
|
|
1189
|
+
break;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
data.spread = data.offer - data.bid;
|
|
1193
|
+
console.log(">>>>>>>>>>>>>>>>>>>>", data);
|
|
881
1194
|
if (!marketDataPrices.has(symbol)) {
|
|
1195
|
+
parser.logger.log({
|
|
1196
|
+
level: "info",
|
|
1197
|
+
message: `Creating new price history array for symbol: ${symbol}`
|
|
1198
|
+
});
|
|
882
1199
|
marketDataPrices.set(symbol, []);
|
|
883
1200
|
}
|
|
884
1201
|
const prices = marketDataPrices.get(symbol);
|
|
885
1202
|
prices.push(data);
|
|
1203
|
+
parser.logger.log({
|
|
1204
|
+
level: "info",
|
|
1205
|
+
message: `Updated price history for ${symbol}. Current size: ${prices.length}`
|
|
1206
|
+
});
|
|
886
1207
|
if (prices.length > maxPriceHistory) {
|
|
887
1208
|
prices.splice(0, prices.length - maxPriceHistory);
|
|
1209
|
+
parser.logger.log({
|
|
1210
|
+
level: "info",
|
|
1211
|
+
message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
|
|
1212
|
+
});
|
|
888
1213
|
}
|
|
889
1214
|
onPriceUpdate?.(symbol, data);
|
|
1215
|
+
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
|
|
1216
|
+
if (mdReqID) {
|
|
1217
|
+
const callback = pendingRequests.get(mdReqID);
|
|
1218
|
+
if (callback) {
|
|
1219
|
+
callback(message);
|
|
1220
|
+
pendingRequests.delete(mdReqID);
|
|
1221
|
+
parser.logger.log({
|
|
1222
|
+
level: "info",
|
|
1223
|
+
message: `Resolved market data request for ID: ${mdReqID}`
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
890
1227
|
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
891
1228
|
const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
|
|
892
1229
|
const callback = pendingRequests.get(reqId);
|
|
@@ -899,6 +1236,39 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
|
|
|
899
1236
|
|
|
900
1237
|
// src/MCPRemote.ts
|
|
901
1238
|
var transports = {};
|
|
1239
|
+
function jsonSchemaToZod(schema) {
|
|
1240
|
+
if (schema.type === "object") {
|
|
1241
|
+
const shape = {};
|
|
1242
|
+
for (const [key, prop] of Object.entries(schema.properties || {})) {
|
|
1243
|
+
const propSchema = prop;
|
|
1244
|
+
if (propSchema.type === "string") {
|
|
1245
|
+
if (propSchema.enum) {
|
|
1246
|
+
shape[key] = import_zod.z.enum(propSchema.enum);
|
|
1247
|
+
} else {
|
|
1248
|
+
shape[key] = import_zod.z.string();
|
|
1249
|
+
}
|
|
1250
|
+
} else if (propSchema.type === "number") {
|
|
1251
|
+
shape[key] = import_zod.z.number();
|
|
1252
|
+
} else if (propSchema.type === "boolean") {
|
|
1253
|
+
shape[key] = import_zod.z.boolean();
|
|
1254
|
+
} else if (propSchema.type === "array") {
|
|
1255
|
+
if (propSchema.items.type === "string") {
|
|
1256
|
+
shape[key] = import_zod.z.array(import_zod.z.string());
|
|
1257
|
+
} else if (propSchema.items.type === "number") {
|
|
1258
|
+
shape[key] = import_zod.z.array(import_zod.z.number());
|
|
1259
|
+
} else if (propSchema.items.type === "boolean") {
|
|
1260
|
+
shape[key] = import_zod.z.array(import_zod.z.boolean());
|
|
1261
|
+
} else {
|
|
1262
|
+
shape[key] = import_zod.z.array(import_zod.z.any());
|
|
1263
|
+
}
|
|
1264
|
+
} else {
|
|
1265
|
+
shape[key] = import_zod.z.any();
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
return shape;
|
|
1269
|
+
}
|
|
1270
|
+
return {};
|
|
1271
|
+
}
|
|
902
1272
|
var MCPRemote = class extends MCPBase {
|
|
903
1273
|
/**
|
|
904
1274
|
* Port number the server will listen on.
|
|
@@ -941,7 +1311,7 @@ var MCPRemote = class extends MCPBase {
|
|
|
941
1311
|
*/
|
|
942
1312
|
marketDataPrices = /* @__PURE__ */ new Map();
|
|
943
1313
|
/**
|
|
944
|
-
* Maximum number of price
|
|
1314
|
+
* Maximum number of price history entries to keep per symbol
|
|
945
1315
|
* @private
|
|
946
1316
|
*/
|
|
947
1317
|
MAX_PRICE_HISTORY = 1e5;
|
|
@@ -963,55 +1333,22 @@ var MCPRemote = class extends MCPBase {
|
|
|
963
1333
|
this.parser,
|
|
964
1334
|
this.pendingRequests,
|
|
965
1335
|
this.marketDataPrices,
|
|
966
|
-
this.MAX_PRICE_HISTORY
|
|
967
|
-
(symbol, data) => {
|
|
968
|
-
this.mcpServer?.tool(
|
|
969
|
-
"priceUpdate",
|
|
970
|
-
{
|
|
971
|
-
description: "Price update notification",
|
|
972
|
-
schema: import_zod.z.object({
|
|
973
|
-
symbol: import_zod.z.string(),
|
|
974
|
-
timestamp: import_zod.z.number(),
|
|
975
|
-
bid: import_zod.z.number(),
|
|
976
|
-
offer: import_zod.z.number(),
|
|
977
|
-
spread: import_zod.z.number(),
|
|
978
|
-
volume: import_zod.z.number()
|
|
979
|
-
})
|
|
980
|
-
},
|
|
981
|
-
() => ({
|
|
982
|
-
content: [
|
|
983
|
-
{
|
|
984
|
-
type: "text",
|
|
985
|
-
text: JSON.stringify({ symbol, ...data })
|
|
986
|
-
}
|
|
987
|
-
]
|
|
988
|
-
})
|
|
989
|
-
);
|
|
990
|
-
}
|
|
1336
|
+
this.MAX_PRICE_HISTORY
|
|
991
1337
|
);
|
|
1338
|
+
this.logger?.log({
|
|
1339
|
+
level: "info",
|
|
1340
|
+
message: `Market Data Prices TEST: ${JSON.stringify(this.marketDataPrices)}`
|
|
1341
|
+
});
|
|
992
1342
|
}
|
|
993
1343
|
});
|
|
994
1344
|
this.httpServer = (0, import_node_http.createServer)(async (req, res) => {
|
|
995
|
-
console.log(req.headers);
|
|
996
|
-
this.logger?.log({
|
|
997
|
-
level: "info",
|
|
998
|
-
message: `Incoming request: ${req.method} ${req.url}`
|
|
999
|
-
});
|
|
1000
1345
|
if (!req.url || !req.method) {
|
|
1001
|
-
this.logger?.log({
|
|
1002
|
-
level: "error",
|
|
1003
|
-
message: "Invalid request: missing URL or method"
|
|
1004
|
-
});
|
|
1005
1346
|
res.writeHead(400);
|
|
1006
1347
|
res.end("Bad Request");
|
|
1007
1348
|
return;
|
|
1008
1349
|
}
|
|
1009
1350
|
if (req.url === "/mcp") {
|
|
1010
1351
|
const sessionId = req.headers["mcp-session-id"];
|
|
1011
|
-
this.logger?.log({
|
|
1012
|
-
level: "info",
|
|
1013
|
-
message: `MCP request received. Session ID: ${sessionId || "none"}, headers: ${req.headers}`
|
|
1014
|
-
});
|
|
1015
1352
|
if (req.method === "POST") {
|
|
1016
1353
|
const bodyChunks = [];
|
|
1017
1354
|
req.on("data", (chunk) => {
|
|
@@ -1022,47 +1359,23 @@ var MCPRemote = class extends MCPBase {
|
|
|
1022
1359
|
const body = Buffer.concat(bodyChunks).toString();
|
|
1023
1360
|
try {
|
|
1024
1361
|
parsed = JSON.parse(body);
|
|
1025
|
-
this.logger?.log({
|
|
1026
|
-
level: "info",
|
|
1027
|
-
message: `Parsed request body: ${JSON.stringify(parsed)}`
|
|
1028
|
-
});
|
|
1029
1362
|
} catch (err) {
|
|
1030
|
-
this.logger?.log({
|
|
1031
|
-
level: "error",
|
|
1032
|
-
message: `Failed to parse JSON body: ${err}`
|
|
1033
|
-
});
|
|
1034
1363
|
res.writeHead(400);
|
|
1035
1364
|
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
1036
1365
|
return;
|
|
1037
1366
|
}
|
|
1038
1367
|
let transport;
|
|
1039
1368
|
if (sessionId && transports[sessionId]) {
|
|
1040
|
-
this.logger?.log({
|
|
1041
|
-
level: "info",
|
|
1042
|
-
message: `Using existing transport for session: ${sessionId}`
|
|
1043
|
-
});
|
|
1044
1369
|
transport = transports[sessionId];
|
|
1045
1370
|
} else if (!sessionId && req.method === "POST" && (0, import_types.isInitializeRequest)(parsed)) {
|
|
1046
|
-
this.logger?.log({
|
|
1047
|
-
level: "info",
|
|
1048
|
-
message: "Creating new transport for initialization request"
|
|
1049
|
-
});
|
|
1050
1371
|
transport = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
1051
1372
|
sessionIdGenerator: () => (0, import_node_crypto.randomUUID)(),
|
|
1052
1373
|
onsessioninitialized: (sessionId2) => {
|
|
1053
|
-
this.logger?.log({
|
|
1054
|
-
level: "info",
|
|
1055
|
-
message: `New session initialized: ${sessionId2}`
|
|
1056
|
-
});
|
|
1057
1374
|
transports[sessionId2] = transport;
|
|
1058
1375
|
}
|
|
1059
1376
|
});
|
|
1060
1377
|
transport.onclose = () => {
|
|
1061
1378
|
if (transport.sessionId) {
|
|
1062
|
-
this.logger?.log({
|
|
1063
|
-
level: "info",
|
|
1064
|
-
message: `Session closed: ${transport.sessionId}`
|
|
1065
|
-
});
|
|
1066
1379
|
delete transports[transport.sessionId];
|
|
1067
1380
|
}
|
|
1068
1381
|
};
|
|
@@ -1073,10 +1386,6 @@ var MCPRemote = class extends MCPBase {
|
|
|
1073
1386
|
this.setupTools();
|
|
1074
1387
|
await this.mcpServer.connect(transport);
|
|
1075
1388
|
} else {
|
|
1076
|
-
this.logger?.log({
|
|
1077
|
-
level: "error",
|
|
1078
|
-
message: "Invalid request: No valid session ID provided"
|
|
1079
|
-
});
|
|
1080
1389
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1081
1390
|
res.end(
|
|
1082
1391
|
JSON.stringify({
|
|
@@ -1092,10 +1401,6 @@ var MCPRemote = class extends MCPBase {
|
|
|
1092
1401
|
}
|
|
1093
1402
|
try {
|
|
1094
1403
|
await transport.handleRequest(req, res, parsed);
|
|
1095
|
-
this.logger?.log({
|
|
1096
|
-
level: "info",
|
|
1097
|
-
message: "Request handled successfully"
|
|
1098
|
-
});
|
|
1099
1404
|
} catch (error) {
|
|
1100
1405
|
this.logger?.log({
|
|
1101
1406
|
level: "error",
|
|
@@ -1106,10 +1411,6 @@ var MCPRemote = class extends MCPBase {
|
|
|
1106
1411
|
});
|
|
1107
1412
|
} else if (req.method === "GET" || req.method === "DELETE") {
|
|
1108
1413
|
if (!sessionId || !transports[sessionId]) {
|
|
1109
|
-
this.logger?.log({
|
|
1110
|
-
level: "error",
|
|
1111
|
-
message: `Invalid session ID for ${req.method} request: ${sessionId}`
|
|
1112
|
-
});
|
|
1113
1414
|
res.writeHead(400);
|
|
1114
1415
|
res.end("Invalid or missing session ID");
|
|
1115
1416
|
return;
|
|
@@ -1117,10 +1418,6 @@ var MCPRemote = class extends MCPBase {
|
|
|
1117
1418
|
const transport = transports[sessionId];
|
|
1118
1419
|
try {
|
|
1119
1420
|
await transport.handleRequest(req, res);
|
|
1120
|
-
this.logger?.log({
|
|
1121
|
-
level: "info",
|
|
1122
|
-
message: `${req.method} request handled successfully for session: ${sessionId}`
|
|
1123
|
-
});
|
|
1124
1421
|
} catch (error) {
|
|
1125
1422
|
this.logger?.log({
|
|
1126
1423
|
level: "error",
|
|
@@ -1137,10 +1434,6 @@ var MCPRemote = class extends MCPBase {
|
|
|
1137
1434
|
res.end("Method Not Allowed");
|
|
1138
1435
|
}
|
|
1139
1436
|
} else {
|
|
1140
|
-
this.logger?.log({
|
|
1141
|
-
level: "error",
|
|
1142
|
-
message: `Not found: ${req.url}`
|
|
1143
|
-
});
|
|
1144
1437
|
res.writeHead(404);
|
|
1145
1438
|
res.end("Not Found");
|
|
1146
1439
|
}
|
|
@@ -1170,69 +1463,40 @@ var MCPRemote = class extends MCPBase {
|
|
|
1170
1463
|
});
|
|
1171
1464
|
return;
|
|
1172
1465
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
},
|
|
1179
|
-
async () => {
|
|
1180
|
-
return {
|
|
1181
|
-
content: [
|
|
1182
|
-
{
|
|
1183
|
-
type: "text",
|
|
1184
|
-
text: JSON.stringify(
|
|
1185
|
-
Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
1186
|
-
name,
|
|
1187
|
-
description,
|
|
1188
|
-
inputSchema: schema
|
|
1189
|
-
}))
|
|
1190
|
-
)
|
|
1191
|
-
}
|
|
1192
|
-
]
|
|
1193
|
-
};
|
|
1194
|
-
}
|
|
1466
|
+
const toolHandlers = createToolHandlers(
|
|
1467
|
+
this.parser,
|
|
1468
|
+
this.verifiedOrders,
|
|
1469
|
+
this.pendingRequests,
|
|
1470
|
+
this.marketDataPrices
|
|
1195
1471
|
);
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
if (!handler) {
|
|
1472
|
+
Object.entries(toolSchemas).forEach(([name, { description, schema }]) => {
|
|
1473
|
+
this.mcpServer?.registerTool(
|
|
1474
|
+
name,
|
|
1475
|
+
{
|
|
1476
|
+
description,
|
|
1477
|
+
inputSchema: jsonSchemaToZod(schema)
|
|
1478
|
+
},
|
|
1479
|
+
async (args) => {
|
|
1480
|
+
const handler = toolHandlers[name];
|
|
1481
|
+
if (!handler) {
|
|
1482
|
+
return {
|
|
1483
|
+
content: [
|
|
1484
|
+
{
|
|
1485
|
+
type: "text",
|
|
1486
|
+
text: `Tool not found: ${name}`
|
|
1487
|
+
}
|
|
1488
|
+
],
|
|
1489
|
+
isError: true
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
const result = await handler(args);
|
|
1218
1493
|
return {
|
|
1219
|
-
content:
|
|
1220
|
-
|
|
1221
|
-
type: "text",
|
|
1222
|
-
text: `Tool not found: ${name}`,
|
|
1223
|
-
uri: name
|
|
1224
|
-
}
|
|
1225
|
-
],
|
|
1226
|
-
isError: true
|
|
1494
|
+
content: result.content,
|
|
1495
|
+
isError: result.isError
|
|
1227
1496
|
};
|
|
1228
1497
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
content: result.content,
|
|
1232
|
-
isError: result.isError
|
|
1233
|
-
};
|
|
1234
|
-
}
|
|
1235
|
-
);
|
|
1498
|
+
);
|
|
1499
|
+
});
|
|
1236
1500
|
}
|
|
1237
1501
|
};
|
|
1238
1502
|
// Annotate the CommonJS export names for ESM import in node:
|