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.
- package/build/cjs/MCPLocal.js +138 -152
- package/build/cjs/MCPLocal.js.map +4 -4
- package/build/cjs/MCPRemote.js +435 -1072
- package/build/cjs/MCPRemote.js.map +4 -4
- package/build/esm/MCPLocal.mjs +138 -152
- package/build/esm/MCPLocal.mjs.map +4 -4
- package/build/esm/MCPRemote.mjs +444 -1062
- 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 -33
- package/types/MCPRemote.d.ts +27 -33
- package/types/schemas/index.d.ts +19 -2
- package/types/tools/marketData.d.ts +4 -4
- 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 -1371
- package/build/cjs/index.js.map +0 -7
- package/build/esm/index.mjs +0 -1333
- 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/utils/messageHandler.d.ts +0 -18
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, MDEntryType as MDEntryType2, 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: {
|
|
@@ -360,15 +318,14 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
360
318
|
};
|
|
361
319
|
}
|
|
362
320
|
const chart = new QuickChart();
|
|
363
|
-
chart.setWidth(
|
|
364
|
-
chart.setHeight(
|
|
365
|
-
chart.setBackgroundColor("transparent");
|
|
321
|
+
chart.setWidth(600);
|
|
322
|
+
chart.setHeight(300);
|
|
366
323
|
const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
|
|
367
324
|
const bidData = priceHistory.map((point) => point.bid);
|
|
368
325
|
const offerData = priceHistory.map((point) => point.offer);
|
|
369
326
|
const spreadData = priceHistory.map((point) => point.spread);
|
|
370
327
|
const volumeData = priceHistory.map((point) => point.volume);
|
|
371
|
-
|
|
328
|
+
chart.setConfig({
|
|
372
329
|
type: "line",
|
|
373
330
|
data: {
|
|
374
331
|
labels,
|
|
@@ -403,37 +360,63 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
403
360
|
borderColor: "#007bff",
|
|
404
361
|
backgroundColor: "rgba(0, 123, 255, 0.1)",
|
|
405
362
|
fill: true,
|
|
406
|
-
tension: 0.4
|
|
363
|
+
tension: 0.4,
|
|
364
|
+
yAxisID: "volume"
|
|
407
365
|
}
|
|
408
366
|
]
|
|
409
367
|
},
|
|
410
368
|
options: {
|
|
411
|
-
responsive: true,
|
|
412
369
|
plugins: {
|
|
413
370
|
title: {
|
|
414
371
|
display: true,
|
|
415
|
-
text: `${symbol} Market Data
|
|
372
|
+
text: `${symbol} Market Data`,
|
|
373
|
+
font: {
|
|
374
|
+
size: 16,
|
|
375
|
+
weight: "bold"
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
legend: {
|
|
379
|
+
display: true
|
|
416
380
|
}
|
|
417
381
|
},
|
|
418
382
|
scales: {
|
|
419
383
|
y: {
|
|
420
|
-
beginAtZero: false
|
|
384
|
+
beginAtZero: false,
|
|
385
|
+
grid: {
|
|
386
|
+
color: "#e9ecef"
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
volume: {
|
|
390
|
+
position: "right",
|
|
391
|
+
beginAtZero: true,
|
|
392
|
+
grid: {
|
|
393
|
+
display: false
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
x: {
|
|
397
|
+
grid: {
|
|
398
|
+
display: false
|
|
399
|
+
}
|
|
421
400
|
}
|
|
422
401
|
}
|
|
423
402
|
}
|
|
424
|
-
};
|
|
425
|
-
chart.setConfig(config);
|
|
403
|
+
});
|
|
426
404
|
const imageBuffer = await chart.toBinary();
|
|
427
|
-
const
|
|
405
|
+
const base64Image = imageBuffer.toString("base64");
|
|
406
|
+
console.log("-------------------------------------------");
|
|
407
|
+
console.log("b64", base64Image);
|
|
408
|
+
console.log("-------------------------------------------");
|
|
428
409
|
return {
|
|
429
410
|
content: [
|
|
430
411
|
{
|
|
431
|
-
type: "
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}
|
|
412
|
+
type: "image",
|
|
413
|
+
image: {
|
|
414
|
+
source: {
|
|
415
|
+
data: base64Image
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
uri: "getStockGraph",
|
|
419
|
+
mimeType: "image/png"
|
|
437
420
|
}
|
|
438
421
|
]
|
|
439
422
|
};
|
|
@@ -802,86 +785,9 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
802
785
|
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
803
786
|
});
|
|
804
787
|
|
|
805
|
-
// src/utils/messageHandler.ts
|
|
806
|
-
import { Fields as Fields3, MDEntryType as MDEntryType2, Messages as Messages3 } from "fixparser";
|
|
807
|
-
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
808
|
-
parser.logger.log({
|
|
809
|
-
level: "info",
|
|
810
|
-
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
811
|
-
});
|
|
812
|
-
const msgType = message.messageType;
|
|
813
|
-
if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
814
|
-
const symbol = message.getField(Fields3.Symbol)?.value;
|
|
815
|
-
const entries = message.getField(Fields3.NoMDEntries)?.value;
|
|
816
|
-
let bid = 0;
|
|
817
|
-
let offer = 0;
|
|
818
|
-
let volume = 0;
|
|
819
|
-
const entryTypes = message.getFields(Fields3.MDEntryType);
|
|
820
|
-
const entryPrices = message.getFields(Fields3.MDEntryPx);
|
|
821
|
-
const entrySizes = message.getFields(Fields3.MDEntrySize);
|
|
822
|
-
if (entryTypes && entryPrices && entrySizes) {
|
|
823
|
-
for (let i = 0; i < entries; i++) {
|
|
824
|
-
const entryType = entryTypes[i]?.value;
|
|
825
|
-
const entryPrice = Number.parseFloat(entryPrices[i]?.value);
|
|
826
|
-
const entrySize = Number.parseFloat(entrySizes[i]?.value);
|
|
827
|
-
if (entryType === MDEntryType2.Bid) {
|
|
828
|
-
bid = entryPrice;
|
|
829
|
-
} else if (entryType === MDEntryType2.Offer) {
|
|
830
|
-
offer = entryPrice;
|
|
831
|
-
}
|
|
832
|
-
volume += entrySize;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
const spread = offer - bid;
|
|
836
|
-
const timestamp = Date.now();
|
|
837
|
-
const data = {
|
|
838
|
-
timestamp,
|
|
839
|
-
bid,
|
|
840
|
-
offer,
|
|
841
|
-
spread,
|
|
842
|
-
volume
|
|
843
|
-
};
|
|
844
|
-
if (!marketDataPrices.has(symbol)) {
|
|
845
|
-
marketDataPrices.set(symbol, []);
|
|
846
|
-
}
|
|
847
|
-
const prices = marketDataPrices.get(symbol);
|
|
848
|
-
prices.push(data);
|
|
849
|
-
if (prices.length > maxPriceHistory) {
|
|
850
|
-
prices.splice(0, prices.length - maxPriceHistory);
|
|
851
|
-
}
|
|
852
|
-
onPriceUpdate?.(symbol, data);
|
|
853
|
-
} else if (msgType === Messages3.ExecutionReport) {
|
|
854
|
-
const reqId = message.getField(Fields3.ClOrdID)?.value;
|
|
855
|
-
const callback = pendingRequests.get(reqId);
|
|
856
|
-
if (callback) {
|
|
857
|
-
callback(message);
|
|
858
|
-
pendingRequests.delete(reqId);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
|
|
863
788
|
// src/MCPLocal.ts
|
|
864
|
-
var MCPLocal = class
|
|
865
|
-
|
|
866
|
-
* Map to store verified orders before execution
|
|
867
|
-
* @private
|
|
868
|
-
*/
|
|
869
|
-
verifiedOrders = /* @__PURE__ */ new Map();
|
|
870
|
-
/**
|
|
871
|
-
* Map to store pending requests and their callbacks
|
|
872
|
-
* @private
|
|
873
|
-
*/
|
|
874
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
875
|
-
/**
|
|
876
|
-
* Map to store market data prices for each symbol
|
|
877
|
-
* @private
|
|
878
|
-
*/
|
|
879
|
-
marketDataPrices = /* @__PURE__ */ new Map();
|
|
880
|
-
/**
|
|
881
|
-
* Maximum number of price points to store per symbol
|
|
882
|
-
* @private
|
|
883
|
-
*/
|
|
884
|
-
MAX_PRICE_HISTORY = 1e5;
|
|
789
|
+
var MCPLocal = class {
|
|
790
|
+
parser;
|
|
885
791
|
server = new Server(
|
|
886
792
|
{
|
|
887
793
|
name: "fixparser",
|
|
@@ -903,13 +809,90 @@ var MCPLocal = class extends MCPBase {
|
|
|
903
809
|
}
|
|
904
810
|
);
|
|
905
811
|
transport = new StdioServerTransport();
|
|
812
|
+
onReady = void 0;
|
|
813
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
814
|
+
verifiedOrders = /* @__PURE__ */ new Map();
|
|
815
|
+
marketDataPrices = /* @__PURE__ */ new Map();
|
|
816
|
+
MAX_PRICE_HISTORY = 1e5;
|
|
817
|
+
// Maximum number of price points to store per symbol
|
|
906
818
|
constructor({ logger, onReady }) {
|
|
907
|
-
|
|
819
|
+
if (onReady) this.onReady = onReady;
|
|
908
820
|
}
|
|
909
821
|
async register(parser) {
|
|
910
822
|
this.parser = parser;
|
|
911
823
|
this.parser.addOnMessageCallback((message) => {
|
|
912
|
-
|
|
824
|
+
this.parser?.logger.log({
|
|
825
|
+
level: "info",
|
|
826
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
827
|
+
});
|
|
828
|
+
const msgType = message.messageType;
|
|
829
|
+
if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.ExecutionReport || msgType === Messages3.Reject || msgType === Messages3.MarketDataIncrementalRefresh) {
|
|
830
|
+
this.parser?.logger.log({
|
|
831
|
+
level: "info",
|
|
832
|
+
message: `MCP Server handling message type: ${msgType}`
|
|
833
|
+
});
|
|
834
|
+
let id;
|
|
835
|
+
if (msgType === Messages3.MarketDataIncrementalRefresh || msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
836
|
+
const symbol = message.getField(Fields3.Symbol);
|
|
837
|
+
const entryType = message.getField(Fields3.MDEntryType);
|
|
838
|
+
const price = message.getField(Fields3.MDEntryPx);
|
|
839
|
+
const size = message.getField(Fields3.MDEntrySize);
|
|
840
|
+
const timestamp = message.getField(Fields3.MDEntryTime)?.value || Date.now();
|
|
841
|
+
if (symbol?.value && price?.value) {
|
|
842
|
+
const symbolStr = String(symbol.value);
|
|
843
|
+
const priceNum = Number(price.value);
|
|
844
|
+
const sizeNum = size?.value ? Number(size.value) : 0;
|
|
845
|
+
const priceHistory = this.marketDataPrices.get(symbolStr) || [];
|
|
846
|
+
const lastEntry = priceHistory[priceHistory.length - 1] || {
|
|
847
|
+
timestamp: 0,
|
|
848
|
+
bid: 0,
|
|
849
|
+
offer: 0,
|
|
850
|
+
spread: 0,
|
|
851
|
+
volume: 0
|
|
852
|
+
};
|
|
853
|
+
const newEntry = {
|
|
854
|
+
timestamp: Number(timestamp),
|
|
855
|
+
bid: entryType?.value === MDEntryType2.Bid ? priceNum : lastEntry.bid,
|
|
856
|
+
offer: entryType?.value === MDEntryType2.Offer ? priceNum : lastEntry.offer,
|
|
857
|
+
spread: entryType?.value === MDEntryType2.Offer ? priceNum - lastEntry.bid : entryType?.value === MDEntryType2.Bid ? lastEntry.offer - priceNum : lastEntry.spread,
|
|
858
|
+
volume: entryType?.value === MDEntryType2.TradeVolume ? sizeNum : lastEntry.volume
|
|
859
|
+
};
|
|
860
|
+
priceHistory.push(newEntry);
|
|
861
|
+
if (priceHistory.length > this.MAX_PRICE_HISTORY) {
|
|
862
|
+
priceHistory.shift();
|
|
863
|
+
}
|
|
864
|
+
this.marketDataPrices.set(symbolStr, priceHistory);
|
|
865
|
+
this.parser?.logger.log({
|
|
866
|
+
level: "info",
|
|
867
|
+
message: `MCP Server added ${symbol}: ${JSON.stringify(newEntry)}`
|
|
868
|
+
});
|
|
869
|
+
this.server.notification({
|
|
870
|
+
method: "priceUpdate",
|
|
871
|
+
params: {
|
|
872
|
+
symbol: symbolStr,
|
|
873
|
+
...newEntry
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
879
|
+
const mdReqID = message.getField(Fields3.MDReqID);
|
|
880
|
+
if (mdReqID) id = String(mdReqID.value);
|
|
881
|
+
} else if (msgType === Messages3.ExecutionReport) {
|
|
882
|
+
const clOrdID = message.getField(Fields3.ClOrdID);
|
|
883
|
+
if (clOrdID) id = String(clOrdID.value);
|
|
884
|
+
} else if (msgType === Messages3.Reject) {
|
|
885
|
+
const refSeqNum = message.getField(Fields3.RefSeqNum);
|
|
886
|
+
if (refSeqNum) id = String(refSeqNum.value);
|
|
887
|
+
}
|
|
888
|
+
if (id) {
|
|
889
|
+
const callback = this.pendingRequests.get(id);
|
|
890
|
+
if (callback) {
|
|
891
|
+
callback(message);
|
|
892
|
+
this.pendingRequests.delete(id);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
913
896
|
});
|
|
914
897
|
this.addWorkflows();
|
|
915
898
|
await this.server.connect(this.transport);
|
|
@@ -924,15 +907,18 @@ var MCPLocal = class extends MCPBase {
|
|
|
924
907
|
if (!this.server) {
|
|
925
908
|
return;
|
|
926
909
|
}
|
|
927
|
-
this.server.setRequestHandler(
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
description,
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
910
|
+
this.server.setRequestHandler(
|
|
911
|
+
z.object({ method: z.literal("tools/list") }),
|
|
912
|
+
async (request, extra) => {
|
|
913
|
+
return {
|
|
914
|
+
tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
915
|
+
name,
|
|
916
|
+
description,
|
|
917
|
+
inputSchema: schema
|
|
918
|
+
}))
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
);
|
|
936
922
|
this.server.setRequestHandler(
|
|
937
923
|
z.object({
|
|
938
924
|
method: z.literal("tools/call"),
|
|
@@ -944,7 +930,7 @@ var MCPLocal = class extends MCPBase {
|
|
|
944
930
|
}).optional()
|
|
945
931
|
})
|
|
946
932
|
}),
|
|
947
|
-
async (request) => {
|
|
933
|
+
async (request, extra) => {
|
|
948
934
|
const { name, arguments: args } = request.params;
|
|
949
935
|
const toolHandlers = createToolHandlers(
|
|
950
936
|
this.parser,
|