Describe table
describe_tableRetrieve column metadata including names and types for any table in your connected database. Specify table name optionally with schema to get detailed schema information for development and debugging tasks.
Instructions
Return column metadata for a table in a configured database connection.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| connection | No | default | |
| table | Yes | ||
| schema | No |
Implementation Reference
- The main handler function that validates inputs, retrieves the adapter from the pool, calls adapter.describeTable(), and returns column metadata or throws errors.
export async function describeTableHandler( input: DescribeTableInput, config: McpDevtoolsConfig, ): Promise<ToolResult<DescribeTableOutput>> { if (input.table.trim().length === 0) { throw new ValidationError("table must be a non-empty string"); } if (config.databases[input.connection] === undefined) { throw new ConfigError(`Database connection '${input.connection}' is not configured`, { available: Object.keys(config.databases), }); } const pool = getPool(config); const adapter = await pool.get(input.connection); const columns = await adapter.describeTable(input.table, input.schema); if (columns.length === 0) { const where = input.schema !== undefined ? `${input.schema}.${input.table}` : input.table; throw new DatabaseError(`Table not found: ${where}`, { table: input.table, schema: input.schema ?? null, }); } return ok({ table: input.table, schema: input.schema ?? null, columns, }); } - Zod input schema (connection, table, schema) and TypeScript output interfaces (DescribeTableColumn, DescribeTableOutput).
export const DescribeTableInput = z.object({ connection: z.string().default("default"), table: z.string().min(1), schema: z.string().optional(), }); export type DescribeTableInput = z.infer<typeof DescribeTableInput>; export interface DescribeTableColumn { name: string; dataType: string; nullable: boolean; defaultValue: string | null; isPrimaryKey: boolean; } export interface DescribeTableOutput { table: string; schema: string | null; columns: DescribeTableColumn[]; } - src/tools/index.ts:108-114 (registration)Tool registration via defineTool() with name 'describe_table', linking inputSchema and handler.
defineTool({ name: "describe_table", title: "Describe table", description: "Return column metadata for a table in a configured database connection.", inputSchema: DescribeTableInput, handler: describeTableHandler, }), - Postgres adapter's describeTable implementation querying information_schema.columns and pg_index for primary keys.
async describeTable(table: string, schema = "public"): Promise<ColumnInfo[]> { const result = await this.query( `SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_name = $1 AND table_schema = $2 ORDER BY ordinal_position`, [table, schema], ); const pkResult = await this.query( `SELECT a.attname AS column_name FROM pg_index i JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) WHERE i.indrelid = ($1 || '.' || $2)::regclass AND i.indisprimary`, [schema, table], ).catch(() => ({ rows: [] as Record<string, unknown>[] })); const pkSet = new Set(pkResult.rows.map((r) => r.column_name as string)); return result.rows.map((r) => ({ name: r.column_name as string, dataType: r.data_type as string, nullable: (r.is_nullable as string) === "YES", defaultValue: (r.column_default as string | null) ?? null, isPrimaryKey: pkSet.has(r.column_name as string), })); }, - MySQL adapter's describeTable implementation querying information_schema.columns with optional schema filtering.
async describeTable(table: string, schema?: string): Promise<ColumnInfo[]> { const sql = schema ? `SELECT column_name AS column_name, data_type AS data_type, is_nullable AS is_nullable, column_default AS column_default, column_key AS column_key FROM information_schema.columns WHERE table_name = ? AND table_schema = ? ORDER BY ordinal_position` : `SELECT column_name AS column_name, data_type AS data_type, is_nullable AS is_nullable, column_default AS column_default, column_key AS column_key FROM information_schema.columns WHERE table_name = ? AND table_schema = DATABASE() ORDER BY ordinal_position`; const params = schema ? [table, schema] : [table]; const result = await this.query(sql, params); return result.rows.map((r) => ({ name: r.column_name as string, dataType: r.data_type as string, nullable: (r.is_nullable as string) === "YES", defaultValue: (r.column_default as string | null) ?? null, isPrimaryKey: r.column_key === "PRI", })); },