UNPKG

mcpipe

Version:

Decorate stdio MCP servers with debugging and other capabilities.

90 lines (89 loc) 3.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformServerToClientMessage = transformServerToClientMessage; exports.transformClientToServerMessage = transformClientToServerMessage; /** * Type guard to check if an object is a potential JSON-RPC message. */ function isJsonMessage(obj) { return typeof obj === 'object' && obj !== null && !Array.isArray(obj); } // Type guards for specific MCP message types function isListToolsResult(message) { return message.jsonrpc === "2.0" && isJsonMessage(message.result) && Array.isArray(message.result.tools); } function isCallToolResult(message) { return message.jsonrpc === "2.0" && isJsonMessage(message.result) && (typeof message.result.content !== 'undefined' || typeof message.result.toolName === 'string'); } function isCallToolRequest(message) { return message.jsonrpc === "2.0" && message.method === "tools/call" && isJsonMessage(message.params) && typeof message.params.name === 'string'; } // Message transformation functions function transformListToolsResult(message, prefix) { if (!isJsonMessage(message.result) || !Array.isArray(message.result.tools)) { return { message, isModified: false }; } let isModified = false; message.result.tools.forEach(tool => { if (isJsonMessage(tool) && typeof tool.name === 'string') { tool.name = prefix + tool.name; isModified = true; } }); return { message, isModified }; } function transformCallToolResult(message, prefix) { if (!isJsonMessage(message.result)) { return { message, isModified: false }; } let isModified = false; // Handle legacy toolName field for backwards compatibility with protocol versions <= 2024-10-07 // Note: Current MCP protocol (2025-03-26+) does not include toolName in CallToolResult if (typeof message.result.toolName === 'string') { message.result.toolName = prefix + message.result.toolName; isModified = true; } // Current protocol versions don't include tool names in CallToolResult, // so no transformation is needed for modern servers return { message, isModified }; } function transformCallToolRequest(message, prefix) { if (!isJsonMessage(message.params) || typeof message.params.name !== 'string') { return { message, isModified: false }; } let isModified = false; const originalFullName = message.params.name; if (originalFullName.startsWith(prefix)) { message.params.name = originalFullName.substring(prefix.length); isModified = true; } return { message, isModified }; } // transformation dispatcher for server->client messages function transformServerToClientMessage(message, prefix) { if (isJsonMessage(message)) { if (isListToolsResult(message)) { return transformListToolsResult(message, prefix); } if (isCallToolResult(message)) { return transformCallToolResult(message, prefix); } } return { message, isModified: false }; } // transformation dispatcher for client->server messages function transformClientToServerMessage(message, prefix) { if (isJsonMessage(message)) { if (isCallToolRequest(message)) { return transformCallToolRequest(message, prefix); } } return { message, isModified: false }; }