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

126 lines (125 loc) 6.11 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const logger_util_js_1 = require("../utils/logger.util.js"); const error_handler_util_js_1 = require("../utils/error-handler.util.js"); const atlassian_pages_formatter_js_1 = require("./atlassian.pages.formatter.js"); const vendor_atlassian_pages_service_js_1 = __importDefault(require("../services/vendor.atlassian.pages.service.js")); const defaults_util_js_1 = require("../utils/defaults.util.js"); /** * Controller for managing Confluence pages. * Provides functionality for listing pages and retrieving page details. */ // Create a contextualized logger for this file const controllerLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.pages.controller.ts'); // Log controller initialization controllerLogger.debug('Confluence pages controller initialized'); /** * List pages from Confluence with filtering options * @param options - Options for filtering pages * @param options.spaceId - Filter by space ID(s) * @param options.containerId - Alternative form of spaceId for consistency across services * @param options.query - Filter by text in title, content or labels * @param options.status - Filter by page status * @param options.sort - Sort order for results * @param options.limit - Maximum number of pages to return * @param options.cursor - Pagination cursor for subsequent requests * @returns Promise with formatted pages list content * @throws Error if page listing fails */ async function list(options = {}) { const methodLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.pages.controller.ts', 'list'); methodLogger.debug('Listing Confluence pages with options:', options); try { // Create defaults object with proper typing const defaults = { limit: defaults_util_js_1.DEFAULT_PAGE_SIZE, sort: '-modified-date', status: ['current'], }; // Apply defaults to ensure all standard properties are set const mergedOptions = (0, defaults_util_js_1.applyDefaults)(options, defaults); // Support containerId (standardized) or spaceId (Confluence-specific) const spaceId = options.containerId || options.spaceId; // Map controller options to service parameters const params = { ...(spaceId && { spaceId }), ...(mergedOptions.query && { query: mergedOptions.query }), ...(mergedOptions.status && { status: mergedOptions.status }), ...(mergedOptions.sort && { sort: mergedOptions.sort }), // Additional parameters with defaults limit: mergedOptions.limit, cursor: mergedOptions.cursor, bodyFormat: 'storage', }; methodLogger.debug('Using service params:', params); // Get pages data from the API const pagesData = await vendor_atlassian_pages_service_js_1.default.list(params); // Log only summary information instead of the entire response methodLogger.debug(`Retrieved ${pagesData.results.length} pages. Has more: ${pagesData._links?.next ? 'yes' : 'no'}`); // The formatPagesList function expects a pagesData parameter with results // Extract the nextCursor from the links const nextCursor = pagesData._links?.next?.split('cursor=')[1] || ''; const formattedPages = (0, atlassian_pages_formatter_js_1.formatPagesList)(pagesData.results); return { content: formattedPages, pagination: { count: pagesData.results.length, hasMore: !!pagesData._links?.next, nextCursor: nextCursor, }, }; } catch (error) { // Use the standardized error handler return (0, error_handler_util_js_1.handleControllerError)(error, { entityType: 'Pages', operation: 'listing', source: 'controllers/atlassian.pages.controller.ts@list', }); } } /** * Get details of a specific Confluence page * @param args - Object containing the ID of the page to retrieve * @param args.pageId - The ID of the page * @returns Promise with formatted page details content * @throws Error if page retrieval fails */ async function get(args) { const { pageId } = args; const methodLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.pages.controller.ts', 'get'); methodLogger.debug(`Getting Confluence page with ID: ${pageId}...`); try { // Map controller options to service parameters const params = { bodyFormat: defaults_util_js_1.PAGE_DEFAULTS.BODY_FORMAT, includeLabels: defaults_util_js_1.PAGE_DEFAULTS.INCLUDE_LABELS, includeProperties: defaults_util_js_1.PAGE_DEFAULTS.INCLUDE_PROPERTIES, includeWebresources: defaults_util_js_1.PAGE_DEFAULTS.INCLUDE_WEBRESOURCES, includeCollaborators: defaults_util_js_1.PAGE_DEFAULTS.INCLUDE_COLLABORATORS, includeVersion: defaults_util_js_1.PAGE_DEFAULTS.INCLUDE_VERSION, }; methodLogger.debug('Using service params:', params); // Get page data from the API const pageData = await vendor_atlassian_pages_service_js_1.default.get(pageId, params); // Log only key information instead of the entire response methodLogger.debug(`Retrieved page: ${pageData.title} (${pageData.id})`); // Format the page data for display const formattedPage = (0, atlassian_pages_formatter_js_1.formatPageDetails)(pageData); return { content: formattedPage, }; } catch (error) { return (0, error_handler_util_js_1.handleControllerError)(error, { entityType: 'Page', entityId: pageId, operation: 'retrieving', source: 'controllers/atlassian.pages.controller.ts@get', }); } } exports.default = { list, get };