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

135 lines (134 loc) 6.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const logger_util_js_1 = require("../utils/logger.util.js"); const error_util_js_1 = require("../utils/error.util.js"); const atlassian_api_controller_js_1 = require("../controllers/atlassian.api.controller.js"); /** * CLI module for generic Confluence API access. * Provides commands for making GET, POST, PUT, PATCH, and DELETE requests to any Confluence API endpoint. */ // Create a contextualized logger for this file const cliLogger = logger_util_js_1.Logger.forContext('cli/atlassian.api.cli.ts'); // Log CLI initialization cliLogger.debug('Confluence API CLI module initialized'); /** * Parse JSON string with error handling and basic validation * @param jsonString - JSON string to parse * @param fieldName - Name of the field for error messages * @returns Parsed JSON object */ function parseJson(jsonString, fieldName) { let parsed; try { parsed = JSON.parse(jsonString); } catch { throw new Error(`Invalid JSON in --${fieldName}. Please provide valid JSON.`); } // Validate that the parsed value is an object (not null, array, or primitive) if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) { throw new Error(`Invalid --${fieldName}: expected a JSON object, got ${parsed === null ? 'null' : Array.isArray(parsed) ? 'array' : typeof parsed}.`); } return parsed; } /** * Register a read command (GET/DELETE - no body) * @param program - Commander program instance * @param name - Command name * @param description - Command description * @param handler - Controller handler function */ function registerReadCommand(program, name, description, handler) { program .command(name) .description(description) .requiredOption('-p, --path <path>', 'API endpoint path (e.g., "/wiki/api/v2/spaces", "/wiki/api/v2/pages/{id}").') .option('-q, --query-params <json>', 'Query parameters as JSON string (e.g., \'{"limit": "25"}\').') .option('--jq <expression>', 'JMESPath expression to filter/transform the response.') .option('-o, --output-format <format>', 'Output format: "toon" (default, token-efficient) or "json".', 'toon') .action(async (options) => { const actionLogger = cliLogger.forMethod(name); try { actionLogger.debug(`CLI ${name} called`, options); // Parse query params if provided let queryParams; if (options.queryParams) { queryParams = parseJson(options.queryParams, 'query-params'); } const result = await handler({ path: options.path, queryParams, jq: options.jq, outputFormat: options.outputFormat, }); console.log(result.content); } catch (error) { (0, error_util_js_1.handleCliError)(error); } }); } /** * Register a write command (POST/PUT/PATCH - with body) * @param program - Commander program instance * @param name - Command name * @param description - Command description * @param handler - Controller handler function */ function registerWriteCommand(program, name, description, handler) { program .command(name) .description(description) .requiredOption('-p, --path <path>', 'API endpoint path (e.g., "/wiki/api/v2/pages", "/wiki/api/v2/pages/{id}/labels").') .requiredOption('-b, --body <json>', 'Request body as JSON string.') .option('-q, --query-params <json>', 'Query parameters as JSON string.') .option('--jq <expression>', 'JMESPath expression to filter/transform the response.') .option('-o, --output-format <format>', 'Output format: "toon" (default, token-efficient) or "json".', 'toon') .action(async (options) => { const actionLogger = cliLogger.forMethod(name); try { actionLogger.debug(`CLI ${name} called`, options); // Parse body const body = parseJson(options.body, 'body'); // Parse query params if provided let queryParams; if (options.queryParams) { queryParams = parseJson(options.queryParams, 'query-params'); } const result = await handler({ path: options.path, body, queryParams, jq: options.jq, outputFormat: options.outputFormat, }); console.log(result.content); } catch (error) { (0, error_util_js_1.handleCliError)(error); } }); } /** * Register generic Confluence API CLI commands with the Commander program * * @param program - The Commander program instance to register commands with */ function register(program) { const methodLogger = logger_util_js_1.Logger.forContext('cli/atlassian.api.cli.ts', 'register'); methodLogger.debug('Registering Confluence API CLI commands...'); // Register GET command registerReadCommand(program, 'get', 'GET any Confluence endpoint. Returns JSON, optionally filtered with JMESPath.', atlassian_api_controller_js_1.handleGet); // Register POST command registerWriteCommand(program, 'post', 'POST to any Confluence endpoint. Returns JSON, optionally filtered with JMESPath.', atlassian_api_controller_js_1.handlePost); // Register PUT command registerWriteCommand(program, 'put', 'PUT to any Confluence endpoint. Returns JSON, optionally filtered with JMESPath.', atlassian_api_controller_js_1.handlePut); // Register PATCH command registerWriteCommand(program, 'patch', 'PATCH any Confluence endpoint. Returns JSON, optionally filtered with JMESPath.', atlassian_api_controller_js_1.handlePatch); // Register DELETE command registerReadCommand(program, 'delete', 'DELETE any Confluence endpoint. Returns JSON (if any), optionally filtered with JMESPath.', atlassian_api_controller_js_1.handleDelete); methodLogger.debug('CLI commands registered successfully'); } exports.default = { register };