Skip to main content
Glama

MRP Calculator MCP Server

index.ts11 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; import { validateMRPInput } from './validator.js'; import { calculateMRP } from './calculator.js'; import { MRPInput } from './types.js'; class MRPCalculatorServer { private server: Server; constructor() { this.server = new Server( { name: 'mrp-calculator', version: '1.0.0', }, { capabilities: { tools: { calculate_order_need: { name: 'calculate_order_need', description: 'Calculate MRP order need based on forecast, inventory, and delivery schedule', inputSchema: { type: 'object', properties: { sku_location: { type: 'object', properties: { sku: { type: 'string' }, location: { type: 'string' } }, required: ['sku', 'location'] }, analysis_date: { type: 'string' }, must_order_point: { type: 'number' }, current_balance: { type: 'number' }, open_orders: { type: 'array', items: { type: 'object', properties: { quantity: { type: 'number' }, delivery_date: { type: 'string' } } } }, delivery_schedule: { type: 'object', properties: { first_delivery: { type: 'string' }, second_delivery: { type: 'string' }, lead_time: { type: 'number' } } }, forecast_periods: { type: 'array', items: { type: 'object', properties: { start_date: { type: 'string' }, end_date: { type: 'string' }, quantity: { type: 'number' } } } }, batch_sizes: { type: 'array', items: { type: 'number' } } }, required: ['sku_location', 'analysis_date', 'must_order_point', 'current_balance', 'open_orders', 'delivery_schedule', 'forecast_periods'] } } } }, } ); this.setupToolHandlers(); // Error handling this.server.onerror = (error) => console.error('[MCP Error]', error); process.on('SIGINT', async () => { await this.server.close(); process.exit(0); }); } private setupToolHandlers() { // Add ListToolsRequestSchema handler this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [{ name: 'calculate_order_need', description: 'Calculate MRP order need based on forecast, inventory, and delivery schedule', inputSchema: { type: 'object', properties: { sku_location: { type: 'object', properties: { sku: { type: 'string' }, location: { type: 'string' } }, required: ['sku', 'location'] }, analysis_date: { type: 'string' }, must_order_point: { type: 'number' }, current_balance: { type: 'number' }, open_orders: { type: 'array', items: { type: 'object', properties: { quantity: { type: 'number' }, delivery_date: { type: 'string' } } } }, delivery_schedule: { type: 'object', properties: { first_delivery: { type: 'string' }, second_delivery: { type: 'string' }, lead_time: { type: 'number' } } }, forecast_periods: { type: 'array', items: { type: 'object', properties: { start_date: { type: 'string' }, end_date: { type: 'string' }, quantity: { type: 'number' } } } }, batch_sizes: { type: 'array', items: { type: 'number' } } }, required: ['sku_location', 'analysis_date', 'must_order_point', 'current_balance', 'open_orders', 'delivery_schedule', 'forecast_periods'] } }] })); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== 'calculate_order_need') { return { content: [{ type: 'text', text: `Unknown tool: ${request.params.name}`, }], isError: true, }; } try { // Type assertion with validation const rawInput = request.params.arguments as Record<string, unknown>; const deliverySchedule = rawInput.delivery_schedule as Record<string, unknown>; const input: MRPInput = { sku_location: rawInput.sku_location as { sku: string; location: string }, analysis_date: String(rawInput.analysis_date), must_order_point: Number(rawInput.must_order_point), current_balance: Number(rawInput.current_balance), open_orders: (rawInput.open_orders as Array<any>).map(order => ({ quantity: Number(order.quantity), delivery_date: String(order.delivery_date) })), delivery_schedule: { first_delivery: String(deliverySchedule.first_delivery), second_delivery: String(deliverySchedule.second_delivery), lead_time: Number(deliverySchedule.lead_time) }, forecast_periods: (rawInput.forecast_periods as Array<any>).map(period => ({ start_date: String(period.start_date), end_date: String(period.end_date), quantity: Number(period.quantity) })), batch_sizes: rawInput.batch_sizes ? (rawInput.batch_sizes as number[]) : undefined }; // Validate input const validationResult = validateMRPInput(input); if (!validationResult.isValid) { return { content: [{ type: 'text', text: `Validation failed:\n${validationResult.messages.map(m => `${m.type}: ${m.message}`).join('\n')}`, }], isError: true, }; } // Calculate MRP const result = calculateMRP(input); // Format response const response = { order_need: result.order_need, calculation_steps: result.calculation_steps.map(step => `${step.step}: ${step.description} = ${step.value}` ).join('\n'), projected_balances: result.projected_balances.map(pb => `${pb.date}: ${pb.starting_balance} → ${pb.ending_balance}` ).join('\n'), validation: result.validation.messages.join('\n') }; return { content: [{ type: 'text', text: JSON.stringify(response, null, 2), }], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [{ type: 'text', text: `Error calculating MRP: ${errorMessage}`, }], isError: true, }; } }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('MRP Calculator MCP server running on stdio'); } } const server = new MRPCalculatorServer(); server.run().catch(console.error);

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/brandon-butterwick/MRP_Calculation'

If you have feedback or need assistance with the MCP directory API, please join our Discord server