feat: Initial confluence-mcp server for realtime collaboration

Provides 8 MCP tools for Confluence Cloud:
- confluence_list_spaces, confluence_create_space
- confluence_search, confluence_get_page
- confluence_create_page, confluence_update_page
- confluence_get_comments, confluence_add_comment

Uses Confluence REST API v2 with basic auth.
Registered in Claude Code and mcp-proxy.

Refs: CF-935

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-02-10 18:09:30 +02:00
commit 2768650b42
3824 changed files with 859428 additions and 0 deletions

108
dist/index.js vendored Normal file
View File

@@ -0,0 +1,108 @@
#!/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);
});