#!/usr/bin/env node
/**
* MCP Server for Human-in-the-Loop - stdio transport
*
* This server implements the Model Context Protocol with stdio transport,
* allowing MCP clients like Claude Code to interact with human input tools
* through standard input/output.
*/
import { createMCPServer, startMCPServer, setupGracefulShutdown } from './core/server.js';
import { RequestManager } from './core/request-manager.js';
import { startBrowserBridge } from './core/browser-bridge.js';
/**
* Parse command line arguments
*/
function parseArgs(): { port: number; help: boolean; portSpecified: boolean; exitAfterCommand: boolean } {
const args = process.argv.slice(2);
let port = 3000; // Default port
let help = false;
let portSpecified = false;
let exitAfterCommand = false;
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === '--port' || arg === '-p') {
const portArg = args[i + 1];
if (!portArg || isNaN(Number(portArg))) {
if (process.env.ASK_ME_MCP_DEBUG) {
console.error('[ask-me-mcp] Error: --port requires a valid port number');
}
process.exit(1);
}
port = Number(portArg);
if (port < 1 || port > 65535) {
if (process.env.ASK_ME_MCP_DEBUG) {
console.error('[ask-me-mcp] Error: Port must be between 1 and 65535');
}
process.exit(1);
}
portSpecified = true;
i++; // Skip the next argument since it's the port value
} else if (arg === '--help' || arg === '-h') {
help = true;
} else if (arg === '--exit-after-command') {
exitAfterCommand = true;
} else if (arg.startsWith('-')) {
if (process.env.ASK_ME_MCP_DEBUG) {
console.error(`[ask-me-mcp] Error: Unknown argument: ${arg}`);
console.error('[ask-me-mcp] Use --help for usage information');
}
process.exit(1);
}
}
return { port, help, portSpecified, exitAfterCommand };
}
/**
* Display help message
*/
function showHelp(): void {
if (process.env.ASK_ME_MCP_DEBUG) {
console.error(`
Ask-Me MCP Server - Human-in-the-Loop MCP Server
Usage: node main.js [options]
Options:
--port, -p <number> Port for the browser bridge HTTP server (default: 3000)
If not specified, auto-discovers available port starting from 3000
If specified, uses exact port (will fail if port is in use)
--exit-after-command Exit server after handling first MCP command (debug only)
--help, -h Show this help message
Examples:
node main.js # Auto-discover port starting from 3000
node main.js --port 4711 # Use exact port 4711
node main.js -p 8080 # Use exact port 8080
node main.js --exit-after-command # Exit after first MCP command (debug)
The server uses stdio transport for MCP communication and starts an HTTP server
for browser UI communication on the specified port.
`);
}
}
/**
* Main application entry point
*/
async function main() {
try {
// Parse command line arguments
const { port, help, portSpecified, exitAfterCommand } = parseArgs();
if (help) {
showHelp();
process.exit(0);
}
// Initialize request manager
const requestManager = new RequestManager();
// Create and configure the MCP server
const server = createMCPServer(
{
name: 'ask-me-mcp',
version: '1.0.0',
description: 'Human-in-the-Loop MCP Server',
},
requestManager,
exitAfterCommand
);
// Start the browser bridge HTTP server with specified port
const httpServer = await startBrowserBridge(requestManager.getStorage(), port, portSpecified);
// Start the MCP server with stdio transport
await startMCPServer(server);
// Setup graceful shutdown handling
setupGracefulShutdown(server, httpServer);
} catch (error) {
if (process.env.ASK_ME_MCP_DEBUG) {
console.error('[ask-me-mcp] Fatal error:', error);
console.error('[ask-me-mcp] Stack trace:', error instanceof Error ? error.stack : 'No stack trace');
}
process.exit(1);
}
}
// Start the application
main();