@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
146 lines (145 loc) • 4.68 kB
JavaScript
;
/**
* Standardized formatting utilities for consistent output across all CLI and Tool interfaces.
* These functions should be used by all formatters to ensure consistent formatting.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatDate = formatDate;
exports.formatHeading = formatHeading;
exports.formatPagination = formatPagination;
exports.formatUrl = formatUrl;
exports.formatSeparator = formatSeparator;
exports.formatBulletList = formatBulletList;
exports.formatNumberedList = formatNumberedList;
/**
* Format a date in a standardized way: YYYY-MM-DD HH:MM:SS UTC
* @param dateString - ISO date string or Date object
* @returns Formatted date string
*/
function formatDate(dateString) {
if (!dateString) {
return 'Not available';
}
try {
const date = typeof dateString === 'string' ? new Date(dateString) : dateString;
// Format: YYYY-MM-DD HH:MM:SS UTC
return date
.toISOString()
.replace('T', ' ')
.replace(/\.\d+Z$/, ' UTC');
}
catch {
return 'Invalid date';
}
}
/**
* Format a heading with the specified level (markdown)
* @param text - The heading text
* @param level - The heading level (1-6, defaults to 1)
* @returns Formatted heading
*/
function formatHeading(text, level = 1) {
const hashes = '#'.repeat(Math.max(1, Math.min(6, level)));
return `${hashes} ${text}`;
}
/**
* Format pagination information
* @param count - The number of items in the current page
* @param hasMore - Whether there are more items to fetch
* @param nextCursor - The cursor for the next page (if available)
* @returns Formatted pagination details
*/
function formatPagination(count, hasMore, nextCursor) {
const lines = [];
// Append the count information
lines.push(`**Results:** ${count} items`);
// Append pagination information if available
if (hasMore) {
lines.push('**More results available:** Use the pagination cursor to fetch the next page.');
if (nextCursor) {
lines.push(`**Next cursor:** \`${nextCursor}\``);
}
}
else {
lines.push('**No more results available.**');
}
return lines.join('\n');
}
/**
* Format a URL as a markdown link
* @param url - The URL to format
* @param title - Optional title for the link
* @returns Formatted URL as a markdown link
*/
function formatUrl(url, title) {
return `[${title || url}](${url})`;
}
/**
* Format a separator line
* @returns Formatted separator line
*/
function formatSeparator() {
return '---';
}
/**
* Format a bullet list from an object
* @param items - The object to format as a bullet list
* @param formatter - Optional function to format keys
* @returns Formatted bullet list
*/
function formatBulletList(items, formatter = (key) => key) {
const lines = [];
for (const [key, value] of Object.entries(items)) {
if (value === undefined || value === null) {
continue;
}
const formattedKey = formatter(key);
if (typeof value === 'object' && value !== null && 'url' in value) {
const urlObj = value;
// Handle URL objects with title
const urlTitle = urlObj.title || urlObj.url;
lines.push(`- **${formattedKey}**: ${formatUrl(String(urlObj.url), String(urlTitle))}`);
}
else if (typeof value === 'string' &&
(value.startsWith('http://') || value.startsWith('https://'))) {
// Handle URL strings
lines.push(`- **${formattedKey}**: ${formatUrl(value)}`);
}
else if (value instanceof Date) {
// Handle dates
lines.push(`- **${formattedKey}**: ${formatDate(value)}`);
}
else if (Array.isArray(value)) {
// Handle arrays
lines.push(`- **${formattedKey}**: ${value.join(', ')}`);
}
else {
// Handle all other types
lines.push(`- **${formattedKey}**: ${String(value)}`);
}
}
return lines.join('\n');
}
/**
* Format a numbered list from an array
* @param items - The array of items to format
* @param formatter - Function to format each item
* @returns Formatted numbered list
*/
function formatNumberedList(items, formatter) {
return items
.map((item, index) => {
const formattedItem = formatter(item, index);
return `${index + 1}. ${formattedItem}`;
})
.join('\n\n');
}
exports.default = {
formatDate,
formatHeading,
formatPagination,
formatUrl,
formatSeparator,
formatBulletList,
formatNumberedList,
};