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/esm/MCPLocal.mjs
CHANGED
|
@@ -1,51 +1,9 @@
|
|
|
1
1
|
// src/MCPLocal.ts
|
|
2
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { Fields as Fields3, Messages as Messages3 } from "fixparser";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
|
|
6
|
-
// src/MCPBase.ts
|
|
7
|
-
var MCPBase = class {
|
|
8
|
-
/**
|
|
9
|
-
* Optional logger instance for diagnostics and output.
|
|
10
|
-
* @protected
|
|
11
|
-
*/
|
|
12
|
-
logger;
|
|
13
|
-
/**
|
|
14
|
-
* FIXParser instance, set during plugin register().
|
|
15
|
-
* @protected
|
|
16
|
-
*/
|
|
17
|
-
parser;
|
|
18
|
-
/**
|
|
19
|
-
* Called when server is setup and listening.
|
|
20
|
-
* @protected
|
|
21
|
-
*/
|
|
22
|
-
onReady = void 0;
|
|
23
|
-
/**
|
|
24
|
-
* Map to store verified orders before execution
|
|
25
|
-
* @protected
|
|
26
|
-
*/
|
|
27
|
-
verifiedOrders = /* @__PURE__ */ new Map();
|
|
28
|
-
/**
|
|
29
|
-
* Map to store pending market data requests
|
|
30
|
-
* @protected
|
|
31
|
-
*/
|
|
32
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
33
|
-
/**
|
|
34
|
-
* Map to store market data prices
|
|
35
|
-
* @protected
|
|
36
|
-
*/
|
|
37
|
-
marketDataPrices = /* @__PURE__ */ new Map();
|
|
38
|
-
/**
|
|
39
|
-
* Maximum number of price history entries to keep per symbol
|
|
40
|
-
* @protected
|
|
41
|
-
*/
|
|
42
|
-
MAX_PRICE_HISTORY = 1e5;
|
|
43
|
-
constructor({ logger, onReady }) {
|
|
44
|
-
this.logger = logger;
|
|
45
|
-
this.onReady = onReady;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
7
|
// src/schemas/schemas.ts
|
|
50
8
|
var toolSchemas = {
|
|
51
9
|
parse: {
|
|
@@ -129,7 +87,7 @@ var toolSchemas = {
|
|
|
129
87
|
}
|
|
130
88
|
},
|
|
131
89
|
executeOrder: {
|
|
132
|
-
description: "Executes a verified order. verifyOrder must be called before executeOrder.",
|
|
90
|
+
description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
|
|
133
91
|
schema: {
|
|
134
92
|
type: "object",
|
|
135
93
|
properties: {
|
|
@@ -246,12 +204,12 @@ var toolSchemas = {
|
|
|
246
204
|
"X",
|
|
247
205
|
"Y",
|
|
248
206
|
"Z"
|
|
249
|
-
]
|
|
250
|
-
|
|
251
|
-
|
|
207
|
+
],
|
|
208
|
+
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"
|
|
209
|
+
}
|
|
252
210
|
}
|
|
253
211
|
},
|
|
254
|
-
required: ["mdUpdateType", "symbols", "mdReqID", "subscriptionRequestType"]
|
|
212
|
+
required: ["mdUpdateType", "symbols", "mdReqID", "subscriptionRequestType", "mdEntryTypes"]
|
|
255
213
|
}
|
|
256
214
|
},
|
|
257
215
|
getStockGraph: {
|
|
@@ -277,68 +235,14 @@ var toolSchemas = {
|
|
|
277
235
|
};
|
|
278
236
|
|
|
279
237
|
// src/tools/marketData.ts
|
|
280
|
-
import { Field, Fields,
|
|
238
|
+
import { Field, Fields, Messages } from "fixparser";
|
|
281
239
|
import QuickChart from "quickchart-js";
|
|
282
240
|
var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
283
241
|
return async (args) => {
|
|
284
242
|
try {
|
|
285
|
-
parser.logger.log({
|
|
286
|
-
level: "info",
|
|
287
|
-
message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
|
|
288
|
-
});
|
|
289
243
|
const response = new Promise((resolve) => {
|
|
290
244
|
pendingRequests.set(args.mdReqID, resolve);
|
|
291
|
-
parser.logger.log({
|
|
292
|
-
level: "info",
|
|
293
|
-
message: `Registered callback for market data request ID: ${args.mdReqID}`
|
|
294
|
-
});
|
|
295
245
|
});
|
|
296
|
-
const entryTypes = args.mdEntryTypes || [
|
|
297
|
-
MDEntryType.Bid,
|
|
298
|
-
MDEntryType.Offer,
|
|
299
|
-
MDEntryType.Trade,
|
|
300
|
-
MDEntryType.IndexValue,
|
|
301
|
-
MDEntryType.OpeningPrice,
|
|
302
|
-
MDEntryType.ClosingPrice,
|
|
303
|
-
MDEntryType.SettlementPrice,
|
|
304
|
-
MDEntryType.TradingSessionHighPrice,
|
|
305
|
-
MDEntryType.TradingSessionLowPrice,
|
|
306
|
-
MDEntryType.VWAP,
|
|
307
|
-
MDEntryType.Imbalance,
|
|
308
|
-
MDEntryType.TradeVolume,
|
|
309
|
-
MDEntryType.OpenInterest,
|
|
310
|
-
MDEntryType.CompositeUnderlyingPrice,
|
|
311
|
-
MDEntryType.SimulatedSellPrice,
|
|
312
|
-
MDEntryType.SimulatedBuyPrice,
|
|
313
|
-
MDEntryType.MarginRate,
|
|
314
|
-
MDEntryType.MidPrice,
|
|
315
|
-
MDEntryType.EmptyBook,
|
|
316
|
-
MDEntryType.SettleHighPrice,
|
|
317
|
-
MDEntryType.SettleLowPrice,
|
|
318
|
-
MDEntryType.PriorSettlePrice,
|
|
319
|
-
MDEntryType.SessionHighBid,
|
|
320
|
-
MDEntryType.SessionLowOffer,
|
|
321
|
-
MDEntryType.EarlyPrices,
|
|
322
|
-
MDEntryType.AuctionClearingPrice,
|
|
323
|
-
MDEntryType.SwapValueFactor,
|
|
324
|
-
MDEntryType.DailyValueAdjustmentForLongPositions,
|
|
325
|
-
MDEntryType.CumulativeValueAdjustmentForLongPositions,
|
|
326
|
-
MDEntryType.DailyValueAdjustmentForShortPositions,
|
|
327
|
-
MDEntryType.CumulativeValueAdjustmentForShortPositions,
|
|
328
|
-
MDEntryType.FixingPrice,
|
|
329
|
-
MDEntryType.CashRate,
|
|
330
|
-
MDEntryType.RecoveryRate,
|
|
331
|
-
MDEntryType.RecoveryRateForLong,
|
|
332
|
-
MDEntryType.RecoveryRateForShort,
|
|
333
|
-
MDEntryType.MarketBid,
|
|
334
|
-
MDEntryType.MarketOffer,
|
|
335
|
-
MDEntryType.ShortSaleMinPrice,
|
|
336
|
-
MDEntryType.PreviousClosingPrice,
|
|
337
|
-
MDEntryType.ThresholdLimitPriceBanding,
|
|
338
|
-
MDEntryType.DailyFinancingValue,
|
|
339
|
-
MDEntryType.AccruedFinancingValue,
|
|
340
|
-
MDEntryType.TWAP
|
|
341
|
-
];
|
|
342
246
|
const messageFields = [
|
|
343
247
|
new Field(Fields.MsgType, Messages.MarketDataRequest),
|
|
344
248
|
new Field(Fields.SenderCompID, parser.sender),
|
|
@@ -354,16 +258,12 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
354
258
|
args.symbols.forEach((symbol) => {
|
|
355
259
|
messageFields.push(new Field(Fields.Symbol, symbol));
|
|
356
260
|
});
|
|
357
|
-
messageFields.push(new Field(Fields.NoMDEntryTypes,
|
|
358
|
-
|
|
261
|
+
messageFields.push(new Field(Fields.NoMDEntryTypes, args.mdEntryTypes.length));
|
|
262
|
+
args.mdEntryTypes.forEach((entryType) => {
|
|
359
263
|
messageFields.push(new Field(Fields.MDEntryType, entryType));
|
|
360
264
|
});
|
|
361
265
|
const mdr = parser.createMessage(...messageFields);
|
|
362
266
|
if (!parser.connected) {
|
|
363
|
-
parser.logger.log({
|
|
364
|
-
level: "error",
|
|
365
|
-
message: "Not connected. Cannot send market data request."
|
|
366
|
-
});
|
|
367
267
|
return {
|
|
368
268
|
content: [
|
|
369
269
|
{
|
|
@@ -375,16 +275,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
375
275
|
isError: true
|
|
376
276
|
};
|
|
377
277
|
}
|
|
378
|
-
parser.logger.log({
|
|
379
|
-
level: "info",
|
|
380
|
-
message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
|
|
381
|
-
});
|
|
382
278
|
parser.send(mdr);
|
|
383
279
|
const fixData = await response;
|
|
384
|
-
parser.logger.log({
|
|
385
|
-
level: "info",
|
|
386
|
-
message: `Received market data response for request ID: ${args.mdReqID}`
|
|
387
|
-
});
|
|
388
280
|
return {
|
|
389
281
|
content: [
|
|
390
282
|
{
|
|
@@ -425,73 +317,18 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
425
317
|
};
|
|
426
318
|
}
|
|
427
319
|
const chart = new QuickChart();
|
|
428
|
-
chart.setWidth(
|
|
429
|
-
chart.setHeight(
|
|
430
|
-
chart.setBackgroundColor("transparent");
|
|
320
|
+
chart.setWidth(600);
|
|
321
|
+
chart.setHeight(300);
|
|
431
322
|
const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
const spreadData = priceHistory.map((point) => point.spread);
|
|
435
|
-
const volumeData = priceHistory.map((point) => point.volume);
|
|
436
|
-
const tradeData = priceHistory.map((point) => point.trade);
|
|
437
|
-
const vwapData = priceHistory.map((point) => point.vwap);
|
|
438
|
-
const twapData = priceHistory.map((point) => point.twap);
|
|
439
|
-
const config = {
|
|
323
|
+
const data = priceHistory.map((point) => point.price);
|
|
324
|
+
chart.setConfig({
|
|
440
325
|
type: "line",
|
|
441
326
|
data: {
|
|
442
327
|
labels,
|
|
443
328
|
datasets: [
|
|
444
329
|
{
|
|
445
|
-
label:
|
|
446
|
-
data
|
|
447
|
-
borderColor: "#28a745",
|
|
448
|
-
backgroundColor: "rgba(40, 167, 69, 0.1)",
|
|
449
|
-
fill: false,
|
|
450
|
-
tension: 0.4
|
|
451
|
-
},
|
|
452
|
-
{
|
|
453
|
-
label: "Offer",
|
|
454
|
-
data: offerData,
|
|
455
|
-
borderColor: "#dc3545",
|
|
456
|
-
backgroundColor: "rgba(220, 53, 69, 0.1)",
|
|
457
|
-
fill: false,
|
|
458
|
-
tension: 0.4
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
label: "Spread",
|
|
462
|
-
data: spreadData,
|
|
463
|
-
borderColor: "#6c757d",
|
|
464
|
-
backgroundColor: "rgba(108, 117, 125, 0.1)",
|
|
465
|
-
fill: false,
|
|
466
|
-
tension: 0.4
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
label: "Trade",
|
|
470
|
-
data: tradeData,
|
|
471
|
-
borderColor: "#ffc107",
|
|
472
|
-
backgroundColor: "rgba(255, 193, 7, 0.1)",
|
|
473
|
-
fill: false,
|
|
474
|
-
tension: 0.4
|
|
475
|
-
},
|
|
476
|
-
{
|
|
477
|
-
label: "VWAP",
|
|
478
|
-
data: vwapData,
|
|
479
|
-
borderColor: "#17a2b8",
|
|
480
|
-
backgroundColor: "rgba(23, 162, 184, 0.1)",
|
|
481
|
-
fill: false,
|
|
482
|
-
tension: 0.4
|
|
483
|
-
},
|
|
484
|
-
{
|
|
485
|
-
label: "TWAP",
|
|
486
|
-
data: twapData,
|
|
487
|
-
borderColor: "#6610f2",
|
|
488
|
-
backgroundColor: "rgba(102, 16, 242, 0.1)",
|
|
489
|
-
fill: false,
|
|
490
|
-
tension: 0.4
|
|
491
|
-
},
|
|
492
|
-
{
|
|
493
|
-
label: "Volume",
|
|
494
|
-
data: volumeData,
|
|
330
|
+
label: symbol,
|
|
331
|
+
data,
|
|
495
332
|
borderColor: "#007bff",
|
|
496
333
|
backgroundColor: "rgba(0, 123, 255, 0.1)",
|
|
497
334
|
fill: true,
|
|
@@ -500,32 +337,43 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
500
337
|
]
|
|
501
338
|
},
|
|
502
339
|
options: {
|
|
503
|
-
responsive: true,
|
|
504
340
|
plugins: {
|
|
505
341
|
title: {
|
|
506
342
|
display: true,
|
|
507
|
-
text: `${symbol}
|
|
343
|
+
text: `${symbol} Price History`,
|
|
344
|
+
font: {
|
|
345
|
+
size: 16,
|
|
346
|
+
weight: "bold"
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
legend: {
|
|
350
|
+
display: true
|
|
508
351
|
}
|
|
509
352
|
},
|
|
510
353
|
scales: {
|
|
511
354
|
y: {
|
|
512
|
-
beginAtZero: false
|
|
355
|
+
beginAtZero: false,
|
|
356
|
+
grid: {
|
|
357
|
+
color: "#e9ecef"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
x: {
|
|
361
|
+
grid: {
|
|
362
|
+
display: false
|
|
363
|
+
}
|
|
513
364
|
}
|
|
514
365
|
}
|
|
515
366
|
}
|
|
516
|
-
};
|
|
517
|
-
chart.setConfig(config);
|
|
367
|
+
});
|
|
518
368
|
const imageBuffer = await chart.toBinary();
|
|
519
|
-
const
|
|
369
|
+
const base64Image = imageBuffer.toString("base64");
|
|
520
370
|
return {
|
|
521
371
|
content: [
|
|
522
372
|
{
|
|
523
|
-
type: "
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
blob: base64
|
|
528
|
-
}
|
|
373
|
+
type: "image",
|
|
374
|
+
text: base64Image,
|
|
375
|
+
uri: "getStockGraph",
|
|
376
|
+
mimeType: "image/png"
|
|
529
377
|
}
|
|
530
378
|
]
|
|
531
379
|
};
|
|
@@ -534,7 +382,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
534
382
|
content: [
|
|
535
383
|
{
|
|
536
384
|
type: "text",
|
|
537
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
|
|
385
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate stock graph"}`,
|
|
538
386
|
uri: "getStockGraph"
|
|
539
387
|
}
|
|
540
388
|
],
|
|
@@ -567,53 +415,9 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
567
415
|
{
|
|
568
416
|
symbol,
|
|
569
417
|
count: priceHistory.length,
|
|
570
|
-
|
|
418
|
+
prices: priceHistory.map((point) => ({
|
|
571
419
|
timestamp: new Date(point.timestamp).toISOString(),
|
|
572
|
-
|
|
573
|
-
offer: point.offer,
|
|
574
|
-
spread: point.spread,
|
|
575
|
-
volume: point.volume,
|
|
576
|
-
trade: point.trade,
|
|
577
|
-
indexValue: point.indexValue,
|
|
578
|
-
openingPrice: point.openingPrice,
|
|
579
|
-
closingPrice: point.closingPrice,
|
|
580
|
-
settlementPrice: point.settlementPrice,
|
|
581
|
-
tradingSessionHighPrice: point.tradingSessionHighPrice,
|
|
582
|
-
tradingSessionLowPrice: point.tradingSessionLowPrice,
|
|
583
|
-
vwap: point.vwap,
|
|
584
|
-
imbalance: point.imbalance,
|
|
585
|
-
openInterest: point.openInterest,
|
|
586
|
-
compositeUnderlyingPrice: point.compositeUnderlyingPrice,
|
|
587
|
-
simulatedSellPrice: point.simulatedSellPrice,
|
|
588
|
-
simulatedBuyPrice: point.simulatedBuyPrice,
|
|
589
|
-
marginRate: point.marginRate,
|
|
590
|
-
midPrice: point.midPrice,
|
|
591
|
-
emptyBook: point.emptyBook,
|
|
592
|
-
settleHighPrice: point.settleHighPrice,
|
|
593
|
-
settleLowPrice: point.settleLowPrice,
|
|
594
|
-
priorSettlePrice: point.priorSettlePrice,
|
|
595
|
-
sessionHighBid: point.sessionHighBid,
|
|
596
|
-
sessionLowOffer: point.sessionLowOffer,
|
|
597
|
-
earlyPrices: point.earlyPrices,
|
|
598
|
-
auctionClearingPrice: point.auctionClearingPrice,
|
|
599
|
-
swapValueFactor: point.swapValueFactor,
|
|
600
|
-
dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
|
|
601
|
-
cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
|
|
602
|
-
dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
|
|
603
|
-
cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
|
|
604
|
-
fixingPrice: point.fixingPrice,
|
|
605
|
-
cashRate: point.cashRate,
|
|
606
|
-
recoveryRate: point.recoveryRate,
|
|
607
|
-
recoveryRateForLong: point.recoveryRateForLong,
|
|
608
|
-
recoveryRateForShort: point.recoveryRateForShort,
|
|
609
|
-
marketBid: point.marketBid,
|
|
610
|
-
marketOffer: point.marketOffer,
|
|
611
|
-
shortSaleMinPrice: point.shortSaleMinPrice,
|
|
612
|
-
previousClosingPrice: point.previousClosingPrice,
|
|
613
|
-
thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
|
|
614
|
-
dailyFinancingValue: point.dailyFinancingValue,
|
|
615
|
-
accruedFinancingValue: point.accruedFinancingValue,
|
|
616
|
-
twap: point.twap
|
|
420
|
+
price: point.price
|
|
617
421
|
}))
|
|
618
422
|
},
|
|
619
423
|
null,
|
|
@@ -628,7 +432,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
628
432
|
content: [
|
|
629
433
|
{
|
|
630
434
|
type: "text",
|
|
631
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
435
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
|
|
632
436
|
uri: "getStockPriceHistory"
|
|
633
437
|
}
|
|
634
438
|
],
|
|
@@ -736,7 +540,7 @@ Parameters verified:
|
|
|
736
540
|
- Symbol: ${args.symbol}
|
|
737
541
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
738
542
|
|
|
739
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
543
|
+
To execute this order, call the executeOrder tool with these exact same parameters.`,
|
|
740
544
|
uri: "verifyOrder"
|
|
741
545
|
}
|
|
742
546
|
]
|
|
@@ -935,290 +739,9 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
935
739
|
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
936
740
|
});
|
|
937
741
|
|
|
938
|
-
// src/utils/messageHandler.ts
|
|
939
|
-
import { Fields as Fields3, MDEntryType as MDEntryType2, Messages as Messages3 } from "fixparser";
|
|
940
|
-
function getEnumValue(enumObj, name) {
|
|
941
|
-
return enumObj[name] || name;
|
|
942
|
-
}
|
|
943
|
-
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
944
|
-
parser.logger.log({
|
|
945
|
-
level: "info",
|
|
946
|
-
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
947
|
-
});
|
|
948
|
-
const msgType = message.messageType;
|
|
949
|
-
if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.MarketDataIncrementalRefresh) {
|
|
950
|
-
const symbol = message.getField(Fields3.Symbol)?.value;
|
|
951
|
-
parser.logger.log({
|
|
952
|
-
level: "info",
|
|
953
|
-
message: `Processing market data for symbol: ${symbol}`
|
|
954
|
-
});
|
|
955
|
-
const fixJson = message.toFIXJSON();
|
|
956
|
-
const entries = fixJson.Body?.NoMDEntries || [];
|
|
957
|
-
parser.logger.log({
|
|
958
|
-
level: "info",
|
|
959
|
-
message: `Found ${entries.length} market data entries`
|
|
960
|
-
});
|
|
961
|
-
const data = {
|
|
962
|
-
timestamp: Date.now(),
|
|
963
|
-
bid: 0,
|
|
964
|
-
offer: 0,
|
|
965
|
-
spread: 0,
|
|
966
|
-
volume: 0,
|
|
967
|
-
trade: 0,
|
|
968
|
-
indexValue: 0,
|
|
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
|
-
const enumValue = getEnumValue(MDEntryType2, entryType);
|
|
1020
|
-
switch (enumValue) {
|
|
1021
|
-
case MDEntryType2.Bid:
|
|
1022
|
-
data.bid = price;
|
|
1023
|
-
break;
|
|
1024
|
-
case MDEntryType2.Offer:
|
|
1025
|
-
data.offer = price;
|
|
1026
|
-
break;
|
|
1027
|
-
case MDEntryType2.Trade:
|
|
1028
|
-
data.trade = price;
|
|
1029
|
-
break;
|
|
1030
|
-
case MDEntryType2.IndexValue:
|
|
1031
|
-
data.indexValue = price;
|
|
1032
|
-
break;
|
|
1033
|
-
case MDEntryType2.OpeningPrice:
|
|
1034
|
-
data.openingPrice = price;
|
|
1035
|
-
break;
|
|
1036
|
-
case MDEntryType2.ClosingPrice:
|
|
1037
|
-
data.closingPrice = price;
|
|
1038
|
-
break;
|
|
1039
|
-
case MDEntryType2.SettlementPrice:
|
|
1040
|
-
data.settlementPrice = price;
|
|
1041
|
-
break;
|
|
1042
|
-
case MDEntryType2.TradingSessionHighPrice:
|
|
1043
|
-
data.tradingSessionHighPrice = price;
|
|
1044
|
-
break;
|
|
1045
|
-
case MDEntryType2.TradingSessionLowPrice:
|
|
1046
|
-
data.tradingSessionLowPrice = price;
|
|
1047
|
-
break;
|
|
1048
|
-
case MDEntryType2.VWAP:
|
|
1049
|
-
data.vwap = price;
|
|
1050
|
-
break;
|
|
1051
|
-
case MDEntryType2.Imbalance:
|
|
1052
|
-
data.imbalance = size;
|
|
1053
|
-
break;
|
|
1054
|
-
case MDEntryType2.TradeVolume:
|
|
1055
|
-
data.volume = size;
|
|
1056
|
-
break;
|
|
1057
|
-
case MDEntryType2.OpenInterest:
|
|
1058
|
-
data.openInterest = size;
|
|
1059
|
-
break;
|
|
1060
|
-
case MDEntryType2.CompositeUnderlyingPrice:
|
|
1061
|
-
data.compositeUnderlyingPrice = price;
|
|
1062
|
-
break;
|
|
1063
|
-
case MDEntryType2.SimulatedSellPrice:
|
|
1064
|
-
data.simulatedSellPrice = price;
|
|
1065
|
-
break;
|
|
1066
|
-
case MDEntryType2.SimulatedBuyPrice:
|
|
1067
|
-
data.simulatedBuyPrice = price;
|
|
1068
|
-
break;
|
|
1069
|
-
case MDEntryType2.MarginRate:
|
|
1070
|
-
data.marginRate = price;
|
|
1071
|
-
break;
|
|
1072
|
-
case MDEntryType2.MidPrice:
|
|
1073
|
-
data.midPrice = price;
|
|
1074
|
-
break;
|
|
1075
|
-
case MDEntryType2.EmptyBook:
|
|
1076
|
-
data.emptyBook = 1;
|
|
1077
|
-
break;
|
|
1078
|
-
case MDEntryType2.SettleHighPrice:
|
|
1079
|
-
data.settleHighPrice = price;
|
|
1080
|
-
break;
|
|
1081
|
-
case MDEntryType2.SettleLowPrice:
|
|
1082
|
-
data.settleLowPrice = price;
|
|
1083
|
-
break;
|
|
1084
|
-
case MDEntryType2.PriorSettlePrice:
|
|
1085
|
-
data.priorSettlePrice = price;
|
|
1086
|
-
break;
|
|
1087
|
-
case MDEntryType2.SessionHighBid:
|
|
1088
|
-
data.sessionHighBid = price;
|
|
1089
|
-
break;
|
|
1090
|
-
case MDEntryType2.SessionLowOffer:
|
|
1091
|
-
data.sessionLowOffer = price;
|
|
1092
|
-
break;
|
|
1093
|
-
case MDEntryType2.EarlyPrices:
|
|
1094
|
-
data.earlyPrices = price;
|
|
1095
|
-
break;
|
|
1096
|
-
case MDEntryType2.AuctionClearingPrice:
|
|
1097
|
-
data.auctionClearingPrice = price;
|
|
1098
|
-
break;
|
|
1099
|
-
case MDEntryType2.SwapValueFactor:
|
|
1100
|
-
data.swapValueFactor = price;
|
|
1101
|
-
break;
|
|
1102
|
-
case MDEntryType2.DailyValueAdjustmentForLongPositions:
|
|
1103
|
-
data.dailyValueAdjustmentForLongPositions = price;
|
|
1104
|
-
break;
|
|
1105
|
-
case MDEntryType2.CumulativeValueAdjustmentForLongPositions:
|
|
1106
|
-
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1107
|
-
break;
|
|
1108
|
-
case MDEntryType2.DailyValueAdjustmentForShortPositions:
|
|
1109
|
-
data.dailyValueAdjustmentForShortPositions = price;
|
|
1110
|
-
break;
|
|
1111
|
-
case MDEntryType2.CumulativeValueAdjustmentForShortPositions:
|
|
1112
|
-
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1113
|
-
break;
|
|
1114
|
-
case MDEntryType2.FixingPrice:
|
|
1115
|
-
data.fixingPrice = price;
|
|
1116
|
-
break;
|
|
1117
|
-
case MDEntryType2.CashRate:
|
|
1118
|
-
data.cashRate = price;
|
|
1119
|
-
break;
|
|
1120
|
-
case MDEntryType2.RecoveryRate:
|
|
1121
|
-
data.recoveryRate = price;
|
|
1122
|
-
break;
|
|
1123
|
-
case MDEntryType2.RecoveryRateForLong:
|
|
1124
|
-
data.recoveryRateForLong = price;
|
|
1125
|
-
break;
|
|
1126
|
-
case MDEntryType2.RecoveryRateForShort:
|
|
1127
|
-
data.recoveryRateForShort = price;
|
|
1128
|
-
break;
|
|
1129
|
-
case MDEntryType2.MarketBid:
|
|
1130
|
-
data.marketBid = price;
|
|
1131
|
-
break;
|
|
1132
|
-
case MDEntryType2.MarketOffer:
|
|
1133
|
-
data.marketOffer = price;
|
|
1134
|
-
break;
|
|
1135
|
-
case MDEntryType2.ShortSaleMinPrice:
|
|
1136
|
-
data.shortSaleMinPrice = price;
|
|
1137
|
-
break;
|
|
1138
|
-
case MDEntryType2.PreviousClosingPrice:
|
|
1139
|
-
data.previousClosingPrice = price;
|
|
1140
|
-
break;
|
|
1141
|
-
case MDEntryType2.ThresholdLimitPriceBanding:
|
|
1142
|
-
data.thresholdLimitPriceBanding = price;
|
|
1143
|
-
break;
|
|
1144
|
-
case MDEntryType2.DailyFinancingValue:
|
|
1145
|
-
data.dailyFinancingValue = price;
|
|
1146
|
-
break;
|
|
1147
|
-
case MDEntryType2.AccruedFinancingValue:
|
|
1148
|
-
data.accruedFinancingValue = price;
|
|
1149
|
-
break;
|
|
1150
|
-
case MDEntryType2.TWAP:
|
|
1151
|
-
data.twap = price;
|
|
1152
|
-
break;
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
data.spread = data.offer - data.bid;
|
|
1156
|
-
console.log(">>>>>>>>>>>>>>>>>>>>", data);
|
|
1157
|
-
if (!marketDataPrices.has(symbol)) {
|
|
1158
|
-
parser.logger.log({
|
|
1159
|
-
level: "info",
|
|
1160
|
-
message: `Creating new price history array for symbol: ${symbol}`
|
|
1161
|
-
});
|
|
1162
|
-
marketDataPrices.set(symbol, []);
|
|
1163
|
-
}
|
|
1164
|
-
const prices = marketDataPrices.get(symbol);
|
|
1165
|
-
prices.push(data);
|
|
1166
|
-
parser.logger.log({
|
|
1167
|
-
level: "info",
|
|
1168
|
-
message: `Updated price history for ${symbol}. Current size: ${prices.length}`
|
|
1169
|
-
});
|
|
1170
|
-
if (prices.length > maxPriceHistory) {
|
|
1171
|
-
prices.splice(0, prices.length - maxPriceHistory);
|
|
1172
|
-
parser.logger.log({
|
|
1173
|
-
level: "info",
|
|
1174
|
-
message: `Trimmed price history for ${symbol} to ${maxPriceHistory} entries`
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
onPriceUpdate?.(symbol, data);
|
|
1178
|
-
const mdReqID = message.getField(Fields3.MDReqID)?.value;
|
|
1179
|
-
if (mdReqID) {
|
|
1180
|
-
const callback = pendingRequests.get(mdReqID);
|
|
1181
|
-
if (callback) {
|
|
1182
|
-
callback(message);
|
|
1183
|
-
pendingRequests.delete(mdReqID);
|
|
1184
|
-
parser.logger.log({
|
|
1185
|
-
level: "info",
|
|
1186
|
-
message: `Resolved market data request for ID: ${mdReqID}`
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
} else if (msgType === Messages3.ExecutionReport) {
|
|
1191
|
-
const reqId = message.getField(Fields3.ClOrdID)?.value;
|
|
1192
|
-
const callback = pendingRequests.get(reqId);
|
|
1193
|
-
if (callback) {
|
|
1194
|
-
callback(message);
|
|
1195
|
-
pendingRequests.delete(reqId);
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
742
|
// src/MCPLocal.ts
|
|
1201
|
-
var MCPLocal = class
|
|
1202
|
-
|
|
1203
|
-
* Map to store verified orders before execution
|
|
1204
|
-
* @private
|
|
1205
|
-
*/
|
|
1206
|
-
verifiedOrders = /* @__PURE__ */ new Map();
|
|
1207
|
-
/**
|
|
1208
|
-
* Map to store pending requests and their callbacks
|
|
1209
|
-
* @private
|
|
1210
|
-
*/
|
|
1211
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
1212
|
-
/**
|
|
1213
|
-
* Map to store market data prices for each symbol
|
|
1214
|
-
* @private
|
|
1215
|
-
*/
|
|
1216
|
-
marketDataPrices = /* @__PURE__ */ new Map();
|
|
1217
|
-
/**
|
|
1218
|
-
* Maximum number of price history entries to keep per symbol
|
|
1219
|
-
* @private
|
|
1220
|
-
*/
|
|
1221
|
-
MAX_PRICE_HISTORY = 1e5;
|
|
743
|
+
var MCPLocal = class {
|
|
744
|
+
parser;
|
|
1222
745
|
server = new Server(
|
|
1223
746
|
{
|
|
1224
747
|
name: "fixparser",
|
|
@@ -1240,13 +763,77 @@ var MCPLocal = class extends MCPBase {
|
|
|
1240
763
|
}
|
|
1241
764
|
);
|
|
1242
765
|
transport = new StdioServerTransport();
|
|
766
|
+
onReady = void 0;
|
|
767
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
768
|
+
verifiedOrders = /* @__PURE__ */ new Map();
|
|
769
|
+
marketDataPrices = /* @__PURE__ */ new Map();
|
|
770
|
+
MAX_PRICE_HISTORY = 1e5;
|
|
771
|
+
// Maximum number of price points to store per symbol
|
|
1243
772
|
constructor({ logger, onReady }) {
|
|
1244
|
-
|
|
773
|
+
if (onReady) this.onReady = onReady;
|
|
1245
774
|
}
|
|
1246
775
|
async register(parser) {
|
|
1247
776
|
this.parser = parser;
|
|
1248
777
|
this.parser.addOnMessageCallback((message) => {
|
|
1249
|
-
|
|
778
|
+
this.parser?.logger.log({
|
|
779
|
+
level: "info",
|
|
780
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
781
|
+
});
|
|
782
|
+
const msgType = message.messageType;
|
|
783
|
+
if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.ExecutionReport || msgType === Messages3.Reject || msgType === Messages3.MarketDataIncrementalRefresh) {
|
|
784
|
+
this.parser?.logger.log({
|
|
785
|
+
level: "info",
|
|
786
|
+
message: `MCP Server handling message type: ${msgType}`
|
|
787
|
+
});
|
|
788
|
+
let id;
|
|
789
|
+
if (msgType === Messages3.MarketDataIncrementalRefresh || msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
790
|
+
const symbol = message.getField(Fields3.Symbol);
|
|
791
|
+
const price = message.getField(Fields3.MDEntryPx);
|
|
792
|
+
const timestamp = message.getField(Fields3.MDEntryTime)?.value || Date.now();
|
|
793
|
+
if (symbol?.value && price?.value) {
|
|
794
|
+
const symbolStr = String(symbol.value);
|
|
795
|
+
const priceNum = Number(price.value);
|
|
796
|
+
const priceHistory = this.marketDataPrices.get(symbolStr) || [];
|
|
797
|
+
priceHistory.push({
|
|
798
|
+
timestamp: Number(timestamp),
|
|
799
|
+
price: priceNum
|
|
800
|
+
});
|
|
801
|
+
if (priceHistory.length > this.MAX_PRICE_HISTORY) {
|
|
802
|
+
priceHistory.shift();
|
|
803
|
+
}
|
|
804
|
+
this.marketDataPrices.set(symbolStr, priceHistory);
|
|
805
|
+
this.parser?.logger.log({
|
|
806
|
+
level: "info",
|
|
807
|
+
message: `MCP Server added ${symbol}: ${priceNum}`
|
|
808
|
+
});
|
|
809
|
+
this.server.notification({
|
|
810
|
+
method: "priceUpdate",
|
|
811
|
+
params: {
|
|
812
|
+
symbol: symbolStr,
|
|
813
|
+
price: priceNum,
|
|
814
|
+
timestamp: Number(timestamp)
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
820
|
+
const mdReqID = message.getField(Fields3.MDReqID);
|
|
821
|
+
if (mdReqID) id = String(mdReqID.value);
|
|
822
|
+
} else if (msgType === Messages3.ExecutionReport) {
|
|
823
|
+
const clOrdID = message.getField(Fields3.ClOrdID);
|
|
824
|
+
if (clOrdID) id = String(clOrdID.value);
|
|
825
|
+
} else if (msgType === Messages3.Reject) {
|
|
826
|
+
const refSeqNum = message.getField(Fields3.RefSeqNum);
|
|
827
|
+
if (refSeqNum) id = String(refSeqNum.value);
|
|
828
|
+
}
|
|
829
|
+
if (id) {
|
|
830
|
+
const callback = this.pendingRequests.get(id);
|
|
831
|
+
if (callback) {
|
|
832
|
+
callback(message);
|
|
833
|
+
this.pendingRequests.delete(id);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
1250
837
|
});
|
|
1251
838
|
this.addWorkflows();
|
|
1252
839
|
await this.server.connect(this.transport);
|
|
@@ -1261,15 +848,18 @@ var MCPLocal = class extends MCPBase {
|
|
|
1261
848
|
if (!this.server) {
|
|
1262
849
|
return;
|
|
1263
850
|
}
|
|
1264
|
-
this.server.setRequestHandler(
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
description,
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
851
|
+
this.server.setRequestHandler(
|
|
852
|
+
z.object({ method: z.literal("tools/list") }),
|
|
853
|
+
async (request, extra) => {
|
|
854
|
+
return {
|
|
855
|
+
tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
856
|
+
name,
|
|
857
|
+
description,
|
|
858
|
+
inputSchema: schema
|
|
859
|
+
}))
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
);
|
|
1273
863
|
this.server.setRequestHandler(
|
|
1274
864
|
z.object({
|
|
1275
865
|
method: z.literal("tools/call"),
|
|
@@ -1281,7 +871,7 @@ var MCPLocal = class extends MCPBase {
|
|
|
1281
871
|
}).optional()
|
|
1282
872
|
})
|
|
1283
873
|
}),
|
|
1284
|
-
async (request) => {
|
|
874
|
+
async (request, extra) => {
|
|
1285
875
|
const { name, arguments: args } = request.params;
|
|
1286
876
|
const toolHandlers = createToolHandlers(
|
|
1287
877
|
this.parser,
|