@1mcp/agent
Version:
One MCP server to aggregate them all - A unified Model Context Protocol server implementation
116 lines (115 loc) • 3.79 kB
JavaScript
#!/usr/bin/env node
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { setupServer } from './server.js';
import logger from './logger/logger.js';
import configReloadService from './services/configReloadService.js';
import { ConfigManager } from './config/configManager.js';
import { ExpressServer } from './server/expressServer.js';
import { PORT, HOST } from './constants.js';
// Parse command line arguments
const argv = yargs(hideBin(process.argv))
.usage('Usage: $0 [options]')
.options({
transport: {
alias: 't',
describe: 'Transport type to use (stdio or sse)',
type: 'string',
choices: ['stdio', 'sse'],
default: 'sse',
},
port: {
alias: 'P',
describe: 'SSE port to listen on, applicable when transport is sse',
type: 'number',
default: PORT,
},
host: {
alias: 'H',
describe: 'SSE host to listen on, applicable when transport is sse',
type: 'string',
default: HOST,
},
config: {
alias: 'c',
describe: 'Path to the config file',
type: 'string',
default: undefined,
},
tags: {
alias: 'g',
describe: 'Tags to filter clients (comma-separated)',
type: 'string',
default: undefined,
},
})
.help()
.alias('help', 'h')
.parseSync();
/**
* Set up graceful shutdown handling
*/
function setupGracefulShutdown(serverManager) {
const shutdown = async () => {
logger.info('Shutting down server...');
// Stop the configuration reload service
configReloadService.stop();
// Close all transports
for (const [sessionId, transport] of serverManager.getTransports().entries()) {
try {
transport?.close();
logger.info(`Closed transport: ${sessionId}`);
}
catch (error) {
logger.error(`Error closing transport ${sessionId}: ${error}`);
}
}
logger.info('Server shutdown complete');
process.exit(0);
};
// Handle various signals for graceful shutdown
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
process.on('SIGHUP', shutdown);
}
/**
* Start the server using the specified transport.
*/
async function main() {
try {
ConfigManager.getInstance(argv.config);
// Initialize server and get server manager with custom config path if provided
const serverManager = await setupServer();
// Set up graceful shutdown handling
setupGracefulShutdown(serverManager);
if (argv.transport === 'stdio') {
// Use stdio transport
const transport = new StdioServerTransport();
// Parse and validate tags from CLI if provided
let tags;
if (argv.tags) {
tags = argv.tags.split(',').filter((tag) => tag.trim().length > 0);
if (tags.length === 0) {
logger.warn('No valid tags provided, ignoring tags parameter');
tags = undefined;
}
}
await serverManager.connectTransport(transport, 'stdio', tags);
logger.info('Server started with stdio transport');
}
else {
// Use HTTP/SSE transport
const expressServer = new ExpressServer(serverManager);
expressServer.start(argv.port, argv.host);
}
}
catch (error) {
logger.error('Server error:', error);
process.exit(1);
}
}
main().catch((error) => {
logger.error('Server error:', error);
process.exit(1);
});