formatResult
Convert scraped data into structured formats like markdown, HTML, or JSON. Save outputs to a specified file or default directory, with optional image inclusion for flexible content formatting.
Instructions
Format scraped data into different structured formats (markdown, HTML, JSON)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | The scraped data to format | |
| format | Yes | The format to convert the data to | |
| includeImages | No | Whether to include images in the formatted output (default: true) | |
| output | No | File path to save the formatted result. If not provided, will use the default directory. |
Input Schema (JSON Schema)
{
"properties": {
"data": {
"description": "The scraped data to format",
"type": "object"
},
"format": {
"description": "The format to convert the data to",
"enum": [
"markdown",
"html",
"json"
],
"type": "string"
},
"includeImages": {
"description": "Whether to include images in the formatted output (default: true)",
"type": "boolean"
},
"output": {
"description": "File path to save the formatted result. If not provided, will use the default directory.",
"type": "string"
}
},
"required": [
"data",
"format"
],
"type": "object"
}
Implementation Reference
- src/tools/formatResult.ts:167-210 (handler)Main handler function that formats scraped data into specified format (markdown, HTML, JSON) and handles file saving.handler: async (params: FormatResultParams): Promise<{ formatted: string; format: string; savedTo?: string }> => { const { data, format, includeImages = true, output } = params; try { let formatted: string; switch (format) { case 'markdown': formatted = formatAsMarkdown(data, includeImages); break; case 'html': formatted = formatAsHTML(data, includeImages); break; case 'json': formatted = JSON.stringify(data, null, 2); break; default: throw new Error(`Unsupported format: ${format}`); } // Save to file if output path is provided or use default directory let savedTo: string | undefined; if (output) { savedTo = await saveToFile(formatted, output, format, data); } else { // Save to default location if no output specified but we have a default dir const defaultFilename = generateDefaultFilename(data, format); savedTo = await saveToFile(formatted, defaultFilename, format, data); } // For large JSON data, truncate the response to avoid overwhelming the LLM if (format === 'json' && formatted.length > 10000) { formatted = formatted.substring(0, 10000) + '... (truncated for display, full content saved to file)'; } return { formatted, format, ...(savedTo && { savedTo }) }; } catch (error) { throw new Error(`Failed to format result: ${error instanceof Error ? error.message : String(error)}`); } }
- src/types.ts:33-41 (schema)TypeScript interfaces defining input parameters for the formatResult tool.// Format options for the formatResult tool export type FormatType = 'markdown' | 'html' | 'json'; export interface FormatResultParams { data: ScraperResponse; format: FormatType; includeImages?: boolean; output?: string; // File path to save the formatted result }
- src/config.ts:65-71 (registration)Registration of the formatResult tool in the main MCP server configuration.tools: [ scrapeFocused, scrapeBalanced, scrapeDeep, // analyzeUrl, formatResult ],
- src/tools/formatResult.ts:10-54 (helper)Helper function to format scraped data as Markdown using json2md library.function formatAsMarkdown(data: ScraperResponse, includeImages: boolean): string { const mdData: json2md.DataObject[] = []; // Add title mdData.push({ h1: data.title }); // Add metadata if available if (data.metadata && Object.keys(data.metadata).length > 0) { mdData.push({ h2: 'Metadata' }); const metadataItems: string[] = []; for (const [key, value] of Object.entries(data.metadata)) { if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { metadataItems.push(`**${key}**: ${value}`); } } if (metadataItems.length > 0) { mdData.push({ ul: metadataItems }); } } // Add content mdData.push({ h2: 'Content' }); if (data.content && data.content.length > 0) { data.content.forEach(section => { mdData.push({ p: section }); }); } // Add images if requested and available if (includeImages && data.images && data.images.length > 0) { mdData.push({ h2: 'Images' }); data.images.forEach(image => { const alt = image.alt || 'Image'; mdData.push({ img: { title: alt, source: image.url }}); }); } return json2md(mdData); }
- src/tools/formatResult.ts:107-138 (helper)Helper function to save the formatted content to a file, handling paths and directories.async function saveToFile(content: string, outputPath: string, format: string, data: ScraperResponse): Promise<string> { try { // Check if outputPath is absolute or relative let resolvedPath = outputPath; // If the path is not absolute, use the default output directory if (!path.isAbsolute(outputPath)) { resolvedPath = path.join(config.serverOptions.defaultOutputDir, outputPath); } // If only a directory is provided (no filename), generate a filename const stats = await fs.stat(resolvedPath).catch(() => null); if (stats && stats.isDirectory()) { resolvedPath = path.join(resolvedPath, generateDefaultFilename(data, format)); } else if (!path.extname(resolvedPath)) { // If no extension, add one based on format const extension = format === 'markdown' ? '.md' : format === 'html' ? '.html' : '.json'; resolvedPath = `${resolvedPath}${extension}`; } // Ensure the directory exists const dir = path.dirname(resolvedPath); await fs.mkdir(dir, { recursive: true }); // Write the content to the file await fs.writeFile(resolvedPath, content, 'utf-8'); return resolvedPath; } catch (error) { throw new Error(`Failed to save formatted result: ${error instanceof Error ? error.message : String(error)}`); } }