UNPKG

@aashari/mcp-server-atlassian-confluence

Version:

Node.js/TypeScript MCP server for Atlassian Confluence. Provides tools enabling AI systems (LLMs) to list/get spaces & pages (content formatted as Markdown) and search via CQL. Connects AI seamlessly to Confluence knowledge bases using the standard MCP in

78 lines (77 loc) 2.85 kB
"use strict"; /** * Markdown utility functions for converting HTML to Markdown * Uses Turndown library for HTML to Markdown conversion * * @see https://github.com/mixmark-io/turndown */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.htmlToMarkdown = htmlToMarkdown; const turndown_1 = __importDefault(require("turndown")); const logger_util_js_1 = require("./logger.util.js"); // Create a singleton instance of TurndownService with default options const turndownService = new turndown_1.default({ headingStyle: 'atx', // Use # style headings bulletListMarker: '-', // Use - for bullet lists codeBlockStyle: 'fenced', // Use ``` for code blocks emDelimiter: '_', // Use _ for emphasis strongDelimiter: '**', // Use ** for strong linkStyle: 'inlined', // Use [text](url) for links linkReferenceStyle: 'full', // Use [text][id] + [id]: url for reference links }); // Add custom rule for strikethrough turndownService.addRule('strikethrough', { filter: (node) => { return (node.nodeName.toLowerCase() === 'del' || node.nodeName.toLowerCase() === 's' || node.nodeName.toLowerCase() === 'strike'); }, replacement: (content) => `~~${content}~~`, }); // Add custom rule for tables to improve table formatting turndownService.addRule('tableCell', { filter: ['th', 'td'], replacement: (content, _node) => { // Simplify content by consolidating whitespace const simplifiedContent = content.replace(/\s+/g, ' ').trim(); return ` ${simplifiedContent} |`; }, }); turndownService.addRule('tableRow', { filter: 'tr', replacement: (content, node) => { let output = `|${content}\n`; // If this is the first row in a table head, add the header separator row if (node.parentNode && 'tagName' in node.parentNode && node.parentNode.tagName === 'THEAD') { const cellCount = node.childNodes.length; output += '|' + ' --- |'.repeat(cellCount) + '\n'; } return output; }, }); /** * Convert HTML content to Markdown * * @param html - The HTML content to convert * @returns The converted Markdown content */ function htmlToMarkdown(html) { if (!html || html.trim() === '') { return ''; } try { const markdown = turndownService.turndown(html); return markdown; } catch (error) { const conversionLogger = logger_util_js_1.Logger.forContext('utils/markdown.util.ts', 'htmlToMarkdown'); conversionLogger.error('Error converting HTML to Markdown:', error); // Return the original HTML if conversion fails return html; } }