fixparser-plugin-mcp 9.1.6-da9cb1d7 → 9.1.7-27ef5b7b

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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/MCPRemote.ts"],
4
+ "sourcesContent": ["import { randomUUID } from 'node:crypto';\nimport { createServer } from 'node:http';\nimport type { Server } from 'node:http';\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nimport {\n Field,\n Fields,\n HandlInst,\n type IFIXParser,\n type Logger,\n MDEntryType,\n type Message,\n Messages,\n OrdType,\n SubscriptionRequestType,\n TimeInForce,\n} from 'fixparser';\nimport type { IPlugin } from 'fixparser-common';\n\nexport type PluginOptions = {\n port: number;\n logger?: Logger;\n onReady: () => void;\n};\n\nconst transports: Record<string, StreamableHTTPServerTransport> = {};\n\nexport class MCPRemote implements IPlugin<IFIXParser> {\n /**\n * Port number the server will listen on.\n * @private\n */\n private port: number;\n\n /**\n * Optional logger instance for diagnostics and output.\n * @private\n */\n private logger: Logger | undefined;\n\n /**\n * FIXParser instance, set during plugin register().\n * @private\n */\n private parser: IFIXParser | undefined;\n\n /**\n * Node.js HTTP server instance created internally.\n * @private\n */\n private server: Server | undefined;\n\n /**\n * MCP server instance handling MCP protocol logic.\n * @private\n */\n private mcpServer: McpServer | undefined;\n\n /**\n * Optional name of the plugin/server instance.\n * @private\n */\n private name: string | undefined;\n\n /**\n * Optional version string of the plugin/server.\n * @private\n */\n private version: string | undefined;\n\n /**\n * Called when server is setup and listening.\n * @private\n */\n private onReady: (() => void) | undefined = undefined;\n\n /**\n * A map of pending market data requests, keyed by MDReqID.\n * Each entry contains a resolver function that is called when the corresponding\n * FIX Message is received.\n * @private\n * @type {Map<string, (data: Message) => void>}\n */\n private pendingRequests: Map<string, (data: Message) => void> = new Map<string, (data: Message) => void>();\n\n constructor({ port, logger, onReady }: PluginOptions) {\n this.port = port;\n if (logger) this.logger = logger;\n if (onReady) this.onReady = onReady;\n }\n\n public async register(parser: IFIXParser): Promise<void> {\n this.parser = parser;\n this.parser.addOnMessageCallback((message: Message) => {\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${parser.protocol?.toUpperCase()}): << received ${message.description}`,\n });\n const msgType = message.messageType;\n if (msgType === Messages.MarketDataSnapshotFullRefresh || msgType === Messages.ExecutionReport) {\n const idField =\n msgType === Messages.MarketDataSnapshotFullRefresh\n ? message.getField(Fields.MDReqID)\n : message.getField(Fields.ClOrdID);\n if (idField) {\n const id = idField.value;\n if (typeof id === 'string' || typeof id === 'number') {\n const callback = this.pendingRequests.get(String(id));\n if (callback) {\n callback(message);\n this.pendingRequests.delete(String(id));\n }\n }\n }\n }\n });\n\n this.logger = parser.logger;\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): -- Plugin registered. Creating MCP server on port ${this.port}...`,\n });\n\n // In-memory client store for /register endpoint\n // const clients: Record<string, { client_id: string; client_secret: string }> = {};\n\n this.server = createServer(async (req, res) => {\n if (!req.url || !req.method) {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n\n const url = new URL(req.url, `http://${req.headers.host}`);\n\n // === OIDC + OAuth endpoints ===\n if (url.pathname === '/.well-known/oauth-authorization-server') {\n const config = {\n issuer: 'https://accounts.google.com',\n authorization_endpoint: 'https://accounts.google.com/o/oauth2/v2/auth',\n token_endpoint: 'https://oauth2.googleapis.com/token',\n jwks_uri: 'https://www.googleapis.com/oauth2/v3/certs',\n response_types_supported: [\n 'code',\n 'token',\n 'id_token',\n 'code token',\n 'code id_token',\n 'token id_token',\n 'code token id_token',\n ],\n subject_types_supported: ['public'],\n id_token_signing_alg_values_supported: ['RS256'],\n scopes_supported: ['openid', 'email', 'profile'],\n token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post'],\n };\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(config));\n return;\n }\n\n // if (url.pathname === '/register' && req.method === 'POST') {\n // // Dynamic client registration (fake)\n // const bodyChunks: Buffer[] = [];\n // req.on('data', (chunk) => {\n // bodyChunks.push(chunk);\n // });\n // req.on('end', () => {\n // // Parse request body (JSON)\n // try {\n // JSON.parse(Buffer.concat(bodyChunks).toString());\n // } catch {\n // res.writeHead(400, { 'Content-Type': 'application/json' });\n // res.end(JSON.stringify({ error: 'Invalid JSON' }));\n // return;\n // }\n // const client_id = `client-${randomUUID()}`;\n // const client_secret = `secret-${randomUUID()}`;\n // clients[client_id] = { client_id, client_secret };\n //\n // const response = {\n // client_id,\n // client_secret,\n // client_id_issued_at: Math.floor(Date.now() / 1000),\n // client_secret_expires_at: 0,\n // };\n // res.writeHead(201, { 'Content-Type': 'application/json' });\n // res.end(JSON.stringify(response));\n // });\n // return;\n // }\n\n // if (url.pathname === '/authorize') {\n // // OAuth2 Authorization endpoint - redirect with fake code\n // const redirect_uri = url.searchParams.get('redirect_uri');\n // const state = url.searchParams.get('state') || '';\n // if (!redirect_uri) {\n // res.writeHead(400);\n // res.end('Missing redirect_uri');\n // return;\n // }\n // const code = `code-${randomUUID()}`;\n // const redirectUrl = `${redirect_uri}?code=${code}&state=${encodeURIComponent(state)}`;\n // res.writeHead(302, { Location: redirectUrl });\n // res.end();\n // return;\n // }\n\n // if (url.pathname === '/token' && req.method === 'POST') {\n // // OAuth2 Token endpoint - exchange code for fake token\n // const bodyChunks: Buffer[] = [];\n // req.on('data', (chunk) => {\n // bodyChunks.push(chunk);\n // });\n // req.on('end', () => {\n // // Not verifying anything, just respond with a fake token\n // const tokenResponse = {\n // access_token: `access-${randomUUID()}`,\n // token_type: 'Bearer',\n // expires_in: 3600,\n // id_token: `id-${randomUUID()}`, // fake id_token for OIDC\n // };\n // res.writeHead(200, { 'Content-Type': 'application/json' });\n // res.end(JSON.stringify(tokenResponse));\n // });\n // return;\n // }\n\n // === Your existing MCP handling at path \"/\" ===\n if (url.pathname === '/') {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (req.method === 'POST') {\n const bodyChunks: Buffer[] = [];\n req.on('data', (chunk) => {\n bodyChunks.push(chunk);\n });\n req.on('end', async () => {\n let parsed: Record<string, any>;\n const body = Buffer.concat(bodyChunks).toString();\n try {\n parsed = JSON.parse(body);\n } catch (err) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: 'Invalid JSON' }));\n return;\n }\n\n let transport: StreamableHTTPServerTransport;\n\n if (sessionId && transports[sessionId]) {\n transport = transports[sessionId];\n } else if (!sessionId && req.method === 'POST' && isInitializeRequest(parsed)) {\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (sessionId) => {\n transports[sessionId] = transport;\n },\n });\n\n transport.onclose = () => {\n if (transport.sessionId) {\n delete transports[transport.sessionId];\n }\n };\n\n this.mcpServer = new McpServer({\n name: this.name || 'FIXParser',\n version: this.version || '1.0.0',\n });\n\n this.addWorkflows();\n\n await this.mcpServer.connect(transport);\n } else {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: No valid session ID provided',\n },\n id: null,\n }),\n );\n return;\n }\n\n await transport.handleRequest(req, res, parsed);\n });\n } else if (req.method === 'GET' || req.method === 'DELETE') {\n if (!sessionId || !transports[sessionId]) {\n res.writeHead(400);\n res.end('Invalid or missing session ID');\n return;\n }\n const transport = transports[sessionId];\n await transport.handleRequest(req, res);\n } else {\n res.writeHead(405);\n res.end('Method Not Allowed');\n }\n return;\n }\n\n // Unknown path\n res.writeHead(404);\n res.end('Not Found');\n });\n\n this.server.listen(this.port, () => {\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): -- Server listening on http://localhost:${this.port}...`,\n });\n });\n\n if (this.onReady) {\n this.onReady();\n }\n }\n\n private addWorkflows(): void {\n if (!this.parser) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- FIXParser instance not initialized. Ignoring setup of workflows...',\n });\n return;\n }\n\n if (!this.mcpServer) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- MCP Server not initialized. Ignoring setup of workflows...',\n });\n return;\n }\n\n // Parse FIX message\n this.mcpServer.tool(\n 'parse',\n 'Parses a FIX message and describes it in plain language',\n { fixString: z.string() },\n async ({ fixString }) => {\n const parsedMessage = this.parser?.parse(fixString);\n if (!parsedMessage || parsedMessage.length === 0) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Failed to parse FIX string',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Failed to parse FIX string',\n },\n ],\n };\n }\n return {\n content: [\n {\n type: 'text',\n text: parsedMessage\n ? `${parsedMessage[0].description} - ${parsedMessage[0].messageTypeDescription}`\n : '',\n },\n ],\n };\n },\n );\n this.mcpServer.prompt(\n 'parse',\n 'Parses a FIX message and describes it in plain language',\n { fixString: z.string() },\n ({ fixString }) => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please parse and explain this FIX message: ${fixString}`,\n },\n },\n ],\n }),\n );\n\n // Encode FIX message\n this.mcpServer.tool(\n 'parseToJSON',\n 'Parses a FIX message into JSON',\n { fixString: z.string() },\n async ({ fixString }) => {\n const parsedMessage = this.parser?.parse(fixString);\n if (!parsedMessage || parsedMessage.length === 0) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Failed to parse FIX string',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Failed to parse FIX string',\n },\n ],\n };\n }\n return {\n content: [\n {\n type: 'text',\n text: parsedMessage ? JSON.stringify(parsedMessage[0].toFIXJSON()) : '',\n },\n ],\n };\n },\n );\n this.mcpServer.prompt(\n 'parseToJSON',\n 'Parses a FIX message into JSON',\n { fixString: z.string() },\n ({ fixString }) => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please parse the FIX message to JSON: ${fixString}`,\n },\n },\n ],\n }),\n );\n\n // Execute New Order Single\n this.mcpServer.tool(\n 'newOrderSingle',\n 'Creates and sends a New Order Single',\n {\n clOrdID: z.string(),\n handlInst: z.enum(['1', '2', '3']).default(HandlInst.AutomatedExecutionNoIntervention).optional(),\n quantity: z.number(),\n price: z.number(),\n ordType: z\n .enum([\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'F',\n 'G',\n 'H',\n 'I',\n 'J',\n 'K',\n 'L',\n 'M',\n 'P',\n 'Q',\n 'R',\n 'S',\n ])\n .default(OrdType.Market)\n .optional(),\n side: z.enum(['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']), // 1 = Buy, 2 = Sell...\n symbol: z.string(),\n timeInForce: z\n .enum(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C'])\n .default(TimeInForce.Day)\n .optional(),\n },\n async ({ clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce }) => {\n const response = new Promise((resolve) => {\n this.pendingRequests.set(clOrdID, resolve);\n });\n\n const order: Message | undefined = this.parser?.createMessage(\n new Field(Fields.MsgType, Messages.NewOrderSingle),\n new Field(Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),\n new Field(Fields.SenderCompID, this.parser?.sender),\n new Field(Fields.TargetCompID, this.parser?.target),\n new Field(Fields.SendingTime, this.parser?.getTimestamp()),\n new Field(Fields.ClOrdID, clOrdID),\n new Field(Fields.Side, side),\n new Field(Fields.Symbol, symbol),\n new Field(Fields.OrderQty, quantity),\n new Field(Fields.Price, price),\n new Field(Fields.OrdType, ordType),\n new Field(Fields.HandlInst, handlInst),\n new Field(Fields.TimeInForce, timeInForce),\n new Field(Fields.TransactTime, this.parser?.getTimestamp()),\n );\n\n if (!this.parser?.connected) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Not connected. Ignoring message.',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Not connected. Ignoring message.',\n },\n ],\n };\n }\n\n this.parser?.send(order!);\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${order?.description}`,\n });\n\n const fixData = await response;\n\n return {\n content: [\n {\n type: 'text',\n text: `Execution Report for order ${clOrdID}: ${JSON.stringify((fixData as Message).toFIXJSON())}`,\n },\n ],\n };\n },\n );\n this.mcpServer.prompt(\n 'newOrderSingle',\n 'Creates and sends a New Order Single',\n {\n clOrdID: z.string(),\n handlInst: z.string(),\n quantity: z.string(),\n price: z.string(),\n ordType: z.string(),\n side: z.string(),\n symbol: z.string(),\n timeInForce: z.string(),\n },\n ({ clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce }) => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Create a New Order Single FIX message with the following parameters:',\n `- ClOrdID: ${clOrdID}`,\n `- HandlInst: ${handlInst ?? 'default'}`,\n `- Quantity: ${quantity}`,\n `- Price: ${price}`,\n `- OrdType: ${ordType ?? 'default (Market)'}`,\n `- Side: ${side}`,\n `- Symbol: ${symbol}`,\n `- TimeInForce: ${timeInForce ?? 'default (Day)'}`,\n '',\n 'Format the response as a JSON object with FIX tag numbers as keys and their corresponding values.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n\n // Market Data Request\n this.mcpServer.tool(\n 'marketDataRequest',\n 'Sends a request for Market Data with the given symbol',\n {\n mdUpdateType: z.enum(['0', '1']).default('0').optional(), // MDUpdateType.FullRefresh\n symbol: z.string(),\n mdReqID: z.string(),\n subscriptionRequestType: z\n .enum(['0', '1', '2'])\n .default(SubscriptionRequestType.SnapshotAndUpdates)\n .optional(),\n mdEntryType: z\n .enum([\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'F',\n 'G',\n 'H',\n 'J',\n 'K',\n 'L',\n 'M',\n 'N',\n 'O',\n 'P',\n 'Q',\n 'S',\n 'R',\n 'T',\n 'U',\n 'V',\n 'W',\n 'X',\n 'Y',\n 'Z',\n 'a',\n 'b',\n 'c',\n 'd',\n 'e',\n 'g',\n 'h',\n 'i',\n 't',\n ])\n .default(MDEntryType.Bid)\n .optional(),\n },\n async ({ mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType }) => {\n const response = new Promise((resolve) => {\n this.pendingRequests.set(mdReqID, resolve);\n });\n\n const marketDataRequest = this.parser?.createMessage(\n new Field(Fields.MsgType, Messages.MarketDataRequest),\n new Field(Fields.SenderCompID, this.parser?.sender),\n new Field(Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),\n new Field(Fields.TargetCompID, this.parser?.target),\n new Field(Fields.SendingTime, this.parser?.getTimestamp()),\n new Field(Fields.MarketDepth, 0),\n new Field(Fields.MDUpdateType, mdUpdateType),\n new Field(Fields.NoRelatedSym, 1),\n new Field(Fields.Symbol, symbol),\n new Field(Fields.MDReqID, mdReqID),\n new Field(Fields.SubscriptionRequestType, subscriptionRequestType),\n new Field(Fields.NoMDEntryTypes, 1),\n new Field(Fields.MDEntryType, mdEntryType),\n );\n\n if (!this.parser?.connected) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Not connected. Ignoring message.',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Not connected. Ignoring message.',\n },\n ],\n };\n }\n\n this.parser?.send(marketDataRequest!);\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${marketDataRequest?.description}`,\n });\n\n const fixData = await response;\n\n return {\n content: [\n {\n type: 'text',\n text: `Market data for ${symbol}: ${JSON.stringify((fixData as Message).toFIXJSON())}`,\n },\n ],\n };\n },\n );\n this.mcpServer.prompt(\n 'marketDataRequest',\n 'Sends a request for Market Data with the given symbol',\n {\n mdUpdateType: z.string(),\n symbol: z.string(),\n mdReqID: z.string(),\n subscriptionRequestType: z.string(),\n mdEntryType: z.string(),\n },\n ({ mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType }) => ({\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Create a Market Data Request FIX message with the following parameters:',\n `- MDUpdateType: ${mdUpdateType ?? 'default (0 = FullRefresh)'}`,\n `- Symbol: ${symbol}`,\n `- MDReqID: ${mdReqID}`,\n `- SubscriptionRequestType: ${subscriptionRequestType ?? 'default (0 = Snapshot + Updates)'}`,\n `- MDEntryType: ${mdEntryType ?? 'default (0 = Bid)'}`,\n '',\n 'Format the response as a JSON object with FIX tag numbers as keys and their corresponding values.',\n ].join('\\n'),\n },\n },\n ],\n }),\n );\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["sessionId"]
7
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ "use strict";var r=require("fixparser");var w=require("@modelcontextprotocol/sdk/server/index.js"),T=require("@modelcontextprotocol/sdk/server/stdio.js"),c=require("@modelcontextprotocol/sdk/types.js"),e=require("fixparser"),S={type:"object",properties:{fixString:{type:"string",description:"FIX message string to parse"}},required:["fixString"]},f={type:"object",properties:{fixString:{type:"string",description:"FIX message string to parse"}},required:["fixString"]},I={type:"object",properties:{clOrdID:{type:"string",description:"Client Order ID"},handlInst:{type:"string",enum:["1","2","3"],default:e.HandlInst.AutomatedExecutionNoIntervention,description:"Handling instruction"},quantity:{type:"number",description:"Order quantity"},price:{type:"number",description:"Order price"},ordType:{type:"string",enum:["1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","P","Q","R","S"],default:e.OrdType.Market,description:"Order type"},side:{type:"string",enum:["1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H"],description:"Order side (1=Buy, 2=Sell)"},symbol:{type:"string",description:"Trading symbol"},timeInForce:{type:"string",enum:["0","1","2","3","4","5","6","7","8","9","A","B","C"],default:e.TimeInForce.Day,description:"Time in force"}},required:["clOrdID","quantity","price","side","symbol"]},q={type:"object",properties:{mdUpdateType:{type:"string",enum:["0","1"],default:"0",description:"Market data update type"},symbol:{type:"string",description:"Trading symbol"},mdReqID:{type:"string",description:"Market data request ID"},subscriptionRequestType:{type:"string",enum:["0","1","2"],default:e.SubscriptionRequestType.SnapshotAndUpdates,description:"Subscription request type"},mdEntryType:{type:"string",enum:["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","O","P","Q","S","R","T","U","V","W","X","Y","Z","a","b","c","d","e","g","h","i","t"],default:e.MDEntryType.Bid,description:"Market data entry type"}},required:["symbol","mdReqID"]},F=class{logger;parser;server=new w.Server({name:"fixparser",version:"1.0.0"},{capabilities:{tools:{},prompts:{},resources:{}}});transport=new T.StdioServerTransport;onReady=void 0;pendingRequests=new Map;constructor({logger:n,onReady:a}){n&&(this.logger=n),a&&(this.onReady=a)}async register(n){this.parser=n,this.parser.addOnMessageCallback(a=>{this.logger?.log({level:"info",message:`FIXParser (MCP): (${n.protocol?.toUpperCase()}): << received ${a.description}`});let o=a.messageType;if(o===e.Messages.MarketDataSnapshotFullRefresh||o===e.Messages.ExecutionReport){let i=o===e.Messages.MarketDataSnapshotFullRefresh?a.getField(e.Fields.MDReqID):a.getField(e.Fields.ClOrdID);if(i){let t=i.value;if(typeof t=="string"||typeof t=="number"){let s=this.pendingRequests.get(String(t));s&&(s(a),this.pendingRequests.delete(String(t)))}}}}),this.logger=n.logger,this.addWorkflows(),await this.server.connect(this.transport),this.onReady&&this.onReady()}addWorkflows(){if(!this.parser){this.logger?.log({level:"error",message:"FIXParser (MCP): -- FIXParser instance not initialized. Ignoring setup of workflows..."});return}if(!this.server){this.logger?.log({level:"error",message:"FIXParser (MCP): -- MCP Server not initialized. Ignoring setup of workflows..."});return}let n=(a,o)=>{let i={};for(let[t,s]of Object.entries(o.properties||{})){let p=s,d=a?.[t];if(p.required&&d==null)throw new Error(`Required property '${t}' is missing`);d!==void 0?i[t]=d:p.default!==void 0&&(i[t]=p.default)}return i};this.server.setRequestHandler(c.ListResourcesRequestSchema,async()=>({resources:[]})),this.server.setRequestHandler(c.ListToolsRequestSchema,async()=>({tools:[{name:"parse",description:"Parses a FIX message and describes it in plain language",inputSchema:S},{name:"parseToJSON",description:"Parses a FIX message into JSON",inputSchema:f},{name:"newOrderSingle",description:"Creates and sends a New Order Single",inputSchema:I},{name:"marketDataRequest",description:"Sends a request for Market Data with the given symbol",inputSchema:q}]})),this.server.setRequestHandler(c.CallToolRequestSchema,async a=>{let{name:o,arguments:i}=a.params;switch(o){case"parse":try{let{fixString:t}=n(i,S),s=this.parser?.parse(t);return!s||s.length===0?{isError:!0,content:[{type:"text",text:"Error: Failed to parse FIX string"}]}:{content:[{type:"text",text:`Parsed FIX message: ${t} (placeholder implementation)`}]}}catch(t){return{isError:!0,content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Failed to parse FIX string"}`}]}}case"parseToJSON":try{let{fixString:t}=n(i,f),s=this.parser?.parse(t);return!s||s.length===0?{isError:!0,content:[{type:"text",text:"Error: Failed to parse FIX string"}]}:{content:[{type:"text",text:JSON.stringify({fixString:t,parsed:"placeholder"})}]}}catch(t){return{isError:!0,content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Failed to parse FIX string"}`}]}}case"newOrderSingle":try{let{clOrdID:t,handlInst:s,quantity:p,price:d,ordType:g,side:u,symbol:l,timeInForce:m}=n(i,I),y=new Promise(x=>{this.pendingRequests.set(t,x)}),h=this.parser?.createMessage(new e.Field(e.Fields.MsgType,e.Messages.NewOrderSingle),new e.Field(e.Fields.MsgSeqNum,this.parser?.getNextTargetMsgSeqNum()),new e.Field(e.Fields.SenderCompID,this.parser?.sender),new e.Field(e.Fields.TargetCompID,this.parser?.target),new e.Field(e.Fields.SendingTime,this.parser?.getTimestamp()),new e.Field(e.Fields.ClOrdID,t),new e.Field(e.Fields.Side,u),new e.Field(e.Fields.Symbol,l),new e.Field(e.Fields.OrderQty,p),new e.Field(e.Fields.Price,d),new e.Field(e.Fields.OrdType,g),new e.Field(e.Fields.HandlInst,s),new e.Field(e.Fields.TimeInForce,m),new e.Field(e.Fields.TransactTime,this.parser?.getTimestamp()));if(!this.parser?.connected)return this.logger?.log({level:"error",message:"FIXParser (MCP): -- Not connected. Ignoring message."}),{isError:!0,content:[{type:"text",text:"Error: Not connected. Ignoring message."}]};this.parser?.send(h),this.logger?.log({level:"info",message:`FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${h?.description}`});let M=await y;return{content:[{type:"text",text:`Execution Report for order ${t}: ${JSON.stringify(M.toFIXJSON())}`}]}}catch(t){return{isError:!0,content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Failed to create order"}`}]}}case"marketDataRequest":try{let{mdUpdateType:t,symbol:s,mdReqID:p,subscriptionRequestType:d,mdEntryType:g}=n(i,q),u=new Promise(y=>{this.pendingRequests.set(p,y)}),l=this.parser?.createMessage(new e.Field(e.Fields.MsgType,e.Messages.MarketDataRequest),new e.Field(e.Fields.SenderCompID,this.parser?.sender),new e.Field(e.Fields.MsgSeqNum,this.parser?.getNextTargetMsgSeqNum()),new e.Field(e.Fields.TargetCompID,this.parser?.target),new e.Field(e.Fields.SendingTime,this.parser?.getTimestamp()),new e.Field(e.Fields.MarketDepth,0),new e.Field(e.Fields.MDUpdateType,t),new e.Field(e.Fields.NoRelatedSym,1),new e.Field(e.Fields.Symbol,s),new e.Field(e.Fields.MDReqID,p),new e.Field(e.Fields.SubscriptionRequestType,d),new e.Field(e.Fields.NoMDEntryTypes,1),new e.Field(e.Fields.MDEntryType,g));if(!this.parser?.connected)return this.logger?.log({level:"error",message:"FIXParser (MCP): -- Not connected. Ignoring message."}),{isError:!0,content:[{type:"text",text:"Error: Not connected. Ignoring message."}]};this.parser?.send(l),this.logger?.log({level:"info",message:`FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${l?.description}`});let m=await u;return{content:[{type:"text",text:`Market data for ${s}: ${JSON.stringify(m.toFIXJSON())}`}]}}catch(t){return{isError:!0,content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Failed to request market data"}`}]}}default:throw new Error(`Unknown tool: ${o}`)}}),this.server.setRequestHandler(c.ListPromptsRequestSchema,async()=>({prompts:[{name:"parse",description:"Parses a FIX message and describes it in plain language",arguments:[{name:"fixString",description:"FIX message string to parse",required:!0}]},{name:"parseToJSON",description:"Parses a FIX message into JSON",arguments:[{name:"fixString",description:"FIX message string to parse",required:!0}]},{name:"newOrderSingle",description:"Creates and sends a New Order Single",arguments:[{name:"clOrdID",description:"Client Order ID",required:!0},{name:"handlInst",description:"Handling instruction",required:!1},{name:"quantity",description:"Order quantity",required:!0},{name:"price",description:"Order price",required:!0},{name:"ordType",description:"Order type",required:!1},{name:"side",description:"Order side (1=Buy, 2=Sell)",required:!0},{name:"symbol",description:"Trading symbol",required:!0},{name:"timeInForce",description:"Time in force",required:!1}]},{name:"marketDataRequest",description:"Sends a request for Market Data with the given symbol",arguments:[{name:"mdUpdateType",description:"Market data update type",required:!1},{name:"symbol",description:"Trading symbol",required:!0},{name:"mdReqID",description:"Market data request ID",required:!0},{name:"subscriptionRequestType",description:"Subscription request type",required:!1},{name:"mdEntryType",description:"Market data entry type",required:!1}]}]})),this.server.setRequestHandler(c.GetPromptRequestSchema,async a=>{let{name:o,arguments:i}=a.params;switch(o){case"parse":return{messages:[{role:"user",content:{type:"text",text:`Please parse and explain this FIX message: ${i?.fixString||""}`}}]};case"parseToJSON":return{messages:[{role:"user",content:{type:"text",text:`Please parse the FIX message to JSON: ${i?.fixString||""}`}}]};case"newOrderSingle":{let{clOrdID:t,handlInst:s,quantity:p,price:d,ordType:g,side:u,symbol:l,timeInForce:m}=i||{};return{messages:[{role:"user",content:{type:"text",text:["Create a New Order Single FIX message with the following parameters:",`- ClOrdID: ${t}`,`- HandlInst: ${s??"default"}`,`- Quantity: ${p}`,`- Price: ${d}`,`- OrdType: ${g??"default (Market)"}`,`- Side: ${u}`,`- Symbol: ${l}`,`- TimeInForce: ${m??"default (Day)"}`,"","Format the response as a JSON object with FIX tag numbers as keys and their corresponding values."].join(`
3
+ `)}}]}}case"marketDataRequest":{let{mdUpdateType:t,symbol:s,mdReqID:p,subscriptionRequestType:d,mdEntryType:g}=i||{};return{messages:[{role:"user",content:{type:"text",text:["Create a Market Data Request FIX message with the following parameters:",`- MDUpdateType: ${t??"default (0 = FullRefresh)"}`,`- Symbol: ${s}`,`- MDReqID: ${p}`,`- SubscriptionRequestType: ${d??"default (0 = Snapshot + Updates)"}`,`- MDEntryType: ${g??"default (0 = Bid)"}`,"","Format the response as a JSON object with FIX tag numbers as keys and their corresponding values."].join(`
4
+ `)}}]}}default:throw new Error(`Unknown prompt: ${o}`)}}),process.on("SIGINT",async()=>{await this.server.close(),process.exit(0)})}};var R=async()=>{await r.LicenseManager.setLicenseKey(process.env.FIXPARSER_LICENSE_KEY);let n=new r.FIXParser({plugins:[new F({port:3099,onReady:()=>{}})]}),a=()=>{let s=n.createMessage(new r.Field(r.Fields.MsgType,r.Messages.Logon),new r.Field(r.Fields.MsgSeqNum,n.getNextTargetMsgSeqNum()),new r.Field(r.Fields.SenderCompID,o),new r.Field(r.Fields.SendingTime,n.getTimestamp()),new r.Field(r.Fields.TargetCompID,i),new r.Field(r.Fields.ResetSeqNumFlag,r.ResetSeqNumFlag.Yes),new r.Field(r.Fields.EncryptMethod,r.EncryptMethod.None),new r.Field(r.Fields.HeartBtInt,10));n.send(s)},o="CLIENT2",i="EXECUTOR",t={host:"localhost",port:5001,protocol:"tcp",sender:o,target:i,fixVersion:"FIX.4.4",logging:!1,onOpen:()=>{a()},onMessage:s=>{},onClose:()=>{}};n.connect(t)};R().catch(n=>console.error("Error initializing server:",n));
5
+ //# sourceMappingURL=example_mcp_local.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../examples/example_mcp_local.ts", "../../src/MCPLocal.ts"],
4
+ "sourcesContent": ["import {\n EncryptMethod,\n FIXParser,\n Field,\n Fields,\n LicenseManager,\n type Message,\n Messages,\n type Options,\n ResetSeqNumFlag,\n} from 'fixparser';\nimport { MCPLocal } from 'fixparser-plugin-mcp';\n\nconst initializeServer = async () => {\n await LicenseManager.setLicenseKey(process.env.FIXPARSER_LICENSE_KEY);\n\n const fixParser: FIXParser = new FIXParser({\n plugins: [new MCPLocal({ port: 3099, onReady: () => {} })],\n });\n\n const sendLogon = () => {\n const logon = fixParser.createMessage(\n new Field(Fields.MsgType, Messages.Logon),\n new Field(Fields.MsgSeqNum, fixParser.getNextTargetMsgSeqNum()),\n new Field(Fields.SenderCompID, SENDER),\n new Field(Fields.SendingTime, fixParser.getTimestamp()),\n new Field(Fields.TargetCompID, TARGET),\n new Field(Fields.ResetSeqNumFlag, ResetSeqNumFlag.Yes),\n new Field(Fields.EncryptMethod, EncryptMethod.None),\n new Field(Fields.HeartBtInt, 10),\n );\n fixParser.send(logon);\n };\n\n const SENDER = 'CLIENT2';\n const TARGET = 'EXECUTOR';\n const CONNECT_PARAMS: Options = {\n host: 'localhost',\n port: 5001,\n protocol: 'tcp',\n sender: SENDER,\n target: TARGET,\n fixVersion: 'FIX.4.4',\n logging: false,\n onOpen: () => {\n sendLogon();\n },\n onMessage: (message: Message) => {},\n onClose: () => {},\n };\n\n fixParser.connect(CONNECT_PARAMS);\n};\n\ninitializeServer().catch((err) => console.error('Error initializing server:', err));\n", "import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport {\n Field,\n Fields,\n HandlInst,\n type IFIXParser,\n type Logger,\n MDEntryType,\n type Message,\n Messages,\n OrdType,\n SubscriptionRequestType,\n TimeInForce,\n} from 'fixparser';\nimport type { IPlugin } from 'fixparser-common';\nimport type { PluginOptions } from './PluginOptions';\n\n// Define JSON Schemas\nconst parseInputSchema = {\n type: 'object',\n properties: {\n fixString: {\n type: 'string',\n description: 'FIX message string to parse',\n },\n },\n required: ['fixString'],\n};\n\nconst parseToJSONInputSchema = {\n type: 'object',\n properties: {\n fixString: {\n type: 'string',\n description: 'FIX message string to parse',\n },\n },\n required: ['fixString'],\n};\n\nconst newOrderSingleInputSchema = {\n type: 'object',\n properties: {\n clOrdID: {\n type: 'string',\n description: 'Client Order ID',\n },\n handlInst: {\n type: 'string',\n enum: ['1', '2', '3'],\n default: HandlInst.AutomatedExecutionNoIntervention,\n description: 'Handling instruction',\n },\n quantity: {\n type: 'number',\n description: 'Order quantity',\n },\n price: {\n type: 'number',\n description: 'Order price',\n },\n ordType: {\n type: 'string',\n enum: [\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'F',\n 'G',\n 'H',\n 'I',\n 'J',\n 'K',\n 'L',\n 'M',\n 'P',\n 'Q',\n 'R',\n 'S',\n ],\n default: OrdType.Market,\n description: 'Order type',\n },\n side: {\n type: 'string',\n enum: ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'],\n description: 'Order side (1=Buy, 2=Sell)',\n },\n symbol: {\n type: 'string',\n description: 'Trading symbol',\n },\n timeInForce: {\n type: 'string',\n enum: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C'],\n default: TimeInForce.Day,\n description: 'Time in force',\n },\n },\n required: ['clOrdID', 'quantity', 'price', 'side', 'symbol'],\n};\n\nconst marketDataRequestInputSchema = {\n type: 'object',\n properties: {\n mdUpdateType: {\n type: 'string',\n enum: ['0', '1'],\n default: '0',\n description: 'Market data update type',\n },\n symbol: {\n type: 'string',\n description: 'Trading symbol',\n },\n mdReqID: {\n type: 'string',\n description: 'Market data request ID',\n },\n subscriptionRequestType: {\n type: 'string',\n enum: ['0', '1', '2'],\n default: SubscriptionRequestType.SnapshotAndUpdates,\n description: 'Subscription request type',\n },\n mdEntryType: {\n type: 'string',\n enum: [\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'F',\n 'G',\n 'H',\n 'J',\n 'K',\n 'L',\n 'M',\n 'N',\n 'O',\n 'P',\n 'Q',\n 'S',\n 'R',\n 'T',\n 'U',\n 'V',\n 'W',\n 'X',\n 'Y',\n 'Z',\n 'a',\n 'b',\n 'c',\n 'd',\n 'e',\n 'g',\n 'h',\n 'i',\n 't',\n ],\n default: MDEntryType.Bid,\n description: 'Market data entry type',\n },\n },\n required: ['symbol', 'mdReqID'],\n};\n\nexport class MCPLocal implements IPlugin<IFIXParser> {\n private logger: Logger | undefined;\n private parser: IFIXParser | undefined;\n private server: Server = new Server(\n {\n name: 'fixparser',\n version: '1.0.0',\n },\n {\n capabilities: {\n tools: {},\n prompts: {},\n resources: {},\n },\n },\n );\n private transport: StdioServerTransport = new StdioServerTransport();\n private onReady: (() => void) | undefined = undefined;\n\n private pendingRequests: Map<string, (data: Message) => void> = new Map();\n\n constructor({ logger, onReady }: PluginOptions) {\n if (logger) this.logger = logger;\n if (onReady) this.onReady = onReady;\n }\n\n public async register(parser: IFIXParser): Promise<void> {\n this.parser = parser;\n this.parser.addOnMessageCallback((message: Message) => {\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${parser.protocol?.toUpperCase()}): << received ${message.description}`,\n });\n const msgType = message.messageType;\n if (msgType === Messages.MarketDataSnapshotFullRefresh || msgType === Messages.ExecutionReport) {\n const idField =\n msgType === Messages.MarketDataSnapshotFullRefresh\n ? message.getField(Fields.MDReqID)\n : message.getField(Fields.ClOrdID);\n if (idField) {\n const id = idField.value;\n if (typeof id === 'string' || typeof id === 'number') {\n const callback = this.pendingRequests.get(String(id));\n if (callback) {\n callback(message);\n this.pendingRequests.delete(String(id));\n }\n }\n }\n }\n });\n\n this.logger = parser.logger;\n\n this.addWorkflows();\n\n await this.server.connect(this.transport);\n\n if (this.onReady) {\n this.onReady();\n }\n }\n\n private addWorkflows() {\n if (!this.parser) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- FIXParser instance not initialized. Ignoring setup of workflows...',\n });\n return;\n }\n\n if (!this.server) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- MCP Server not initialized. Ignoring setup of workflows...',\n });\n return;\n }\n\n // Helper function to validate and parse arguments\n const validateArgs = (args: any, schema: any): any => {\n // Basic validation - in a real implementation, you might want to use a proper JSON Schema validator\n const result: any = {};\n\n for (const [key, propSchema] of Object.entries(schema.properties || {})) {\n const prop = propSchema as any;\n const value = args?.[key];\n\n if (prop.required && (value === undefined || value === null)) {\n throw new Error(`Required property '${key}' is missing`);\n }\n\n if (value !== undefined) {\n // Apply defaults\n result[key] = value;\n } else if (prop.default !== undefined) {\n result[key] = prop.default;\n }\n }\n\n return result;\n };\n\n // Empty handler for resources\n this.server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [],\n };\n });\n\n // Handler for listing available tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'parse',\n description: 'Parses a FIX message and describes it in plain language',\n inputSchema: parseInputSchema,\n },\n {\n name: 'parseToJSON',\n description: 'Parses a FIX message into JSON',\n inputSchema: parseToJSONInputSchema,\n },\n {\n name: 'newOrderSingle',\n description: 'Creates and sends a New Order Single',\n inputSchema: newOrderSingleInputSchema,\n },\n {\n name: 'marketDataRequest',\n description: 'Sends a request for Market Data with the given symbol',\n inputSchema: marketDataRequestInputSchema,\n },\n ],\n };\n });\n\n // Handler for tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'parse': {\n try {\n const { fixString } = validateArgs(args, parseInputSchema);\n const parsedMessage = this.parser?.parse(fixString);\n if (!parsedMessage || parsedMessage.length === 0) {\n return {\n isError: true,\n content: [{ type: 'text', text: 'Error: Failed to parse FIX string' }],\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: `Parsed FIX message: ${fixString} (placeholder implementation)`,\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to parse FIX string'}`,\n },\n ],\n };\n }\n }\n\n case 'parseToJSON': {\n try {\n const { fixString } = validateArgs(args, parseToJSONInputSchema);\n const parsedMessage = this.parser?.parse(fixString);\n if (!parsedMessage || parsedMessage.length === 0) {\n return {\n isError: true,\n content: [{ type: 'text', text: 'Error: Failed to parse FIX string' }],\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ fixString, parsed: 'placeholder' }),\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to parse FIX string'}`,\n },\n ],\n };\n }\n }\n\n case 'newOrderSingle': {\n try {\n const { clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce } =\n validateArgs(args, newOrderSingleInputSchema);\n\n const response = new Promise((resolve) => {\n this.pendingRequests.set(clOrdID, resolve);\n });\n\n const order: Message | undefined = this.parser?.createMessage(\n new Field(Fields.MsgType, Messages.NewOrderSingle),\n new Field(Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),\n new Field(Fields.SenderCompID, this.parser?.sender),\n new Field(Fields.TargetCompID, this.parser?.target),\n new Field(Fields.SendingTime, this.parser?.getTimestamp()),\n new Field(Fields.ClOrdID, clOrdID),\n new Field(Fields.Side, side),\n new Field(Fields.Symbol, symbol),\n new Field(Fields.OrderQty, quantity),\n new Field(Fields.Price, price),\n new Field(Fields.OrdType, ordType),\n new Field(Fields.HandlInst, handlInst),\n new Field(Fields.TimeInForce, timeInForce),\n new Field(Fields.TransactTime, this.parser?.getTimestamp()),\n );\n\n if (!this.parser?.connected) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Not connected. Ignoring message.',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Not connected. Ignoring message.',\n },\n ],\n };\n }\n\n this.parser?.send(order!);\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${order?.description}`,\n });\n\n const fixData = await response;\n return {\n content: [\n {\n type: 'text',\n text: `Execution Report for order ${clOrdID}: ${JSON.stringify((fixData as Message).toFIXJSON())}`,\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to create order'}`,\n },\n ],\n };\n }\n }\n\n case 'marketDataRequest': {\n try {\n const { mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType } = validateArgs(\n args,\n marketDataRequestInputSchema,\n );\n\n const response = new Promise((resolve) => {\n this.pendingRequests.set(mdReqID, resolve);\n });\n\n const marketDataRequest = this.parser?.createMessage(\n new Field(Fields.MsgType, Messages.MarketDataRequest),\n new Field(Fields.SenderCompID, this.parser?.sender),\n new Field(Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),\n new Field(Fields.TargetCompID, this.parser?.target),\n new Field(Fields.SendingTime, this.parser?.getTimestamp()),\n new Field(Fields.MarketDepth, 0),\n new Field(Fields.MDUpdateType, mdUpdateType),\n new Field(Fields.NoRelatedSym, 1),\n new Field(Fields.Symbol, symbol),\n new Field(Fields.MDReqID, mdReqID),\n new Field(Fields.SubscriptionRequestType, subscriptionRequestType),\n new Field(Fields.NoMDEntryTypes, 1),\n new Field(Fields.MDEntryType, mdEntryType),\n );\n\n if (!this.parser?.connected) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Not connected. Ignoring message.',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Not connected. Ignoring message.',\n },\n ],\n };\n }\n\n this.parser?.send(marketDataRequest!);\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${marketDataRequest?.description}`,\n });\n\n const fixData = await response;\n\n return {\n content: [\n {\n type: 'text',\n text: `Market data for ${symbol}: ${JSON.stringify((fixData as Message).toFIXJSON())}`,\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to request market data'}`,\n },\n ],\n };\n }\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n });\n\n this.server.setRequestHandler(ListPromptsRequestSchema, async () => {\n return {\n prompts: [\n {\n name: 'parse',\n description: 'Parses a FIX message and describes it in plain language',\n arguments: [\n {\n name: 'fixString',\n description: 'FIX message string to parse',\n required: true,\n },\n ],\n },\n {\n name: 'parseToJSON',\n description: 'Parses a FIX message into JSON',\n arguments: [\n {\n name: 'fixString',\n description: 'FIX message string to parse',\n required: true,\n },\n ],\n },\n {\n name: 'newOrderSingle',\n description: 'Creates and sends a New Order Single',\n arguments: [\n {\n name: 'clOrdID',\n description: 'Client Order ID',\n required: true,\n },\n {\n name: 'handlInst',\n description: 'Handling instruction',\n required: false,\n },\n {\n name: 'quantity',\n description: 'Order quantity',\n required: true,\n },\n {\n name: 'price',\n description: 'Order price',\n required: true,\n },\n {\n name: 'ordType',\n description: 'Order type',\n required: false,\n },\n {\n name: 'side',\n description: 'Order side (1=Buy, 2=Sell)',\n required: true,\n },\n {\n name: 'symbol',\n description: 'Trading symbol',\n required: true,\n },\n {\n name: 'timeInForce',\n description: 'Time in force',\n required: false,\n },\n ],\n },\n {\n name: 'marketDataRequest',\n description: 'Sends a request for Market Data with the given symbol',\n arguments: [\n {\n name: 'mdUpdateType',\n description: 'Market data update type',\n required: false,\n },\n {\n name: 'symbol',\n description: 'Trading symbol',\n required: true,\n },\n {\n name: 'mdReqID',\n description: 'Market data request ID',\n required: true,\n },\n {\n name: 'subscriptionRequestType',\n description: 'Subscription request type',\n required: false,\n },\n {\n name: 'mdEntryType',\n description: 'Market data entry type',\n required: false,\n },\n ],\n },\n ],\n };\n });\n\n // Handler for getting specific prompts\n this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'parse': {\n const fixString = args?.fixString || '';\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please parse and explain this FIX message: ${fixString}`,\n },\n },\n ],\n };\n }\n\n case 'parseToJSON': {\n const fixString = args?.fixString || '';\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please parse the FIX message to JSON: ${fixString}`,\n },\n },\n ],\n };\n }\n\n case 'newOrderSingle': {\n const { clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce } = args || {};\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Create a New Order Single FIX message with the following parameters:',\n `- ClOrdID: ${clOrdID}`,\n `- HandlInst: ${handlInst ?? 'default'}`,\n `- Quantity: ${quantity}`,\n `- Price: ${price}`,\n `- OrdType: ${ordType ?? 'default (Market)'}`,\n `- Side: ${side}`,\n `- Symbol: ${symbol}`,\n `- TimeInForce: ${timeInForce ?? 'default (Day)'}`,\n '',\n 'Format the response as a JSON object with FIX tag numbers as keys and their corresponding values.',\n ].join('\\n'),\n },\n },\n ],\n };\n }\n\n case 'marketDataRequest': {\n const { mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType } = args || {};\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Create a Market Data Request FIX message with the following parameters:',\n `- MDUpdateType: ${mdUpdateType ?? 'default (0 = FullRefresh)'}`,\n `- Symbol: ${symbol}`,\n `- MDReqID: ${mdReqID}`,\n `- SubscriptionRequestType: ${subscriptionRequestType ?? 'default (0 = Snapshot + Updates)'}`,\n `- MDEntryType: ${mdEntryType ?? 'default (0 = Bid)'}`,\n '',\n 'Format the response as a JSON object with FIX tag numbers as keys and their corresponding values.',\n ].join('\\n'),\n },\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown prompt: ${name}`);\n }\n });\n\n process.on('SIGINT', async () => {\n await this.server.close();\n process.exit(0);\n });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_fixparser", "import_server", "import_stdio", "import_types", "import_fixparser", "parseInputSchema", "parseToJSONInputSchema", "newOrderSingleInputSchema", "marketDataRequestInputSchema", "MCPLocal", "logger", "onReady", "parser", "message", "msgType", "idField", "id", "callback", "validateArgs", "args", "schema", "result", "key", "propSchema", "prop", "value", "request", "name", "fixString", "parsedMessage", "error", "clOrdID", "handlInst", "quantity", "price", "ordType", "side", "symbol", "timeInForce", "response", "resolve", "order", "fixData", "mdUpdateType", "mdReqID", "subscriptionRequestType", "mdEntryType", "marketDataRequest", "initializeServer", "fixParser", "MCPLocal", "sendLogon", "logon", "SENDER", "TARGET", "CONNECT_PARAMS", "message", "err"]
7
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import{EncryptMethod as J,FIXParser as U,Field as c,Fields as g,LicenseManager as H,Messages as L,ResetSeqNumFlag as A}from"fixparser";import{Server as R}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as D}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as O,GetPromptRequestSchema as E,ListPromptsRequestSchema as b,ListResourcesRequestSchema as N,ListToolsRequestSchema as v}from"@modelcontextprotocol/sdk/types.js";import{Field as r,Fields as t,HandlInst as C,MDEntryType as P,Messages as h,OrdType as X,SubscriptionRequestType as k,TimeInForce as $}from"fixparser";var I={type:"object",properties:{fixString:{type:"string",description:"FIX message string to parse"}},required:["fixString"]},q={type:"object",properties:{fixString:{type:"string",description:"FIX message string to parse"}},required:["fixString"]},w={type:"object",properties:{clOrdID:{type:"string",description:"Client Order ID"},handlInst:{type:"string",enum:["1","2","3"],default:C.AutomatedExecutionNoIntervention,description:"Handling instruction"},quantity:{type:"number",description:"Order quantity"},price:{type:"number",description:"Order price"},ordType:{type:"string",enum:["1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","P","Q","R","S"],default:X.Market,description:"Order type"},side:{type:"string",enum:["1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H"],description:"Order side (1=Buy, 2=Sell)"},symbol:{type:"string",description:"Trading symbol"},timeInForce:{type:"string",enum:["0","1","2","3","4","5","6","7","8","9","A","B","C"],default:$.Day,description:"Time in force"}},required:["clOrdID","quantity","price","side","symbol"]},T={type:"object",properties:{mdUpdateType:{type:"string",enum:["0","1"],default:"0",description:"Market data update type"},symbol:{type:"string",description:"Trading symbol"},mdReqID:{type:"string",description:"Market data request ID"},subscriptionRequestType:{type:"string",enum:["0","1","2"],default:k.SnapshotAndUpdates,description:"Subscription request type"},mdEntryType:{type:"string",enum:["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","O","P","Q","S","R","T","U","V","W","X","Y","Z","a","b","c","d","e","g","h","i","t"],default:P.Bid,description:"Market data entry type"}},required:["symbol","mdReqID"]},F=class{logger;parser;server=new R({name:"fixparser",version:"1.0.0"},{capabilities:{tools:{},prompts:{},resources:{}}});transport=new D;onReady=void 0;pendingRequests=new Map;constructor({logger:n,onReady:a}){n&&(this.logger=n),a&&(this.onReady=a)}async register(n){this.parser=n,this.parser.addOnMessageCallback(a=>{this.logger?.log({level:"info",message:`FIXParser (MCP): (${n.protocol?.toUpperCase()}): << received ${a.description}`});let o=a.messageType;if(o===h.MarketDataSnapshotFullRefresh||o===h.ExecutionReport){let i=o===h.MarketDataSnapshotFullRefresh?a.getField(t.MDReqID):a.getField(t.ClOrdID);if(i){let e=i.value;if(typeof e=="string"||typeof e=="number"){let s=this.pendingRequests.get(String(e));s&&(s(a),this.pendingRequests.delete(String(e)))}}}}),this.logger=n.logger,this.addWorkflows(),await this.server.connect(this.transport),this.onReady&&this.onReady()}addWorkflows(){if(!this.parser){this.logger?.log({level:"error",message:"FIXParser (MCP): -- FIXParser instance not initialized. Ignoring setup of workflows..."});return}if(!this.server){this.logger?.log({level:"error",message:"FIXParser (MCP): -- MCP Server not initialized. Ignoring setup of workflows..."});return}let n=(a,o)=>{let i={};for(let[e,s]of Object.entries(o.properties||{})){let p=s,d=a?.[e];if(p.required&&d==null)throw new Error(`Required property '${e}' is missing`);d!==void 0?i[e]=d:p.default!==void 0&&(i[e]=p.default)}return i};this.server.setRequestHandler(N,async()=>({resources:[]})),this.server.setRequestHandler(v,async()=>({tools:[{name:"parse",description:"Parses a FIX message and describes it in plain language",inputSchema:I},{name:"parseToJSON",description:"Parses a FIX message into JSON",inputSchema:q},{name:"newOrderSingle",description:"Creates and sends a New Order Single",inputSchema:w},{name:"marketDataRequest",description:"Sends a request for Market Data with the given symbol",inputSchema:T}]})),this.server.setRequestHandler(O,async a=>{let{name:o,arguments:i}=a.params;switch(o){case"parse":try{let{fixString:e}=n(i,I),s=this.parser?.parse(e);return!s||s.length===0?{isError:!0,content:[{type:"text",text:"Error: Failed to parse FIX string"}]}:{content:[{type:"text",text:`Parsed FIX message: ${e} (placeholder implementation)`}]}}catch(e){return{isError:!0,content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Failed to parse FIX string"}`}]}}case"parseToJSON":try{let{fixString:e}=n(i,q),s=this.parser?.parse(e);return!s||s.length===0?{isError:!0,content:[{type:"text",text:"Error: Failed to parse FIX string"}]}:{content:[{type:"text",text:JSON.stringify({fixString:e,parsed:"placeholder"})}]}}catch(e){return{isError:!0,content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Failed to parse FIX string"}`}]}}case"newOrderSingle":try{let{clOrdID:e,handlInst:s,quantity:p,price:d,ordType:l,side:m,symbol:u,timeInForce:y}=n(i,w),S=new Promise(x=>{this.pendingRequests.set(e,x)}),f=this.parser?.createMessage(new r(t.MsgType,h.NewOrderSingle),new r(t.MsgSeqNum,this.parser?.getNextTargetMsgSeqNum()),new r(t.SenderCompID,this.parser?.sender),new r(t.TargetCompID,this.parser?.target),new r(t.SendingTime,this.parser?.getTimestamp()),new r(t.ClOrdID,e),new r(t.Side,m),new r(t.Symbol,u),new r(t.OrderQty,p),new r(t.Price,d),new r(t.OrdType,l),new r(t.HandlInst,s),new r(t.TimeInForce,y),new r(t.TransactTime,this.parser?.getTimestamp()));if(!this.parser?.connected)return this.logger?.log({level:"error",message:"FIXParser (MCP): -- Not connected. Ignoring message."}),{isError:!0,content:[{type:"text",text:"Error: Not connected. Ignoring message."}]};this.parser?.send(f),this.logger?.log({level:"info",message:`FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${f?.description}`});let M=await S;return{content:[{type:"text",text:`Execution Report for order ${e}: ${JSON.stringify(M.toFIXJSON())}`}]}}catch(e){return{isError:!0,content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Failed to create order"}`}]}}case"marketDataRequest":try{let{mdUpdateType:e,symbol:s,mdReqID:p,subscriptionRequestType:d,mdEntryType:l}=n(i,T),m=new Promise(S=>{this.pendingRequests.set(p,S)}),u=this.parser?.createMessage(new r(t.MsgType,h.MarketDataRequest),new r(t.SenderCompID,this.parser?.sender),new r(t.MsgSeqNum,this.parser?.getNextTargetMsgSeqNum()),new r(t.TargetCompID,this.parser?.target),new r(t.SendingTime,this.parser?.getTimestamp()),new r(t.MarketDepth,0),new r(t.MDUpdateType,e),new r(t.NoRelatedSym,1),new r(t.Symbol,s),new r(t.MDReqID,p),new r(t.SubscriptionRequestType,d),new r(t.NoMDEntryTypes,1),new r(t.MDEntryType,l));if(!this.parser?.connected)return this.logger?.log({level:"error",message:"FIXParser (MCP): -- Not connected. Ignoring message."}),{isError:!0,content:[{type:"text",text:"Error: Not connected. Ignoring message."}]};this.parser?.send(u),this.logger?.log({level:"info",message:`FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${u?.description}`});let y=await m;return{content:[{type:"text",text:`Market data for ${s}: ${JSON.stringify(y.toFIXJSON())}`}]}}catch(e){return{isError:!0,content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Failed to request market data"}`}]}}default:throw new Error(`Unknown tool: ${o}`)}}),this.server.setRequestHandler(b,async()=>({prompts:[{name:"parse",description:"Parses a FIX message and describes it in plain language",arguments:[{name:"fixString",description:"FIX message string to parse",required:!0}]},{name:"parseToJSON",description:"Parses a FIX message into JSON",arguments:[{name:"fixString",description:"FIX message string to parse",required:!0}]},{name:"newOrderSingle",description:"Creates and sends a New Order Single",arguments:[{name:"clOrdID",description:"Client Order ID",required:!0},{name:"handlInst",description:"Handling instruction",required:!1},{name:"quantity",description:"Order quantity",required:!0},{name:"price",description:"Order price",required:!0},{name:"ordType",description:"Order type",required:!1},{name:"side",description:"Order side (1=Buy, 2=Sell)",required:!0},{name:"symbol",description:"Trading symbol",required:!0},{name:"timeInForce",description:"Time in force",required:!1}]},{name:"marketDataRequest",description:"Sends a request for Market Data with the given symbol",arguments:[{name:"mdUpdateType",description:"Market data update type",required:!1},{name:"symbol",description:"Trading symbol",required:!0},{name:"mdReqID",description:"Market data request ID",required:!0},{name:"subscriptionRequestType",description:"Subscription request type",required:!1},{name:"mdEntryType",description:"Market data entry type",required:!1}]}]})),this.server.setRequestHandler(E,async a=>{let{name:o,arguments:i}=a.params;switch(o){case"parse":return{messages:[{role:"user",content:{type:"text",text:`Please parse and explain this FIX message: ${i?.fixString||""}`}}]};case"parseToJSON":return{messages:[{role:"user",content:{type:"text",text:`Please parse the FIX message to JSON: ${i?.fixString||""}`}}]};case"newOrderSingle":{let{clOrdID:e,handlInst:s,quantity:p,price:d,ordType:l,side:m,symbol:u,timeInForce:y}=i||{};return{messages:[{role:"user",content:{type:"text",text:["Create a New Order Single FIX message with the following parameters:",`- ClOrdID: ${e}`,`- HandlInst: ${s??"default"}`,`- Quantity: ${p}`,`- Price: ${d}`,`- OrdType: ${l??"default (Market)"}`,`- Side: ${m}`,`- Symbol: ${u}`,`- TimeInForce: ${y??"default (Day)"}`,"","Format the response as a JSON object with FIX tag numbers as keys and their corresponding values."].join(`
3
+ `)}}]}}case"marketDataRequest":{let{mdUpdateType:e,symbol:s,mdReqID:p,subscriptionRequestType:d,mdEntryType:l}=i||{};return{messages:[{role:"user",content:{type:"text",text:["Create a Market Data Request FIX message with the following parameters:",`- MDUpdateType: ${e??"default (0 = FullRefresh)"}`,`- Symbol: ${s}`,`- MDReqID: ${p}`,`- SubscriptionRequestType: ${d??"default (0 = Snapshot + Updates)"}`,`- MDEntryType: ${l??"default (0 = Bid)"}`,"","Format the response as a JSON object with FIX tag numbers as keys and their corresponding values."].join(`
4
+ `)}}]}}default:throw new Error(`Unknown prompt: ${o}`)}}),process.on("SIGINT",async()=>{await this.server.close(),process.exit(0)})}};var j=async()=>{await H.setLicenseKey(process.env.FIXPARSER_LICENSE_KEY);let n=new U({plugins:[new F({port:3099,onReady:()=>{}})]}),a=()=>{let s=n.createMessage(new c(g.MsgType,L.Logon),new c(g.MsgSeqNum,n.getNextTargetMsgSeqNum()),new c(g.SenderCompID,o),new c(g.SendingTime,n.getTimestamp()),new c(g.TargetCompID,i),new c(g.ResetSeqNumFlag,A.Yes),new c(g.EncryptMethod,J.None),new c(g.HeartBtInt,10));n.send(s)},o="CLIENT2",i="EXECUTOR",e={host:"localhost",port:5001,protocol:"tcp",sender:o,target:i,fixVersion:"FIX.4.4",logging:!1,onOpen:()=>{a()},onMessage:s=>{},onClose:()=>{}};n.connect(e)};j().catch(n=>console.error("Error initializing server:",n));
5
+ //# sourceMappingURL=example_mcp_local.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../examples/example_mcp_local.ts", "../../src/MCPLocal.ts"],
4
+ "sourcesContent": ["import {\n EncryptMethod,\n FIXParser,\n Field,\n Fields,\n LicenseManager,\n type Message,\n Messages,\n type Options,\n ResetSeqNumFlag,\n} from 'fixparser';\nimport { MCPLocal } from 'fixparser-plugin-mcp';\n\nconst initializeServer = async () => {\n await LicenseManager.setLicenseKey(process.env.FIXPARSER_LICENSE_KEY);\n\n const fixParser: FIXParser = new FIXParser({\n plugins: [new MCPLocal({ port: 3099, onReady: () => {} })],\n });\n\n const sendLogon = () => {\n const logon = fixParser.createMessage(\n new Field(Fields.MsgType, Messages.Logon),\n new Field(Fields.MsgSeqNum, fixParser.getNextTargetMsgSeqNum()),\n new Field(Fields.SenderCompID, SENDER),\n new Field(Fields.SendingTime, fixParser.getTimestamp()),\n new Field(Fields.TargetCompID, TARGET),\n new Field(Fields.ResetSeqNumFlag, ResetSeqNumFlag.Yes),\n new Field(Fields.EncryptMethod, EncryptMethod.None),\n new Field(Fields.HeartBtInt, 10),\n );\n fixParser.send(logon);\n };\n\n const SENDER = 'CLIENT2';\n const TARGET = 'EXECUTOR';\n const CONNECT_PARAMS: Options = {\n host: 'localhost',\n port: 5001,\n protocol: 'tcp',\n sender: SENDER,\n target: TARGET,\n fixVersion: 'FIX.4.4',\n logging: false,\n onOpen: () => {\n sendLogon();\n },\n onMessage: (message: Message) => {},\n onClose: () => {},\n };\n\n fixParser.connect(CONNECT_PARAMS);\n};\n\ninitializeServer().catch((err) => console.error('Error initializing server:', err));\n", "import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport {\n Field,\n Fields,\n HandlInst,\n type IFIXParser,\n type Logger,\n MDEntryType,\n type Message,\n Messages,\n OrdType,\n SubscriptionRequestType,\n TimeInForce,\n} from 'fixparser';\nimport type { IPlugin } from 'fixparser-common';\nimport type { PluginOptions } from './PluginOptions';\n\n// Define JSON Schemas\nconst parseInputSchema = {\n type: 'object',\n properties: {\n fixString: {\n type: 'string',\n description: 'FIX message string to parse',\n },\n },\n required: ['fixString'],\n};\n\nconst parseToJSONInputSchema = {\n type: 'object',\n properties: {\n fixString: {\n type: 'string',\n description: 'FIX message string to parse',\n },\n },\n required: ['fixString'],\n};\n\nconst newOrderSingleInputSchema = {\n type: 'object',\n properties: {\n clOrdID: {\n type: 'string',\n description: 'Client Order ID',\n },\n handlInst: {\n type: 'string',\n enum: ['1', '2', '3'],\n default: HandlInst.AutomatedExecutionNoIntervention,\n description: 'Handling instruction',\n },\n quantity: {\n type: 'number',\n description: 'Order quantity',\n },\n price: {\n type: 'number',\n description: 'Order price',\n },\n ordType: {\n type: 'string',\n enum: [\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'F',\n 'G',\n 'H',\n 'I',\n 'J',\n 'K',\n 'L',\n 'M',\n 'P',\n 'Q',\n 'R',\n 'S',\n ],\n default: OrdType.Market,\n description: 'Order type',\n },\n side: {\n type: 'string',\n enum: ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'],\n description: 'Order side (1=Buy, 2=Sell)',\n },\n symbol: {\n type: 'string',\n description: 'Trading symbol',\n },\n timeInForce: {\n type: 'string',\n enum: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C'],\n default: TimeInForce.Day,\n description: 'Time in force',\n },\n },\n required: ['clOrdID', 'quantity', 'price', 'side', 'symbol'],\n};\n\nconst marketDataRequestInputSchema = {\n type: 'object',\n properties: {\n mdUpdateType: {\n type: 'string',\n enum: ['0', '1'],\n default: '0',\n description: 'Market data update type',\n },\n symbol: {\n type: 'string',\n description: 'Trading symbol',\n },\n mdReqID: {\n type: 'string',\n description: 'Market data request ID',\n },\n subscriptionRequestType: {\n type: 'string',\n enum: ['0', '1', '2'],\n default: SubscriptionRequestType.SnapshotAndUpdates,\n description: 'Subscription request type',\n },\n mdEntryType: {\n type: 'string',\n enum: [\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'F',\n 'G',\n 'H',\n 'J',\n 'K',\n 'L',\n 'M',\n 'N',\n 'O',\n 'P',\n 'Q',\n 'S',\n 'R',\n 'T',\n 'U',\n 'V',\n 'W',\n 'X',\n 'Y',\n 'Z',\n 'a',\n 'b',\n 'c',\n 'd',\n 'e',\n 'g',\n 'h',\n 'i',\n 't',\n ],\n default: MDEntryType.Bid,\n description: 'Market data entry type',\n },\n },\n required: ['symbol', 'mdReqID'],\n};\n\nexport class MCPLocal implements IPlugin<IFIXParser> {\n private logger: Logger | undefined;\n private parser: IFIXParser | undefined;\n private server: Server = new Server(\n {\n name: 'fixparser',\n version: '1.0.0',\n },\n {\n capabilities: {\n tools: {},\n prompts: {},\n resources: {},\n },\n },\n );\n private transport: StdioServerTransport = new StdioServerTransport();\n private onReady: (() => void) | undefined = undefined;\n\n private pendingRequests: Map<string, (data: Message) => void> = new Map();\n\n constructor({ logger, onReady }: PluginOptions) {\n if (logger) this.logger = logger;\n if (onReady) this.onReady = onReady;\n }\n\n public async register(parser: IFIXParser): Promise<void> {\n this.parser = parser;\n this.parser.addOnMessageCallback((message: Message) => {\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${parser.protocol?.toUpperCase()}): << received ${message.description}`,\n });\n const msgType = message.messageType;\n if (msgType === Messages.MarketDataSnapshotFullRefresh || msgType === Messages.ExecutionReport) {\n const idField =\n msgType === Messages.MarketDataSnapshotFullRefresh\n ? message.getField(Fields.MDReqID)\n : message.getField(Fields.ClOrdID);\n if (idField) {\n const id = idField.value;\n if (typeof id === 'string' || typeof id === 'number') {\n const callback = this.pendingRequests.get(String(id));\n if (callback) {\n callback(message);\n this.pendingRequests.delete(String(id));\n }\n }\n }\n }\n });\n\n this.logger = parser.logger;\n\n this.addWorkflows();\n\n await this.server.connect(this.transport);\n\n if (this.onReady) {\n this.onReady();\n }\n }\n\n private addWorkflows() {\n if (!this.parser) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- FIXParser instance not initialized. Ignoring setup of workflows...',\n });\n return;\n }\n\n if (!this.server) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- MCP Server not initialized. Ignoring setup of workflows...',\n });\n return;\n }\n\n // Helper function to validate and parse arguments\n const validateArgs = (args: any, schema: any): any => {\n // Basic validation - in a real implementation, you might want to use a proper JSON Schema validator\n const result: any = {};\n\n for (const [key, propSchema] of Object.entries(schema.properties || {})) {\n const prop = propSchema as any;\n const value = args?.[key];\n\n if (prop.required && (value === undefined || value === null)) {\n throw new Error(`Required property '${key}' is missing`);\n }\n\n if (value !== undefined) {\n // Apply defaults\n result[key] = value;\n } else if (prop.default !== undefined) {\n result[key] = prop.default;\n }\n }\n\n return result;\n };\n\n // Empty handler for resources\n this.server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [],\n };\n });\n\n // Handler for listing available tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'parse',\n description: 'Parses a FIX message and describes it in plain language',\n inputSchema: parseInputSchema,\n },\n {\n name: 'parseToJSON',\n description: 'Parses a FIX message into JSON',\n inputSchema: parseToJSONInputSchema,\n },\n {\n name: 'newOrderSingle',\n description: 'Creates and sends a New Order Single',\n inputSchema: newOrderSingleInputSchema,\n },\n {\n name: 'marketDataRequest',\n description: 'Sends a request for Market Data with the given symbol',\n inputSchema: marketDataRequestInputSchema,\n },\n ],\n };\n });\n\n // Handler for tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'parse': {\n try {\n const { fixString } = validateArgs(args, parseInputSchema);\n const parsedMessage = this.parser?.parse(fixString);\n if (!parsedMessage || parsedMessage.length === 0) {\n return {\n isError: true,\n content: [{ type: 'text', text: 'Error: Failed to parse FIX string' }],\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: `Parsed FIX message: ${fixString} (placeholder implementation)`,\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to parse FIX string'}`,\n },\n ],\n };\n }\n }\n\n case 'parseToJSON': {\n try {\n const { fixString } = validateArgs(args, parseToJSONInputSchema);\n const parsedMessage = this.parser?.parse(fixString);\n if (!parsedMessage || parsedMessage.length === 0) {\n return {\n isError: true,\n content: [{ type: 'text', text: 'Error: Failed to parse FIX string' }],\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ fixString, parsed: 'placeholder' }),\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to parse FIX string'}`,\n },\n ],\n };\n }\n }\n\n case 'newOrderSingle': {\n try {\n const { clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce } =\n validateArgs(args, newOrderSingleInputSchema);\n\n const response = new Promise((resolve) => {\n this.pendingRequests.set(clOrdID, resolve);\n });\n\n const order: Message | undefined = this.parser?.createMessage(\n new Field(Fields.MsgType, Messages.NewOrderSingle),\n new Field(Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),\n new Field(Fields.SenderCompID, this.parser?.sender),\n new Field(Fields.TargetCompID, this.parser?.target),\n new Field(Fields.SendingTime, this.parser?.getTimestamp()),\n new Field(Fields.ClOrdID, clOrdID),\n new Field(Fields.Side, side),\n new Field(Fields.Symbol, symbol),\n new Field(Fields.OrderQty, quantity),\n new Field(Fields.Price, price),\n new Field(Fields.OrdType, ordType),\n new Field(Fields.HandlInst, handlInst),\n new Field(Fields.TimeInForce, timeInForce),\n new Field(Fields.TransactTime, this.parser?.getTimestamp()),\n );\n\n if (!this.parser?.connected) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Not connected. Ignoring message.',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Not connected. Ignoring message.',\n },\n ],\n };\n }\n\n this.parser?.send(order!);\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${order?.description}`,\n });\n\n const fixData = await response;\n return {\n content: [\n {\n type: 'text',\n text: `Execution Report for order ${clOrdID}: ${JSON.stringify((fixData as Message).toFIXJSON())}`,\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to create order'}`,\n },\n ],\n };\n }\n }\n\n case 'marketDataRequest': {\n try {\n const { mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType } = validateArgs(\n args,\n marketDataRequestInputSchema,\n );\n\n const response = new Promise((resolve) => {\n this.pendingRequests.set(mdReqID, resolve);\n });\n\n const marketDataRequest = this.parser?.createMessage(\n new Field(Fields.MsgType, Messages.MarketDataRequest),\n new Field(Fields.SenderCompID, this.parser?.sender),\n new Field(Fields.MsgSeqNum, this.parser?.getNextTargetMsgSeqNum()),\n new Field(Fields.TargetCompID, this.parser?.target),\n new Field(Fields.SendingTime, this.parser?.getTimestamp()),\n new Field(Fields.MarketDepth, 0),\n new Field(Fields.MDUpdateType, mdUpdateType),\n new Field(Fields.NoRelatedSym, 1),\n new Field(Fields.Symbol, symbol),\n new Field(Fields.MDReqID, mdReqID),\n new Field(Fields.SubscriptionRequestType, subscriptionRequestType),\n new Field(Fields.NoMDEntryTypes, 1),\n new Field(Fields.MDEntryType, mdEntryType),\n );\n\n if (!this.parser?.connected) {\n this.logger?.log({\n level: 'error',\n message: 'FIXParser (MCP): -- Not connected. Ignoring message.',\n });\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: 'Error: Not connected. Ignoring message.',\n },\n ],\n };\n }\n\n this.parser?.send(marketDataRequest!);\n this.logger?.log({\n level: 'info',\n message: `FIXParser (MCP): (${this.parser?.protocol?.toUpperCase()}): >> sent ${marketDataRequest?.description}`,\n });\n\n const fixData = await response;\n\n return {\n content: [\n {\n type: 'text',\n text: `Market data for ${symbol}: ${JSON.stringify((fixData as Message).toFIXJSON())}`,\n },\n ],\n };\n } catch (error) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Failed to request market data'}`,\n },\n ],\n };\n }\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n });\n\n this.server.setRequestHandler(ListPromptsRequestSchema, async () => {\n return {\n prompts: [\n {\n name: 'parse',\n description: 'Parses a FIX message and describes it in plain language',\n arguments: [\n {\n name: 'fixString',\n description: 'FIX message string to parse',\n required: true,\n },\n ],\n },\n {\n name: 'parseToJSON',\n description: 'Parses a FIX message into JSON',\n arguments: [\n {\n name: 'fixString',\n description: 'FIX message string to parse',\n required: true,\n },\n ],\n },\n {\n name: 'newOrderSingle',\n description: 'Creates and sends a New Order Single',\n arguments: [\n {\n name: 'clOrdID',\n description: 'Client Order ID',\n required: true,\n },\n {\n name: 'handlInst',\n description: 'Handling instruction',\n required: false,\n },\n {\n name: 'quantity',\n description: 'Order quantity',\n required: true,\n },\n {\n name: 'price',\n description: 'Order price',\n required: true,\n },\n {\n name: 'ordType',\n description: 'Order type',\n required: false,\n },\n {\n name: 'side',\n description: 'Order side (1=Buy, 2=Sell)',\n required: true,\n },\n {\n name: 'symbol',\n description: 'Trading symbol',\n required: true,\n },\n {\n name: 'timeInForce',\n description: 'Time in force',\n required: false,\n },\n ],\n },\n {\n name: 'marketDataRequest',\n description: 'Sends a request for Market Data with the given symbol',\n arguments: [\n {\n name: 'mdUpdateType',\n description: 'Market data update type',\n required: false,\n },\n {\n name: 'symbol',\n description: 'Trading symbol',\n required: true,\n },\n {\n name: 'mdReqID',\n description: 'Market data request ID',\n required: true,\n },\n {\n name: 'subscriptionRequestType',\n description: 'Subscription request type',\n required: false,\n },\n {\n name: 'mdEntryType',\n description: 'Market data entry type',\n required: false,\n },\n ],\n },\n ],\n };\n });\n\n // Handler for getting specific prompts\n this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'parse': {\n const fixString = args?.fixString || '';\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please parse and explain this FIX message: ${fixString}`,\n },\n },\n ],\n };\n }\n\n case 'parseToJSON': {\n const fixString = args?.fixString || '';\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `Please parse the FIX message to JSON: ${fixString}`,\n },\n },\n ],\n };\n }\n\n case 'newOrderSingle': {\n const { clOrdID, handlInst, quantity, price, ordType, side, symbol, timeInForce } = args || {};\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Create a New Order Single FIX message with the following parameters:',\n `- ClOrdID: ${clOrdID}`,\n `- HandlInst: ${handlInst ?? 'default'}`,\n `- Quantity: ${quantity}`,\n `- Price: ${price}`,\n `- OrdType: ${ordType ?? 'default (Market)'}`,\n `- Side: ${side}`,\n `- Symbol: ${symbol}`,\n `- TimeInForce: ${timeInForce ?? 'default (Day)'}`,\n '',\n 'Format the response as a JSON object with FIX tag numbers as keys and their corresponding values.',\n ].join('\\n'),\n },\n },\n ],\n };\n }\n\n case 'marketDataRequest': {\n const { mdUpdateType, symbol, mdReqID, subscriptionRequestType, mdEntryType } = args || {};\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Create a Market Data Request FIX message with the following parameters:',\n `- MDUpdateType: ${mdUpdateType ?? 'default (0 = FullRefresh)'}`,\n `- Symbol: ${symbol}`,\n `- MDReqID: ${mdReqID}`,\n `- SubscriptionRequestType: ${subscriptionRequestType ?? 'default (0 = Snapshot + Updates)'}`,\n `- MDEntryType: ${mdEntryType ?? 'default (0 = Bid)'}`,\n '',\n 'Format the response as a JSON object with FIX tag numbers as keys and their corresponding values.',\n ].join('\\n'),\n },\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown prompt: ${name}`);\n }\n });\n\n process.on('SIGINT', async () => {\n await this.server.close();\n process.exit(0);\n });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["EncryptMethod", "FIXParser", "Field", "Fields", "LicenseManager", "Messages", "ResetSeqNumFlag", "Server", "StdioServerTransport", "CallToolRequestSchema", "GetPromptRequestSchema", "ListPromptsRequestSchema", "ListResourcesRequestSchema", "ListToolsRequestSchema", "Field", "Fields", "HandlInst", "MDEntryType", "Messages", "OrdType", "SubscriptionRequestType", "TimeInForce", "parseInputSchema", "parseToJSONInputSchema", "newOrderSingleInputSchema", "marketDataRequestInputSchema", "MCPLocal", "logger", "onReady", "parser", "message", "msgType", "idField", "id", "callback", "validateArgs", "args", "schema", "result", "key", "propSchema", "prop", "value", "request", "name", "fixString", "parsedMessage", "error", "clOrdID", "handlInst", "quantity", "price", "ordType", "side", "symbol", "timeInForce", "response", "resolve", "order", "fixData", "mdUpdateType", "mdReqID", "subscriptionRequestType", "mdEntryType", "marketDataRequest", "initializeServer", "LicenseManager", "fixParser", "FIXParser", "MCPLocal", "sendLogon", "logon", "Field", "Fields", "Messages", "SENDER", "TARGET", "ResetSeqNumFlag", "EncryptMethod", "CONNECT_PARAMS", "message", "err"]
7
+ }
package/package.json CHANGED
@@ -1,33 +1,43 @@
1
1
  {
2
2
  "name": "fixparser-plugin-mcp",
3
- "version": "9.1.6-da9cb1d7",
4
- "description": "FIXParser MCP plugin",
3
+ "version": "9.1.7-27ef5b7b",
4
+ "description": "FIXParser MCP plugin (Local/Remote)",
5
5
  "files": [
6
6
  "./build/",
7
+ "./build-examples/",
7
8
  "./types/",
8
9
  "./LICENSE.md"
9
10
  ],
11
+ "main": "./build/cjs/MCPLocal.js",
12
+ "type": "module",
10
13
  "repository": {
11
14
  "type": "git",
12
15
  "url": "git+https://gitlab.com/logotype/fixparser.git"
13
16
  },
17
+ "bin": {
18
+ "fixparser-mcp-local": "build-examples/esm/example_mcp_local.mjs"
19
+ },
14
20
  "scripts": {
15
21
  "build": "npm run clean && npm run types && npm run build:main",
16
22
  "build:main": "node --experimental-strip-types -r ./../../esbuild-hook.ts ./scripts/build",
17
23
  "clean": "node --experimental-strip-types -r ./../../esbuild-hook.ts ./scripts/clean",
18
24
  "test": "echo 'No tests in the fixparser-plugin-mcp package'",
19
25
  "types": "tsc --declaration --emitDeclarationOnly --stripInternal --declarationDir ./types",
20
- "example:mcp_server": "tsx examples/run-example.ts example_mcp_server.ts",
21
- "example:mcp_client": "tsx examples/run-example.ts example_mcp_client.ts",
26
+ "example:mcp_local": "tsx examples/run-example.ts example_mcp_local.ts",
27
+ "example:mcp_remote": "tsx examples/run-example.ts example_mcp_remote.ts",
28
+ "example:mcp_remote_client": "tsx examples/run-example.ts example_mcp_remote_client.ts",
22
29
  "prepare": "husky",
23
30
  "upgrade-interactive": "ncu -u -t latest"
24
31
  },
25
32
  "author": "Victor Norgren",
26
33
  "dependencies": {
27
34
  "@modelcontextprotocol/sdk": "1.12.0",
28
- "fixparser": "*",
29
- "fixparser-common": "*",
30
- "zod": "3.25.27"
35
+ "body-parser": "2.2.0",
36
+ "express": "5.1.0",
37
+ "fixparser": "9.1.7-2eb6d03c",
38
+ "fixparser-common": "9.1.7-2eb6d03c",
39
+ "zod": "3.25.27",
40
+ "zod-to-json-schema": "3.24.5"
31
41
  },
32
42
  "keywords": [
33
43
  "FIXParser",
@@ -37,16 +47,20 @@
37
47
  "AI",
38
48
  "MCP Server",
39
49
  "Model Context Protocol",
50
+ "AI Trading Agent",
40
51
  "LLM"
41
52
  ],
42
53
  "homepage": "https://fixparser.dev",
43
- "license": "SEE LICENSE IN LICENSE.md",
44
- "types": "./types/MCPPlugin.d.ts",
54
+ "license": "LICENSE.md",
55
+ "types": "./types/MCPLocal.d.ts",
45
56
  "exports": {
46
57
  ".": {
47
- "types": "./types/MCPPlugin.d.ts",
48
- "import": "./build/esm/MCPPlugin.mjs",
49
- "require": "./build/cjs/MCPPlugin.js"
58
+ "types": "./types/MCPLocal.d.ts",
59
+ "import": "./build/esm/MCPLocal.mjs",
60
+ "require": "./build/cjs/MCPLocal.js"
50
61
  }
62
+ },
63
+ "devDependencies": {
64
+ "@types/express": "5.0.2"
51
65
  }
52
66
  }
@@ -0,0 +1,14 @@
1
+ import { type IFIXParser } from 'fixparser';
2
+ import type { IPlugin } from 'fixparser-common';
3
+ import type { PluginOptions } from './PluginOptions';
4
+ export declare class MCPLocal implements IPlugin<IFIXParser> {
5
+ private logger;
6
+ private parser;
7
+ private server;
8
+ private transport;
9
+ private onReady;
10
+ private pendingRequests;
11
+ constructor({ logger, onReady }: PluginOptions);
12
+ register(parser: IFIXParser): Promise<void>;
13
+ private addWorkflows;
14
+ }
@@ -5,7 +5,7 @@ export type PluginOptions = {
5
5
  logger?: Logger;
6
6
  onReady: () => void;
7
7
  };
8
- export declare class MCPPlugin implements IPlugin<IFIXParser> {
8
+ export declare class MCPRemote implements IPlugin<IFIXParser> {
9
9
  /**
10
10
  * Port number the server will listen on.
11
11
  * @private
@@ -0,0 +1,6 @@
1
+ import type { Logger } from 'fixparser';
2
+ export type PluginOptions = {
3
+ port: number;
4
+ logger?: Logger;
5
+ onReady: () => void;
6
+ };
package/types/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export { MCPPlugin, PluginOptions } from './MCPPlugin';
1
+ export { PluginOptions } from './PluginOptions';
2
+ export { MCPLocal } from './MCPLocal';
3
+ export { MCPRemote } from './MCPRemote';