#!/usr/bin/env node /** * Confluence MCP Server * * Provides Confluence Cloud page CRUD and collaboration via Model Context Protocol. * Tools: confluence_list_spaces, confluence_create_space, confluence_search, * confluence_get_page, confluence_create_page, confluence_update_page, * confluence_get_comments, confluence_add_comment */ import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import dotenv from 'dotenv'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const envPath = join(__dirname, '..', '.env'); dotenv.config({ path: envPath, override: true }); import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { ListToolsRequestSchema, CallToolRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { toolDefinitions, handleListSpaces, handleCreateSpace, handleSearch, handleGetPage, handleCreatePage, handleUpdatePage, handleGetComments, handleAddComment, } from './tools.js'; const server = new Server({ name: 'confluence-mcp', version: '1.0.0' }, { capabilities: { tools: {} } }); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: toolDefinitions, })); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; const a = args; let result; try { switch (name) { case 'confluence_list_spaces': result = await handleListSpaces({ limit: a.limit }); break; case 'confluence_create_space': result = await handleCreateSpace({ key: a.key, name: a.name, description: a.description, }); break; case 'confluence_search': result = await handleSearch({ query: a.query, space_id: a.space_id, limit: a.limit, }); break; case 'confluence_get_page': result = await handleGetPage({ page_id: String(a.page_id) }); break; case 'confluence_create_page': result = await handleCreatePage({ space_id: a.space_id, title: a.title, body: a.body, parent_id: a.parent_id, }); break; case 'confluence_update_page': result = await handleUpdatePage({ page_id: String(a.page_id), title: a.title, body: a.body, version_number: a.version_number, version_message: a.version_message, }); break; case 'confluence_get_comments': result = await handleGetComments({ page_id: String(a.page_id), limit: a.limit, }); break; case 'confluence_add_comment': result = await handleAddComment({ page_id: String(a.page_id), body: a.body, }); break; default: result = `Unknown tool: ${name}`; } } catch (error) { const message = error instanceof Error ? error.message : String(error); result = `Error: ${message}`; } return { content: [{ type: 'text', text: result }], }; }); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('confluence-mcp: Server started'); } main().catch((error) => { console.error('confluence-mcp: Fatal error:', error); process.exit(1); }); process.on('SIGINT', async () => { await server.close(); process.exit(0); }); process.on('SIGTERM', async () => { await server.close(); process.exit(0); });