index.ts•3.28 kB
/**
* MCP Server Starter Template
*
* This is a reference implementation of a Model Context Protocol (MCP) server.
* It demonstrates best practices for:
* - Server initialization and configuration
* - Tool registration and management
* - Error handling and logging
* - Resource cleanup
*
* For more information about MCP, visit:
* https://modelcontextprotocol.io
*/
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { initializeWebDriver, quitWebDriver } from "./services/seleniumService.js";
import { registerSeleniumTools } from "./tools/index.js";
/**
* Create a new MCP server instance with full capabilities
*/
const server = new McpServer({
name: "selenium-mcp-server",
version: "0.1.0",
capabilities: {
tools: {},
resources: {},
prompts: {},
streaming: true
}
});
/**
* Helper function to send log messages to the client
*/
function logMessage(level: 'info' | 'warn' | 'error', message: string) {
console.error(`[${level.toUpperCase()}] ${message}`);
}
/**
* Set up error handling for the server
*/
process.on('uncaughtException', (error: Error) => {
logMessage('error', `Uncaught error: ${error.message}`);
console.error('Server error:', error);
});
// Register example tools
try {
registerSeleniumTools(server);
logMessage('info', 'Successfully registered all tools');
} catch (error) {
logMessage('error', `Failed to register tools: ${error instanceof Error ? error.message : 'Unknown error'}`);
process.exit(1);
}
/**
* Set up proper cleanup on process termination
*/
async function cleanup() {
try {
await server.close();
logMessage('info', 'Server shutdown completed');
} catch (error) {
logMessage('error', `Error during shutdown: ${error instanceof Error ? error.message : 'Unknown error'}`);
} finally {
process.exit(0);
}
}
// Handle termination signals
process.on('SIGTERM', cleanup);
process.on('SIGINT', cleanup);
/**
* Main server startup function
*/
async function main() {
try {
// Initialize WebDriver before connecting transport
await initializeWebDriver();
// Connect transport
const transport = new StdioServerTransport();
await server.connect(transport);
console.log("Selenium MCP Server connected via stdio.");
console.log("Ready to accept requests.");
// Setup graceful shutdown
process.on('SIGINT', handleShutdown);
process.on('SIGTERM', handleShutdown);
process.on('exit', async (code) => {
console.log(`Server exiting with code: ${code}`);
// Ensure WebDriver quits even on non-signal exits, if possible
await quitWebDriver();
});
} catch (error) {
console.error("Failed to start Selenium MCP server:", error);
await quitWebDriver(); // Attempt cleanup even on startup failure
process.exit(1);
}
}
// Shutdown handler
async function handleShutdown() {
console.log("Received shutdown signal.");
await quitWebDriver();
// Optionally disconnect server transport if needed
// server.disconnect();
process.exit(0);
}
// Start the server
main().catch((error) => {
console.error('Fatal error in main():', error);
process.exit(1);
});