Skip to main content
Glama
format.ts3.13 kB
import { Format, CHARACTER_LIMIT } from '../types.js'; /** * Formats output in JSON or Markdown based on the format parameter */ export function formatOutput( data: any, format: Format, options?: { title?: string; truncate?: boolean; } ): string { let output: string; if (format === 'json') { output = JSON.stringify(data, null, 2); } else { // Markdown format output = formatAsMarkdown(data, options?.title); } // Truncate if needed if (options?.truncate !== false && output.length > CHARACTER_LIMIT) { output = output.substring(0, CHARACTER_LIMIT) + '\n\n[... Output truncated at 25,000 characters. Use filters or pagination to reduce output size.]'; } return output; } /** * Formats data as Markdown for human-readable output */ function formatAsMarkdown(data: any, title?: string): string { let md = ''; if (title) { md += `# ${title}\n\n`; } if (Array.isArray(data)) { // Format array as a list or table if (data.length === 0) { md += '*No items found*\n'; } else if (typeof data[0] === 'object') { md += formatArrayAsMarkdownTable(data); } else { data.forEach((item, index) => { md += `${index + 1}. ${item}\n`; }); } } else if (typeof data === 'object' && data !== null) { // Format object as key-value pairs for (const [key, value] of Object.entries(data)) { if (typeof value === 'object' && value !== null) { md += `**${formatKey(key)}:**\n${formatAsMarkdown(value)}\n`; } else { md += `**${formatKey(key)}:** ${value}\n`; } } } else { md += String(data); } return md; } /** * Formats an array of objects as a Markdown table */ function formatArrayAsMarkdownTable(data: any[]): string { if (data.length === 0) return '*No items found*\n'; // Get all unique keys from all objects const keys = Array.from( new Set(data.flatMap(item => Object.keys(item))) ); // Create header let table = `| ${keys.map(formatKey).join(' | ')} |\n`; table += `| ${keys.map(() => '---').join(' | ')} |\n`; // Create rows data.forEach(item => { const row = keys.map(key => { const value = item[key]; if (value === null || value === undefined) return '-'; if (typeof value === 'object') return JSON.stringify(value); return String(value); }); table += `| ${row.join(' | ')} |\n`; }); return table; } /** * Formats a camelCase or snake_case key into a readable label */ function formatKey(key: string): string { return key .replace(/([A-Z])/g, ' $1') .replace(/_/g, ' ') .replace(/^./, str => str.toUpperCase()) .trim(); } /** * Creates a successful response with formatted content */ export function createSuccessResponse( data: any, format: Format = 'markdown', options?: { title?: string; structuredContent?: any; } ) { const formattedText = formatOutput(data, format, options); return { content: [{ type: 'text', text: formattedText }], ...(options?.structuredContent && { structuredContent: options.structuredContent }) }; }

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/CaullenOmdahl/expo-mcp-server'

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