Skip to main content
Glama

Describe table

describe_table

Retrieve 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

TableJSON Schema
NameRequiredDescriptionDefault
connectionNodefault
tableYes
schemaNo

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[];
    }
  • 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",
      }));
    },
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavior. It implies a read-only operation but does not state idempotency, safety, or error handling for missing tables.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence is concise and front-loaded, but overly minimal for a tool with three parameters and no annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, low parameter coverage, and no annotations, the description lacks information on return format, error handling, and parameter usage, making it incomplete for accurate invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% (no parameter descriptions in the schema). The tool description adds no explanation for the three parameters (connection, table, schema), failing to clarify their meanings or constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns column metadata for a table in a configured database connection, distinguishing it from siblings like list_tables (lists tables) and query_db (executes queries).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives, such as query_db or list_tables. No prerequisites or conditions mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marin1321/mcp-devtools'

If you have feedback or need assistance with the MCP directory API, please join our Discord server