fixparser-plugin-mcp 9.1.7-be52c470 → 9.1.7-bfafe1e3

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.
@@ -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: {
@@ -394,15 +352,14 @@ var createGetStockGraphHandler = (marketDataPrices) => {
394
352
  };
395
353
  }
396
354
  const chart = new import_quickchart_js.default();
397
- chart.setWidth(1200);
398
- chart.setHeight(600);
399
- chart.setBackgroundColor("transparent");
355
+ chart.setWidth(600);
356
+ chart.setHeight(300);
400
357
  const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
401
358
  const bidData = priceHistory.map((point) => point.bid);
402
359
  const offerData = priceHistory.map((point) => point.offer);
403
360
  const spreadData = priceHistory.map((point) => point.spread);
404
361
  const volumeData = priceHistory.map((point) => point.volume);
405
- const config = {
362
+ chart.setConfig({
406
363
  type: "line",
407
364
  data: {
408
365
  labels,
@@ -437,37 +394,63 @@ var createGetStockGraphHandler = (marketDataPrices) => {
437
394
  borderColor: "#007bff",
438
395
  backgroundColor: "rgba(0, 123, 255, 0.1)",
439
396
  fill: true,
440
- tension: 0.4
397
+ tension: 0.4,
398
+ yAxisID: "volume"
441
399
  }
442
400
  ]
443
401
  },
444
402
  options: {
445
- responsive: true,
446
403
  plugins: {
447
404
  title: {
448
405
  display: true,
449
- text: `${symbol} Market Data`
406
+ text: `${symbol} Market Data`,
407
+ font: {
408
+ size: 16,
409
+ weight: "bold"
410
+ }
411
+ },
412
+ legend: {
413
+ display: true
450
414
  }
451
415
  },
452
416
  scales: {
453
417
  y: {
454
- beginAtZero: false
418
+ beginAtZero: false,
419
+ grid: {
420
+ color: "#e9ecef"
421
+ }
422
+ },
423
+ volume: {
424
+ position: "right",
425
+ beginAtZero: true,
426
+ grid: {
427
+ display: false
428
+ }
429
+ },
430
+ x: {
431
+ grid: {
432
+ display: false
433
+ }
455
434
  }
456
435
  }
457
436
  }
458
- };
459
- chart.setConfig(config);
437
+ });
460
438
  const imageBuffer = await chart.toBinary();
461
- const base64 = imageBuffer.toString("base64");
439
+ const base64Image = imageBuffer.toString("base64");
440
+ console.log("-------------------------------------------");
441
+ console.log("b64", base64Image);
442
+ console.log("-------------------------------------------");
462
443
  return {
463
444
  content: [
464
445
  {
465
- type: "resource",
466
- resource: {
467
- uri: "resource://graph",
468
- mimeType: "image/png",
469
- blob: base64
470
- }
446
+ type: "image",
447
+ image: {
448
+ source: {
449
+ data: base64Image
450
+ }
451
+ },
452
+ uri: "getStockGraph",
453
+ mimeType: "image/png"
471
454
  }
472
455
  ]
473
456
  };
@@ -836,86 +819,9 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
836
819
  getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
837
820
  });
838
821
 
839
- // src/utils/messageHandler.ts
840
- var import_fixparser3 = require("fixparser");
841
- function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
842
- parser.logger.log({
843
- level: "info",
844
- message: `MCP Server received message: ${message.messageType}: ${message.description}`
845
- });
846
- const msgType = message.messageType;
847
- if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
848
- const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
849
- const entries = message.getField(import_fixparser3.Fields.NoMDEntries)?.value;
850
- let bid = 0;
851
- let offer = 0;
852
- let volume = 0;
853
- const entryTypes = message.getFields(import_fixparser3.Fields.MDEntryType);
854
- const entryPrices = message.getFields(import_fixparser3.Fields.MDEntryPx);
855
- const entrySizes = message.getFields(import_fixparser3.Fields.MDEntrySize);
856
- if (entryTypes && entryPrices && entrySizes) {
857
- for (let i = 0; i < entries; i++) {
858
- const entryType = entryTypes[i]?.value;
859
- const entryPrice = Number.parseFloat(entryPrices[i]?.value);
860
- const entrySize = Number.parseFloat(entrySizes[i]?.value);
861
- if (entryType === import_fixparser3.MDEntryType.Bid) {
862
- bid = entryPrice;
863
- } else if (entryType === import_fixparser3.MDEntryType.Offer) {
864
- offer = entryPrice;
865
- }
866
- volume += entrySize;
867
- }
868
- }
869
- const spread = offer - bid;
870
- const timestamp = Date.now();
871
- const data = {
872
- timestamp,
873
- bid,
874
- offer,
875
- spread,
876
- volume
877
- };
878
- if (!marketDataPrices.has(symbol)) {
879
- marketDataPrices.set(symbol, []);
880
- }
881
- const prices = marketDataPrices.get(symbol);
882
- prices.push(data);
883
- if (prices.length > maxPriceHistory) {
884
- prices.splice(0, prices.length - maxPriceHistory);
885
- }
886
- onPriceUpdate?.(symbol, data);
887
- } else if (msgType === import_fixparser3.Messages.ExecutionReport) {
888
- const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
889
- const callback = pendingRequests.get(reqId);
890
- if (callback) {
891
- callback(message);
892
- pendingRequests.delete(reqId);
893
- }
894
- }
895
- }
896
-
897
822
  // src/MCPLocal.ts
898
- var MCPLocal = class extends MCPBase {
899
- /**
900
- * Map to store verified orders before execution
901
- * @private
902
- */
903
- verifiedOrders = /* @__PURE__ */ new Map();
904
- /**
905
- * Map to store pending requests and their callbacks
906
- * @private
907
- */
908
- pendingRequests = /* @__PURE__ */ new Map();
909
- /**
910
- * Map to store market data prices for each symbol
911
- * @private
912
- */
913
- marketDataPrices = /* @__PURE__ */ new Map();
914
- /**
915
- * Maximum number of price points to store per symbol
916
- * @private
917
- */
918
- MAX_PRICE_HISTORY = 1e5;
823
+ var MCPLocal = class {
824
+ parser;
919
825
  server = new import_server.Server(
920
826
  {
921
827
  name: "fixparser",
@@ -937,13 +843,90 @@ var MCPLocal = class extends MCPBase {
937
843
  }
938
844
  );
939
845
  transport = new import_stdio.StdioServerTransport();
846
+ onReady = void 0;
847
+ pendingRequests = /* @__PURE__ */ new Map();
848
+ verifiedOrders = /* @__PURE__ */ new Map();
849
+ marketDataPrices = /* @__PURE__ */ new Map();
850
+ MAX_PRICE_HISTORY = 1e5;
851
+ // Maximum number of price points to store per symbol
940
852
  constructor({ logger, onReady }) {
941
- super({ logger, onReady });
853
+ if (onReady) this.onReady = onReady;
942
854
  }
943
855
  async register(parser) {
944
856
  this.parser = parser;
945
857
  this.parser.addOnMessageCallback((message) => {
946
- handleMessage(message, this.parser, this.pendingRequests, this.marketDataPrices, this.MAX_PRICE_HISTORY);
858
+ this.parser?.logger.log({
859
+ level: "info",
860
+ message: `MCP Server received message: ${message.messageType}: ${message.description}`
861
+ });
862
+ const msgType = message.messageType;
863
+ if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser3.Messages.ExecutionReport || msgType === import_fixparser3.Messages.Reject || msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh) {
864
+ this.parser?.logger.log({
865
+ level: "info",
866
+ message: `MCP Server handling message type: ${msgType}`
867
+ });
868
+ let id;
869
+ if (msgType === import_fixparser3.Messages.MarketDataIncrementalRefresh || msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
870
+ const symbol = message.getField(import_fixparser3.Fields.Symbol);
871
+ const entryType = message.getField(import_fixparser3.Fields.MDEntryType);
872
+ const price = message.getField(import_fixparser3.Fields.MDEntryPx);
873
+ const size = message.getField(import_fixparser3.Fields.MDEntrySize);
874
+ const timestamp = message.getField(import_fixparser3.Fields.MDEntryTime)?.value || Date.now();
875
+ if (symbol?.value && price?.value) {
876
+ const symbolStr = String(symbol.value);
877
+ const priceNum = Number(price.value);
878
+ const sizeNum = size?.value ? Number(size.value) : 0;
879
+ const priceHistory = this.marketDataPrices.get(symbolStr) || [];
880
+ const lastEntry = priceHistory[priceHistory.length - 1] || {
881
+ timestamp: 0,
882
+ bid: 0,
883
+ offer: 0,
884
+ spread: 0,
885
+ volume: 0
886
+ };
887
+ const newEntry = {
888
+ timestamp: Number(timestamp),
889
+ bid: entryType?.value === import_fixparser3.MDEntryType.Bid ? priceNum : lastEntry.bid,
890
+ offer: entryType?.value === import_fixparser3.MDEntryType.Offer ? priceNum : lastEntry.offer,
891
+ spread: entryType?.value === import_fixparser3.MDEntryType.Offer ? priceNum - lastEntry.bid : entryType?.value === import_fixparser3.MDEntryType.Bid ? lastEntry.offer - priceNum : lastEntry.spread,
892
+ volume: entryType?.value === import_fixparser3.MDEntryType.TradeVolume ? sizeNum : lastEntry.volume
893
+ };
894
+ priceHistory.push(newEntry);
895
+ if (priceHistory.length > this.MAX_PRICE_HISTORY) {
896
+ priceHistory.shift();
897
+ }
898
+ this.marketDataPrices.set(symbolStr, priceHistory);
899
+ this.parser?.logger.log({
900
+ level: "info",
901
+ message: `MCP Server added ${symbol}: ${JSON.stringify(newEntry)}`
902
+ });
903
+ this.server.notification({
904
+ method: "priceUpdate",
905
+ params: {
906
+ symbol: symbolStr,
907
+ ...newEntry
908
+ }
909
+ });
910
+ }
911
+ }
912
+ if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
913
+ const mdReqID = message.getField(import_fixparser3.Fields.MDReqID);
914
+ if (mdReqID) id = String(mdReqID.value);
915
+ } else if (msgType === import_fixparser3.Messages.ExecutionReport) {
916
+ const clOrdID = message.getField(import_fixparser3.Fields.ClOrdID);
917
+ if (clOrdID) id = String(clOrdID.value);
918
+ } else if (msgType === import_fixparser3.Messages.Reject) {
919
+ const refSeqNum = message.getField(import_fixparser3.Fields.RefSeqNum);
920
+ if (refSeqNum) id = String(refSeqNum.value);
921
+ }
922
+ if (id) {
923
+ const callback = this.pendingRequests.get(id);
924
+ if (callback) {
925
+ callback(message);
926
+ this.pendingRequests.delete(id);
927
+ }
928
+ }
929
+ }
947
930
  });
948
931
  this.addWorkflows();
949
932
  await this.server.connect(this.transport);
@@ -958,15 +941,18 @@ var MCPLocal = class extends MCPBase {
958
941
  if (!this.server) {
959
942
  return;
960
943
  }
961
- this.server.setRequestHandler(import_zod.z.object({ method: import_zod.z.literal("tools/list") }), async () => {
962
- return {
963
- tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
964
- name,
965
- description,
966
- inputSchema: schema
967
- }))
968
- };
969
- });
944
+ this.server.setRequestHandler(
945
+ import_zod.z.object({ method: import_zod.z.literal("tools/list") }),
946
+ async (request, extra) => {
947
+ return {
948
+ tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
949
+ name,
950
+ description,
951
+ inputSchema: schema
952
+ }))
953
+ };
954
+ }
955
+ );
970
956
  this.server.setRequestHandler(
971
957
  import_zod.z.object({
972
958
  method: import_zod.z.literal("tools/call"),
@@ -978,7 +964,7 @@ var MCPLocal = class extends MCPBase {
978
964
  }).optional()
979
965
  })
980
966
  }),
981
- async (request) => {
967
+ async (request, extra) => {
982
968
  const { name, arguments: args } = request.params;
983
969
  const toolHandlers = createToolHandlers(
984
970
  this.parser,