Skip to main content
Glama

USQL MCP Server

by jvm
describe-table.ts4.98 kB
/** * describe_table tool - Get schema information for a table */ import { Tool } from "@modelcontextprotocol/sdk/types.js"; import { DescribeTableInput, RawOutput } from "../types/index.js"; import { createLogger } from "../utils/logger.js"; import { createUsqlError, formatMcpError } from "../utils/error-handler.js"; import { validateConnectionString } from "../usql/connection.js"; import { executeUsqlQuery } from "../usql/process-executor.js"; import { parseUsqlError } from "../usql/parser.js"; import { getQueryTimeout, resolveConnectionStringOrDefault } from "../usql/config.js"; const logger = createLogger("usql-mcp:tools:describe-table"); export const describeTableSchema: Tool = { name: "describe_table", description: "Get detailed schema information for a specific table (columns, types, constraints)", inputSchema: { type: "object", properties: { connection_string: { type: "string", description: 'Database connection URL or configured connection name (e.g., "oracle" for USQL_ORACLE)', }, table: { type: "string", description: "Table name to describe", }, database: { type: "string", description: "Optional database name (if not specified in connection)", }, output_format: { type: "string", enum: ["json", "csv"], description: "Output format for results (default: json)", }, timeout_ms: { type: ["number", "null"], description: "Optional timeout in milliseconds for this call (overrides defaults). Use null for unlimited.", minimum: 1, }, }, required: ["table"], }, }; export async function handleDescribeTable(input: DescribeTableInput): Promise<RawOutput> { const outputFormat = input.output_format || "json"; logger.debug("[describe-table] Handling request", { connectionStringInput: input.connection_string, table: input.table, database: input.database, outputFormat, }); let resolvedConnectionString: string | undefined; try { if (!input.table || typeof input.table !== "string") { throw createUsqlError("InvalidInput", "table is required and must be a string"); } // Resolve connection string try { resolvedConnectionString = resolveConnectionStringOrDefault(input.connection_string); } catch (error) { throw createUsqlError("InvalidConnection", `Failed to resolve connection: ${String(error)}`); } if (!validateConnectionString(resolvedConnectionString)) { throw createUsqlError( "InvalidConnection", `Invalid connection string format: ${resolvedConnectionString}` ); } // Build describe query // Use usql's \d command to describe table const query = `\\d ${input.table}`; const timeoutOverride = input.timeout_ms === null ? undefined : typeof input.timeout_ms === "number" && Number.isFinite(input.timeout_ms) ? input.timeout_ms : undefined; const timeout = timeoutOverride ?? getQueryTimeout(); logger.debug("[describe-table] Executing describe command", { timeout, table: input.table, outputFormat, }); const result = await executeUsqlQuery(resolvedConnectionString, query, { timeout, format: outputFormat, }); logger.debug("[describe-table] Command executed", { exitCode: result.exitCode, stdoutLength: result.stdout.length, stderrLength: result.stderr.length, }); // Check for errors if (result.exitCode !== 0) { if (result.stderr) { const errorMessage = parseUsqlError(result.stderr); throw createUsqlError("DescribeTableError", errorMessage, { exitCode: result.exitCode, table: input.table, }); } // Some databases don't error on missing table, check output if (!result.stdout.trim()) { throw createUsqlError( "TableNotFound", `Table not found: ${input.table}`, { table: input.table } ); } } // Check for empty output if (!result.stdout.trim()) { throw createUsqlError( "TableNotFound", `Table not found: ${input.table}`, { table: input.table } ); } logger.debug("[describe-table] Table schema retrieved", { table: input.table, outputFormat, }); return { format: outputFormat as "json" | "csv", content: result.stdout, }; } catch (error) { const connectionForError = resolvedConnectionString ?? input.connection_string; const mcpError = formatMcpError( error, connectionForError || input.table || input.database ? { connectionString: connectionForError, table: input.table, database: input.database, } : undefined ); logger.error("[describe-table] Error describing table", error); throw mcpError; } }

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/jvm/usql-mcp'

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