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.
- package/build/cjs/MCPLocal.js +35 -367
- package/build/cjs/MCPLocal.js.map +2 -2
- package/build/cjs/MCPRemote.js +176 -435
- package/build/cjs/MCPRemote.js.map +2 -2
- package/build/cjs/index.js +177 -436
- package/build/cjs/index.js.map +2 -2
- package/build/esm/MCPLocal.mjs +35 -367
- package/build/esm/MCPLocal.mjs.map +2 -2
- package/build/esm/MCPRemote.mjs +176 -435
- package/build/esm/MCPRemote.mjs.map +2 -2
- package/build/esm/index.mjs +177 -436
- package/build/esm/index.mjs.map +2 -2
- package/build-examples/cjs/example_mcp_local.js +16 -0
- package/build-examples/cjs/example_mcp_local.js.map +7 -0
- package/build-examples/cjs/example_mcp_remote.js +16 -0
- package/build-examples/cjs/example_mcp_remote.js.map +7 -0
- package/build-examples/esm/example_mcp_local.mjs +16 -0
- package/build-examples/esm/example_mcp_local.mjs.map +7 -0
- package/build-examples/esm/example_mcp_remote.mjs +16 -0
- package/build-examples/esm/example_mcp_remote.mjs.map +7 -0
- package/package.json +1 -1
- package/types/MCPBase.d.ts +49 -0
- package/types/MCPLocal.d.ts +40 -0
- package/types/MCPRemote.d.ts +66 -0
- package/types/PluginOptions.d.ts +6 -0
- package/types/index.d.ts +3 -0
- package/types/schemas/index.d.ts +15 -0
- package/types/schemas/schemas.d.ts +168 -0
- package/types/tools/index.d.ts +17 -0
- package/types/tools/marketData.d.ts +40 -0
- package/types/tools/order.d.ts +12 -0
- package/types/tools/parse.d.ts +5 -0
- package/types/tools/parseToJSON.d.ts +5 -0
- package/types/utils/messageHandler.d.ts +18 -0
package/build/esm/MCPRemote.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
816
|
+
if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
950
817
|
const symbol = message.getField(Fields3.Symbol)?.value;
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
const
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
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
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
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:
|
|
1456
|
-
|
|
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 {
|