fixparser-plugin-mcp 9.1.7-67ba45e9 → 9.1.7-6afc89c5
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 +123 -533
- package/build/cjs/MCPLocal.js.map +4 -4
- package/build/cjs/MCPRemote.js +435 -1333
- package/build/cjs/MCPRemote.js.map +4 -4
- package/build/esm/MCPLocal.mjs +124 -534
- package/build/esm/MCPLocal.mjs.map +4 -4
- package/build/esm/MCPRemote.mjs +444 -1323
- 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 +16 -0
- package/types/MCPRemote.d.ts +60 -0
- package/types/PluginOptions.d.ts +6 -0
- package/types/index.d.ts +3 -0
- package/types/schemas/index.d.ts +27 -0
- package/types/schemas/schemas.d.ts +168 -0
- package/types/tools/index.d.ts +14 -0
- package/types/tools/marketData.d.ts +34 -0
- package/types/tools/order.d.ts +11 -0
- package/types/tools/parse.d.ts +5 -0
- package/types/tools/parseToJSON.d.ts +5 -0
- package/build/cjs/index.js +0 -1632
- package/build/cjs/index.js.map +0 -7
- package/build/esm/index.mjs +0 -1594
- 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/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: {
|
|
@@ -280,12 +238,12 @@ var toolSchemas = {
|
|
|
280
238
|
"X",
|
|
281
239
|
"Y",
|
|
282
240
|
"Z"
|
|
283
|
-
]
|
|
284
|
-
|
|
285
|
-
|
|
241
|
+
],
|
|
242
|
+
description: "Market Data Entry Types: 0=Bid, 1=Offer, 2=Trade, 3=Index Value, 4=Opening Price, 5=Closing Price, 6=Settlement Price, 7=High Price, 8=Low Price, 9=Trade Volume, A=Open Interest, B=Simulated Sell Price, C=Simulated Buy Price, D=Empty Book, E=Session High Bid, F=Session Low Offer, G=Fixing Price, H=Electronic Volume, I=Threshold Limits and Price Band Variation, J=Clearing Price, K=Open Interest Change, L=Last Trade Price, M=Last Trade Volume, N=Last Trade Time, O=Last Trade Tick, P=Last Trade Exchange, Q=Last Trade ID, R=Last Trade Side, S=Last Trade Price Change, T=Last Trade Price Change Percent, U=Last Trade Price Change Basis Points, V=Last Trade Price Change Points, W=Last Trade Price Change Ticks, X=Last Trade Price Change Ticks Percent, Y=Last Trade Price Change Ticks Basis Points, Z=Last Trade Price Change Ticks Points"
|
|
243
|
+
}
|
|
286
244
|
}
|
|
287
245
|
},
|
|
288
|
-
required: ["mdUpdateType", "symbols", "mdReqID", "subscriptionRequestType"]
|
|
246
|
+
required: ["mdUpdateType", "symbols", "mdReqID", "subscriptionRequestType", "mdEntryTypes"]
|
|
289
247
|
}
|
|
290
248
|
},
|
|
291
249
|
getStockGraph: {
|
|
@@ -316,63 +274,9 @@ 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
|
-
];
|
|
376
280
|
const messageFields = [
|
|
377
281
|
new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
|
|
378
282
|
new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
|
|
@@ -388,16 +292,12 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
388
292
|
args.symbols.forEach((symbol) => {
|
|
389
293
|
messageFields.push(new import_fixparser.Field(import_fixparser.Fields.Symbol, symbol));
|
|
390
294
|
});
|
|
391
|
-
messageFields.push(new import_fixparser.Field(import_fixparser.Fields.NoMDEntryTypes,
|
|
392
|
-
|
|
295
|
+
messageFields.push(new import_fixparser.Field(import_fixparser.Fields.NoMDEntryTypes, args.mdEntryTypes.length));
|
|
296
|
+
args.mdEntryTypes.forEach((entryType) => {
|
|
393
297
|
messageFields.push(new import_fixparser.Field(import_fixparser.Fields.MDEntryType, entryType));
|
|
394
298
|
});
|
|
395
299
|
const mdr = parser.createMessage(...messageFields);
|
|
396
300
|
if (!parser.connected) {
|
|
397
|
-
parser.logger.log({
|
|
398
|
-
level: "error",
|
|
399
|
-
message: "Not connected. Cannot send market data request."
|
|
400
|
-
});
|
|
401
301
|
return {
|
|
402
302
|
content: [
|
|
403
303
|
{
|
|
@@ -409,16 +309,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
409
309
|
isError: true
|
|
410
310
|
};
|
|
411
311
|
}
|
|
412
|
-
parser.logger.log({
|
|
413
|
-
level: "info",
|
|
414
|
-
message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
|
|
415
|
-
});
|
|
416
312
|
parser.send(mdr);
|
|
417
313
|
const fixData = await response;
|
|
418
|
-
parser.logger.log({
|
|
419
|
-
level: "info",
|
|
420
|
-
message: `Received market data response for request ID: ${args.mdReqID}`
|
|
421
|
-
});
|
|
422
314
|
return {
|
|
423
315
|
content: [
|
|
424
316
|
{
|
|
@@ -459,73 +351,18 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
459
351
|
};
|
|
460
352
|
}
|
|
461
353
|
const chart = new import_quickchart_js.default();
|
|
462
|
-
chart.setWidth(
|
|
463
|
-
chart.setHeight(
|
|
464
|
-
chart.setBackgroundColor("transparent");
|
|
354
|
+
chart.setWidth(600);
|
|
355
|
+
chart.setHeight(300);
|
|
465
356
|
const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
const spreadData = priceHistory.map((point) => point.spread);
|
|
469
|
-
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
|
-
const config = {
|
|
357
|
+
const data = priceHistory.map((point) => point.price);
|
|
358
|
+
chart.setConfig({
|
|
474
359
|
type: "line",
|
|
475
360
|
data: {
|
|
476
361
|
labels,
|
|
477
362
|
datasets: [
|
|
478
363
|
{
|
|
479
|
-
label:
|
|
480
|
-
data
|
|
481
|
-
borderColor: "#28a745",
|
|
482
|
-
backgroundColor: "rgba(40, 167, 69, 0.1)",
|
|
483
|
-
fill: false,
|
|
484
|
-
tension: 0.4
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
label: "Offer",
|
|
488
|
-
data: offerData,
|
|
489
|
-
borderColor: "#dc3545",
|
|
490
|
-
backgroundColor: "rgba(220, 53, 69, 0.1)",
|
|
491
|
-
fill: false,
|
|
492
|
-
tension: 0.4
|
|
493
|
-
},
|
|
494
|
-
{
|
|
495
|
-
label: "Spread",
|
|
496
|
-
data: spreadData,
|
|
497
|
-
borderColor: "#6c757d",
|
|
498
|
-
backgroundColor: "rgba(108, 117, 125, 0.1)",
|
|
499
|
-
fill: false,
|
|
500
|
-
tension: 0.4
|
|
501
|
-
},
|
|
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
|
-
{
|
|
527
|
-
label: "Volume",
|
|
528
|
-
data: volumeData,
|
|
364
|
+
label: symbol,
|
|
365
|
+
data,
|
|
529
366
|
borderColor: "#007bff",
|
|
530
367
|
backgroundColor: "rgba(0, 123, 255, 0.1)",
|
|
531
368
|
fill: true,
|
|
@@ -534,32 +371,43 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
534
371
|
]
|
|
535
372
|
},
|
|
536
373
|
options: {
|
|
537
|
-
responsive: true,
|
|
538
374
|
plugins: {
|
|
539
375
|
title: {
|
|
540
376
|
display: true,
|
|
541
|
-
text: `${symbol}
|
|
377
|
+
text: `${symbol} Price History`,
|
|
378
|
+
font: {
|
|
379
|
+
size: 16,
|
|
380
|
+
weight: "bold"
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
legend: {
|
|
384
|
+
display: true
|
|
542
385
|
}
|
|
543
386
|
},
|
|
544
387
|
scales: {
|
|
545
388
|
y: {
|
|
546
|
-
beginAtZero: false
|
|
389
|
+
beginAtZero: false,
|
|
390
|
+
grid: {
|
|
391
|
+
color: "#e9ecef"
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
x: {
|
|
395
|
+
grid: {
|
|
396
|
+
display: false
|
|
397
|
+
}
|
|
547
398
|
}
|
|
548
399
|
}
|
|
549
400
|
}
|
|
550
|
-
};
|
|
551
|
-
chart.setConfig(config);
|
|
401
|
+
});
|
|
552
402
|
const imageBuffer = await chart.toBinary();
|
|
553
|
-
const
|
|
403
|
+
const base64Image = imageBuffer.toString("base64");
|
|
554
404
|
return {
|
|
555
405
|
content: [
|
|
556
406
|
{
|
|
557
|
-
type: "
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
blob: base64
|
|
562
|
-
}
|
|
407
|
+
type: "image",
|
|
408
|
+
text: base64Image,
|
|
409
|
+
uri: "getStockGraph",
|
|
410
|
+
mimeType: "image/png"
|
|
563
411
|
}
|
|
564
412
|
]
|
|
565
413
|
};
|
|
@@ -568,7 +416,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
568
416
|
content: [
|
|
569
417
|
{
|
|
570
418
|
type: "text",
|
|
571
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
|
|
419
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate stock graph"}`,
|
|
572
420
|
uri: "getStockGraph"
|
|
573
421
|
}
|
|
574
422
|
],
|
|
@@ -601,53 +449,9 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
601
449
|
{
|
|
602
450
|
symbol,
|
|
603
451
|
count: priceHistory.length,
|
|
604
|
-
|
|
452
|
+
prices: priceHistory.map((point) => ({
|
|
605
453
|
timestamp: new Date(point.timestamp).toISOString(),
|
|
606
|
-
|
|
607
|
-
offer: point.offer,
|
|
608
|
-
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
|
|
454
|
+
price: point.price
|
|
651
455
|
}))
|
|
652
456
|
},
|
|
653
457
|
null,
|
|
@@ -662,7 +466,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
662
466
|
content: [
|
|
663
467
|
{
|
|
664
468
|
type: "text",
|
|
665
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
469
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
|
|
666
470
|
uri: "getStockPriceHistory"
|
|
667
471
|
}
|
|
668
472
|
],
|
|
@@ -770,7 +574,7 @@ Parameters verified:
|
|
|
770
574
|
- Symbol: ${args.symbol}
|
|
771
575
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
772
576
|
|
|
773
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
577
|
+
To execute this order, call the executeOrder tool with these exact same parameters.`,
|
|
774
578
|
uri: "verifyOrder"
|
|
775
579
|
}
|
|
776
580
|
]
|
|
@@ -969,290 +773,9 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
969
773
|
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
970
774
|
});
|
|
971
775
|
|
|
972
|
-
// src/utils/messageHandler.ts
|
|
973
|
-
var import_fixparser3 = require("fixparser");
|
|
974
|
-
function getEnumValue(enumObj, name) {
|
|
975
|
-
return enumObj[name] || name;
|
|
976
|
-
}
|
|
977
|
-
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
978
|
-
parser.logger.log({
|
|
979
|
-
level: "info",
|
|
980
|
-
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
981
|
-
});
|
|
982
|
-
const msgType = message.messageType;
|
|
983
|
-
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
|
|
984
|
-
const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
|
|
985
|
-
parser.logger.log({
|
|
986
|
-
level: "info",
|
|
987
|
-
message: `Processing market data for symbol: ${symbol}`
|
|
988
|
-
});
|
|
989
|
-
const fixJson = message.toFIXJSON();
|
|
990
|
-
const entries = fixJson.Body?.NoMDEntries || [];
|
|
991
|
-
parser.logger.log({
|
|
992
|
-
level: "info",
|
|
993
|
-
message: `Found ${entries.length} market data entries`
|
|
994
|
-
});
|
|
995
|
-
const data = {
|
|
996
|
-
timestamp: Date.now(),
|
|
997
|
-
bid: 0,
|
|
998
|
-
offer: 0,
|
|
999
|
-
spread: 0,
|
|
1000
|
-
volume: 0,
|
|
1001
|
-
trade: 0,
|
|
1002
|
-
indexValue: 0,
|
|
1003
|
-
openingPrice: 0,
|
|
1004
|
-
closingPrice: 0,
|
|
1005
|
-
settlementPrice: 0,
|
|
1006
|
-
tradingSessionHighPrice: 0,
|
|
1007
|
-
tradingSessionLowPrice: 0,
|
|
1008
|
-
vwap: 0,
|
|
1009
|
-
imbalance: 0,
|
|
1010
|
-
openInterest: 0,
|
|
1011
|
-
compositeUnderlyingPrice: 0,
|
|
1012
|
-
simulatedSellPrice: 0,
|
|
1013
|
-
simulatedBuyPrice: 0,
|
|
1014
|
-
marginRate: 0,
|
|
1015
|
-
midPrice: 0,
|
|
1016
|
-
emptyBook: 0,
|
|
1017
|
-
settleHighPrice: 0,
|
|
1018
|
-
settleLowPrice: 0,
|
|
1019
|
-
priorSettlePrice: 0,
|
|
1020
|
-
sessionHighBid: 0,
|
|
1021
|
-
sessionLowOffer: 0,
|
|
1022
|
-
earlyPrices: 0,
|
|
1023
|
-
auctionClearingPrice: 0,
|
|
1024
|
-
swapValueFactor: 0,
|
|
1025
|
-
dailyValueAdjustmentForLongPositions: 0,
|
|
1026
|
-
cumulativeValueAdjustmentForLongPositions: 0,
|
|
1027
|
-
dailyValueAdjustmentForShortPositions: 0,
|
|
1028
|
-
cumulativeValueAdjustmentForShortPositions: 0,
|
|
1029
|
-
fixingPrice: 0,
|
|
1030
|
-
cashRate: 0,
|
|
1031
|
-
recoveryRate: 0,
|
|
1032
|
-
recoveryRateForLong: 0,
|
|
1033
|
-
recoveryRateForShort: 0,
|
|
1034
|
-
marketBid: 0,
|
|
1035
|
-
marketOffer: 0,
|
|
1036
|
-
shortSaleMinPrice: 0,
|
|
1037
|
-
previousClosingPrice: 0,
|
|
1038
|
-
thresholdLimitPriceBanding: 0,
|
|
1039
|
-
dailyFinancingValue: 0,
|
|
1040
|
-
accruedFinancingValue: 0,
|
|
1041
|
-
twap: 0
|
|
1042
|
-
};
|
|
1043
|
-
for (const entry of entries) {
|
|
1044
|
-
const entryType = entry.MDEntryType;
|
|
1045
|
-
const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
|
|
1046
|
-
const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
|
|
1047
|
-
if (entryType === import_fixparser3.MDEntryType.Bid || entryType === import_fixparser3.MDEntryType.Offer || entryType === import_fixparser3.MDEntryType.TradeVolume) {
|
|
1048
|
-
parser.logger.log({
|
|
1049
|
-
level: "info",
|
|
1050
|
-
message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
const enumValue = getEnumValue(import_fixparser3.MDEntryType, entryType);
|
|
1054
|
-
switch (enumValue) {
|
|
1055
|
-
case import_fixparser3.MDEntryType.Bid:
|
|
1056
|
-
data.bid = price;
|
|
1057
|
-
break;
|
|
1058
|
-
case import_fixparser3.MDEntryType.Offer:
|
|
1059
|
-
data.offer = price;
|
|
1060
|
-
break;
|
|
1061
|
-
case import_fixparser3.MDEntryType.Trade:
|
|
1062
|
-
data.trade = price;
|
|
1063
|
-
break;
|
|
1064
|
-
case import_fixparser3.MDEntryType.IndexValue:
|
|
1065
|
-
data.indexValue = price;
|
|
1066
|
-
break;
|
|
1067
|
-
case import_fixparser3.MDEntryType.OpeningPrice:
|
|
1068
|
-
data.openingPrice = price;
|
|
1069
|
-
break;
|
|
1070
|
-
case import_fixparser3.MDEntryType.ClosingPrice:
|
|
1071
|
-
data.closingPrice = price;
|
|
1072
|
-
break;
|
|
1073
|
-
case import_fixparser3.MDEntryType.SettlementPrice:
|
|
1074
|
-
data.settlementPrice = price;
|
|
1075
|
-
break;
|
|
1076
|
-
case import_fixparser3.MDEntryType.TradingSessionHighPrice:
|
|
1077
|
-
data.tradingSessionHighPrice = price;
|
|
1078
|
-
break;
|
|
1079
|
-
case import_fixparser3.MDEntryType.TradingSessionLowPrice:
|
|
1080
|
-
data.tradingSessionLowPrice = price;
|
|
1081
|
-
break;
|
|
1082
|
-
case import_fixparser3.MDEntryType.VWAP:
|
|
1083
|
-
data.vwap = price;
|
|
1084
|
-
break;
|
|
1085
|
-
case import_fixparser3.MDEntryType.Imbalance:
|
|
1086
|
-
data.imbalance = size;
|
|
1087
|
-
break;
|
|
1088
|
-
case import_fixparser3.MDEntryType.TradeVolume:
|
|
1089
|
-
data.volume = size;
|
|
1090
|
-
break;
|
|
1091
|
-
case import_fixparser3.MDEntryType.OpenInterest:
|
|
1092
|
-
data.openInterest = size;
|
|
1093
|
-
break;
|
|
1094
|
-
case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
|
|
1095
|
-
data.compositeUnderlyingPrice = price;
|
|
1096
|
-
break;
|
|
1097
|
-
case import_fixparser3.MDEntryType.SimulatedSellPrice:
|
|
1098
|
-
data.simulatedSellPrice = price;
|
|
1099
|
-
break;
|
|
1100
|
-
case import_fixparser3.MDEntryType.SimulatedBuyPrice:
|
|
1101
|
-
data.simulatedBuyPrice = price;
|
|
1102
|
-
break;
|
|
1103
|
-
case import_fixparser3.MDEntryType.MarginRate:
|
|
1104
|
-
data.marginRate = price;
|
|
1105
|
-
break;
|
|
1106
|
-
case import_fixparser3.MDEntryType.MidPrice:
|
|
1107
|
-
data.midPrice = price;
|
|
1108
|
-
break;
|
|
1109
|
-
case import_fixparser3.MDEntryType.EmptyBook:
|
|
1110
|
-
data.emptyBook = 1;
|
|
1111
|
-
break;
|
|
1112
|
-
case import_fixparser3.MDEntryType.SettleHighPrice:
|
|
1113
|
-
data.settleHighPrice = price;
|
|
1114
|
-
break;
|
|
1115
|
-
case import_fixparser3.MDEntryType.SettleLowPrice:
|
|
1116
|
-
data.settleLowPrice = price;
|
|
1117
|
-
break;
|
|
1118
|
-
case import_fixparser3.MDEntryType.PriorSettlePrice:
|
|
1119
|
-
data.priorSettlePrice = price;
|
|
1120
|
-
break;
|
|
1121
|
-
case import_fixparser3.MDEntryType.SessionHighBid:
|
|
1122
|
-
data.sessionHighBid = price;
|
|
1123
|
-
break;
|
|
1124
|
-
case import_fixparser3.MDEntryType.SessionLowOffer:
|
|
1125
|
-
data.sessionLowOffer = price;
|
|
1126
|
-
break;
|
|
1127
|
-
case import_fixparser3.MDEntryType.EarlyPrices:
|
|
1128
|
-
data.earlyPrices = price;
|
|
1129
|
-
break;
|
|
1130
|
-
case import_fixparser3.MDEntryType.AuctionClearingPrice:
|
|
1131
|
-
data.auctionClearingPrice = price;
|
|
1132
|
-
break;
|
|
1133
|
-
case import_fixparser3.MDEntryType.SwapValueFactor:
|
|
1134
|
-
data.swapValueFactor = price;
|
|
1135
|
-
break;
|
|
1136
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
|
|
1137
|
-
data.dailyValueAdjustmentForLongPositions = price;
|
|
1138
|
-
break;
|
|
1139
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
|
|
1140
|
-
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1141
|
-
break;
|
|
1142
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
|
|
1143
|
-
data.dailyValueAdjustmentForShortPositions = price;
|
|
1144
|
-
break;
|
|
1145
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
|
|
1146
|
-
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1147
|
-
break;
|
|
1148
|
-
case import_fixparser3.MDEntryType.FixingPrice:
|
|
1149
|
-
data.fixingPrice = price;
|
|
1150
|
-
break;
|
|
1151
|
-
case import_fixparser3.MDEntryType.CashRate:
|
|
1152
|
-
data.cashRate = price;
|
|
1153
|
-
break;
|
|
1154
|
-
case import_fixparser3.MDEntryType.RecoveryRate:
|
|
1155
|
-
data.recoveryRate = price;
|
|
1156
|
-
break;
|
|
1157
|
-
case import_fixparser3.MDEntryType.RecoveryRateForLong:
|
|
1158
|
-
data.recoveryRateForLong = price;
|
|
1159
|
-
break;
|
|
1160
|
-
case import_fixparser3.MDEntryType.RecoveryRateForShort:
|
|
1161
|
-
data.recoveryRateForShort = price;
|
|
1162
|
-
break;
|
|
1163
|
-
case import_fixparser3.MDEntryType.MarketBid:
|
|
1164
|
-
data.marketBid = price;
|
|
1165
|
-
break;
|
|
1166
|
-
case import_fixparser3.MDEntryType.MarketOffer:
|
|
1167
|
-
data.marketOffer = price;
|
|
1168
|
-
break;
|
|
1169
|
-
case import_fixparser3.MDEntryType.ShortSaleMinPrice:
|
|
1170
|
-
data.shortSaleMinPrice = price;
|
|
1171
|
-
break;
|
|
1172
|
-
case import_fixparser3.MDEntryType.PreviousClosingPrice:
|
|
1173
|
-
data.previousClosingPrice = price;
|
|
1174
|
-
break;
|
|
1175
|
-
case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
|
|
1176
|
-
data.thresholdLimitPriceBanding = price;
|
|
1177
|
-
break;
|
|
1178
|
-
case import_fixparser3.MDEntryType.DailyFinancingValue:
|
|
1179
|
-
data.dailyFinancingValue = price;
|
|
1180
|
-
break;
|
|
1181
|
-
case import_fixparser3.MDEntryType.AccruedFinancingValue:
|
|
1182
|
-
data.accruedFinancingValue = price;
|
|
1183
|
-
break;
|
|
1184
|
-
case import_fixparser3.MDEntryType.TWAP:
|
|
1185
|
-
data.twap = price;
|
|
1186
|
-
break;
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
data.spread = data.offer - data.bid;
|
|
1190
|
-
console.log(">>>>>>>>>>>>>>>>>>>>", data);
|
|
1191
|
-
if (!marketDataPrices.has(symbol)) {
|
|
1192
|
-
parser.logger.log({
|
|
1193
|
-
level: "info",
|
|
1194
|
-
message: `Creating new price history array for symbol: ${symbol}`
|
|
1195
|
-
});
|
|
1196
|
-
marketDataPrices.set(symbol, []);
|
|
1197
|
-
}
|
|
1198
|
-
const prices = marketDataPrices.get(symbol);
|
|
1199
|
-
prices.push(data);
|
|
1200
|
-
parser.logger.log({
|
|
1201
|
-
level: "info",
|
|
1202
|
-
message: `Updated price history for ${symbol}. Current size: ${prices.length}`
|
|
1203
|
-
});
|
|
1204
|
-
if (prices.length > maxPriceHistory) {
|
|
1205
|
-
prices.splice(0, prices.length - maxPriceHistory);
|
|
1206
|
-
parser.logger.log({
|
|
1207
|
-
level: "info",
|
|
1208
|
-
message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
|
|
1209
|
-
});
|
|
1210
|
-
}
|
|
1211
|
-
onPriceUpdate?.(symbol, data);
|
|
1212
|
-
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
|
|
1213
|
-
if (mdReqID) {
|
|
1214
|
-
const callback = pendingRequests.get(mdReqID);
|
|
1215
|
-
if (callback) {
|
|
1216
|
-
callback(message);
|
|
1217
|
-
pendingRequests.delete(mdReqID);
|
|
1218
|
-
parser.logger.log({
|
|
1219
|
-
level: "info",
|
|
1220
|
-
message: `Resolved market data request for ID: ${mdReqID}`
|
|
1221
|
-
});
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
1225
|
-
const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
|
|
1226
|
-
const callback = pendingRequests.get(reqId);
|
|
1227
|
-
if (callback) {
|
|
1228
|
-
callback(message);
|
|
1229
|
-
pendingRequests.delete(reqId);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
776
|
// src/MCPLocal.ts
|
|
1235
|
-
var MCPLocal = class
|
|
1236
|
-
|
|
1237
|
-
* Map to store verified orders before execution
|
|
1238
|
-
* @private
|
|
1239
|
-
*/
|
|
1240
|
-
verifiedOrders = /* @__PURE__ */ new Map();
|
|
1241
|
-
/**
|
|
1242
|
-
* Map to store pending requests and their callbacks
|
|
1243
|
-
* @private
|
|
1244
|
-
*/
|
|
1245
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
1246
|
-
/**
|
|
1247
|
-
* Map to store market data prices for each symbol
|
|
1248
|
-
* @private
|
|
1249
|
-
*/
|
|
1250
|
-
marketDataPrices = /* @__PURE__ */ new Map();
|
|
1251
|
-
/**
|
|
1252
|
-
* Maximum number of price history entries to keep per symbol
|
|
1253
|
-
* @private
|
|
1254
|
-
*/
|
|
1255
|
-
MAX_PRICE_HISTORY = 1e5;
|
|
777
|
+
var MCPLocal = class {
|
|
778
|
+
parser;
|
|
1256
779
|
server = new import_server.Server(
|
|
1257
780
|
{
|
|
1258
781
|
name: "fixparser",
|
|
@@ -1274,13 +797,77 @@ var MCPLocal = class extends MCPBase {
|
|
|
1274
797
|
}
|
|
1275
798
|
);
|
|
1276
799
|
transport = new import_stdio.StdioServerTransport();
|
|
800
|
+
onReady = void 0;
|
|
801
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
802
|
+
verifiedOrders = /* @__PURE__ */ new Map();
|
|
803
|
+
marketDataPrices = /* @__PURE__ */ new Map();
|
|
804
|
+
MAX_PRICE_HISTORY = 1e5;
|
|
805
|
+
// Maximum number of price points to store per symbol
|
|
1277
806
|
constructor({ logger, onReady }) {
|
|
1278
|
-
|
|
807
|
+
if (onReady) this.onReady = onReady;
|
|
1279
808
|
}
|
|
1280
809
|
async register(parser) {
|
|
1281
810
|
this.parser = parser;
|
|
1282
811
|
this.parser.addOnMessageCallback((message) => {
|
|
1283
|
-
|
|
812
|
+
this.parser?.logger.log({
|
|
813
|
+
level: "info",
|
|
814
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
815
|
+
});
|
|
816
|
+
const msgType = message.messageType;
|
|
817
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.ExecutionReport || msgType === import_fixparser3.Messages.Reject || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
|
|
818
|
+
this.parser?.logger.log({
|
|
819
|
+
level: "info",
|
|
820
|
+
message: `MCP Server handling message type: ${msgType}`
|
|
821
|
+
});
|
|
822
|
+
let id;
|
|
823
|
+
if (msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh || msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
824
|
+
const symbol = message.getField(import_fixparser3.Fields.Symbol);
|
|
825
|
+
const price = message.getField(import_fixparser3.Fields.MDEntryPx);
|
|
826
|
+
const timestamp = message.getField(import_fixparser3.Fields.MDEntryTime)?.value || Date.now();
|
|
827
|
+
if (symbol?.value && price?.value) {
|
|
828
|
+
const symbolStr = String(symbol.value);
|
|
829
|
+
const priceNum = Number(price.value);
|
|
830
|
+
const priceHistory = this.marketDataPrices.get(symbolStr) || [];
|
|
831
|
+
priceHistory.push({
|
|
832
|
+
timestamp: Number(timestamp),
|
|
833
|
+
price: priceNum
|
|
834
|
+
});
|
|
835
|
+
if (priceHistory.length > this.MAX_PRICE_HISTORY) {
|
|
836
|
+
priceHistory.shift();
|
|
837
|
+
}
|
|
838
|
+
this.marketDataPrices.set(symbolStr, priceHistory);
|
|
839
|
+
this.parser?.logger.log({
|
|
840
|
+
level: "info",
|
|
841
|
+
message: `MCP Server added ${symbol}: ${priceNum}`
|
|
842
|
+
});
|
|
843
|
+
this.server.notification({
|
|
844
|
+
method: "priceUpdate",
|
|
845
|
+
params: {
|
|
846
|
+
symbol: symbolStr,
|
|
847
|
+
price: priceNum,
|
|
848
|
+
timestamp: Number(timestamp)
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
854
|
+
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID);
|
|
855
|
+
if (mdReqID) id = String(mdReqID.value);
|
|
856
|
+
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
857
|
+
const clOrdID = message.getField(import_fixparser3.Fields.ClOrdID);
|
|
858
|
+
if (clOrdID) id = String(clOrdID.value);
|
|
859
|
+
} else if (msgType === import_fixparser3.Messages.Reject) {
|
|
860
|
+
const refSeqNum = message.getField(import_fixparser3.Fields.RefSeqNum);
|
|
861
|
+
if (refSeqNum) id = String(refSeqNum.value);
|
|
862
|
+
}
|
|
863
|
+
if (id) {
|
|
864
|
+
const callback = this.pendingRequests.get(id);
|
|
865
|
+
if (callback) {
|
|
866
|
+
callback(message);
|
|
867
|
+
this.pendingRequests.delete(id);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
1284
871
|
});
|
|
1285
872
|
this.addWorkflows();
|
|
1286
873
|
await this.server.connect(this.transport);
|
|
@@ -1295,15 +882,18 @@ var MCPLocal = class extends MCPBase {
|
|
|
1295
882
|
if (!this.server) {
|
|
1296
883
|
return;
|
|
1297
884
|
}
|
|
1298
|
-
this.server.setRequestHandler(
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
description,
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
885
|
+
this.server.setRequestHandler(
|
|
886
|
+
import_zod.z.object({ method: import_zod.z.literal("tools/list") }),
|
|
887
|
+
async (request, extra) => {
|
|
888
|
+
return {
|
|
889
|
+
tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
890
|
+
name,
|
|
891
|
+
description,
|
|
892
|
+
inputSchema: schema
|
|
893
|
+
}))
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
);
|
|
1307
897
|
this.server.setRequestHandler(
|
|
1308
898
|
import_zod.z.object({
|
|
1309
899
|
method: import_zod.z.literal("tools/call"),
|
|
@@ -1315,7 +905,7 @@ var MCPLocal = class extends MCPBase {
|
|
|
1315
905
|
}).optional()
|
|
1316
906
|
})
|
|
1317
907
|
}),
|
|
1318
|
-
async (request) => {
|
|
908
|
+
async (request, extra) => {
|
|
1319
909
|
const { name, arguments: args } = request.params;
|
|
1320
910
|
const toolHandlers = createToolHandlers(
|
|
1321
911
|
this.parser,
|