@mcp-shark/mcp-shark
Version:
Aggregate multiple Model Context Protocol (MCP) servers into a single unified interface with a powerful monitoring UI. Prov deep visibility into every request and response.
81 lines (68 loc) • 2.81 kB
JavaScript
import { spawn } from 'node:child_process';
import * as path from 'node:path';
import { findMcpServerPath } from './paths.js';
import { enhancePath } from '../../paths.js';
import { getMcpConfigPath, getWorkingDirectory } from 'mcp-shark-common/configs/index.js';
const MAX_LOG_LINES = 10000;
export function createLogEntry(mcpSharkLogs, broadcastLogUpdate) {
return function logEntry(type, data) {
const timestamp = new Date().toISOString();
const line = data.toString();
mcpSharkLogs.push({ timestamp, type, line });
if (mcpSharkLogs.length > MAX_LOG_LINES) {
mcpSharkLogs.shift();
}
broadcastLogUpdate({ timestamp, type, line });
};
}
export function spawnMcpSharkServer(mcpSharkJsPath, mcpsJsonPath, logEntry) {
const mcpServerPath = findMcpServerPath();
const nodeExecutable = process.execPath || 'node';
const enhancedPath = enhancePath(process.env.PATH);
logEntry('info', `[UI Server] Spawning MCP-Shark server...`);
logEntry('info', `[UI Server] Executable: ${nodeExecutable}`);
logEntry('info', `[UI Server] Script: ${mcpSharkJsPath}`);
logEntry('info', `[UI Server] Config: ${mcpsJsonPath}`);
logEntry('info', `[UI Server] CWD: ${mcpServerPath}`);
logEntry('info', `[UI Server] Data dir: ${getWorkingDirectory()}`);
logEntry('info', `[UI Server] Enhanced PATH: ${enhancedPath}`);
const processHandle = spawn(nodeExecutable, [mcpSharkJsPath, mcpsJsonPath], {
cwd: mcpServerPath,
stdio: ['ignore', 'pipe', 'pipe'],
env: {
...process.env,
PATH: enhancedPath,
},
});
console.log(`[UI Server] MCP-Shark process spawned with PID: ${processHandle.pid}`);
processHandle.stdout.on('data', (data) => {
logEntry('stdout', data);
process.stdout.write(data);
});
processHandle.stderr.on('data', (data) => {
logEntry('stderr', data);
process.stderr.write(data);
});
return processHandle;
}
export function setupProcessHandlers(processHandle, logEntry, onError, onExit) {
processHandle.on('error', (err) => {
console.error('Failed to start mcp-shark server:', err);
logEntry('error', `Failed to start mcp-shark server: ${err.message}`);
if (onError) onError(err);
});
processHandle.on('exit', (code, signal) => {
const message = `MCP Shark server process exited with code ${code}${signal ? ` (signal: ${signal})` : ''}`;
console.log(`[UI Server] ${message}`);
logEntry('exit', message);
if (code !== 0 && code !== null) {
console.error(`[UI Server] MCP-Shark process exited with non-zero code: ${code}`);
logEntry('error', `Process exited with code ${code}`);
}
if (onExit) onExit(code, signal);
});
}
export function getMcpSharkJsPath() {
const mcpServerPath = findMcpServerPath();
return path.join(mcpServerPath, 'mcp-shark.js');
}