fixparser-plugin-mcp 9.1.7-edd9ee17 → 9.1.7-eea80766
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 +117 -482
- package/build/cjs/MCPLocal.js.map +4 -4
- package/build/cjs/MCPRemote.js +435 -1328
- package/build/cjs/MCPRemote.js.map +4 -4
- package/build/esm/MCPLocal.mjs +117 -482
- package/build/esm/MCPLocal.mjs.map +4 -4
- package/build/esm/MCPRemote.mjs +444 -1318
- package/build/esm/MCPRemote.mjs.map +4 -4
- package/build-examples/cjs/example_mcp_local.js +7 -7
- package/build-examples/cjs/example_mcp_local.js.map +4 -4
- package/build-examples/esm/example_mcp_local.mjs +7 -7
- package/build-examples/esm/example_mcp_local.mjs.map +4 -4
- package/package.json +7 -7
- package/types/MCPLocal.d.ts +9 -25
- package/types/MCPRemote.d.ts +27 -25
- package/types/schemas/index.d.ts +15 -3
- package/types/tools/index.d.ts +11 -2
- package/types/tools/marketData.d.ts +28 -7
- package/types/tools/order.d.ts +3 -4
- package/types/tools/parse.d.ts +2 -2
- package/types/tools/parseToJSON.d.ts +2 -2
- package/build/cjs/index.js +0 -1627
- package/build/cjs/index.js.map +0 -7
- package/build/esm/index.mjs +0 -1589
- package/build/esm/index.mjs.map +0 -7
- package/build-examples/cjs/example_mcp_remote.js +0 -16
- package/build-examples/cjs/example_mcp_remote.js.map +0 -7
- package/build-examples/esm/example_mcp_remote.mjs +0 -16
- package/build-examples/esm/example_mcp_remote.mjs.map +0 -7
- package/types/MCPBase.d.ts +0 -49
- package/types/schemas/marketData.d.ts +0 -48
- package/types/utils/messageHandler.d.ts +0 -12
package/build/cjs/MCPLocal.js
CHANGED
|
@@ -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(
|
|
463
|
-
chart.setHeight(
|
|
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,17 +415,24 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
550
415
|
};
|
|
551
416
|
chart.setConfig(config);
|
|
552
417
|
const imageBuffer = await chart.toBinary();
|
|
553
|
-
const
|
|
418
|
+
const base64Image = imageBuffer.toString("base64");
|
|
554
419
|
return {
|
|
555
420
|
content: [
|
|
556
421
|
{
|
|
557
|
-
type: "
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
mimeType: "image/png",
|
|
561
|
-
blob: base64
|
|
562
|
-
}
|
|
422
|
+
type: "image",
|
|
423
|
+
data: base64Image,
|
|
424
|
+
mimeType: "image/png"
|
|
563
425
|
}
|
|
426
|
+
// {
|
|
427
|
+
// type: 'image',
|
|
428
|
+
// image: {
|
|
429
|
+
// source: {
|
|
430
|
+
// filename: 'graph.png',
|
|
431
|
+
// data: `data:image/png;base64,${base64Image}`,
|
|
432
|
+
// },
|
|
433
|
+
// },
|
|
434
|
+
// mimeType: 'image/png',
|
|
435
|
+
// },
|
|
564
436
|
]
|
|
565
437
|
};
|
|
566
438
|
} catch (error) {
|
|
@@ -568,7 +440,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
568
440
|
content: [
|
|
569
441
|
{
|
|
570
442
|
type: "text",
|
|
571
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate
|
|
443
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
|
|
572
444
|
uri: "getStockGraph"
|
|
573
445
|
}
|
|
574
446
|
],
|
|
@@ -606,48 +478,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
606
478
|
bid: point.bid,
|
|
607
479
|
offer: point.offer,
|
|
608
480
|
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
|
|
481
|
+
volume: point.volume
|
|
651
482
|
}))
|
|
652
483
|
},
|
|
653
484
|
null,
|
|
@@ -662,7 +493,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
662
493
|
content: [
|
|
663
494
|
{
|
|
664
495
|
type: "text",
|
|
665
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
496
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
|
|
666
497
|
uri: "getStockPriceHistory"
|
|
667
498
|
}
|
|
668
499
|
],
|
|
@@ -770,7 +601,7 @@ Parameters verified:
|
|
|
770
601
|
- Symbol: ${args.symbol}
|
|
771
602
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
772
603
|
|
|
773
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
604
|
+
To execute this order, call the executeOrder tool with these exact same parameters.`,
|
|
774
605
|
uri: "verifyOrder"
|
|
775
606
|
}
|
|
776
607
|
]
|
|
@@ -969,285 +800,9 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
969
800
|
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
970
801
|
});
|
|
971
802
|
|
|
972
|
-
// src/utils/messageHandler.ts
|
|
973
|
-
var import_fixparser3 = require("fixparser");
|
|
974
|
-
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
975
|
-
parser.logger.log({
|
|
976
|
-
level: "info",
|
|
977
|
-
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
978
|
-
});
|
|
979
|
-
const msgType = message.messageType;
|
|
980
|
-
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
|
|
981
|
-
const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
|
|
982
|
-
parser.logger.log({
|
|
983
|
-
level: "info",
|
|
984
|
-
message: `Processing market data for symbol: ${symbol}`
|
|
985
|
-
});
|
|
986
|
-
const fixJson = message.toFIXJSON();
|
|
987
|
-
const entries = fixJson.Body?.NoMDEntries || [];
|
|
988
|
-
parser.logger.log({
|
|
989
|
-
level: "info",
|
|
990
|
-
message: `Found ${entries.length} market data entries`
|
|
991
|
-
});
|
|
992
|
-
const data = {
|
|
993
|
-
timestamp: Date.now(),
|
|
994
|
-
bid: 0,
|
|
995
|
-
offer: 0,
|
|
996
|
-
spread: 0,
|
|
997
|
-
volume: 0,
|
|
998
|
-
trade: 0,
|
|
999
|
-
indexValue: 0,
|
|
1000
|
-
openingPrice: 0,
|
|
1001
|
-
closingPrice: 0,
|
|
1002
|
-
settlementPrice: 0,
|
|
1003
|
-
tradingSessionHighPrice: 0,
|
|
1004
|
-
tradingSessionLowPrice: 0,
|
|
1005
|
-
vwap: 0,
|
|
1006
|
-
imbalance: 0,
|
|
1007
|
-
openInterest: 0,
|
|
1008
|
-
compositeUnderlyingPrice: 0,
|
|
1009
|
-
simulatedSellPrice: 0,
|
|
1010
|
-
simulatedBuyPrice: 0,
|
|
1011
|
-
marginRate: 0,
|
|
1012
|
-
midPrice: 0,
|
|
1013
|
-
emptyBook: 0,
|
|
1014
|
-
settleHighPrice: 0,
|
|
1015
|
-
settleLowPrice: 0,
|
|
1016
|
-
priorSettlePrice: 0,
|
|
1017
|
-
sessionHighBid: 0,
|
|
1018
|
-
sessionLowOffer: 0,
|
|
1019
|
-
earlyPrices: 0,
|
|
1020
|
-
auctionClearingPrice: 0,
|
|
1021
|
-
swapValueFactor: 0,
|
|
1022
|
-
dailyValueAdjustmentForLongPositions: 0,
|
|
1023
|
-
cumulativeValueAdjustmentForLongPositions: 0,
|
|
1024
|
-
dailyValueAdjustmentForShortPositions: 0,
|
|
1025
|
-
cumulativeValueAdjustmentForShortPositions: 0,
|
|
1026
|
-
fixingPrice: 0,
|
|
1027
|
-
cashRate: 0,
|
|
1028
|
-
recoveryRate: 0,
|
|
1029
|
-
recoveryRateForLong: 0,
|
|
1030
|
-
recoveryRateForShort: 0,
|
|
1031
|
-
marketBid: 0,
|
|
1032
|
-
marketOffer: 0,
|
|
1033
|
-
shortSaleMinPrice: 0,
|
|
1034
|
-
previousClosingPrice: 0,
|
|
1035
|
-
thresholdLimitPriceBanding: 0,
|
|
1036
|
-
dailyFinancingValue: 0,
|
|
1037
|
-
accruedFinancingValue: 0,
|
|
1038
|
-
twap: 0
|
|
1039
|
-
};
|
|
1040
|
-
for (const entry of entries) {
|
|
1041
|
-
const entryType = entry.MDEntryType;
|
|
1042
|
-
const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
|
|
1043
|
-
const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
|
|
1044
|
-
if (entryType === import_fixparser3.MDEntryType.Bid || entryType === import_fixparser3.MDEntryType.Offer || entryType === import_fixparser3.MDEntryType.TradeVolume) {
|
|
1045
|
-
parser.logger.log({
|
|
1046
|
-
level: "info",
|
|
1047
|
-
message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
switch (entryType) {
|
|
1051
|
-
case import_fixparser3.MDEntryType.Bid:
|
|
1052
|
-
data.bid = price;
|
|
1053
|
-
break;
|
|
1054
|
-
case import_fixparser3.MDEntryType.Offer:
|
|
1055
|
-
data.offer = price;
|
|
1056
|
-
break;
|
|
1057
|
-
case import_fixparser3.MDEntryType.Trade:
|
|
1058
|
-
data.trade = price;
|
|
1059
|
-
break;
|
|
1060
|
-
case import_fixparser3.MDEntryType.IndexValue:
|
|
1061
|
-
data.indexValue = price;
|
|
1062
|
-
break;
|
|
1063
|
-
case import_fixparser3.MDEntryType.OpeningPrice:
|
|
1064
|
-
data.openingPrice = price;
|
|
1065
|
-
break;
|
|
1066
|
-
case import_fixparser3.MDEntryType.ClosingPrice:
|
|
1067
|
-
data.closingPrice = price;
|
|
1068
|
-
break;
|
|
1069
|
-
case import_fixparser3.MDEntryType.SettlementPrice:
|
|
1070
|
-
data.settlementPrice = price;
|
|
1071
|
-
break;
|
|
1072
|
-
case import_fixparser3.MDEntryType.TradingSessionHighPrice:
|
|
1073
|
-
data.tradingSessionHighPrice = price;
|
|
1074
|
-
break;
|
|
1075
|
-
case import_fixparser3.MDEntryType.TradingSessionLowPrice:
|
|
1076
|
-
data.tradingSessionLowPrice = price;
|
|
1077
|
-
break;
|
|
1078
|
-
case import_fixparser3.MDEntryType.VWAP:
|
|
1079
|
-
data.vwap = price;
|
|
1080
|
-
break;
|
|
1081
|
-
case import_fixparser3.MDEntryType.Imbalance:
|
|
1082
|
-
data.imbalance = size;
|
|
1083
|
-
break;
|
|
1084
|
-
case import_fixparser3.MDEntryType.TradeVolume:
|
|
1085
|
-
data.volume = size;
|
|
1086
|
-
break;
|
|
1087
|
-
case import_fixparser3.MDEntryType.OpenInterest:
|
|
1088
|
-
data.openInterest = size;
|
|
1089
|
-
break;
|
|
1090
|
-
case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
|
|
1091
|
-
data.compositeUnderlyingPrice = price;
|
|
1092
|
-
break;
|
|
1093
|
-
case import_fixparser3.MDEntryType.SimulatedSellPrice:
|
|
1094
|
-
data.simulatedSellPrice = price;
|
|
1095
|
-
break;
|
|
1096
|
-
case import_fixparser3.MDEntryType.SimulatedBuyPrice:
|
|
1097
|
-
data.simulatedBuyPrice = price;
|
|
1098
|
-
break;
|
|
1099
|
-
case import_fixparser3.MDEntryType.MarginRate:
|
|
1100
|
-
data.marginRate = price;
|
|
1101
|
-
break;
|
|
1102
|
-
case import_fixparser3.MDEntryType.MidPrice:
|
|
1103
|
-
data.midPrice = price;
|
|
1104
|
-
break;
|
|
1105
|
-
case import_fixparser3.MDEntryType.EmptyBook:
|
|
1106
|
-
data.emptyBook = 1;
|
|
1107
|
-
break;
|
|
1108
|
-
case import_fixparser3.MDEntryType.SettleHighPrice:
|
|
1109
|
-
data.settleHighPrice = price;
|
|
1110
|
-
break;
|
|
1111
|
-
case import_fixparser3.MDEntryType.SettleLowPrice:
|
|
1112
|
-
data.settleLowPrice = price;
|
|
1113
|
-
break;
|
|
1114
|
-
case import_fixparser3.MDEntryType.PriorSettlePrice:
|
|
1115
|
-
data.priorSettlePrice = price;
|
|
1116
|
-
break;
|
|
1117
|
-
case import_fixparser3.MDEntryType.SessionHighBid:
|
|
1118
|
-
data.sessionHighBid = price;
|
|
1119
|
-
break;
|
|
1120
|
-
case import_fixparser3.MDEntryType.SessionLowOffer:
|
|
1121
|
-
data.sessionLowOffer = price;
|
|
1122
|
-
break;
|
|
1123
|
-
case import_fixparser3.MDEntryType.EarlyPrices:
|
|
1124
|
-
data.earlyPrices = price;
|
|
1125
|
-
break;
|
|
1126
|
-
case import_fixparser3.MDEntryType.AuctionClearingPrice:
|
|
1127
|
-
data.auctionClearingPrice = price;
|
|
1128
|
-
break;
|
|
1129
|
-
case import_fixparser3.MDEntryType.SwapValueFactor:
|
|
1130
|
-
data.swapValueFactor = price;
|
|
1131
|
-
break;
|
|
1132
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
|
|
1133
|
-
data.dailyValueAdjustmentForLongPositions = price;
|
|
1134
|
-
break;
|
|
1135
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
|
|
1136
|
-
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1137
|
-
break;
|
|
1138
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
|
|
1139
|
-
data.dailyValueAdjustmentForShortPositions = price;
|
|
1140
|
-
break;
|
|
1141
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
|
|
1142
|
-
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1143
|
-
break;
|
|
1144
|
-
case import_fixparser3.MDEntryType.FixingPrice:
|
|
1145
|
-
data.fixingPrice = price;
|
|
1146
|
-
break;
|
|
1147
|
-
case import_fixparser3.MDEntryType.CashRate:
|
|
1148
|
-
data.cashRate = price;
|
|
1149
|
-
break;
|
|
1150
|
-
case import_fixparser3.MDEntryType.RecoveryRate:
|
|
1151
|
-
data.recoveryRate = price;
|
|
1152
|
-
break;
|
|
1153
|
-
case import_fixparser3.MDEntryType.RecoveryRateForLong:
|
|
1154
|
-
data.recoveryRateForLong = price;
|
|
1155
|
-
break;
|
|
1156
|
-
case import_fixparser3.MDEntryType.RecoveryRateForShort:
|
|
1157
|
-
data.recoveryRateForShort = price;
|
|
1158
|
-
break;
|
|
1159
|
-
case import_fixparser3.MDEntryType.MarketBid:
|
|
1160
|
-
data.marketBid = price;
|
|
1161
|
-
break;
|
|
1162
|
-
case import_fixparser3.MDEntryType.MarketOffer:
|
|
1163
|
-
data.marketOffer = price;
|
|
1164
|
-
break;
|
|
1165
|
-
case import_fixparser3.MDEntryType.ShortSaleMinPrice:
|
|
1166
|
-
data.shortSaleMinPrice = price;
|
|
1167
|
-
break;
|
|
1168
|
-
case import_fixparser3.MDEntryType.PreviousClosingPrice:
|
|
1169
|
-
data.previousClosingPrice = price;
|
|
1170
|
-
break;
|
|
1171
|
-
case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
|
|
1172
|
-
data.thresholdLimitPriceBanding = price;
|
|
1173
|
-
break;
|
|
1174
|
-
case import_fixparser3.MDEntryType.DailyFinancingValue:
|
|
1175
|
-
data.dailyFinancingValue = price;
|
|
1176
|
-
break;
|
|
1177
|
-
case import_fixparser3.MDEntryType.AccruedFinancingValue:
|
|
1178
|
-
data.accruedFinancingValue = price;
|
|
1179
|
-
break;
|
|
1180
|
-
case import_fixparser3.MDEntryType.TWAP:
|
|
1181
|
-
data.twap = price;
|
|
1182
|
-
break;
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
data.spread = data.offer - data.bid;
|
|
1186
|
-
if (!marketDataPrices.has(symbol)) {
|
|
1187
|
-
parser.logger.log({
|
|
1188
|
-
level: "info",
|
|
1189
|
-
message: `Creating new price history array for symbol: ${symbol}`
|
|
1190
|
-
});
|
|
1191
|
-
marketDataPrices.set(symbol, []);
|
|
1192
|
-
}
|
|
1193
|
-
const prices = marketDataPrices.get(symbol);
|
|
1194
|
-
prices.push(data);
|
|
1195
|
-
parser.logger.log({
|
|
1196
|
-
level: "info",
|
|
1197
|
-
message: `Updated price history for ${symbol}. Current size: ${prices.length}`
|
|
1198
|
-
});
|
|
1199
|
-
if (prices.length > maxPriceHistory) {
|
|
1200
|
-
prices.splice(0, prices.length - maxPriceHistory);
|
|
1201
|
-
parser.logger.log({
|
|
1202
|
-
level: "info",
|
|
1203
|
-
message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
|
|
1204
|
-
});
|
|
1205
|
-
}
|
|
1206
|
-
onPriceUpdate?.(symbol, data);
|
|
1207
|
-
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
|
|
1208
|
-
if (mdReqID) {
|
|
1209
|
-
const callback = pendingRequests.get(mdReqID);
|
|
1210
|
-
if (callback) {
|
|
1211
|
-
callback(message);
|
|
1212
|
-
pendingRequests.delete(mdReqID);
|
|
1213
|
-
parser.logger.log({
|
|
1214
|
-
level: "info",
|
|
1215
|
-
message: `Resolved market data request for ID: ${mdReqID}`
|
|
1216
|
-
});
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
1220
|
-
const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
|
|
1221
|
-
const callback = pendingRequests.get(reqId);
|
|
1222
|
-
if (callback) {
|
|
1223
|
-
callback(message);
|
|
1224
|
-
pendingRequests.delete(reqId);
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
803
|
// src/MCPLocal.ts
|
|
1230
|
-
var MCPLocal = class
|
|
1231
|
-
|
|
1232
|
-
* Map to store verified orders before execution
|
|
1233
|
-
* @private
|
|
1234
|
-
*/
|
|
1235
|
-
verifiedOrders = /* @__PURE__ */ new Map();
|
|
1236
|
-
/**
|
|
1237
|
-
* Map to store pending requests and their callbacks
|
|
1238
|
-
* @private
|
|
1239
|
-
*/
|
|
1240
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
1241
|
-
/**
|
|
1242
|
-
* Map to store market data prices for each symbol
|
|
1243
|
-
* @private
|
|
1244
|
-
*/
|
|
1245
|
-
marketDataPrices = /* @__PURE__ */ new Map();
|
|
1246
|
-
/**
|
|
1247
|
-
* Maximum number of price history entries to keep per symbol
|
|
1248
|
-
* @private
|
|
1249
|
-
*/
|
|
1250
|
-
MAX_PRICE_HISTORY = 1e5;
|
|
804
|
+
var MCPLocal = class {
|
|
805
|
+
parser;
|
|
1251
806
|
server = new import_server.Server(
|
|
1252
807
|
{
|
|
1253
808
|
name: "fixparser",
|
|
@@ -1269,13 +824,90 @@ var MCPLocal = class extends MCPBase {
|
|
|
1269
824
|
}
|
|
1270
825
|
);
|
|
1271
826
|
transport = new import_stdio.StdioServerTransport();
|
|
827
|
+
onReady = void 0;
|
|
828
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
829
|
+
verifiedOrders = /* @__PURE__ */ new Map();
|
|
830
|
+
marketDataPrices = /* @__PURE__ */ new Map();
|
|
831
|
+
MAX_PRICE_HISTORY = 1e5;
|
|
832
|
+
// Maximum number of price points to store per symbol
|
|
1272
833
|
constructor({ logger, onReady }) {
|
|
1273
|
-
|
|
834
|
+
if (onReady) this.onReady = onReady;
|
|
1274
835
|
}
|
|
1275
836
|
async register(parser) {
|
|
1276
837
|
this.parser = parser;
|
|
1277
838
|
this.parser.addOnMessageCallback((message) => {
|
|
1278
|
-
|
|
839
|
+
this.parser?.logger.log({
|
|
840
|
+
level: "info",
|
|
841
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
842
|
+
});
|
|
843
|
+
const msgType = message.messageType;
|
|
844
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.ExecutionReport || msgType === import_fixparser3.Messages.Reject || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
|
|
845
|
+
this.parser?.logger.log({
|
|
846
|
+
level: "info",
|
|
847
|
+
message: `MCP Server handling message type: ${msgType}`
|
|
848
|
+
});
|
|
849
|
+
let id;
|
|
850
|
+
if (msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh || msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
851
|
+
const symbol = message.getField(import_fixparser3.Fields.Symbol);
|
|
852
|
+
const entryType = message.getField(import_fixparser3.Fields.MDEntryType);
|
|
853
|
+
const price = message.getField(import_fixparser3.Fields.MDEntryPx);
|
|
854
|
+
const size = message.getField(import_fixparser3.Fields.MDEntrySize);
|
|
855
|
+
const timestamp = message.getField(import_fixparser3.Fields.MDEntryTime)?.value || Date.now();
|
|
856
|
+
if (symbol?.value && price?.value) {
|
|
857
|
+
const symbolStr = String(symbol.value);
|
|
858
|
+
const priceNum = Number(price.value);
|
|
859
|
+
const sizeNum = size?.value ? Number(size.value) : 0;
|
|
860
|
+
const priceHistory = this.marketDataPrices.get(symbolStr) || [];
|
|
861
|
+
const lastEntry = priceHistory[priceHistory.length - 1] || {
|
|
862
|
+
timestamp: 0,
|
|
863
|
+
bid: 0,
|
|
864
|
+
offer: 0,
|
|
865
|
+
spread: 0,
|
|
866
|
+
volume: 0
|
|
867
|
+
};
|
|
868
|
+
const newEntry = {
|
|
869
|
+
timestamp: Number(timestamp),
|
|
870
|
+
bid: entryType?.value === import_fixparser3.MDEntryType.Bid ? priceNum : lastEntry.bid,
|
|
871
|
+
offer: entryType?.value === import_fixparser3.MDEntryType.Offer ? priceNum : lastEntry.offer,
|
|
872
|
+
spread: entryType?.value === import_fixparser3.MDEntryType.Offer ? priceNum - lastEntry.bid : entryType?.value === import_fixparser3.MDEntryType.Bid ? lastEntry.offer - priceNum : lastEntry.spread,
|
|
873
|
+
volume: entryType?.value === import_fixparser3.MDEntryType.TradeVolume ? sizeNum : lastEntry.volume
|
|
874
|
+
};
|
|
875
|
+
priceHistory.push(newEntry);
|
|
876
|
+
if (priceHistory.length > this.MAX_PRICE_HISTORY) {
|
|
877
|
+
priceHistory.shift();
|
|
878
|
+
}
|
|
879
|
+
this.marketDataPrices.set(symbolStr, priceHistory);
|
|
880
|
+
this.parser?.logger.log({
|
|
881
|
+
level: "info",
|
|
882
|
+
message: `MCP Server added ${symbol}: ${JSON.stringify(newEntry)}`
|
|
883
|
+
});
|
|
884
|
+
this.server.notification({
|
|
885
|
+
method: "priceUpdate",
|
|
886
|
+
params: {
|
|
887
|
+
symbol: symbolStr,
|
|
888
|
+
...newEntry
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
894
|
+
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID);
|
|
895
|
+
if (mdReqID) id = String(mdReqID.value);
|
|
896
|
+
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
897
|
+
const clOrdID = message.getField(import_fixparser3.Fields.ClOrdID);
|
|
898
|
+
if (clOrdID) id = String(clOrdID.value);
|
|
899
|
+
} else if (msgType === import_fixparser3.Messages.Reject) {
|
|
900
|
+
const refSeqNum = message.getField(import_fixparser3.Fields.RefSeqNum);
|
|
901
|
+
if (refSeqNum) id = String(refSeqNum.value);
|
|
902
|
+
}
|
|
903
|
+
if (id) {
|
|
904
|
+
const callback = this.pendingRequests.get(id);
|
|
905
|
+
if (callback) {
|
|
906
|
+
callback(message);
|
|
907
|
+
this.pendingRequests.delete(id);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
1279
911
|
});
|
|
1280
912
|
this.addWorkflows();
|
|
1281
913
|
await this.server.connect(this.transport);
|
|
@@ -1290,15 +922,18 @@ var MCPLocal = class extends MCPBase {
|
|
|
1290
922
|
if (!this.server) {
|
|
1291
923
|
return;
|
|
1292
924
|
}
|
|
1293
|
-
this.server.setRequestHandler(
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
description,
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
925
|
+
this.server.setRequestHandler(
|
|
926
|
+
import_zod.z.object({ method: import_zod.z.literal("tools/list") }),
|
|
927
|
+
async (request, extra) => {
|
|
928
|
+
return {
|
|
929
|
+
tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
930
|
+
name,
|
|
931
|
+
description,
|
|
932
|
+
inputSchema: schema
|
|
933
|
+
}))
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
);
|
|
1302
937
|
this.server.setRequestHandler(
|
|
1303
938
|
import_zod.z.object({
|
|
1304
939
|
method: import_zod.z.literal("tools/call"),
|
|
@@ -1310,7 +945,7 @@ var MCPLocal = class extends MCPBase {
|
|
|
1310
945
|
}).optional()
|
|
1311
946
|
})
|
|
1312
947
|
}),
|
|
1313
|
-
async (request) => {
|
|
948
|
+
async (request, extra) => {
|
|
1314
949
|
const { name, arguments: args } = request.params;
|
|
1315
950
|
const toolHandlers = createToolHandlers(
|
|
1316
951
|
this.parser,
|