import { parseMySQLConnectionString, DEFAULT_CONFIG } from '../server/McpServer.js';
import type { McpServerConfig, TransportType, DatabaseConfig, PoolConfig, OAuthConfig } from '../types/index.js';
/**
* Parse command line arguments
*/
export function parseArgs(argv: string[] = process.argv.slice(2)): {
config: Partial<McpServerConfig>;
databases: DatabaseConfig[];
oauth: OAuthConfig | undefined;
shouldExit: boolean;
} {
const args = argv;
const config: Partial<McpServerConfig> = {};
const databases: DatabaseConfig[] = [];
// Default pool config
const poolConfig: PoolConfig = {
connectionLimit: 10,
waitForConnections: true,
queueLimit: 0
};
// OAuth config
let oauthEnabled = false;
let oauthIssuer: string | undefined;
let oauthAudience: string | undefined;
let oauthJwksUri: string | undefined;
let oauthClockTolerance: number | undefined;
// MySQL connection params
let mysqlHost: string | undefined;
let mysqlPort = 3306;
let mysqlUser: string | undefined;
let mysqlPassword: string | undefined;
let mysqlDatabase: string | undefined;
for (let i = 0; i < args.length; i++) {
const arg = args[i];
const nextArg = args[i + 1];
switch (arg) {
case '--transport':
case '-t':
if (nextArg && !nextArg.startsWith('-')) {
config.transport = nextArg as TransportType;
i++;
}
break;
case '--port':
case '-p':
if (nextArg && !nextArg.startsWith('-')) {
config.port = parseInt(nextArg, 10);
i++;
}
break;
case '--mysql':
case '-m':
if (nextArg && !nextArg.startsWith('-')) {
// Parse connection string
const dbConfig = parseMySQLConnectionString(nextArg);
dbConfig.pool = poolConfig;
databases.push(dbConfig);
i++;
}
break;
case '--mysql-host':
if (nextArg && !nextArg.startsWith('-')) {
mysqlHost = nextArg;
i++;
}
break;
case '--mysql-port':
if (nextArg && !nextArg.startsWith('-')) {
mysqlPort = parseInt(nextArg, 10);
i++;
}
break;
case '--mysql-user':
if (nextArg && !nextArg.startsWith('-')) {
mysqlUser = nextArg;
i++;
}
break;
case '--mysql-password':
if (nextArg && !nextArg.startsWith('-')) {
mysqlPassword = nextArg;
i++;
}
break;
case '--mysql-database':
if (nextArg && !nextArg.startsWith('-')) {
mysqlDatabase = nextArg;
i++;
}
break;
case '--pool-size':
if (nextArg && !nextArg.startsWith('-')) {
poolConfig.connectionLimit = parseInt(nextArg, 10);
i++;
}
break;
case '--pool-timeout':
if (nextArg && !nextArg.startsWith('-')) {
poolConfig.acquireTimeout = parseInt(nextArg, 10);
i++;
}
break;
case '--pool-queue-limit':
if (nextArg && !nextArg.startsWith('-')) {
poolConfig.queueLimit = parseInt(nextArg, 10);
i++;
}
break;
case '--tool-filter':
case '-f':
// Note: tool filter values can start with '-' (e.g., "-base,-ecosystem,+starter")
// so we can't use the usual !nextArg.startsWith('-') check
if (nextArg !== undefined) {
config.toolFilter = nextArg;
i++;
}
break;
case '--name':
if (nextArg && !nextArg.startsWith('-')) {
config.name = nextArg;
i++;
}
break;
// OAuth options
case '--oauth-enabled':
case '-o':
oauthEnabled = true;
break;
case '--oauth-issuer':
if (nextArg && !nextArg.startsWith('-')) {
oauthIssuer = nextArg;
i++;
}
break;
case '--oauth-audience':
if (nextArg && !nextArg.startsWith('-')) {
oauthAudience = nextArg;
i++;
}
break;
case '--oauth-jwks-uri':
if (nextArg && !nextArg.startsWith('-')) {
oauthJwksUri = nextArg;
i++;
}
break;
case '--oauth-clock-tolerance':
if (nextArg && !nextArg.startsWith('-')) {
oauthClockTolerance = parseInt(nextArg, 10);
i++;
}
break;
case '--version':
case '-v':
console.error(`mysql-mcp version ${DEFAULT_CONFIG.version}`);
return { config, databases, oauth: undefined, shouldExit: true };
case '--help':
case '-h':
printHelp();
return { config, databases, oauth: undefined, shouldExit: true };
default:
if (arg?.startsWith('-')) {
console.error(`Unknown option: ${arg}`);
printHelp();
process.exit(1);
}
}
}
// Build database config from individual params if provided
if (mysqlHost || mysqlUser || mysqlDatabase) {
// Check required fields
if (!mysqlHost) {
mysqlHost = process.env['MYSQL_HOST'] ?? 'localhost';
}
if (!mysqlUser) {
mysqlUser = process.env['MYSQL_USER'];
}
if (!mysqlPassword) {
mysqlPassword = process.env['MYSQL_PASSWORD'];
}
if (!mysqlDatabase) {
mysqlDatabase = process.env['MYSQL_DATABASE'];
}
if (mysqlUser && mysqlDatabase) {
databases.push({
type: 'mysql',
host: mysqlHost,
port: mysqlPort,
username: mysqlUser,
password: mysqlPassword,
database: mysqlDatabase,
pool: poolConfig
});
}
}
// Check environment variables as fallback
if (databases.length === 0) {
const envHost = process.env['MYSQL_HOST'];
const envUser = process.env['MYSQL_USER'];
const envPassword = process.env['MYSQL_PASSWORD'];
const envDatabase = process.env['MYSQL_DATABASE'];
const envPort = process.env['MYSQL_PORT'];
const envPoolSize = process.env['MYSQL_POOL_SIZE'];
if (envHost && envUser && envDatabase) {
if (envPoolSize) {
poolConfig.connectionLimit = parseInt(envPoolSize, 10);
}
databases.push({
type: 'mysql',
host: envHost,
port: envPort ? parseInt(envPort, 10) : 3306,
username: envUser,
password: envPassword,
database: envDatabase,
pool: poolConfig
});
}
}
// Check for tool filter in environment
if (!config.toolFilter) {
config.toolFilter = process.env['MYSQL_MCP_TOOL_FILTER'] ?? process.env['TOOL_FILTER'];
}
// Check OAuth environment variables
if (!oauthEnabled && process.env['OAUTH_ENABLED'] === 'true') {
oauthEnabled = true;
}
if (!oauthIssuer) {
oauthIssuer = process.env['OAUTH_ISSUER'];
}
if (!oauthAudience) {
oauthAudience = process.env['OAUTH_AUDIENCE'];
}
if (!oauthJwksUri) {
oauthJwksUri = process.env['OAUTH_JWKS_URI'];
}
if (oauthClockTolerance === undefined && process.env['OAUTH_CLOCK_TOLERANCE']) {
oauthClockTolerance = parseInt(process.env['OAUTH_CLOCK_TOLERANCE'], 10);
}
// Build OAuth config if enabled
let oauth: OAuthConfig | undefined;
if (oauthEnabled) {
oauth = {
enabled: true,
authorizationServerUrl: oauthIssuer,
issuer: oauthIssuer,
audience: oauthAudience,
jwksUri: oauthJwksUri,
clockTolerance: oauthClockTolerance
};
}
return { config, databases, oauth, shouldExit: false };
}
/**
* Print help message
*/
export function printHelp(): void {
console.error(`
mysql-mcp - Enterprise MySQL MCP Server
Usage: mysql-mcp [options]
Connection Options:
--mysql, -m <url> MySQL connection string
(mysql://user:pass@host:port/database)
--mysql-host <host> MySQL host (default: localhost)
--mysql-port <port> MySQL port (default: 3306)
--mysql-user <user> MySQL username
--mysql-password <pass> MySQL password
--mysql-database <db> MySQL database name
Pool Options:
--pool-size <n> Connection pool size (default: 10)
--pool-timeout <ms> Connection acquire timeout (default: 10000)
--pool-queue-limit <n> Queue limit for waiting requests (default: 0)
Server Options:
--transport, -t <type> Transport type: stdio, http, sse (default: stdio)
--port, -p <port> HTTP port for http/sse transports
--tool-filter, -f <filter> Tool filter string (e.g., "-replication,-partitioning")
--name <name> Server name (default: mysql-mcp)
OAuth Options:
--oauth-enabled, -o Enable OAuth 2.0 authentication
--oauth-issuer <url> Authorization server URL (issuer)
--oauth-audience <aud> Expected token audience
--oauth-jwks-uri <url> JWKS URI (auto-discovered from issuer if not set)
--oauth-clock-tolerance <s> Clock tolerance in seconds (default: 60)
Other:
--version, -v Show version
--help, -h Show this help
Environment Variables:
MYSQL_HOST MySQL host
MYSQL_PORT MySQL port
MYSQL_USER MySQL username
MYSQL_PASSWORD MySQL password
MYSQL_DATABASE MySQL database
MYSQL_POOL_SIZE Connection pool size
MYSQL_MCP_TOOL_FILTER Tool filter string
LOG_LEVEL Log level (debug, info, warn, error)
OAUTH_ENABLED Enable OAuth (true/false)
OAUTH_ISSUER Authorization server URL
OAUTH_AUDIENCE Expected token audience
OAUTH_JWKS_URI JWKS endpoint URL
OAUTH_CLOCK_TOLERANCE Clock tolerance in seconds
`);
}