add_comment
Add a comment to a MySQL table or column. Preview changes with dryRun before execution.
Instructions
Safely add a comment to a table or column. This tool only modifies comments — it cannot alter table structure, column types, or data. Set dryRun=true to preview the generated SQL without executing it. Use describe_table first to verify column names. Not available in read-only mode.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name. | |
| column | No | Column name. If omitted, sets a table-level comment. | |
| comment | Yes | Comment text to set. | |
| database | No | Database name. Uses the current database if omitted. | |
| dryRun | No | If true, returns the generated SQL without executing it. Defaults to false. |
Implementation Reference
- src/tools/add-comment.ts:28-154 (handler)The main handler function for the add_comment tool. Accepts table, column (optional), comment, database (optional), and dryRun parameters. Validates identifiers, resolves the database, then either sets a table-level comment via ALTER TABLE ... COMMENT = '...' or sets a column-level comment by reconstructing the column definition and using ALTER TABLE MODIFY COLUMN. Supports dry-run mode to preview SQL without executing.
export function createAddCommentHandler(runner: QueryRunner, isReadonly: boolean) { return async ({ table, column, comment, database, dryRun, }: { table: string; column?: string; comment: string; database?: string; dryRun?: boolean; }) => { if (isReadonly) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Error: Server is in read-only mode. Modifying comments is not allowed.', }, ], }; } const tableValidation = validateIdentifier(table, 'Table'); if (!tableValidation.valid) { return { isError: true as const, content: [{ type: 'text' as const, text: tableValidation.message! }], }; } if (column) { const columnValidation = validateIdentifier(column, 'Column'); if (!columnValidation.valid) { return { isError: true as const, content: [{ type: 'text' as const, text: columnValidation.message! }], }; } } if (database) { const dbValidation = validateIdentifier(database, 'Database'); if (!dbValidation.valid) { return { isError: true as const, content: [{ type: 'text' as const, text: dbValidation.message! }], }; } } try { return await runner.withConnection(async (query) => { const db = await resolveDatabase(query, database); if (!db) { return { isError: true as const, content: [ { type: 'text' as const, text: 'Error: No database selected. Specify a database name or set MYSQL_DATABASE.', }, ], }; } const fullName = `\`${db}\`.\`${table}\``; const escapedComment = escapeStringValue(comment); if (!column) { const sql = `ALTER TABLE ${fullName} COMMENT = '${escapedComment}'`; if (dryRun) { return { content: [{ type: 'text' as const, text: `[dry-run] SQL preview:\n${sql}` }], }; } await query(sql); return { content: [{ type: 'text' as const, text: `Table comment updated: ${table}` }], }; } 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)}`; const [rows] = await query(colSql); const colInfo = (rows as Record<string, unknown>[])[0]; if (!colInfo) { return { isError: true as const, content: [ { type: 'text' as const, text: `Error: Column '${column}' doesn't exist in table '${table}'.\nHint: use describe_table to check available columns.`, }, ], }; } let modifySql = `ALTER TABLE ${fullName} MODIFY COLUMN \`${column}\` ${colInfo.COLUMN_TYPE}`; if (colInfo.IS_NULLABLE === 'NO') modifySql += ' NOT NULL'; if (colInfo.COLUMN_DEFAULT != null) modifySql += ` DEFAULT '${escapeStringValue(String(colInfo.COLUMN_DEFAULT))}'`; if (colInfo.EXTRA) modifySql += ` ${colInfo.EXTRA}`; modifySql += ` COMMENT '${escapedComment}'`; if (dryRun) { return { content: [{ type: 'text' as const, text: `[dry-run] SQL preview:\n${modifySql}` }], }; } await query(modifySql); return { content: [{ type: 'text' as const, text: `Column comment updated: ${table}.${column}` }], }; }); } catch (error) { return { isError: true as const, content: [{ type: 'text' as const, text: formatError(error) }], }; } }; } - src/tools/add-comment.ts:10-26 (schema)Schema and configuration for the add_comment tool. Defines input parameters: table (required string), column (optional string), comment (required string), database (optional string), dryRun (optional boolean).
export const addCommentToolConfig = { title: 'Add Comment', description: 'Safely add a comment to a table or column. This tool only modifies comments — it cannot alter table structure, column types, or data. ' + 'Set dryRun=true to preview the generated SQL without executing it. ' + 'Use describe_table first to verify column names. Not available in read-only mode.', inputSchema: { table: z.string().describe('Table name.'), column: z.string().optional().describe('Column name. If omitted, sets a table-level comment.'), comment: z.string().describe('Comment text to set.'), database: z.string().optional().describe('Database name. Uses the current database if omitted.'), dryRun: z .boolean() .optional() .describe('If true, returns the generated SQL without executing it. Defaults to false.'), }, }; - src/tools/index.ts:47-52 (registration)Registration of the add_comment tool with the MCP server. Uses addCommentToolName ('add_comment'), its description, input schema, and the handler created by createAddCommentHandler (passing readonly flag).
server.tool( addCommentToolName, addCommentToolConfig.description, addCommentToolConfig.inputSchema, createAddCommentHandler(runner, readonly), ); - src/tools/add-comment.ts:8-8 (helper)The tool name constant 'add_comment' used for registration and identification.
export const addCommentToolName = 'add_comment'; - src/tools/sql-escape.ts:1-7 (helper)SQL escape utilities used by add_comment handler to safely escape comment strings and quoted values before embedding in SQL.
export function escapeStringValue(value: string): string { return value.replace(/\\/g, '\\\\').replace(/'/g, "''"); } export function quoteStringValue(value: string): string { return `'${escapeStringValue(value)}'`; }