Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions src/generator/server-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ export function generateMcpServerCode(
// Determine which transport to include
let transportImport = '';
let transportCode = '';
const webServicerPortNumberStatement = `${options.port ?? "process.env['PORT'] === undefined ? undefined : parseInt(process.env['PORT'], 10)"}`;

switch (options.transport) {
case 'web':
transportImport = `\nimport { setupWebServer } from "./web-server.js";`;
transportCode = `// Set up Web Server transport
try {
await setupWebServer(server, ${options.port || 3000});
await setupWebServer(server, ${webServicerPortNumberStatement});
} catch (error) {
console.error("Error setting up web server:", error);
process.exit(1);
Expand All @@ -61,7 +62,7 @@ export function generateMcpServerCode(
transportImport = `\nimport { setupStreamableHttpServer } from "./streamable-http.js";`;
transportCode = `// Set up StreamableHTTP transport
try {
await setupStreamableHttpServer(server, ${options.port || 3000});
await setupStreamableHttpServer(server, ${webServicerPortNumberStatement});
} catch (error) {
console.error("Error setting up StreamableHTTP server:", error);
process.exit(1);
Expand All @@ -81,6 +82,25 @@ export function generateMcpServerCode(
break;
}

const mainDeclaration= options.generateLib === true ? '' : `
/**
* Cleanup function for graceful shutdown
*/
async function cleanup() {
console.error("Shutting down MCP server...");
process.exit(0);
}

// Register signal handlers
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

// Start the server
main().catch((error) => {
console.error("Fatal error in main execution:", error);
process.exit(1);
});`;

// Generate the full server code
return `#!/usr/bin/env node
/**
Expand All @@ -89,8 +109,8 @@ export function generateMcpServerCode(
*/

// Load environment variables from .env file
import dotenv from 'dotenv';
dotenv.config();
import { config } from 'dotenv';
config();

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
Expand Down Expand Up @@ -159,27 +179,11 @@ ${executeApiToolFunctionCode}
/**
* Main function to start the server
*/
async function main() {
${options.generateLib === true ? 'export ' : ''}async function main() {
${transportCode}
}

/**
* Cleanup function for graceful shutdown
*/
async function cleanup() {
console.error("Shutting down MCP server...");
process.exit(0);
}

// Register signal handlers
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);

// Start the server
main().catch((error) => {
console.error("Fatal error in main execution:", error);
process.exit(1);
});
${mainDeclaration}

/**
* Formats API errors for better readability
Expand Down
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ program
'Port for web or streamable-http transport (default: 3000)',
(val) => parseInt(val, 10)
)
.option(
'-l, --generate-lib <boolean>',
'Indicates whether a library should be generated and hence the \'main\' method not invoked (default: false)',
(val) => normalizeBoolean(val),
false
)
.option(
'--default-include <boolean>',
'Default behavior for x-mcp filtering (true|false, case-insensitive). Default: true (include by default), false = exclude by default',
Expand Down
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface CliOptions {
transport?: TransportType;
/** Server port (for web and streamable-http transports) */
port?: number;
/** Whether the generated code should invoke the main method or expose the main method as a library */
generateLib?: boolean;
/**
* Default behavior for x-mcp filtering.
* true (default) = include by default when x-mcp is missing or invalid;
Expand Down
Loading