@imrieul/mysql-mcp-server 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -662,16 +662,14 @@ async function main() {
662
662
  });
663
663
  const server = createMcpServer(runner, config.readonly, config.maxRows);
664
664
  const transport = new StdioServerTransport();
665
- process.on("SIGINT", async () => {
665
+ const shutdown = async () => {
666
666
  await server.close();
667
667
  await connectionManager.close();
668
668
  process.exit(0);
669
- });
670
- process.on("SIGTERM", async () => {
671
- await server.close();
672
- await connectionManager.close();
673
- process.exit(0);
674
- });
669
+ };
670
+ process.on("SIGINT", shutdown);
671
+ process.on("SIGTERM", shutdown);
672
+ process.stdin.on("end", shutdown);
675
673
  console.error("MySQL MCP Server starting...");
676
674
  console.error(`Readonly mode: ${config.readonly}`);
677
675
  console.error(`Query timeout: ${config.queryTimeout}ms`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/connection.ts","../src/query-runner.ts","../src/server.ts","../src/tools/query.ts","../src/tools/error-hint.ts","../src/tools/execute.ts","../src/tools/list-databases.ts","../src/tools/list-tables.ts","../src/tools/resolve-database.ts","../src/tools/sql-escape.ts","../src/tools/describe-table.ts","../src/tools/format-column.ts","../src/tools/describe-all-tables.ts","../src/tools/add-comment.ts","../src/tools/index.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { resolveConfig } from './config.js';\nimport { createConnectionManager } from './connection.js';\nimport { createQueryRunner } from './query-runner.js';\nimport { createMcpServer } from './server.js';\n\nasync function main(): Promise<void> {\n const config = resolveConfig(process.argv.slice(2));\n const connectionManager = createConnectionManager(config.mysql, { ssl: config.ssl });\n const runner = createQueryRunner(connectionManager.getPool(), {\n readonly: config.readonly,\n queryTimeout: config.queryTimeout,\n });\n\n const server = createMcpServer(runner, config.readonly, config.maxRows);\n const transport = new StdioServerTransport();\n\n process.on('SIGINT', async () => {\n await server.close();\n await connectionManager.close();\n process.exit(0);\n });\n\n process.on('SIGTERM', async () => {\n await server.close();\n await connectionManager.close();\n process.exit(0);\n });\n\n console.error('MySQL MCP Server starting...');\n console.error(`Readonly mode: ${config.readonly}`);\n console.error(`Query timeout: ${config.queryTimeout}ms`);\n console.error(`SSL: ${config.ssl}`);\n\n await server.connect(transport);\n console.error('MySQL MCP Server connected via stdio');\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n","export interface MySQLConfig {\n host: string;\n port: number;\n user: string;\n password: string;\n database?: string;\n}\n\nexport interface AppConfig {\n mysql: MySQLConfig;\n readonly: boolean;\n maxRows: number;\n queryTimeout: number;\n ssl: boolean;\n}\n\nexport function parseConnectionString(connStr: string): MySQLConfig {\n let url: URL;\n try {\n url = new URL(connStr);\n } catch {\n throw new Error(`Invalid connection string: ${connStr}`);\n }\n\n if (url.protocol !== 'mysql:') {\n throw new Error(`Expected mysql:// protocol, got ${url.protocol}`);\n }\n\n const database = url.pathname.slice(1) || undefined;\n\n return {\n host: url.hostname,\n port: url.port ? parseInt(url.port, 10) : 3306,\n user: decodeURIComponent(url.username),\n password: decodeURIComponent(url.password),\n database,\n };\n}\n\nexport function parseEnvConfig(env: Record<string, string | undefined>): MySQLConfig {\n const host = env.MYSQL_HOST;\n const user = env.MYSQL_USER;\n const password = env.MYSQL_PASSWORD;\n\n if (!host) throw new Error('Missing required environment variable: MYSQL_HOST');\n if (!user) throw new Error('Missing required environment variable: MYSQL_USER');\n if (!password) throw new Error('Missing required environment variable: MYSQL_PASSWORD');\n\n return {\n host,\n port: env.MYSQL_PORT ? parseInt(env.MYSQL_PORT, 10) : 3306,\n user,\n password,\n database: env.MYSQL_DATABASE || undefined,\n };\n}\n\nexport function parseArgs(argv: string[]): { connectionString?: string; readonly: boolean } {\n let connectionString: string | undefined;\n let readonly = false;\n\n for (const arg of argv) {\n if (arg === '--readonly') {\n readonly = true;\n } else if (arg.startsWith('mysql://')) {\n connectionString = arg;\n }\n }\n\n return { connectionString, readonly };\n}\n\nexport function resolveConfig(argv: string[], env: Record<string, string | undefined> = process.env): AppConfig {\n const args = parseArgs(argv);\n\n const mysql = args.connectionString ? parseConnectionString(args.connectionString) : parseEnvConfig(env);\n\n const readonly = args.readonly || env.MYSQL_READONLY === 'true';\n const maxRows = env.MYSQL_MAX_ROWS ? parseInt(env.MYSQL_MAX_ROWS, 10) : 100;\n const queryTimeout = env.MYSQL_QUERY_TIMEOUT !== undefined ? parseInt(env.MYSQL_QUERY_TIMEOUT, 10) : 30000;\n const ssl = env.MYSQL_SSL === 'true';\n\n return { mysql, readonly, maxRows, queryTimeout, ssl };\n}\n","import mysql from 'mysql2/promise';\nimport type { Pool } from 'mysql2/promise';\nimport type { MySQLConfig } from './config.js';\n\nexport interface ConnectionManager {\n getPool(): Pool;\n close(): Promise<void>;\n}\n\nexport interface ConnectionOptions {\n ssl?: boolean;\n}\n\nexport function createConnectionManager(config: MySQLConfig, options?: ConnectionOptions): ConnectionManager {\n const poolOptions: mysql.PoolOptions = {\n host: config.host,\n port: config.port,\n user: config.user,\n password: config.password,\n database: config.database,\n connectionLimit: 5,\n waitForConnections: true,\n };\n\n if (options?.ssl) {\n poolOptions.ssl = { rejectUnauthorized: true };\n }\n\n const pool = mysql.createPool(poolOptions);\n\n return {\n getPool() {\n return pool;\n },\n async close() {\n await pool.end();\n },\n };\n}\n","import type { Pool } from 'mysql2/promise';\n\ntype QueryFn = (sql: string) => Promise<[unknown, unknown]>;\n\nexport interface QueryRunner {\n query(sql: string): Promise<[unknown, unknown]>;\n withConnection<T>(fn: (query: QueryFn) => Promise<T>): Promise<T>;\n}\n\nexport class QueryTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Query timeout after ${timeoutMs}ms`);\n this.name = 'QueryTimeoutError';\n }\n}\n\nexport interface QueryRunnerOptions {\n readonly: boolean;\n queryTimeout: number;\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n if (timeoutMs <= 0) return promise;\n\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => setTimeout(() => reject(new QueryTimeoutError(timeoutMs)), timeoutMs)),\n ]);\n}\n\nexport function createQueryRunner(pool: Pool, options: QueryRunnerOptions): QueryRunner {\n const { readonly, queryTimeout } = options;\n\n return {\n async query(sql: string): Promise<[unknown, unknown]> {\n if (!readonly) {\n return withTimeout(pool.query(sql) as Promise<[unknown, unknown]>, queryTimeout);\n }\n\n const conn = await pool.getConnection();\n try {\n await conn.query('SET SESSION TRANSACTION READ ONLY');\n await conn.beginTransaction();\n const result = await withTimeout(conn.query(sql) as Promise<[unknown, unknown]>, queryTimeout);\n await conn.rollback();\n return result;\n } catch (error) {\n try {\n await conn.rollback();\n } catch {\n // rollback 실패 무시\n }\n throw error;\n } finally {\n conn.release();\n }\n },\n\n async withConnection<T>(fn: (query: QueryFn) => Promise<T>): Promise<T> {\n const conn = await pool.getConnection();\n try {\n if (readonly) {\n await conn.query('SET SESSION TRANSACTION READ ONLY');\n await conn.beginTransaction();\n }\n\n const queryFn: QueryFn = (sql: string) =>\n withTimeout(conn.query(sql) as Promise<[unknown, unknown]>, queryTimeout);\n\n const result = await fn(queryFn);\n\n if (readonly) {\n await conn.rollback();\n }\n\n return result;\n } catch (error) {\n if (readonly) {\n try {\n await conn.rollback();\n } catch {\n // rollback 실패 무시\n }\n }\n throw error;\n } finally {\n conn.release();\n }\n },\n };\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { QueryRunner } from './query-runner.js';\nimport { registerAllTools } from './tools/index.js';\n\nexport function createMcpServer(runner: QueryRunner, readonly: boolean, maxRows: number): McpServer {\n const server = new McpServer({\n name: '@imrieul/mysql-mcp-server',\n version: '0.1.0',\n });\n\n registerAllTools(server, runner, readonly, maxRows);\n\n return server;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\n\nexport const queryToolName = 'query';\n\nexport const queryToolConfig = {\n title: 'Query',\n description: 'Execute a read-only SQL query (SELECT, SHOW, DESCRIBE, EXPLAIN).',\n inputSchema: {\n sql: z\n .string()\n .describe(\n 'The SQL query to execute. Only SELECT, SHOW, DESCRIBE, EXPLAIN, and WITH (CTE) statements are allowed.',\n ),\n },\n};\n\nconst ALLOWED_PREFIXES = ['SELECT', 'SHOW', 'DESCRIBE', 'EXPLAIN', 'WITH'];\nconst LIMIT_PREFIXES = ['SELECT', 'WITH'];\n\nfunction needsLimit(normalized: string): boolean {\n if (!LIMIT_PREFIXES.some((p) => normalized.startsWith(p))) return false;\n return !/\\bLIMIT\\b/i.test(normalized);\n}\n\nexport function createQueryHandler(runner: QueryRunner, maxRows: number) {\n return async ({ sql }: { sql: string }) => {\n const normalized = sql.trim().toUpperCase();\n const isAllowed = ALLOWED_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n\n if (!isAllowed) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Only SELECT, SHOW, DESCRIBE, EXPLAIN queries are allowed. Use the \"execute\" tool for data modification.',\n },\n ],\n };\n }\n\n try {\n const finalSql = needsLimit(normalized) ? `${sql.trim()} LIMIT ${maxRows}` : sql;\n const [rows] = await runner.query(finalSql);\n const arr = rows as Record<string, unknown>[];\n if (arr.length === 0) {\n return { content: [{ type: 'text' as const, text: '(empty)' }] };\n }\n const cols = Object.keys(arr[0]);\n const data = arr.map((r) => cols.map((c) => r[c]));\n return {\n content: [{ type: 'text' as const, text: JSON.stringify({ columns: cols, rows: data }) }],\n };\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","const HINTS: [RegExp, string][] = [\n [/Table '.*' doesn't exist/i, 'Hint: use list_tables to check available tables.'],\n [/Unknown column/i, 'Hint: use describe_table to check column names.'],\n [/Unknown database/i, 'Hint: use list_databases to check available databases.'],\n [/Access denied/i, 'Hint: check database user permissions.'],\n [/ECONNREFUSED|ETIMEDOUT|ENOTFOUND/i, 'Hint: check MYSQL_HOST and MYSQL_PORT settings.'],\n [/ER_PARSE_ERROR/i, 'Hint: check SQL syntax.'],\n [/Query timeout/i, 'Hint: increase MYSQL_QUERY_TIMEOUT or optimize the query.'],\n];\n\nexport function formatError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const hint = HINTS.find(([pattern]) => pattern.test(message));\n return hint ? `Error: ${message}\\n${hint[1]}` : `Error: ${message}`;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\n\nexport const executeToolName = 'execute';\n\nexport const executeToolConfig = {\n title: 'Execute',\n description: 'Execute a data modification SQL statement (INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, etc.).',\n inputSchema: {\n sql: z\n .string()\n .describe('The SQL statement to execute. SELECT statements are not allowed here; use the \"query\" tool instead.'),\n },\n};\n\nexport function createExecuteHandler(runner: QueryRunner, isReadonly: boolean) {\n return async ({ sql }: { sql: string }) => {\n if (isReadonly) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Server is in read-only mode. Data modification is not allowed.',\n },\n ],\n };\n }\n\n const normalized = sql.trim().toUpperCase();\n if (normalized.startsWith('SELECT') || normalized.startsWith('WITH')) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Use the \"query\" tool for SELECT statements.',\n },\n ],\n };\n }\n\n try {\n const [result] = await runner.query(sql);\n const r = result as unknown as Record<string, unknown>;\n return {\n content: [\n { type: 'text' as const, text: `affectedRows: ${r.affectedRows}, changedRows: ${r.changedRows ?? 0}` },\n ],\n };\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\n\nexport const listDatabasesToolName = 'list_databases';\n\nexport const listDatabasesToolConfig = {\n title: 'List Databases',\n description: 'List all databases on the MySQL server.',\n};\n\nexport function createListDatabasesHandler(runner: QueryRunner) {\n return async () => {\n try {\n const [rows] = await runner.query('SHOW DATABASES');\n const databases = (rows as Record<string, string>[]).map((r) => Object.values(r)[0]);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(databases) }],\n };\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue } from './sql-escape.js';\n\nexport const listTablesToolName = 'list_tables';\n\nexport const listTablesToolConfig = {\n title: 'List Tables',\n description: 'List all tables in the specified database (or the current database if not specified).',\n inputSchema: {\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createListTablesHandler(runner: QueryRunner) {\n return async ({ database }: { database?: string }) => {\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const sql = `SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = ${quoteStringValue(db)} ORDER BY TABLE_NAME`;\n const [rows] = await query(sql);\n const lines = (rows as Record<string, string>[]).map((r) => {\n const comment = r.TABLE_COMMENT;\n return comment ? `${r.TABLE_NAME} -- ${comment}` : r.TABLE_NAME;\n });\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","type QueryFn = (sql: string) => Promise<[unknown, unknown]>;\n\nexport async function resolveDatabase(query: QueryFn, database?: string): Promise<string | null> {\n if (database) return database;\n const [rows] = await query('SELECT DATABASE() AS db');\n const db = (rows as Record<string, unknown>[])[0]?.db;\n return typeof db === 'string' ? db : null;\n}\n","export function escapeStringValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"''\");\n}\n\nexport function quoteStringValue(value: string): string {\n return `'${escapeStringValue(value)}'`;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue } from './sql-escape.js';\nimport { formatColumn } from './format-column.js';\n\nexport const describeTableToolName = 'describe_table';\n\nexport const describeTableToolConfig = {\n title: 'Describe Table',\n description: 'Show the schema/structure of a table, including column names, types, constraints, and comments.',\n inputSchema: {\n table: z.string().describe('Table name to describe.'),\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createDescribeTableHandler(runner: QueryRunner) {\n return async ({ table, database }: { table: string; database?: string }) => {\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const sql = `SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${quoteStringValue(db)} AND TABLE_NAME = ${quoteStringValue(table)} ORDER BY ORDINAL_POSITION`;\n const [rows] = await query(sql);\n const typedRows = rows as Record<string, unknown>[];\n\n if (typedRows.length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: `Error: Table '${table}' doesn't exist in database '${db}'.\\nHint: use list_tables to check available tables.`,\n },\n ],\n };\n }\n\n const columns = typedRows.map((r) =>\n formatColumn({\n name: String(r.COLUMN_NAME),\n type: String(r.COLUMN_TYPE),\n nullable: r.IS_NULLABLE === 'YES',\n key: String(r.COLUMN_KEY ?? ''),\n defaultValue: r.COLUMN_DEFAULT,\n extra: String(r.EXTRA ?? ''),\n comment: String(r.COLUMN_COMMENT ?? ''),\n }),\n );\n return {\n content: [{ type: 'text' as const, text: `${table}:\\n${columns.join('\\n')}` }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","export interface ColumnInfo {\n name: string;\n type: string;\n nullable: boolean;\n key: string;\n defaultValue: unknown;\n extra: string;\n comment: string;\n}\n\nexport function formatColumn(col: ColumnInfo): string {\n let result = `${col.name} ${col.type}`;\n if (!col.nullable) result += ' NOT NULL';\n if (col.key === 'PRI') result += ' PK';\n else if (col.key === 'UNI') result += ' UNIQUE';\n else if (col.key === 'MUL') result += ' INDEX';\n if (col.defaultValue != null) result += ` DEFAULT ${col.defaultValue}`;\n if (col.extra) result += ` ${col.extra}`;\n if (col.comment) result += ` -- ${col.comment}`;\n return result;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue } from './sql-escape.js';\nimport { formatColumn } from './format-column.js';\n\nexport const describeAllTablesToolName = 'describe_all_tables';\n\nexport const describeAllTablesToolConfig = {\n title: 'Describe All Tables',\n description:\n 'Show the schema of all tables at once. Much more efficient than calling describe_table for each table individually.',\n inputSchema: {\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createDescribeAllTablesHandler(runner: QueryRunner) {\n return async ({ database }: { database?: string }) => {\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const sql = `SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${quoteStringValue(db)} ORDER BY TABLE_NAME, ORDINAL_POSITION`;\n const [rows] = await query(sql);\n const typedRows = rows as Record<string, unknown>[];\n\n if (typedRows.length === 0) {\n return { content: [{ type: 'text' as const, text: '(no tables)' }] };\n }\n\n const tableMap = new Map<string, string[]>();\n for (const r of typedRows) {\n const tableName = String(r.TABLE_NAME);\n const line = formatColumn({\n name: String(r.COLUMN_NAME),\n type: String(r.COLUMN_TYPE),\n nullable: r.IS_NULLABLE === 'YES',\n key: String(r.COLUMN_KEY ?? ''),\n defaultValue: r.COLUMN_DEFAULT,\n extra: String(r.EXTRA ?? ''),\n comment: String(r.COLUMN_COMMENT ?? ''),\n });\n if (!tableMap.has(tableName)) {\n tableMap.set(tableName, []);\n }\n tableMap.get(tableName)!.push(line);\n }\n\n const parts = Array.from(tableMap.entries()).map(([table, lines]) => `${table}:\\n${lines.join('\\n')}`);\n\n return {\n content: [{ type: 'text' as const, text: parts.join('\\n\\n') }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue, escapeStringValue } from './sql-escape.js';\n\nexport const addCommentToolName = 'add_comment';\n\nexport const addCommentToolConfig = {\n title: 'Add Comment',\n description:\n 'Safely add a comment to a table or column. This tool only modifies comments — it cannot alter table structure, column types, or data.',\n inputSchema: {\n table: z.string().describe('Table name.'),\n column: z.string().optional().describe('Column name. If omitted, sets a table-level comment.'),\n comment: z.string().describe('Comment text to set.'),\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createAddCommentHandler(runner: QueryRunner, isReadonly: boolean) {\n return async ({\n table,\n column,\n comment,\n database,\n }: {\n table: string;\n column?: string;\n comment: string;\n database?: string;\n }) => {\n if (isReadonly) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Server is in read-only mode. Modifying comments is not allowed.',\n },\n ],\n };\n }\n\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const fullName = `\\`${db}\\`.\\`${table}\\``;\n const escapedComment = escapeStringValue(comment);\n\n if (!column) {\n const sql = `ALTER TABLE ${fullName} COMMENT = '${escapedComment}'`;\n await query(sql);\n return {\n content: [{ type: 'text' as const, text: `Table comment updated: ${table}` }],\n };\n }\n\n const colSql = `SELECT COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${quoteStringValue(db)} AND TABLE_NAME = ${quoteStringValue(table)} AND COLUMN_NAME = ${quoteStringValue(column)}`;\n const [rows] = await query(colSql);\n const colInfo = (rows as Record<string, unknown>[])[0];\n\n if (!colInfo) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: `Error: Column '${column}' doesn't exist in table '${table}'.\\nHint: use describe_table to check available columns.`,\n },\n ],\n };\n }\n\n let modifySql = `ALTER TABLE ${fullName} MODIFY COLUMN \\`${column}\\` ${colInfo.COLUMN_TYPE}`;\n if (colInfo.IS_NULLABLE === 'NO') modifySql += ' NOT NULL';\n if (colInfo.COLUMN_DEFAULT != null)\n modifySql += ` DEFAULT '${escapeStringValue(String(colInfo.COLUMN_DEFAULT))}'`;\n if (colInfo.EXTRA) modifySql += ` ${colInfo.EXTRA}`;\n modifySql += ` COMMENT '${escapedComment}'`;\n\n await query(modifySql);\n return {\n content: [{ type: 'text' as const, text: `Column comment updated: ${table}.${column}` }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { QueryRunner } from '../query-runner.js';\nimport { queryToolName, queryToolConfig, createQueryHandler } from './query.js';\nimport { executeToolName, executeToolConfig, createExecuteHandler } from './execute.js';\nimport { listDatabasesToolName, listDatabasesToolConfig, createListDatabasesHandler } from './list-databases.js';\nimport { listTablesToolName, listTablesToolConfig, createListTablesHandler } from './list-tables.js';\nimport { describeTableToolName, describeTableToolConfig, createDescribeTableHandler } from './describe-table.js';\nimport {\n describeAllTablesToolName,\n describeAllTablesToolConfig,\n createDescribeAllTablesHandler,\n} from './describe-all-tables.js';\nimport { addCommentToolName, addCommentToolConfig, createAddCommentHandler } from './add-comment.js';\n\nexport function registerAllTools(server: McpServer, runner: QueryRunner, readonly: boolean, maxRows: number): void {\n server.tool(\n queryToolName,\n queryToolConfig.description,\n queryToolConfig.inputSchema,\n createQueryHandler(runner, maxRows),\n );\n server.tool(\n executeToolName,\n executeToolConfig.description,\n executeToolConfig.inputSchema,\n createExecuteHandler(runner, readonly),\n );\n server.tool(listDatabasesToolName, listDatabasesToolConfig.description, createListDatabasesHandler(runner));\n server.tool(\n listTablesToolName,\n listTablesToolConfig.description,\n listTablesToolConfig.inputSchema,\n createListTablesHandler(runner),\n );\n server.tool(\n describeTableToolName,\n describeTableToolConfig.description,\n describeTableToolConfig.inputSchema,\n createDescribeTableHandler(runner),\n );\n server.tool(\n describeAllTablesToolName,\n describeAllTablesToolConfig.description,\n describeAllTablesToolConfig.inputSchema,\n createDescribeAllTablesHandler(runner),\n );\n server.tool(\n addCommentToolName,\n addCommentToolConfig.description,\n addCommentToolConfig.inputSchema,\n createAddCommentHandler(runner, readonly),\n );\n}\n"],"mappings":"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","names":["mysql","z","z","z","z","z","z","z","z","z","z"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/connection.ts","../src/query-runner.ts","../src/server.ts","../src/tools/query.ts","../src/tools/error-hint.ts","../src/tools/execute.ts","../src/tools/list-databases.ts","../src/tools/list-tables.ts","../src/tools/resolve-database.ts","../src/tools/sql-escape.ts","../src/tools/describe-table.ts","../src/tools/format-column.ts","../src/tools/describe-all-tables.ts","../src/tools/add-comment.ts","../src/tools/index.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { resolveConfig } from './config.js';\nimport { createConnectionManager } from './connection.js';\nimport { createQueryRunner } from './query-runner.js';\nimport { createMcpServer } from './server.js';\n\nasync function main(): Promise<void> {\n const config = resolveConfig(process.argv.slice(2));\n const connectionManager = createConnectionManager(config.mysql, { ssl: config.ssl });\n const runner = createQueryRunner(connectionManager.getPool(), {\n readonly: config.readonly,\n queryTimeout: config.queryTimeout,\n });\n\n const server = createMcpServer(runner, config.readonly, config.maxRows);\n const transport = new StdioServerTransport();\n\n const shutdown = async () => {\n await server.close();\n await connectionManager.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n process.stdin.on('end', shutdown);\n\n console.error('MySQL MCP Server starting...');\n console.error(`Readonly mode: ${config.readonly}`);\n console.error(`Query timeout: ${config.queryTimeout}ms`);\n console.error(`SSL: ${config.ssl}`);\n\n await server.connect(transport);\n console.error('MySQL MCP Server connected via stdio');\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n","export interface MySQLConfig {\n host: string;\n port: number;\n user: string;\n password: string;\n database?: string;\n}\n\nexport interface AppConfig {\n mysql: MySQLConfig;\n readonly: boolean;\n maxRows: number;\n queryTimeout: number;\n ssl: boolean;\n}\n\nexport function parseConnectionString(connStr: string): MySQLConfig {\n let url: URL;\n try {\n url = new URL(connStr);\n } catch {\n throw new Error(`Invalid connection string: ${connStr}`);\n }\n\n if (url.protocol !== 'mysql:') {\n throw new Error(`Expected mysql:// protocol, got ${url.protocol}`);\n }\n\n const database = url.pathname.slice(1) || undefined;\n\n return {\n host: url.hostname,\n port: url.port ? parseInt(url.port, 10) : 3306,\n user: decodeURIComponent(url.username),\n password: decodeURIComponent(url.password),\n database,\n };\n}\n\nexport function parseEnvConfig(env: Record<string, string | undefined>): MySQLConfig {\n const host = env.MYSQL_HOST;\n const user = env.MYSQL_USER;\n const password = env.MYSQL_PASSWORD;\n\n if (!host) throw new Error('Missing required environment variable: MYSQL_HOST');\n if (!user) throw new Error('Missing required environment variable: MYSQL_USER');\n if (!password) throw new Error('Missing required environment variable: MYSQL_PASSWORD');\n\n return {\n host,\n port: env.MYSQL_PORT ? parseInt(env.MYSQL_PORT, 10) : 3306,\n user,\n password,\n database: env.MYSQL_DATABASE || undefined,\n };\n}\n\nexport function parseArgs(argv: string[]): { connectionString?: string; readonly: boolean } {\n let connectionString: string | undefined;\n let readonly = false;\n\n for (const arg of argv) {\n if (arg === '--readonly') {\n readonly = true;\n } else if (arg.startsWith('mysql://')) {\n connectionString = arg;\n }\n }\n\n return { connectionString, readonly };\n}\n\nexport function resolveConfig(argv: string[], env: Record<string, string | undefined> = process.env): AppConfig {\n const args = parseArgs(argv);\n\n const mysql = args.connectionString ? parseConnectionString(args.connectionString) : parseEnvConfig(env);\n\n const readonly = args.readonly || env.MYSQL_READONLY === 'true';\n const maxRows = env.MYSQL_MAX_ROWS ? parseInt(env.MYSQL_MAX_ROWS, 10) : 100;\n const queryTimeout = env.MYSQL_QUERY_TIMEOUT !== undefined ? parseInt(env.MYSQL_QUERY_TIMEOUT, 10) : 30000;\n const ssl = env.MYSQL_SSL === 'true';\n\n return { mysql, readonly, maxRows, queryTimeout, ssl };\n}\n","import mysql from 'mysql2/promise';\nimport type { Pool } from 'mysql2/promise';\nimport type { MySQLConfig } from './config.js';\n\nexport interface ConnectionManager {\n getPool(): Pool;\n close(): Promise<void>;\n}\n\nexport interface ConnectionOptions {\n ssl?: boolean;\n}\n\nexport function createConnectionManager(config: MySQLConfig, options?: ConnectionOptions): ConnectionManager {\n const poolOptions: mysql.PoolOptions = {\n host: config.host,\n port: config.port,\n user: config.user,\n password: config.password,\n database: config.database,\n connectionLimit: 5,\n waitForConnections: true,\n };\n\n if (options?.ssl) {\n poolOptions.ssl = { rejectUnauthorized: true };\n }\n\n const pool = mysql.createPool(poolOptions);\n\n return {\n getPool() {\n return pool;\n },\n async close() {\n await pool.end();\n },\n };\n}\n","import type { Pool } from 'mysql2/promise';\n\ntype QueryFn = (sql: string) => Promise<[unknown, unknown]>;\n\nexport interface QueryRunner {\n query(sql: string): Promise<[unknown, unknown]>;\n withConnection<T>(fn: (query: QueryFn) => Promise<T>): Promise<T>;\n}\n\nexport class QueryTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Query timeout after ${timeoutMs}ms`);\n this.name = 'QueryTimeoutError';\n }\n}\n\nexport interface QueryRunnerOptions {\n readonly: boolean;\n queryTimeout: number;\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n if (timeoutMs <= 0) return promise;\n\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => setTimeout(() => reject(new QueryTimeoutError(timeoutMs)), timeoutMs)),\n ]);\n}\n\nexport function createQueryRunner(pool: Pool, options: QueryRunnerOptions): QueryRunner {\n const { readonly, queryTimeout } = options;\n\n return {\n async query(sql: string): Promise<[unknown, unknown]> {\n if (!readonly) {\n return withTimeout(pool.query(sql) as Promise<[unknown, unknown]>, queryTimeout);\n }\n\n const conn = await pool.getConnection();\n try {\n await conn.query('SET SESSION TRANSACTION READ ONLY');\n await conn.beginTransaction();\n const result = await withTimeout(conn.query(sql) as Promise<[unknown, unknown]>, queryTimeout);\n await conn.rollback();\n return result;\n } catch (error) {\n try {\n await conn.rollback();\n } catch {\n // rollback 실패 무시\n }\n throw error;\n } finally {\n conn.release();\n }\n },\n\n async withConnection<T>(fn: (query: QueryFn) => Promise<T>): Promise<T> {\n const conn = await pool.getConnection();\n try {\n if (readonly) {\n await conn.query('SET SESSION TRANSACTION READ ONLY');\n await conn.beginTransaction();\n }\n\n const queryFn: QueryFn = (sql: string) =>\n withTimeout(conn.query(sql) as Promise<[unknown, unknown]>, queryTimeout);\n\n const result = await fn(queryFn);\n\n if (readonly) {\n await conn.rollback();\n }\n\n return result;\n } catch (error) {\n if (readonly) {\n try {\n await conn.rollback();\n } catch {\n // rollback 실패 무시\n }\n }\n throw error;\n } finally {\n conn.release();\n }\n },\n };\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { QueryRunner } from './query-runner.js';\nimport { registerAllTools } from './tools/index.js';\n\nexport function createMcpServer(runner: QueryRunner, readonly: boolean, maxRows: number): McpServer {\n const server = new McpServer({\n name: '@imrieul/mysql-mcp-server',\n version: '0.1.0',\n });\n\n registerAllTools(server, runner, readonly, maxRows);\n\n return server;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\n\nexport const queryToolName = 'query';\n\nexport const queryToolConfig = {\n title: 'Query',\n description: 'Execute a read-only SQL query (SELECT, SHOW, DESCRIBE, EXPLAIN).',\n inputSchema: {\n sql: z\n .string()\n .describe(\n 'The SQL query to execute. Only SELECT, SHOW, DESCRIBE, EXPLAIN, and WITH (CTE) statements are allowed.',\n ),\n },\n};\n\nconst ALLOWED_PREFIXES = ['SELECT', 'SHOW', 'DESCRIBE', 'EXPLAIN', 'WITH'];\nconst LIMIT_PREFIXES = ['SELECT', 'WITH'];\n\nfunction needsLimit(normalized: string): boolean {\n if (!LIMIT_PREFIXES.some((p) => normalized.startsWith(p))) return false;\n return !/\\bLIMIT\\b/i.test(normalized);\n}\n\nexport function createQueryHandler(runner: QueryRunner, maxRows: number) {\n return async ({ sql }: { sql: string }) => {\n const normalized = sql.trim().toUpperCase();\n const isAllowed = ALLOWED_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n\n if (!isAllowed) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Only SELECT, SHOW, DESCRIBE, EXPLAIN queries are allowed. Use the \"execute\" tool for data modification.',\n },\n ],\n };\n }\n\n try {\n const finalSql = needsLimit(normalized) ? `${sql.trim()} LIMIT ${maxRows}` : sql;\n const [rows] = await runner.query(finalSql);\n const arr = rows as Record<string, unknown>[];\n if (arr.length === 0) {\n return { content: [{ type: 'text' as const, text: '(empty)' }] };\n }\n const cols = Object.keys(arr[0]);\n const data = arr.map((r) => cols.map((c) => r[c]));\n return {\n content: [{ type: 'text' as const, text: JSON.stringify({ columns: cols, rows: data }) }],\n };\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","const HINTS: [RegExp, string][] = [\n [/Table '.*' doesn't exist/i, 'Hint: use list_tables to check available tables.'],\n [/Unknown column/i, 'Hint: use describe_table to check column names.'],\n [/Unknown database/i, 'Hint: use list_databases to check available databases.'],\n [/Access denied/i, 'Hint: check database user permissions.'],\n [/ECONNREFUSED|ETIMEDOUT|ENOTFOUND/i, 'Hint: check MYSQL_HOST and MYSQL_PORT settings.'],\n [/ER_PARSE_ERROR/i, 'Hint: check SQL syntax.'],\n [/Query timeout/i, 'Hint: increase MYSQL_QUERY_TIMEOUT or optimize the query.'],\n];\n\nexport function formatError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const hint = HINTS.find(([pattern]) => pattern.test(message));\n return hint ? `Error: ${message}\\n${hint[1]}` : `Error: ${message}`;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\n\nexport const executeToolName = 'execute';\n\nexport const executeToolConfig = {\n title: 'Execute',\n description: 'Execute a data modification SQL statement (INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, etc.).',\n inputSchema: {\n sql: z\n .string()\n .describe('The SQL statement to execute. SELECT statements are not allowed here; use the \"query\" tool instead.'),\n },\n};\n\nexport function createExecuteHandler(runner: QueryRunner, isReadonly: boolean) {\n return async ({ sql }: { sql: string }) => {\n if (isReadonly) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Server is in read-only mode. Data modification is not allowed.',\n },\n ],\n };\n }\n\n const normalized = sql.trim().toUpperCase();\n if (normalized.startsWith('SELECT') || normalized.startsWith('WITH')) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Use the \"query\" tool for SELECT statements.',\n },\n ],\n };\n }\n\n try {\n const [result] = await runner.query(sql);\n const r = result as unknown as Record<string, unknown>;\n return {\n content: [\n { type: 'text' as const, text: `affectedRows: ${r.affectedRows}, changedRows: ${r.changedRows ?? 0}` },\n ],\n };\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\n\nexport const listDatabasesToolName = 'list_databases';\n\nexport const listDatabasesToolConfig = {\n title: 'List Databases',\n description: 'List all databases on the MySQL server.',\n};\n\nexport function createListDatabasesHandler(runner: QueryRunner) {\n return async () => {\n try {\n const [rows] = await runner.query('SHOW DATABASES');\n const databases = (rows as Record<string, string>[]).map((r) => Object.values(r)[0]);\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(databases) }],\n };\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue } from './sql-escape.js';\n\nexport const listTablesToolName = 'list_tables';\n\nexport const listTablesToolConfig = {\n title: 'List Tables',\n description: 'List all tables in the specified database (or the current database if not specified).',\n inputSchema: {\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createListTablesHandler(runner: QueryRunner) {\n return async ({ database }: { database?: string }) => {\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const sql = `SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = ${quoteStringValue(db)} ORDER BY TABLE_NAME`;\n const [rows] = await query(sql);\n const lines = (rows as Record<string, string>[]).map((r) => {\n const comment = r.TABLE_COMMENT;\n return comment ? `${r.TABLE_NAME} -- ${comment}` : r.TABLE_NAME;\n });\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","type QueryFn = (sql: string) => Promise<[unknown, unknown]>;\n\nexport async function resolveDatabase(query: QueryFn, database?: string): Promise<string | null> {\n if (database) return database;\n const [rows] = await query('SELECT DATABASE() AS db');\n const db = (rows as Record<string, unknown>[])[0]?.db;\n return typeof db === 'string' ? db : null;\n}\n","export function escapeStringValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"''\");\n}\n\nexport function quoteStringValue(value: string): string {\n return `'${escapeStringValue(value)}'`;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue } from './sql-escape.js';\nimport { formatColumn } from './format-column.js';\n\nexport const describeTableToolName = 'describe_table';\n\nexport const describeTableToolConfig = {\n title: 'Describe Table',\n description: 'Show the schema/structure of a table, including column names, types, constraints, and comments.',\n inputSchema: {\n table: z.string().describe('Table name to describe.'),\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createDescribeTableHandler(runner: QueryRunner) {\n return async ({ table, database }: { table: string; database?: string }) => {\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const sql = `SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${quoteStringValue(db)} AND TABLE_NAME = ${quoteStringValue(table)} ORDER BY ORDINAL_POSITION`;\n const [rows] = await query(sql);\n const typedRows = rows as Record<string, unknown>[];\n\n if (typedRows.length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: `Error: Table '${table}' doesn't exist in database '${db}'.\\nHint: use list_tables to check available tables.`,\n },\n ],\n };\n }\n\n const columns = typedRows.map((r) =>\n formatColumn({\n name: String(r.COLUMN_NAME),\n type: String(r.COLUMN_TYPE),\n nullable: r.IS_NULLABLE === 'YES',\n key: String(r.COLUMN_KEY ?? ''),\n defaultValue: r.COLUMN_DEFAULT,\n extra: String(r.EXTRA ?? ''),\n comment: String(r.COLUMN_COMMENT ?? ''),\n }),\n );\n return {\n content: [{ type: 'text' as const, text: `${table}:\\n${columns.join('\\n')}` }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","export interface ColumnInfo {\n name: string;\n type: string;\n nullable: boolean;\n key: string;\n defaultValue: unknown;\n extra: string;\n comment: string;\n}\n\nexport function formatColumn(col: ColumnInfo): string {\n let result = `${col.name} ${col.type}`;\n if (!col.nullable) result += ' NOT NULL';\n if (col.key === 'PRI') result += ' PK';\n else if (col.key === 'UNI') result += ' UNIQUE';\n else if (col.key === 'MUL') result += ' INDEX';\n if (col.defaultValue != null) result += ` DEFAULT ${col.defaultValue}`;\n if (col.extra) result += ` ${col.extra}`;\n if (col.comment) result += ` -- ${col.comment}`;\n return result;\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue } from './sql-escape.js';\nimport { formatColumn } from './format-column.js';\n\nexport const describeAllTablesToolName = 'describe_all_tables';\n\nexport const describeAllTablesToolConfig = {\n title: 'Describe All Tables',\n description:\n 'Show the schema of all tables at once. Much more efficient than calling describe_table for each table individually.',\n inputSchema: {\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createDescribeAllTablesHandler(runner: QueryRunner) {\n return async ({ database }: { database?: string }) => {\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const sql = `SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${quoteStringValue(db)} ORDER BY TABLE_NAME, ORDINAL_POSITION`;\n const [rows] = await query(sql);\n const typedRows = rows as Record<string, unknown>[];\n\n if (typedRows.length === 0) {\n return { content: [{ type: 'text' as const, text: '(no tables)' }] };\n }\n\n const tableMap = new Map<string, string[]>();\n for (const r of typedRows) {\n const tableName = String(r.TABLE_NAME);\n const line = formatColumn({\n name: String(r.COLUMN_NAME),\n type: String(r.COLUMN_TYPE),\n nullable: r.IS_NULLABLE === 'YES',\n key: String(r.COLUMN_KEY ?? ''),\n defaultValue: r.COLUMN_DEFAULT,\n extra: String(r.EXTRA ?? ''),\n comment: String(r.COLUMN_COMMENT ?? ''),\n });\n if (!tableMap.has(tableName)) {\n tableMap.set(tableName, []);\n }\n tableMap.get(tableName)!.push(line);\n }\n\n const parts = Array.from(tableMap.entries()).map(([table, lines]) => `${table}:\\n${lines.join('\\n')}`);\n\n return {\n content: [{ type: 'text' as const, text: parts.join('\\n\\n') }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import { z } from 'zod';\nimport type { QueryRunner } from '../query-runner.js';\nimport { formatError } from './error-hint.js';\nimport { resolveDatabase } from './resolve-database.js';\nimport { quoteStringValue, escapeStringValue } from './sql-escape.js';\n\nexport const addCommentToolName = 'add_comment';\n\nexport const addCommentToolConfig = {\n title: 'Add Comment',\n description:\n 'Safely add a comment to a table or column. This tool only modifies comments — it cannot alter table structure, column types, or data.',\n inputSchema: {\n table: z.string().describe('Table name.'),\n column: z.string().optional().describe('Column name. If omitted, sets a table-level comment.'),\n comment: z.string().describe('Comment text to set.'),\n database: z.string().optional().describe('Database name. Uses the current database if omitted.'),\n },\n};\n\nexport function createAddCommentHandler(runner: QueryRunner, isReadonly: boolean) {\n return async ({\n table,\n column,\n comment,\n database,\n }: {\n table: string;\n column?: string;\n comment: string;\n database?: string;\n }) => {\n if (isReadonly) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: Server is in read-only mode. Modifying comments is not allowed.',\n },\n ],\n };\n }\n\n try {\n return await runner.withConnection(async (query) => {\n const db = await resolveDatabase(query, database);\n if (!db) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.',\n },\n ],\n };\n }\n\n const fullName = `\\`${db}\\`.\\`${table}\\``;\n const escapedComment = escapeStringValue(comment);\n\n if (!column) {\n const sql = `ALTER TABLE ${fullName} COMMENT = '${escapedComment}'`;\n await query(sql);\n return {\n content: [{ type: 'text' as const, text: `Table comment updated: ${table}` }],\n };\n }\n\n const colSql = `SELECT COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ${quoteStringValue(db)} AND TABLE_NAME = ${quoteStringValue(table)} AND COLUMN_NAME = ${quoteStringValue(column)}`;\n const [rows] = await query(colSql);\n const colInfo = (rows as Record<string, unknown>[])[0];\n\n if (!colInfo) {\n return {\n isError: true as const,\n content: [\n {\n type: 'text' as const,\n text: `Error: Column '${column}' doesn't exist in table '${table}'.\\nHint: use describe_table to check available columns.`,\n },\n ],\n };\n }\n\n let modifySql = `ALTER TABLE ${fullName} MODIFY COLUMN \\`${column}\\` ${colInfo.COLUMN_TYPE}`;\n if (colInfo.IS_NULLABLE === 'NO') modifySql += ' NOT NULL';\n if (colInfo.COLUMN_DEFAULT != null)\n modifySql += ` DEFAULT '${escapeStringValue(String(colInfo.COLUMN_DEFAULT))}'`;\n if (colInfo.EXTRA) modifySql += ` ${colInfo.EXTRA}`;\n modifySql += ` COMMENT '${escapedComment}'`;\n\n await query(modifySql);\n return {\n content: [{ type: 'text' as const, text: `Column comment updated: ${table}.${column}` }],\n };\n });\n } catch (error) {\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: formatError(error) }],\n };\n }\n };\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { QueryRunner } from '../query-runner.js';\nimport { queryToolName, queryToolConfig, createQueryHandler } from './query.js';\nimport { executeToolName, executeToolConfig, createExecuteHandler } from './execute.js';\nimport { listDatabasesToolName, listDatabasesToolConfig, createListDatabasesHandler } from './list-databases.js';\nimport { listTablesToolName, listTablesToolConfig, createListTablesHandler } from './list-tables.js';\nimport { describeTableToolName, describeTableToolConfig, createDescribeTableHandler } from './describe-table.js';\nimport {\n describeAllTablesToolName,\n describeAllTablesToolConfig,\n createDescribeAllTablesHandler,\n} from './describe-all-tables.js';\nimport { addCommentToolName, addCommentToolConfig, createAddCommentHandler } from './add-comment.js';\n\nexport function registerAllTools(server: McpServer, runner: QueryRunner, readonly: boolean, maxRows: number): void {\n server.tool(\n queryToolName,\n queryToolConfig.description,\n queryToolConfig.inputSchema,\n createQueryHandler(runner, maxRows),\n );\n server.tool(\n executeToolName,\n executeToolConfig.description,\n executeToolConfig.inputSchema,\n createExecuteHandler(runner, readonly),\n );\n server.tool(listDatabasesToolName, listDatabasesToolConfig.description, createListDatabasesHandler(runner));\n server.tool(\n listTablesToolName,\n listTablesToolConfig.description,\n listTablesToolConfig.inputSchema,\n createListTablesHandler(runner),\n );\n server.tool(\n describeTableToolName,\n describeTableToolConfig.description,\n describeTableToolConfig.inputSchema,\n createDescribeTableHandler(runner),\n );\n server.tool(\n describeAllTablesToolName,\n describeAllTablesToolConfig.description,\n describeAllTablesToolConfig.inputSchema,\n createDescribeAllTablesHandler(runner),\n );\n server.tool(\n addCommentToolName,\n addCommentToolConfig.description,\n addCommentToolConfig.inputSchema,\n createAddCommentHandler(runner, readonly),\n );\n}\n"],"mappings":"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","names":["mysql","z","z","z","z","z","z","z","z","z","z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imrieul/mysql-mcp-server",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "MySQL MCP Server - Simple Model Context Protocol server for MySQL database operations",
5
5
  "type": "module",
6
6
  "bin": {