Skip to main content
Glama
markdown-formatter.ts3.01 kB
/** * Markdown Formatter Utility * Lightweight, zero-dependency formatter for markdown output */ /** * Format a single record as markdown KV (code block style) * @param record Object to format * @param title Optional title for the record * @returns Markdown KV string */ export function formatKV(record: Record<string, any>, title?: string): string { const lines: string[] = []; if (title) { lines.push(`## ${title}`); lines.push(''); } lines.push('```'); for (const [key, value] of Object.entries(record)) { const displayValue = formatValue(value); lines.push(`${key}: ${displayValue}`); } lines.push('```'); return lines.join('\n'); } /** * Format multiple records as a markdown table * @param records Array of objects to format * @param columns Optional column configuration (order, rename, filter) * @returns Markdown table string */ export function formatTable( records: Record<string, any>[], columns?: { key: string; label?: string }[] ): string { if (records.length === 0) { return '_No records_'; } // Determine columns from first record if not specified const cols = columns || Object.keys(records[0]).map(key => ({ key, label: key })); const lines: string[] = []; // Header row const headers = cols.map(c => c.label || c.key); lines.push(`| ${headers.join(' | ')} |`); // Separator row lines.push(`| ${cols.map(() => '---').join(' | ')} |`); // Data rows for (const record of records) { const values = cols.map(c => escapeTableCell(formatValue(record[c.key]))); lines.push(`| ${values.join(' | ')} |`); } return lines.join('\n'); } /** * Format value for display (handles undefined, null, arrays, objects) */ function formatValue(value: any): string { if (value === undefined || value === null) { return '-'; } if (Array.isArray(value)) { return value.join(', '); } if (typeof value === 'object') { return JSON.stringify(value); } if (typeof value === 'boolean') { return value ? 'yes' : 'no'; } return String(value); } /** * Escape pipe characters in table cells */ function escapeTableCell(value: string): string { return value.replace(/\|/g, '\\|').replace(/\n/g, ' '); } /** * Format records - auto-selects KV for single, table for multiple * @param records Single record or array of records * @param options Formatting options * @returns Markdown string */ export function format( records: Record<string, any> | Record<string, any>[], options?: { title?: string; columns?: { key: string; label?: string }[]; forceTable?: boolean; } ): string { const { title, columns, forceTable = false } = options || {}; // Handle array if (Array.isArray(records)) { if (records.length === 0) { return '_No records_'; } if (records.length === 1 && !forceTable) { return formatKV(records[0], title); } return formatTable(records, columns); } // Handle single record return formatKV(records, title); }

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/rwese/mcp-backlog'

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