fixparser-plugin-mcp 9.1.7-ff7241ee → 9.2.0
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/RemoteServer.js +18 -0
- package/build/cjs/RemoteServer.js.map +7 -0
- package/build/cjs/StdioServer.js +18 -0
- package/build/cjs/StdioServer.js.map +7 -0
- package/build/esm/RemoteServer.mjs +18 -0
- package/build/esm/RemoteServer.mjs.map +7 -0
- package/build/esm/StdioServer.mjs +18 -0
- package/build/esm/StdioServer.mjs.map +7 -0
- package/package.json +12 -14
- package/build/cjs/MCPLocal.js +0 -1456
- package/build/cjs/MCPLocal.js.map +0 -7
- package/build/cjs/MCPRemote.js +0 -608
- package/build/cjs/MCPRemote.js.map +0 -7
- package/build/esm/MCPLocal.mjs +0 -1431
- package/build/esm/MCPLocal.mjs.map +0 -7
- package/build/esm/MCPRemote.mjs +0 -592
- package/build/esm/MCPRemote.mjs.map +0 -7
- package/build-examples/cjs/example_mcp_local.js +0 -64
- package/build-examples/cjs/example_mcp_local.js.map +0 -7
- package/build-examples/esm/example_mcp_local.mjs +0 -64
- package/build-examples/esm/example_mcp_local.mjs.map +0 -7
- package/types/MCPLocal.d.ts +0 -16
- package/types/MCPRemote.d.ts +0 -60
- package/types/PluginOptions.d.ts +0 -6
- package/types/index.d.ts +0 -3
package/build/cjs/MCPRemote.js
DELETED
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/MCPRemote.ts
|
|
21
|
-
var MCPRemote_exports = {};
|
|
22
|
-
__export(MCPRemote_exports, {
|
|
23
|
-
MCPRemote: () => MCPRemote
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(MCPRemote_exports);
|
|
26
|
-
var import_node_crypto = require("node:crypto");
|
|
27
|
-
var import_node_http = require("node:http");
|
|
28
|
-
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
29
|
-
var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
30
|
-
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
31
|
-
var import_zod = require("zod");
|
|
32
|
-
var import_fixparser = require("fixparser");
|
|
33
|
-
var transports = {};
|
|
34
|
-
var MCPRemote = class {
|
|
35
|
-
/**
|
|
36
|
-
* Port number the server will listen on.
|
|
37
|
-
* @private
|
|
38
|
-
*/
|
|
39
|
-
port;
|
|
40
|
-
/**
|
|
41
|
-
* Optional logger instance for diagnostics and output.
|
|
42
|
-
* @private
|
|
43
|
-
*/
|
|
44
|
-
logger;
|
|
45
|
-
/**
|
|
46
|
-
* FIXParser instance, set during plugin register().
|
|
47
|
-
* @private
|
|
48
|
-
*/
|
|
49
|
-
parser;
|
|
50
|
-
/**
|
|
51
|
-
* Node.js HTTP server instance created internally.
|
|
52
|
-
* @private
|
|
53
|
-
*/
|
|
54
|
-
server;
|
|
55
|
-
/**
|
|
56
|
-
* MCP server instance handling MCP protocol logic.
|
|
57
|
-
* @private
|
|
58
|
-
*/
|
|
59
|
-
mcpServer;
|
|
60
|
-
/**
|
|
61
|
-
* Optional name of the plugin/server instance.
|
|
62
|
-
* @private
|
|
63
|
-
*/
|
|
64
|
-
name;
|
|
65
|
-
/**
|
|
66
|
-
* Optional version string of the plugin/server.
|
|
67
|
-
* @private
|
|
68
|
-
*/
|
|
69
|
-
version;
|
|
70
|
-
/**
|
|
71
|
-
* Called when server is setup and listening.
|
|
72
|
-
* @private
|
|
73
|
-
*/
|
|
74
|
-
onReady = void 0;
|
|
75
|
-
/**
|
|
76
|
-
* A map of pending market data requests, keyed by MDReqID.
|
|
77
|
-
* Each entry contains a resolver function that is called when the corresponding
|
|
78
|
-
* FIX Message is received.
|
|
79
|
-
* @private
|
|
80
|
-
* @type {Map<string, (data: Message) => void>}
|
|
81
|
-
*/
|
|
82
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
83
|
-
constructor({ port, logger, onReady }) {
|
|
84
|
-
this.port = port;
|
|
85
|
-
if (logger) this.logger = logger;
|
|
86
|
-
if (onReady) this.onReady = onReady;
|
|
87
|
-
}
|
|
88
|
-
async register(parser) {
|
|
89
|
-
this.parser = parser;
|
|
90
|
-
this.parser.addOnMessageCallback((message) => {
|
|
91
|
-
this.logger?.log({
|
|
92
|
-
level: "info",
|
|
93
|
-
message: `FIXParser (MCP): (${parser.protocol?.toUpperCase()}): << received ${message.description}`
|
|
94
|
-
});
|
|
95
|
-
const msgType = message.messageType;
|
|
96
|
-
if (msgType === import_fixparser.Messages.MarketDataSnapshotFullRefresh || msgType === import_fixparser.Messages.ExecutionReport) {
|
|
97
|
-
const idField = msgType === import_fixparser.Messages.MarketDataSnapshotFullRefresh ? message.getField(import_fixparser.Fields.MDReqID) : message.getField(import_fixparser.Fields.ClOrdID);
|
|
98
|
-
if (idField) {
|
|
99
|
-
const id = idField.value;
|
|
100
|
-
if (typeof id === "string" || typeof id === "number") {
|
|
101
|
-
const callback = this.pendingRequests.get(String(id));
|
|
102
|
-
if (callback) {
|
|
103
|
-
callback(message);
|
|
104
|
-
this.pendingRequests.delete(String(id));
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
this.logger = parser.logger;
|
|
111
|
-
this.logger?.log({
|
|
112
|
-
level: "info",
|
|
113
|
-
message: `FIXParser (MCP): -- Plugin registered. Creating MCP server on port ${this.port}...`
|
|
114
|
-
});
|
|
115
|
-
this.server = (0, import_node_http.createServer)(async (req, res) => {
|
|
116
|
-
if (!req.url || !req.method) {
|
|
117
|
-
res.writeHead(400);
|
|
118
|
-
res.end("Bad Request");
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
122
|
-
if (url.pathname === "/.well-known/oauth-authorization-server") {
|
|
123
|
-
const config = {
|
|
124
|
-
issuer: "https://accounts.google.com",
|
|
125
|
-
authorization_endpoint: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
126
|
-
token_endpoint: "https://oauth2.googleapis.com/token",
|
|
127
|
-
jwks_uri: "https://www.googleapis.com/oauth2/v3/certs",
|
|
128
|
-
response_types_supported: [
|
|
129
|
-
"code",
|
|
130
|
-
"token",
|
|
131
|
-
"id_token",
|
|
132
|
-
"code token",
|
|
133
|
-
"code id_token",
|
|
134
|
-
"token id_token",
|
|
135
|
-
"code token id_token"
|
|
136
|
-
],
|
|
137
|
-
subject_types_supported: ["public"],
|
|
138
|
-
id_token_signing_alg_values_supported: ["RS256"],
|
|
139
|
-
scopes_supported: ["openid", "email", "profile"],
|
|
140
|
-
token_endpoint_auth_methods_supported: ["client_secret_basic", "client_secret_post"]
|
|
141
|
-
};
|
|
142
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
143
|
-
res.end(JSON.stringify(config));
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if (url.pathname === "/") {
|
|
147
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
148
|
-
if (req.method === "POST") {
|
|
149
|
-
const bodyChunks = [];
|
|
150
|
-
req.on("data", (chunk) => {
|
|
151
|
-
bodyChunks.push(chunk);
|
|
152
|
-
});
|
|
153
|
-
req.on("end", async () => {
|
|
154
|
-
let parsed;
|
|
155
|
-
const body = Buffer.concat(bodyChunks).toString();
|
|
156
|
-
try {
|
|
157
|
-
parsed = JSON.parse(body);
|
|
158
|
-
} catch (err) {
|
|
159
|
-
res.writeHead(400);
|
|
160
|
-
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
let transport;
|
|
164
|
-
if (sessionId && transports[sessionId]) {
|
|
165
|
-
transport = transports[sessionId];
|
|
166
|
-
} else if (!sessionId && req.method === "POST" && (0, import_types.isInitializeRequest)(parsed)) {
|
|
167
|
-
transport = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
168
|
-
sessionIdGenerator: () => (0, import_node_crypto.randomUUID)(),
|
|
169
|
-
onsessioninitialized: (sessionId2) => {
|
|
170
|
-
transports[sessionId2] = transport;
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
transport.onclose = () => {
|
|
174
|
-
if (transport.sessionId) {
|
|
175
|
-
delete transports[transport.sessionId];
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
this.mcpServer = new import_mcp.McpServer({
|
|
179
|
-
name: this.name || "FIXParser",
|
|
180
|
-
version: this.version || "1.0.0"
|
|
181
|
-
});
|
|
182
|
-
this.addWorkflows();
|
|
183
|
-
await this.mcpServer.connect(transport);
|
|
184
|
-
} else {
|
|
185
|
-
res.writeHead(400, { "Content-Type": "application/json" });
|
|
186
|
-
res.end(
|
|
187
|
-
JSON.stringify({
|
|
188
|
-
jsonrpc: "2.0",
|
|
189
|
-
error: {
|
|
190
|
-
code: -32e3,
|
|
191
|
-
message: "Bad Request: No valid session ID provided"
|
|
192
|
-
},
|
|
193
|
-
id: null
|
|
194
|
-
})
|
|
195
|
-
);
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
await transport.handleRequest(req, res, parsed);
|
|
199
|
-
});
|
|
200
|
-
} else if (req.method === "GET" || req.method === "DELETE") {
|
|
201
|
-
if (!sessionId || !transports[sessionId]) {
|
|
202
|
-
res.writeHead(400);
|
|
203
|
-
res.end("Invalid or missing session ID");
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const transport = transports[sessionId];
|
|
207
|
-
await transport.handleRequest(req, res);
|
|
208
|
-
} else {
|
|
209
|
-
res.writeHead(405);
|
|
210
|
-
res.end("Method Not Allowed");
|
|
211
|
-
}
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
res.writeHead(404);
|
|
215
|
-
res.end("Not Found");
|
|
216
|
-
});
|
|
217
|
-
this.server.listen(this.port, () => {
|
|
218
|
-
this.logger?.log({
|
|
219
|
-
level: "info",
|
|
220
|
-
message: `FIXParser (MCP): -- Server listening on http://localhost:${this.port}...`
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
if (this.onReady) {
|
|
224
|
-
this.onReady();
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
addWorkflows() {
|
|
228
|
-
if (!this.parser) {
|
|
229
|
-
this.logger?.log({
|
|
230
|
-
level: "error",
|
|
231
|
-
message: "FIXParser (MCP): -- FIXParser instance not initialized. Ignoring setup of workflows..."
|
|
232
|
-
});
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
if (!this.mcpServer) {
|
|
236
|
-
this.logger?.log({
|
|
237
|
-
level: "error",
|
|
238
|
-
message: "FIXParser (MCP): -- MCP Server not initialized. Ignoring setup of workflows..."
|
|
239
|
-
});
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
this.mcpServer.tool(
|
|
243
|
-
"parse",
|
|
244
|
-
"Parses a FIX message and describes it in plain language",
|
|
245
|
-
{ fixString: import_zod.z.string() },
|
|
246
|
-
async ({ fixString }) => {
|
|
247
|
-
const parsedMessage = this.parser?.parse(fixString);
|
|
248
|
-
if (!parsedMessage || parsedMessage.length === 0) {
|
|
249
|
-
this.logger?.log({
|
|
250
|
-
level: "error",
|
|
251
|
-
message: "FIXParser (MCP): -- Failed to parse FIX string"
|
|
252
|
-
});
|
|
253
|
-
return {
|
|
254
|
-
isError: true,
|
|
255
|
-
content: [
|
|
256
|
-
{
|
|
257
|
-
type: "text",
|
|
258
|
-
text: "Error: Failed to parse FIX string"
|
|
259
|
-
}
|
|
260
|
-
]
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
return {
|
|
264
|
-
content: [
|
|
265
|
-
{
|
|
266
|
-
type: "text",
|
|
267
|
-
text: parsedMessage ? `${parsedMessage[0].description} - ${parsedMessage[0].messageTypeDescription}` : ""
|
|
268
|
-
}
|
|
269
|
-
]
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
);
|
|
273
|
-
this.mcpServer.prompt(
|
|
274
|
-
"parse",
|
|
275
|
-
"Parses a FIX message and describes it in plain language",
|
|
276
|
-
{ fixString: import_zod.z.string() },
|
|
277
|
-
({ fixString }) => ({
|
|
278
|
-
messages: [
|
|
279
|
-
{
|
|
280
|
-
role: "user",
|
|
281
|
-
content: {
|
|
282
|
-
type: "text",
|
|
283
|
-
text: `Please parse and explain this FIX message: ${fixString}`
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
]
|
|
287
|
-
})
|
|
288
|
-
);
|
|
289
|
-
this.mcpServer.tool(
|
|
290
|
-
"parseToJSON",
|
|
291
|
-
"Parses a FIX message into JSON",
|
|
292
|
-
{ fixString: import_zod.z.string() },
|
|
293
|
-
async ({ fixString }) => {
|
|
294
|
-
const parsedMessage = this.parser?.parse(fixString);
|
|
295
|
-
if (!parsedMessage || parsedMessage.length === 0) {
|
|
296
|
-
this.logger?.log({
|
|
297
|
-
level: "error",
|
|
298
|
-
message: "FIXParser (MCP): -- Failed to parse FIX string"
|
|
299
|
-
});
|
|
300
|
-
return {
|
|
301
|
-
isError: true,
|
|
302
|
-
content: [
|
|
303
|
-
{
|
|
304
|
-
type: "text",
|
|
305
|
-
text: "Error: Failed to parse FIX string"
|
|
306
|
-
}
|
|
307
|
-
]
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
return {
|
|
311
|
-
content: [
|
|
312
|
-
{
|
|
313
|
-
type: "text",
|
|
314
|
-
text: parsedMessage ? JSON.stringify(parsedMessage[0].toFIXJSON()) : ""
|
|
315
|
-
}
|
|
316
|
-
]
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
);
|
|
320
|
-
this.mcpServer.prompt(
|
|
321
|
-
"parseToJSON",
|
|
322
|
-
"Parses a FIX message into JSON",
|
|
323
|
-
{ fixString: import_zod.z.string() },
|
|
324
|
-
({ fixString }) => ({
|
|
325
|
-
messages: [
|
|
326
|
-
{
|
|
327
|
-
role: "user",
|
|
328
|
-
content: {
|
|
329
|
-
type: "text",
|
|
330
|
-
text: `Please parse the FIX message to JSON: ${fixString}`
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
]
|
|
334
|
-
})
|
|
335
|
-
);
|
|
336
|
-
this.mcpServer.tool(
|
|
337
|
-
"newOrderSingle",
|
|
338
|
-
"Creates and sends a New Order Single",
|
|
339
|
-
{
|
|
340
|
-
clOrdID: import_zod.z.string(),
|
|
341
|
-
handlInst: import_zod.z.enum(["1", "2", "3"]).default(import_fixparser.HandlInst.AutomatedExecutionNoIntervention).optional(),
|
|
342
|
-
quantity: import_zod.z.number(),
|
|
343
|
-
price: import_zod.z.number(),
|
|
344
|
-
ordType: import_zod.z.enum([
|
|
345
|
-
"1",
|
|
346
|
-
"2",
|
|
347
|
-
"3",
|
|
348
|
-
"4",
|
|
349
|
-
"5",
|
|
350
|
-
"6",
|
|
351
|
-
"7",
|
|
352
|
-
"8",
|
|
353
|
-
"9",
|
|
354
|
-
"A",
|
|
355
|
-
"B",
|
|
356
|
-
"C",
|
|
357
|
-
"D",
|
|
358
|
-
"E",
|
|
359
|
-
"F",
|
|
360
|
-
"G",
|
|
361
|
-
"H",
|
|
362
|
-
"I",
|
|
363
|
-
"J",
|
|
364
|
-
"K",
|
|
365
|
-
"L",
|
|
366
|
-
"M",
|
|
367
|
-
"P",
|
|
368
|
-
"Q",
|
|
369
|
-
"R",
|
|
370
|
-
"S"
|
|
371
|
-
]).default(import_fixparser.OrdType.Market).optional(),
|
|
372
|
-
side: import_zod.z.enum(["1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H"]),
|
|
373
|
-
// 1 = Buy, 2 = Sell...
|
|
374
|
-
symbol: import_zod.z.string(),
|
|
375
|
-
timeInForce: import_zod.z.enum(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C"]).default(import_fixparser.TimeInForce.Day).optional()
|
|
376
|
-
},
|
|
377
|
-
async ({ clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce }) => {
|
|
378
|
-
const response = new Promise((resolve) => {
|
|
379
|
-
this.pendingRequests.set(clOrdID, resolve);
|
|
380
|
-
});
|
|
381
|
-
const order = this.parser?.createMessage(
|
|
382
|
-
new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.NewOrderSingle),
|
|
383
|
-
new import_fixparser.Field(import_fixparser.Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),
|
|
384
|
-
new import_fixparser.Field(import_fixparser.Fields.SenderCompID, this.parser?.sender),
|
|
385
|
-
new import_fixparser.Field(import_fixparser.Fields.TargetCompID, this.parser?.target),
|
|
386
|
-
new import_fixparser.Field(import_fixparser.Fields.SendingTime, this.parser?.getTimestamp()),
|
|
387
|
-
new import_fixparser.Field(import_fixparser.Fields.ClOrdID, clOrdID),
|
|
388
|
-
new import_fixparser.Field(import_fixparser.Fields.Side, side),
|
|
389
|
-
new import_fixparser.Field(import_fixparser.Fields.Symbol, symbol),
|
|
390
|
-
new import_fixparser.Field(import_fixparser.Fields.OrderQty, quantity),
|
|
391
|
-
new import_fixparser.Field(import_fixparser.Fields.Price, price),
|
|
392
|
-
new import_fixparser.Field(import_fixparser.Fields.OrdType, ordType),
|
|
393
|
-
new import_fixparser.Field(import_fixparser.Fields.HandlInst, handlInst),
|
|
394
|
-
new import_fixparser.Field(import_fixparser.Fields.TimeInForce, timeInForce),
|
|
395
|
-
new import_fixparser.Field(import_fixparser.Fields.TransactTime, this.parser?.getTimestamp())
|
|
396
|
-
);
|
|
397
|
-
if (!this.parser?.connected) {
|
|
398
|
-
this.logger?.log({
|
|
399
|
-
level: "error",
|
|
400
|
-
message: "FIXParser (MCP): -- Not connected. Ignoring message."
|
|
401
|
-
});
|
|
402
|
-
return {
|
|
403
|
-
isError: true,
|
|
404
|
-
content: [
|
|
405
|
-
{
|
|
406
|
-
type: "text",
|
|
407
|
-
text: "Error: Not connected. Ignoring message."
|
|
408
|
-
}
|
|
409
|
-
]
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
this.parser?.send(order);
|
|
413
|
-
this.logger?.log({
|
|
414
|
-
level: "info",
|
|
415
|
-
message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${order?.description}`
|
|
416
|
-
});
|
|
417
|
-
const fixData = await response;
|
|
418
|
-
return {
|
|
419
|
-
content: [
|
|
420
|
-
{
|
|
421
|
-
type: "text",
|
|
422
|
-
text: `Execution Report for order ${clOrdID}: ${JSON.stringify(fixData.toFIXJSON())}`
|
|
423
|
-
}
|
|
424
|
-
]
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
);
|
|
428
|
-
this.mcpServer.prompt(
|
|
429
|
-
"newOrderSingle",
|
|
430
|
-
"Creates and sends a New Order Single",
|
|
431
|
-
{
|
|
432
|
-
clOrdID: import_zod.z.string(),
|
|
433
|
-
handlInst: import_zod.z.string(),
|
|
434
|
-
quantity: import_zod.z.string(),
|
|
435
|
-
price: import_zod.z.string(),
|
|
436
|
-
ordType: import_zod.z.string(),
|
|
437
|
-
side: import_zod.z.string(),
|
|
438
|
-
symbol: import_zod.z.string(),
|
|
439
|
-
timeInForce: import_zod.z.string()
|
|
440
|
-
},
|
|
441
|
-
({ clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce }) => ({
|
|
442
|
-
messages: [
|
|
443
|
-
{
|
|
444
|
-
role: "user",
|
|
445
|
-
content: {
|
|
446
|
-
type: "text",
|
|
447
|
-
text: [
|
|
448
|
-
"Create a New Order Single FIX message with the following parameters:",
|
|
449
|
-
`- ClOrdID: ${clOrdID}`,
|
|
450
|
-
`- HandlInst: ${handlInst ?? "default"}`,
|
|
451
|
-
`- Quantity: ${quantity}`,
|
|
452
|
-
`- Price: ${price}`,
|
|
453
|
-
`- OrdType: ${ordType ?? "default (Market)"}`,
|
|
454
|
-
`- Side: ${side}`,
|
|
455
|
-
`- Symbol: ${symbol}`,
|
|
456
|
-
`- TimeInForce: ${timeInForce ?? "default (Day)"}`,
|
|
457
|
-
"",
|
|
458
|
-
"Format the response as a JSON object with FIX tag numbers as keys and their corresponding values."
|
|
459
|
-
].join("\n")
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
]
|
|
463
|
-
})
|
|
464
|
-
);
|
|
465
|
-
this.mcpServer.tool(
|
|
466
|
-
"marketDataRequest",
|
|
467
|
-
"Sends a request for Market Data with the given symbol",
|
|
468
|
-
{
|
|
469
|
-
mdUpdateType: import_zod.z.enum(["0", "1"]).default("0").optional(),
|
|
470
|
-
// MDUpdateType.FullRefresh
|
|
471
|
-
symbol: import_zod.z.string(),
|
|
472
|
-
mdReqID: import_zod.z.string(),
|
|
473
|
-
subscriptionRequestType: import_zod.z.enum(["0", "1", "2"]).default(import_fixparser.SubscriptionRequestType.SnapshotAndUpdates).optional(),
|
|
474
|
-
mdEntryType: import_zod.z.enum([
|
|
475
|
-
"0",
|
|
476
|
-
"1",
|
|
477
|
-
"2",
|
|
478
|
-
"3",
|
|
479
|
-
"4",
|
|
480
|
-
"5",
|
|
481
|
-
"6",
|
|
482
|
-
"7",
|
|
483
|
-
"8",
|
|
484
|
-
"9",
|
|
485
|
-
"A",
|
|
486
|
-
"B",
|
|
487
|
-
"C",
|
|
488
|
-
"D",
|
|
489
|
-
"E",
|
|
490
|
-
"F",
|
|
491
|
-
"G",
|
|
492
|
-
"H",
|
|
493
|
-
"J",
|
|
494
|
-
"K",
|
|
495
|
-
"L",
|
|
496
|
-
"M",
|
|
497
|
-
"N",
|
|
498
|
-
"O",
|
|
499
|
-
"P",
|
|
500
|
-
"Q",
|
|
501
|
-
"S",
|
|
502
|
-
"R",
|
|
503
|
-
"T",
|
|
504
|
-
"U",
|
|
505
|
-
"V",
|
|
506
|
-
"W",
|
|
507
|
-
"X",
|
|
508
|
-
"Y",
|
|
509
|
-
"Z",
|
|
510
|
-
"a",
|
|
511
|
-
"b",
|
|
512
|
-
"c",
|
|
513
|
-
"d",
|
|
514
|
-
"e",
|
|
515
|
-
"g",
|
|
516
|
-
"h",
|
|
517
|
-
"i",
|
|
518
|
-
"t"
|
|
519
|
-
]).default(import_fixparser.MDEntryType.Bid).optional()
|
|
520
|
-
},
|
|
521
|
-
async ({ mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType }) => {
|
|
522
|
-
const response = new Promise((resolve) => {
|
|
523
|
-
this.pendingRequests.set(mdReqID, resolve);
|
|
524
|
-
});
|
|
525
|
-
const marketDataRequest = this.parser?.createMessage(
|
|
526
|
-
new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
|
|
527
|
-
new import_fixparser.Field(import_fixparser.Fields.SenderCompID, this.parser?.sender),
|
|
528
|
-
new import_fixparser.Field(import_fixparser.Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),
|
|
529
|
-
new import_fixparser.Field(import_fixparser.Fields.TargetCompID, this.parser?.target),
|
|
530
|
-
new import_fixparser.Field(import_fixparser.Fields.SendingTime, this.parser?.getTimestamp()),
|
|
531
|
-
new import_fixparser.Field(import_fixparser.Fields.MarketDepth, 0),
|
|
532
|
-
new import_fixparser.Field(import_fixparser.Fields.MDUpdateType, mdUpdateType),
|
|
533
|
-
new import_fixparser.Field(import_fixparser.Fields.NoRelatedSym, 1),
|
|
534
|
-
new import_fixparser.Field(import_fixparser.Fields.Symbol, symbol),
|
|
535
|
-
new import_fixparser.Field(import_fixparser.Fields.MDReqID, mdReqID),
|
|
536
|
-
new import_fixparser.Field(import_fixparser.Fields.SubscriptionRequestType, subscriptionRequestType),
|
|
537
|
-
new import_fixparser.Field(import_fixparser.Fields.NoMDEntryTypes, 1),
|
|
538
|
-
new import_fixparser.Field(import_fixparser.Fields.MDEntryType, mdEntryType)
|
|
539
|
-
);
|
|
540
|
-
if (!this.parser?.connected) {
|
|
541
|
-
this.logger?.log({
|
|
542
|
-
level: "error",
|
|
543
|
-
message: "FIXParser (MCP): -- Not connected. Ignoring message."
|
|
544
|
-
});
|
|
545
|
-
return {
|
|
546
|
-
isError: true,
|
|
547
|
-
content: [
|
|
548
|
-
{
|
|
549
|
-
type: "text",
|
|
550
|
-
text: "Error: Not connected. Ignoring message."
|
|
551
|
-
}
|
|
552
|
-
]
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
this.parser?.send(marketDataRequest);
|
|
556
|
-
this.logger?.log({
|
|
557
|
-
level: "info",
|
|
558
|
-
message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${marketDataRequest?.description}`
|
|
559
|
-
});
|
|
560
|
-
const fixData = await response;
|
|
561
|
-
return {
|
|
562
|
-
content: [
|
|
563
|
-
{
|
|
564
|
-
type: "text",
|
|
565
|
-
text: `Market data for ${symbol}: ${JSON.stringify(fixData.toFIXJSON())}`
|
|
566
|
-
}
|
|
567
|
-
]
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
);
|
|
571
|
-
this.mcpServer.prompt(
|
|
572
|
-
"marketDataRequest",
|
|
573
|
-
"Sends a request for Market Data with the given symbol",
|
|
574
|
-
{
|
|
575
|
-
mdUpdateType: import_zod.z.string(),
|
|
576
|
-
symbol: import_zod.z.string(),
|
|
577
|
-
mdReqID: import_zod.z.string(),
|
|
578
|
-
subscriptionRequestType: import_zod.z.string(),
|
|
579
|
-
mdEntryType: import_zod.z.string()
|
|
580
|
-
},
|
|
581
|
-
({ mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType }) => ({
|
|
582
|
-
messages: [
|
|
583
|
-
{
|
|
584
|
-
role: "user",
|
|
585
|
-
content: {
|
|
586
|
-
type: "text",
|
|
587
|
-
text: [
|
|
588
|
-
"Create a Market Data Request FIX message with the following parameters:",
|
|
589
|
-
`- MDUpdateType: ${mdUpdateType ?? "default (0 = FullRefresh)"}`,
|
|
590
|
-
`- Symbol: ${symbol}`,
|
|
591
|
-
`- MDReqID: ${mdReqID}`,
|
|
592
|
-
`- SubscriptionRequestType: ${subscriptionRequestType ?? "default (0 = Snapshot + Updates)"}`,
|
|
593
|
-
`- MDEntryType: ${mdEntryType ?? "default (0 = Bid)"}`,
|
|
594
|
-
"",
|
|
595
|
-
"Format the response as a JSON object with FIX tag numbers as keys and their corresponding values."
|
|
596
|
-
].join("\n")
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
]
|
|
600
|
-
})
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
605
|
-
0 && (module.exports = {
|
|
606
|
-
MCPRemote
|
|
607
|
-
});
|
|
608
|
-
//# sourceMappingURL=MCPRemote.js.map
|