describe_table
Display a table's schema including column names, types, constraints, and comments. Check structure before writing queries to avoid errors.
Instructions
Show the schema/structure of a table, including column names, types, constraints, and comments. Use this before writing queries to ensure correct column names and types. For inspecting all tables at once, use describe_all_tables instead.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | Table name to describe. | |
| database | No | Database name. Uses the current database if omitted. |
Implementation Reference
- src/tools/describe-table.ts:23-96 (handler)The main handler function for the describe_table tool. Validates identifiers, resolves the database, queries information_schema.COLUMNS for the table's schema, formats each column using formatColumn(), and returns the result.
export function createDescribeTableHandler(runner: QueryRunner) { return async ({ table, database }: { table: string; database?: string }) => { const tableValidation = validateIdentifier(table, 'Table'); if (!tableValidation.valid) { return { isError: true as const, content: [{ type: 'text' as const, text: tableValidation.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 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`; const [rows] = await query(sql); const typedRows = rows as Record<string, unknown>[]; if (typedRows.length === 0) { return { isError: true as const, content: [ { type: 'text' as const, text: `Error: Table '${table}' doesn't exist in database '${db}'.\nHint: use list_tables to check available tables.`, }, ], }; } const columns = typedRows.map((r) => formatColumn({ name: String(r.COLUMN_NAME), type: String(r.COLUMN_TYPE), nullable: r.IS_NULLABLE === 'YES', key: String(r.COLUMN_KEY ?? ''), defaultValue: r.COLUMN_DEFAULT, extra: String(r.EXTRA ?? ''), comment: String(r.COLUMN_COMMENT ?? ''), }), ); return { content: [{ type: 'text' as const, text: `${table}:\n${columns.join('\n')}` }], }; }); } catch (error) { return { isError: true as const, content: [{ type: 'text' as const, text: formatError(error) }], }; } }; } - src/tools/describe-table.ts:11-21 (schema)Input schema definition for describe_table. Defines 'table' (required string) and 'database' (optional string) parameters with Zod validation.
export const describeTableToolConfig = { title: 'Describe Table', description: 'Show the schema/structure of a table, including column names, types, constraints, and comments. ' + 'Use this before writing queries to ensure correct column names and types. ' + 'For inspecting all tables at once, use describe_all_tables instead.', inputSchema: { table: z.string().describe('Table name to describe.'), database: z.string().optional().describe('Database name. Uses the current database if omitted.'), }, }; - src/tools/index.ts:35-40 (registration)Registration of the describe_table tool on the MCP server using server.tool() with name, description, input schema, and handler.
server.tool( describeTableToolName, describeTableToolConfig.description, describeTableToolConfig.inputSchema, createDescribeTableHandler(runner), ); - src/tools/format-column.ts:11-21 (helper)formatColumn helper used by the handler to format column information (name, type, nullable, key, default, extra, comment) into a readable string.
export function formatColumn(col: ColumnInfo): string { let result = `${col.name} ${col.type}`; if (!col.nullable) result += ' NOT NULL'; if (col.key === 'PRI') result += ' PK'; else if (col.key === 'UNI') result += ' UNIQUE'; else if (col.key === 'MUL') result += ' INDEX'; if (col.defaultValue != null) result += ` DEFAULT ${col.defaultValue}`; if (col.extra) result += ` ${col.extra}`; if (col.comment) result += ` -- ${col.comment}`; return result; }