We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jmagar/homelab-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
/**
* Formatting strategy pattern
*
* Provides abstraction for output formatting, enabling support for multiple
* formats (markdown, JSON) without modifying handler code.
*
* To add a new format:
* 1. Implement IFormatter interface
* 2. Add format type to createFormatter function signature
* 3. Add case in createFormatter() switch statement
*
* @example
* ```typescript
* const formatter = createFormatter('json');
* const output = formatter.format(data);
* ```
*/
/**
* Options for controlling formatting behavior
*/
export interface FormatterOptions {
/** Use compact output (no indentation). Defaults to true for JSON, false for Markdown. */
compact?: boolean;
}
/**
* Formatter interface - implement this to add new output formats
*/
export interface IFormatter {
/**
* Format data for output
* @param data - Data to format (any serializable type)
* @returns Formatted string ready for output
*/
format(data: unknown): string;
}
/**
* Markdown formatter - wraps existing markdown formatting functions
*
* This is the default formatter and maintains backward compatibility
* with existing markdown formatting behavior.
*/
export class MarkdownFormatter implements IFormatter {
private readonly indent: number | undefined;
constructor(options?: FormatterOptions) {
// Markdown code blocks default to pretty-print for readability
this.indent = options?.compact ? undefined : 2;
}
/**
* Format data as markdown
*
* If data is already a string (from existing formatters), return as-is.
* Otherwise, serialize as JSON within a code block.
*
* @param data - Data to format
* @returns Markdown formatted string
*/
format(data: unknown): string {
// If data is already a formatted markdown string from existing formatters, return as-is
if (typeof data === "string") {
return data;
}
// For non-string data, serialize as JSON within markdown code block
return `\`\`\`json\n${JSON.stringify(data, null, this.indent)}\n\`\`\``;
}
}
/**
* JSON formatter - outputs data as JSON
*
* Useful for programmatic consumption, API responses, or integration
* with other tools. Defaults to compact output (no indentation) for
* lower CPU and payload overhead.
*/
export class JSONFormatter implements IFormatter {
private readonly indent: number | undefined;
constructor(options?: FormatterOptions) {
// Default to compact (no indentation) for performance
this.indent = options?.compact === false ? 2 : undefined;
}
/**
* Format data as JSON
*
* If data is already a string (from markdown formatters), wrap in object.
* Otherwise, serialize directly as JSON.
*
* @param data - Data to format
* @returns JSON formatted string
*/
format(data: unknown): string {
// If data is already a formatted string from markdown formatters,
// wrap it in a structured object for JSON consumers
if (typeof data === "string") {
return JSON.stringify({ output: data, format: "text" }, null, this.indent);
}
// For structured data, serialize directly
return JSON.stringify(data, null, this.indent);
}
}
/**
* Create formatter for specified format
*
* Factory function that creates formatters based on format type.
* Provides extension point for adding new formats.
*
* @param format - Format type ('markdown' or 'json')
* @param options - Formatting options (compact mode, etc.)
* @returns Formatter instance
* @throws {Error} If format is not supported
*
* @example
* ```typescript
* const formatter = createFormatter('json');
* const output = formatter.format({ key: 'value' });
* // Pretty-print explicitly:
* const pretty = createFormatter('json', { compact: false });
* ```
*/
export function createFormatter(
format: "markdown" | "json",
options?: FormatterOptions
): IFormatter {
switch (format) {
case "markdown":
return new MarkdownFormatter(options);
case "json":
return new JSONFormatter(options);
default: {
// Exhaustive check - TypeScript ensures all formats are handled
const exhaustiveCheck: never = format;
throw new Error(`Unsupported format: ${exhaustiveCheck}`);
}
}
}
/**
* @deprecated Use createFormatter() instead. This class will be removed in a future version.
* Factory for creating formatters based on format type (backward compatibility wrapper)
*/
export const FormatterFactory = {
/** @deprecated Use createFormatter() instead */
create: createFormatter,
} as const;