confluence-tools 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shadowgandor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # confluence-tools
2
+
3
+ CLI and MCP server for Atlassian Confluence. Read, create, update, and delete pages from your terminal or AI agent.
4
+
5
+ ## Features
6
+
7
+ - **CLI** — `confluence` command with full CRUD operations, interactive confirmation prompts, coloured output
8
+ - **MCP server** — Expose the same operations as tools for AI agents (Claude Code, etc.)
9
+ - **Shared core** — Both interfaces use the same TypeScript client; bug fixes and features land in one place
10
+ - **Markdown support** — Automatically converts `.md` files to Confluence storage format
11
+ - **Secure by design** — Credentials are read from environment variables only, never written to disk
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install -g confluence-tools
17
+ ```
18
+
19
+ Or run without installing:
20
+
21
+ ```bash
22
+ npx confluence-tools confluence auth
23
+ ```
24
+
25
+ ### Environment variables
26
+
27
+ ```bash
28
+ export CONFLUENCE_URL="https://your-instance.atlassian.net/wiki"
29
+ export CONFLUENCE_EMAIL="you@example.com"
30
+ export CONFLUENCE_TOKEN="your-api-token"
31
+ ```
32
+
33
+ Generate an API token at https://id.atlassian.com/manage-profile/security/api-tokens
34
+
35
+ ## CLI usage
36
+
37
+ ```bash
38
+ # Verify connection
39
+ confluence auth
40
+
41
+ # List spaces
42
+ confluence spaces
43
+
44
+ # Read a page
45
+ confluence read 12345678
46
+ confluence read 12345678 --json
47
+
48
+ # Search pages in a space
49
+ confluence search -s DEV -t "Architecture"
50
+
51
+ # Create a page (prompts for confirmation)
52
+ confluence create -s DEV -t "New RFC" -f proposal.md
53
+
54
+ # Update a page
55
+ confluence update 12345678 -f updated.md -m "Revised section 3"
56
+
57
+ # Delete a page
58
+ confluence delete 12345678
59
+ ```
60
+
61
+ All write/delete commands prompt for confirmation. Pass `-y` to skip (useful in scripts).
62
+
63
+ ## MCP server usage
64
+
65
+ Add to your Claude Code config (`~/.claude.json` or project `.mcp.json`):
66
+
67
+ ```json
68
+ {
69
+ "mcpServers": {
70
+ "confluence": {
71
+ "command": "confluence-mcp",
72
+ "env": {
73
+ "CONFLUENCE_URL": "https://your-instance.atlassian.net/wiki",
74
+ "CONFLUENCE_EMAIL": "you@example.com",
75
+ "CONFLUENCE_TOKEN": "your-api-token"
76
+ }
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ Or without a global install:
83
+
84
+ ```json
85
+ {
86
+ "mcpServers": {
87
+ "confluence": {
88
+ "command": "npx",
89
+ "args": ["--package=confluence-tools", "-y", "confluence-mcp"],
90
+ "env": {
91
+ "CONFLUENCE_URL": "https://your-instance.atlassian.net/wiki",
92
+ "CONFLUENCE_EMAIL": "you@example.com",
93
+ "CONFLUENCE_TOKEN": "your-api-token"
94
+ }
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Available tools
101
+
102
+ | Tool | Description | Confirmation needed |
103
+ |----------------------------|--------------------------------------|---------------------|
104
+ | `confluence_auth` | Verify connection | No |
105
+ | `confluence_list_spaces` | List spaces | No |
106
+ | `confluence_read_page` | Read page content by ID | No |
107
+ | `confluence_search_pages` | Search by space key and title | No |
108
+ | `confluence_create_page` | Create a new page | **Yes** |
109
+ | `confluence_update_page` | Update an existing page | **Yes** |
110
+ | `confluence_delete_page` | Delete a page | **Yes** |
111
+
112
+ ## Project structure
113
+
114
+ ```
115
+ src/
116
+ ├── core/ # Shared library
117
+ │ ├── client.ts # Confluence REST API client
118
+ │ ├── auth.ts # Environment-based config loader
119
+ │ ├── markdown.ts # Markdown → storage format converter
120
+ │ ├── types.ts # TypeScript interfaces
121
+ │ └── index.ts # Barrel export
122
+ ├── cli/
123
+ │ └── index.ts # Commander.js CLI
124
+ └── mcp/
125
+ └── index.ts # MCP server (stdio transport)
126
+ ```
127
+
128
+ ## Development
129
+
130
+ ```bash
131
+ # Run CLI in dev mode (no build step)
132
+ npm run dev:cli -- auth
133
+ npm run dev:cli -- search -s DEV -t "RFC"
134
+
135
+ # Run MCP server in dev mode
136
+ npm run dev:mcp
137
+
138
+ # Build
139
+ npm run build
140
+
141
+ # Test
142
+ npm test
143
+
144
+ # Lint
145
+ npm run lint
146
+ ```
147
+
148
+ ## License
149
+
150
+ MIT — GeeveeH Software
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import chalk from "chalk";
4
+ import { ConfluenceClient, loadConfigFromEnv, ConfluenceApiError } from "../core/index.js";
5
+ import { resolveBody } from "../core/markdown.js";
6
+ // ── Helpers ────────────────────────────────────────────────────────
7
+ function createClient() {
8
+ const config = loadConfigFromEnv();
9
+ return new ConfluenceClient(config);
10
+ }
11
+ function formatPage(page) {
12
+ return `${chalk.bold(page.title)} ${chalk.dim(`(id: ${page.id}, v${page.version?.number ?? "?"}, ${page.status})`)}`;
13
+ }
14
+ function handleError(err) {
15
+ if (err instanceof ConfluenceApiError) {
16
+ console.error(chalk.red(`✗ API error ${err.statusCode}: ${err.message}`));
17
+ if (err.data)
18
+ console.error(chalk.dim(JSON.stringify(err.data, null, 2)));
19
+ }
20
+ else if (err instanceof Error) {
21
+ console.error(chalk.red(`✗ ${err.message}`));
22
+ }
23
+ process.exit(1);
24
+ }
25
+ // ── Program ────────────────────────────────────────────────────────
26
+ const program = new Command()
27
+ .name("confluence")
28
+ .description("CLI for Atlassian Confluence — create, read, update, delete pages")
29
+ .version("0.1.0");
30
+ // ── auth ────────────────────────────────────────────────────────────
31
+ program
32
+ .command("auth")
33
+ .description("Verify your Confluence connection")
34
+ .action(async () => {
35
+ try {
36
+ const client = createClient();
37
+ const spaces = await client.verifyConnection();
38
+ console.log(chalk.green("✓ Connected successfully."));
39
+ console.log(` Found ${spaces.length} space(s):`);
40
+ for (const s of spaces) {
41
+ console.log(` • ${chalk.bold(s.name)} ${chalk.dim(`[${s.key}]`)}`);
42
+ }
43
+ }
44
+ catch (err) {
45
+ handleError(err);
46
+ }
47
+ });
48
+ // ── spaces ──────────────────────────────────────────────────────────
49
+ program
50
+ .command("spaces")
51
+ .description("List available spaces")
52
+ .option("-l, --limit <n>", "Max spaces to return", "25")
53
+ .action(async (opts) => {
54
+ try {
55
+ const client = createClient();
56
+ const spaces = await client.listSpaces(Number(opts.limit));
57
+ for (const s of spaces) {
58
+ console.log(`${chalk.bold(s.name)} ${chalk.dim(`[${s.key}] id:${s.id}`)}`);
59
+ }
60
+ }
61
+ catch (err) {
62
+ handleError(err);
63
+ }
64
+ });
65
+ // ── read ────────────────────────────────────────────────────────────
66
+ program
67
+ .command("read <pageId>")
68
+ .description("Read a page by ID")
69
+ .option("--json", "Output raw JSON")
70
+ .action(async (pageId, opts) => {
71
+ try {
72
+ const client = createClient();
73
+ const page = await client.getPage(pageId);
74
+ if (opts.json) {
75
+ console.log(JSON.stringify(page, null, 2));
76
+ }
77
+ else {
78
+ console.log(formatPage(page));
79
+ if (page.body?.storage?.value) {
80
+ console.log(chalk.dim("─".repeat(60)));
81
+ console.log(page.body.storage.value);
82
+ }
83
+ }
84
+ }
85
+ catch (err) {
86
+ handleError(err);
87
+ }
88
+ });
89
+ // ── search ──────────────────────────────────────────────────────────
90
+ program
91
+ .command("search")
92
+ .description("Search for pages in a space")
93
+ .requiredOption("-s, --space <key>", "Space key")
94
+ .option("-t, --title <title>", "Filter by title")
95
+ .option("-l, --limit <n>", "Max results", "25")
96
+ .action(async (opts) => {
97
+ try {
98
+ const client = createClient();
99
+ const pages = await client.searchPages({
100
+ spaceKey: opts.space,
101
+ title: opts.title,
102
+ limit: Number(opts.limit),
103
+ });
104
+ if (pages.length === 0) {
105
+ console.log(chalk.yellow("No pages found."));
106
+ return;
107
+ }
108
+ for (const p of pages) {
109
+ console.log(formatPage(p));
110
+ }
111
+ }
112
+ catch (err) {
113
+ handleError(err);
114
+ }
115
+ });
116
+ // ── create ──────────────────────────────────────────────────────────
117
+ program
118
+ .command("create")
119
+ .description("Create a new page")
120
+ .requiredOption("-s, --space <key>", "Space key")
121
+ .requiredOption("-t, --title <title>", "Page title")
122
+ .requiredOption("-f, --file <path>", "Content file (.md, .html) or inline string")
123
+ .option("-p, --parent <id>", "Parent page ID")
124
+ .option("--draft", "Create as draft")
125
+ .option("-y, --yes", "Skip confirmation prompt")
126
+ .action(async (opts) => {
127
+ try {
128
+ const client = createClient();
129
+ // Resolve space key → space ID
130
+ const space = await client.getSpaceByKey(opts.space);
131
+ const body = await resolveBody(opts.file);
132
+ if (!opts.yes) {
133
+ console.log(chalk.yellow("⚠ About to create page:"));
134
+ console.log(` Space: ${space.name} [${space.key}]`);
135
+ console.log(` Title: ${opts.title}`);
136
+ if (opts.parent)
137
+ console.log(` Parent: ${opts.parent}`);
138
+ console.log(` Status: ${opts.draft ? "draft" : "published"}`);
139
+ console.log();
140
+ const ok = await confirm("Proceed?");
141
+ if (!ok) {
142
+ console.log(chalk.dim("Cancelled."));
143
+ return;
144
+ }
145
+ }
146
+ const page = await client.createPage({
147
+ spaceId: space.id,
148
+ title: opts.title,
149
+ body,
150
+ parentId: opts.parent,
151
+ status: opts.draft ? "draft" : "current",
152
+ });
153
+ console.log(chalk.green(`✓ Created: ${formatPage(page)}`));
154
+ console.log(` ${chalk.cyan(pageUrl(page))}`);
155
+ }
156
+ catch (err) {
157
+ handleError(err);
158
+ }
159
+ });
160
+ // ── update ──────────────────────────────────────────────────────────
161
+ program
162
+ .command("update <pageId>")
163
+ .description("Update an existing page")
164
+ .option("-t, --title <title>", "New title")
165
+ .option("-f, --file <path>", "New content file (.md, .html) or inline string")
166
+ .option("-m, --message <msg>", "Version message")
167
+ .option("-y, --yes", "Skip confirmation prompt")
168
+ .action(async (pageId, opts) => {
169
+ try {
170
+ const client = createClient();
171
+ const current = await client.getPage(pageId);
172
+ const body = opts.file ? await resolveBody(opts.file) : undefined;
173
+ if (!opts.yes) {
174
+ console.log(chalk.yellow("⚠ About to update page:"));
175
+ console.log(` Page: ${formatPage(current)}`);
176
+ if (opts.title)
177
+ console.log(` Title: ${current.title} → ${opts.title}`);
178
+ if (body)
179
+ console.log(` Body: will be replaced`);
180
+ console.log();
181
+ const ok = await confirm("Proceed?");
182
+ if (!ok) {
183
+ console.log(chalk.dim("Cancelled."));
184
+ return;
185
+ }
186
+ }
187
+ const updated = await client.updatePage({
188
+ pageId,
189
+ title: opts.title,
190
+ body,
191
+ versionMessage: opts.message,
192
+ });
193
+ console.log(chalk.green(`✓ Updated: ${formatPage(updated)}`));
194
+ console.log(` ${chalk.cyan(pageUrl(updated))}`);
195
+ }
196
+ catch (err) {
197
+ handleError(err);
198
+ }
199
+ });
200
+ // ── delete ──────────────────────────────────────────────────────────
201
+ program
202
+ .command("delete <pageId>")
203
+ .description("Delete a page")
204
+ .option("-y, --yes", "Skip confirmation prompt")
205
+ .action(async (pageId, opts) => {
206
+ try {
207
+ const client = createClient();
208
+ const page = await client.getPage(pageId);
209
+ if (!opts.yes) {
210
+ console.log(chalk.red("⚠ About to DELETE page:"));
211
+ console.log(` ${formatPage(page)}`);
212
+ console.log();
213
+ const ok = await confirm("This cannot be undone. Proceed?");
214
+ if (!ok) {
215
+ console.log(chalk.dim("Cancelled."));
216
+ return;
217
+ }
218
+ }
219
+ await client.deletePage(pageId);
220
+ console.log(chalk.green(`✓ Deleted page "${page.title}" (id: ${pageId})`));
221
+ }
222
+ catch (err) {
223
+ handleError(err);
224
+ }
225
+ });
226
+ // ── Utilities ───────────────────────────────────────────────────────
227
+ function pageUrl(page) {
228
+ const base = page._links?.base ?? process.env.CONFLUENCE_URL ?? "";
229
+ return `${base}/pages/${page.id}`;
230
+ }
231
+ async function confirm(question) {
232
+ const { createInterface } = await import("node:readline");
233
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
234
+ return new Promise((resolve) => {
235
+ rl.question(`${question} [y/N] `, (answer) => {
236
+ rl.close();
237
+ resolve(answer.trim().toLowerCase().startsWith("y"));
238
+ });
239
+ });
240
+ }
241
+ // ── Run ─────────────────────────────────────────────────────────────
242
+ program.parse();
243
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { ConfluenceConfig } from "./types.js";
2
+ /**
3
+ * Resolve Confluence config from environment variables.
4
+ * Throws a clear error if any are missing.
5
+ */
6
+ export declare function loadConfigFromEnv(): ConfluenceConfig;
7
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,gBAAgB,CAqBpD"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Resolve Confluence config from environment variables.
3
+ * Throws a clear error if any are missing.
4
+ */
5
+ export function loadConfigFromEnv() {
6
+ const baseUrl = process.env.CONFLUENCE_URL;
7
+ const email = process.env.CONFLUENCE_EMAIL;
8
+ const token = process.env.CONFLUENCE_TOKEN;
9
+ const missing = [];
10
+ if (!baseUrl)
11
+ missing.push("CONFLUENCE_URL");
12
+ if (!email)
13
+ missing.push("CONFLUENCE_EMAIL");
14
+ if (!token)
15
+ missing.push("CONFLUENCE_TOKEN");
16
+ if (missing.length > 0) {
17
+ throw new Error(`Missing required environment variable(s): ${missing.join(", ")}.\n` +
18
+ `Set them in your shell or .zshrc:\n` +
19
+ ` export CONFLUENCE_URL="https://your-instance.atlassian.net/wiki"\n` +
20
+ ` export CONFLUENCE_EMAIL="you@example.com"\n` +
21
+ ` export CONFLUENCE_TOKEN="your-api-token"`);
22
+ }
23
+ return { baseUrl: baseUrl, email: email, token: token };
24
+ }
25
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAE3C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAE7C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,6CAA6C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAClE,qCAAqC;YACrC,sEAAsE;YACtE,+CAA+C;YAC/C,4CAA4C,CAC/C,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAQ,EAAE,KAAK,EAAE,KAAM,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { ConfluenceConfig, ConfluencePage, ConfluenceSpace, PageCreateInput, PageUpdateInput, PageSearchOptions } from "./types.js";
2
+ export declare class ConfluenceClient {
3
+ private readonly baseUrl;
4
+ private readonly authHeader;
5
+ constructor(config: ConfluenceConfig);
6
+ private request;
7
+ verifyConnection(): Promise<ConfluenceSpace[]>;
8
+ listSpaces(limit?: number): Promise<ConfluenceSpace[]>;
9
+ getSpaceByKey(spaceKey: string): Promise<ConfluenceSpace>;
10
+ getPage(pageId: string): Promise<ConfluencePage>;
11
+ listPages(spaceId: string, limit?: number): Promise<ConfluencePage[]>;
12
+ searchPages(options: PageSearchOptions): Promise<ConfluencePage[]>;
13
+ createPage(input: PageCreateInput): Promise<ConfluencePage>;
14
+ updatePage(input: PageUpdateInput): Promise<ConfluencePage>;
15
+ deletePage(pageId: string): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,eAAe,EAEf,eAAe,EACf,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,MAAM,EAAE,gBAAgB;YAStB,OAAO;IAkCf,gBAAgB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAS9C,UAAU,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAOlD,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAYzD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAMhD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAOjE,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAkBlE,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAsB3D,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IA0B3D,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKhD"}
@@ -0,0 +1,124 @@
1
+ import { ConfluenceApiError, } from "./types.js";
2
+ export class ConfluenceClient {
3
+ baseUrl;
4
+ authHeader;
5
+ constructor(config) {
6
+ // Strip trailing slash
7
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
8
+ const encoded = Buffer.from(`${config.email}:${config.token}`).toString("base64");
9
+ this.authHeader = `Basic ${encoded}`;
10
+ }
11
+ // ── Low-level request helper ─────────────────────────────────────
12
+ async request(path, options = {}) {
13
+ const url = path.startsWith("http") ? path : `${this.baseUrl}${path}`;
14
+ const response = await fetch(url, {
15
+ ...options,
16
+ headers: {
17
+ Authorization: this.authHeader,
18
+ "Content-Type": "application/json",
19
+ Accept: "application/json",
20
+ ...options.headers,
21
+ },
22
+ });
23
+ if (!response.ok) {
24
+ let errorData;
25
+ try {
26
+ errorData = await response.json();
27
+ }
28
+ catch {
29
+ errorData = await response.text();
30
+ }
31
+ throw new ConfluenceApiError(response.status, response.statusText, errorData);
32
+ }
33
+ // 204 No Content (e.g. delete)
34
+ if (response.status === 204)
35
+ return undefined;
36
+ return response.json();
37
+ }
38
+ // ── Authentication check ─────────────────────────────────────────
39
+ async verifyConnection() {
40
+ const result = await this.request("/api/v2/spaces?limit=5");
41
+ return result.results;
42
+ }
43
+ // ── Spaces ───────────────────────────────────────────────────────
44
+ async listSpaces(limit = 25) {
45
+ const result = await this.request(`/api/v2/spaces?limit=${limit}`);
46
+ return result.results;
47
+ }
48
+ async getSpaceByKey(spaceKey) {
49
+ const result = await this.request(`/api/v2/spaces?keys=${encodeURIComponent(spaceKey)}`);
50
+ if (result.results.length === 0) {
51
+ throw new ConfluenceApiError(404, `Space with key "${spaceKey}" not found`);
52
+ }
53
+ return result.results[0];
54
+ }
55
+ // ── Read ─────────────────────────────────────────────────────────
56
+ async getPage(pageId) {
57
+ return this.request(`/api/v2/pages/${pageId}?body-format=storage`);
58
+ }
59
+ async listPages(spaceId, limit = 25) {
60
+ const result = await this.request(`/api/v2/spaces/${spaceId}/pages?limit=${limit}`);
61
+ return result.results;
62
+ }
63
+ async searchPages(options) {
64
+ const params = new URLSearchParams({
65
+ spaceKey: options.spaceKey,
66
+ expand: "body.storage,version",
67
+ limit: String(options.limit ?? 25),
68
+ });
69
+ if (options.title) {
70
+ params.set("title", options.title);
71
+ }
72
+ // CQL-based search uses v1 API
73
+ const result = await this.request(`/rest/api/content?${params.toString()}`);
74
+ return result.results;
75
+ }
76
+ // ── Create ───────────────────────────────────────────────────────
77
+ async createPage(input) {
78
+ const payload = {
79
+ spaceId: input.spaceId,
80
+ status: input.status ?? "current",
81
+ title: input.title,
82
+ body: {
83
+ representation: "storage",
84
+ value: input.body,
85
+ },
86
+ };
87
+ if (input.parentId) {
88
+ payload.parentId = input.parentId;
89
+ }
90
+ return this.request("/api/v2/pages", {
91
+ method: "POST",
92
+ body: JSON.stringify(payload),
93
+ });
94
+ }
95
+ // ── Update ───────────────────────────────────────────────────────
96
+ async updatePage(input) {
97
+ // Fetch current version first
98
+ const current = await this.getPage(input.pageId);
99
+ const payload = {
100
+ id: input.pageId,
101
+ status: "current",
102
+ title: input.title ?? current.title,
103
+ body: {
104
+ representation: "storage",
105
+ value: input.body ?? current.body?.storage?.value ?? "",
106
+ },
107
+ version: {
108
+ number: current.version.number + 1,
109
+ message: input.versionMessage ?? "Updated via confluence-tools",
110
+ },
111
+ };
112
+ return this.request(`/api/v2/pages/${input.pageId}`, {
113
+ method: "PUT",
114
+ body: JSON.stringify(payload),
115
+ });
116
+ }
117
+ // ── Delete ───────────────────────────────────────────────────────
118
+ async deletePage(pageId) {
119
+ await this.request(`/api/v2/pages/${pageId}`, {
120
+ method: "DELETE",
121
+ });
122
+ }
123
+ }
124
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,kBAAkB,GAKnB,MAAM,YAAY,CAAC;AAEpB,MAAM,OAAO,gBAAgB;IACV,OAAO,CAAS;IAChB,UAAU,CAAS;IAEpC,YAAY,MAAwB;QAClC,uBAAuB;QACvB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClF,IAAI,CAAC,UAAU,GAAG,SAAS,OAAO,EAAE,CAAC;IACvC,CAAC;IAED,oEAAoE;IAE5D,KAAK,CAAC,OAAO,CACnB,IAAY,EACZ,UAAuB,EAAE;QAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QAEtE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,GAAG,OAAO;YACV,OAAO,EAAE;gBACP,aAAa,EAAE,IAAI,CAAC,UAAU;gBAC9B,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,kBAAkB;gBAC1B,GAAG,OAAO,CAAC,OAAO;aACnB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,SAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,CAAC;YACD,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAChF,CAAC;QAED,+BAA+B;QAC/B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAc,CAAC;QAEnD,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;IAED,oEAAoE;IAEpE,KAAK,CAAC,gBAAgB;QACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,wBAAwB,CACzB,CAAC;QACF,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,oEAAoE;IAEpE,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,wBAAwB,KAAK,EAAE,CAChC,CAAC;QACF,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAgB;QAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,uBAAuB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CACtD,CAAC;QACF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,QAAQ,aAAa,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED,oEAAoE;IAEpE,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,OAAO,IAAI,CAAC,OAAO,CACjB,iBAAiB,MAAM,sBAAsB,CAC9C,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAe,EAAE,KAAK,GAAG,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,kBAAkB,OAAO,gBAAgB,KAAK,EAAE,CACjD,CAAC;QACF,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA0B;QAC1C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,sBAAsB;YAC9B,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,+BAA+B;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,qBAAqB,MAAM,CAAC,QAAQ,EAAE,EAAE,CACzC,CAAC;QACF,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,oEAAoE;IAEpE,KAAK,CAAC,UAAU,CAAC,KAAsB;QACrC,MAAM,OAAO,GAA4B;YACvC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,SAAS;YACjC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,IAAI,EAAE;gBACJ,cAAc,EAAE,SAAS;gBACzB,KAAK,EAAE,KAAK,CAAC,IAAI;aAClB;SACF,CAAC;QACF,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QACpC,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAiB,eAAe,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,oEAAoE;IAEpE,KAAK,CAAC,UAAU,CAAC,KAAsB;QACrC,8BAA8B;QAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG;YACd,EAAE,EAAE,KAAK,CAAC,MAAM;YAChB,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK;YACnC,IAAI,EAAE;gBACJ,cAAc,EAAE,SAAS;gBACzB,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE;aACxD;YACD,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAClC,OAAO,EAAE,KAAK,CAAC,cAAc,IAAI,8BAA8B;aAChE;SACF,CAAC;QAEF,OAAO,IAAI,CAAC,OAAO,CAAiB,iBAAiB,KAAK,CAAC,MAAM,EAAE,EAAE;YACnE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,oEAAoE;IAEpE,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,MAAM,IAAI,CAAC,OAAO,CAAO,iBAAiB,MAAM,EAAE,EAAE;YAClD,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ export { ConfluenceClient } from "./client.js";
2
+ export { loadConfigFromEnv } from "./auth.js";
3
+ export { markdownToStorage, resolveBody } from "./markdown.js";
4
+ export * from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC/D,cAAc,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { ConfluenceClient } from "./client.js";
2
+ export { loadConfigFromEnv } from "./auth.js";
3
+ export { markdownToStorage, resolveBody } from "./markdown.js";
4
+ export * from "./types.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC/D,cAAc,YAAY,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Lightweight Markdown → Confluence storage format converter.
3
+ *
4
+ * Handles the most common patterns. For full fidelity, consider
5
+ * adding a proper parser (e.g. marked/remark) later.
6
+ */
7
+ export declare function markdownToStorage(md: string): string;
8
+ /**
9
+ * Read content from a file path or treat as inline content.
10
+ * If the string ends in .md, read the file and convert.
11
+ * If it ends in .html or .xml, read the file as-is (assume storage format).
12
+ * Otherwise treat it as inline markdown and convert.
13
+ */
14
+ export declare function resolveBody(input: string): Promise<string>;
15
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/core/markdown.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CA6EpD;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBhE"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Lightweight Markdown → Confluence storage format converter.
3
+ *
4
+ * Handles the most common patterns. For full fidelity, consider
5
+ * adding a proper parser (e.g. marked/remark) later.
6
+ */
7
+ export function markdownToStorage(md) {
8
+ let html = md;
9
+ // Code blocks (fenced) — must come before inline processing
10
+ html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (_match, lang, code) => {
11
+ const langAttr = lang
12
+ ? `<ac:parameter ac:name="language">${lang}</ac:parameter>`
13
+ : "";
14
+ return (`<ac:structured-macro ac:name="code">` +
15
+ `${langAttr}<ac:plain-text-body><![CDATA[${code.trimEnd()}]]></ac:plain-text-body>` +
16
+ `</ac:structured-macro>`);
17
+ });
18
+ // Headings
19
+ html = html.replace(/^######\s+(.+)$/gm, "<h6>$1</h6>");
20
+ html = html.replace(/^#####\s+(.+)$/gm, "<h5>$1</h5>");
21
+ html = html.replace(/^####\s+(.+)$/gm, "<h4>$1</h4>");
22
+ html = html.replace(/^###\s+(.+)$/gm, "<h3>$1</h3>");
23
+ html = html.replace(/^##\s+(.+)$/gm, "<h2>$1</h2>");
24
+ html = html.replace(/^#\s+(.+)$/gm, "<h1>$1</h1>");
25
+ // Bold & italic
26
+ html = html.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
27
+ html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
28
+ html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
29
+ // Inline code
30
+ html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
31
+ // Links
32
+ html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
33
+ // Unordered list items (simple, non-nested)
34
+ html = html.replace(/^(?:- |\* )(.+)$/gm, "<li>$1</li>");
35
+ // Wrap consecutive <li> in <ul>
36
+ html = html.replace(/(<li>.*<\/li>\n?)+/g, (match) => `<ul>\n${match}</ul>\n`);
37
+ // Paragraphs: wrap remaining plain lines
38
+ const lines = html.split("\n");
39
+ const result = [];
40
+ for (const line of lines) {
41
+ const trimmed = line.trim();
42
+ if (trimmed === "" ||
43
+ trimmed.startsWith("<h") ||
44
+ trimmed.startsWith("<ul") ||
45
+ trimmed.startsWith("</ul") ||
46
+ trimmed.startsWith("<li") ||
47
+ trimmed.startsWith("<ac:") ||
48
+ trimmed.startsWith("</ac:") ||
49
+ trimmed.startsWith("<p>") ||
50
+ trimmed.startsWith("<table")) {
51
+ result.push(line);
52
+ }
53
+ else {
54
+ result.push(`<p>${trimmed}</p>`);
55
+ }
56
+ }
57
+ return result
58
+ .join("\n")
59
+ .replace(/\n{3,}/g, "\n\n")
60
+ .trim();
61
+ }
62
+ /**
63
+ * Read content from a file path or treat as inline content.
64
+ * If the string ends in .md, read the file and convert.
65
+ * If it ends in .html or .xml, read the file as-is (assume storage format).
66
+ * Otherwise treat it as inline markdown and convert.
67
+ */
68
+ export async function resolveBody(input) {
69
+ const { readFile } = await import("node:fs/promises");
70
+ if (input.endsWith(".md")) {
71
+ const content = await readFile(input, "utf-8");
72
+ return markdownToStorage(content);
73
+ }
74
+ if (input.endsWith(".html") || input.endsWith(".xml")) {
75
+ return readFile(input, "utf-8");
76
+ }
77
+ // Inline content — if it looks like HTML, pass through; otherwise convert
78
+ if (input.trimStart().startsWith("<")) {
79
+ return input;
80
+ }
81
+ return markdownToStorage(input);
82
+ }
83
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/core/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ export interface ConfluenceConfig {
2
+ baseUrl: string;
3
+ email: string;
4
+ token: string;
5
+ }
6
+ export interface ConfluencePage {
7
+ id: string;
8
+ title: string;
9
+ status: string;
10
+ spaceId: string;
11
+ version: {
12
+ number: number;
13
+ message?: string;
14
+ createdAt?: string;
15
+ };
16
+ body?: {
17
+ storage?: {
18
+ value: string;
19
+ };
20
+ };
21
+ _links?: {
22
+ webui?: string;
23
+ base?: string;
24
+ };
25
+ }
26
+ export interface ConfluenceSpace {
27
+ id: string;
28
+ key: string;
29
+ name: string;
30
+ type: string;
31
+ status: string;
32
+ }
33
+ export interface PageCreateInput {
34
+ spaceId: string;
35
+ title: string;
36
+ body: string;
37
+ parentId?: string;
38
+ status?: "current" | "draft";
39
+ }
40
+ export interface PageUpdateInput {
41
+ pageId: string;
42
+ title?: string;
43
+ body?: string;
44
+ versionMessage?: string;
45
+ }
46
+ export interface PageSearchOptions {
47
+ spaceKey: string;
48
+ title?: string;
49
+ limit?: number;
50
+ }
51
+ export interface PaginatedResponse<T> {
52
+ results: T[];
53
+ _links?: {
54
+ next?: string;
55
+ };
56
+ }
57
+ export interface ApiError {
58
+ statusCode: number;
59
+ message: string;
60
+ data?: unknown;
61
+ }
62
+ export declare class ConfluenceApiError extends Error {
63
+ statusCode: number;
64
+ data?: unknown | undefined;
65
+ constructor(statusCode: number, message: string, data?: unknown | undefined);
66
+ }
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACvC,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAElC,UAAU,EAAE,MAAM;IAElB,IAAI,CAAC,EAAE,OAAO;gBAFd,UAAU,EAAE,MAAM,EACzB,OAAO,EAAE,MAAM,EACR,IAAI,CAAC,EAAE,OAAO,YAAA;CAKxB"}
@@ -0,0 +1,12 @@
1
+ // ── Confluence API types ──────────────────────────────────────────────
2
+ export class ConfluenceApiError extends Error {
3
+ statusCode;
4
+ data;
5
+ constructor(statusCode, message, data) {
6
+ super(`Confluence API ${statusCode}: ${message}`);
7
+ this.statusCode = statusCode;
8
+ this.data = data;
9
+ this.name = "ConfluenceApiError";
10
+ }
11
+ }
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,yEAAyE;AA4DzE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAElC;IAEA;IAHT,YACS,UAAkB,EACzB,OAAe,EACR,IAAc;QAErB,KAAK,CAAC,kBAAkB,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC;QAJ3C,eAAU,GAAV,UAAU,CAAQ;QAElB,SAAI,GAAJ,IAAI,CAAU;QAGrB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { ConfluenceClient, loadConfigFromEnv, ConfluenceApiError } from "../core/index.js";
6
+ import { resolveBody } from "../core/markdown.js";
7
+ // ── Client singleton ───────────────────────────────────────────────
8
+ let _client = null;
9
+ function getClient() {
10
+ if (!_client) {
11
+ const config = loadConfigFromEnv();
12
+ _client = new ConfluenceClient(config);
13
+ }
14
+ return _client;
15
+ }
16
+ function formatError(err) {
17
+ if (err instanceof ConfluenceApiError) {
18
+ return `Confluence API error ${err.statusCode}: ${err.message}${err.data ? "\n" + JSON.stringify(err.data, null, 2) : ""}`;
19
+ }
20
+ if (err instanceof Error)
21
+ return err.message;
22
+ return String(err);
23
+ }
24
+ // ── Server setup ───────────────────────────────────────────────────
25
+ const server = new McpServer({
26
+ name: "confluence",
27
+ version: "0.1.0",
28
+ });
29
+ // ── Tools ──────────────────────────────────────────────────────────
30
+ server.tool("confluence_auth", "Verify the Confluence connection and list accessible spaces", {}, async () => {
31
+ try {
32
+ const spaces = await getClient().verifyConnection();
33
+ const text = [
34
+ "Connected successfully.",
35
+ `Found ${spaces.length} space(s):`,
36
+ ...spaces.map((s) => `• ${s.name} [${s.key}] (id: ${s.id})`),
37
+ ].join("\n");
38
+ return { content: [{ type: "text", text }] };
39
+ }
40
+ catch (err) {
41
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
42
+ }
43
+ });
44
+ server.tool("confluence_list_spaces", "List available Confluence spaces", { limit: z.number().optional().describe("Max number of spaces to return (default 25)") }, async ({ limit }) => {
45
+ try {
46
+ const spaces = await getClient().listSpaces(limit ?? 25);
47
+ const text = spaces
48
+ .map((s) => `${s.name} [${s.key}] (id: ${s.id}, ${s.status})`)
49
+ .join("\n");
50
+ return { content: [{ type: "text", text: text || "No spaces found." }] };
51
+ }
52
+ catch (err) {
53
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
54
+ }
55
+ });
56
+ server.tool("confluence_read_page", "Read a Confluence page by its ID, returning title, metadata, and body content", { pageId: z.string().describe("The Confluence page ID") }, async ({ pageId }) => {
57
+ try {
58
+ const page = await getClient().getPage(pageId);
59
+ const text = [
60
+ `Title: ${page.title}`,
61
+ `ID: ${page.id}`,
62
+ `Status: ${page.status}`,
63
+ `Version: ${page.version.number}`,
64
+ `Space ID: ${page.spaceId}`,
65
+ "",
66
+ "--- Body (storage format) ---",
67
+ page.body?.storage?.value ?? "(empty)",
68
+ ].join("\n");
69
+ return { content: [{ type: "text", text }] };
70
+ }
71
+ catch (err) {
72
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
73
+ }
74
+ });
75
+ server.tool("confluence_search_pages", "Search for pages in a Confluence space by title", {
76
+ spaceKey: z.string().describe("The space key (e.g. 'DEV', 'HR')"),
77
+ title: z.string().optional().describe("Filter by page title (partial match)"),
78
+ limit: z.number().optional().describe("Max results (default 25)"),
79
+ }, async ({ spaceKey, title, limit }) => {
80
+ try {
81
+ const pages = await getClient().searchPages({ spaceKey, title, limit });
82
+ if (pages.length === 0) {
83
+ return { content: [{ type: "text", text: "No pages found." }] };
84
+ }
85
+ const text = pages
86
+ .map((p) => `${p.title} (id: ${p.id}, v${p.version?.number ?? "?"})`)
87
+ .join("\n");
88
+ return { content: [{ type: "text", text }] };
89
+ }
90
+ catch (err) {
91
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
92
+ }
93
+ });
94
+ server.tool("confluence_create_page", "Create a new Confluence page. IMPORTANT: Ask the user for confirmation before calling this tool.", {
95
+ spaceKey: z.string().describe("The space key to create the page in"),
96
+ title: z.string().describe("Page title"),
97
+ body: z.string().describe("Page content in Markdown or Confluence storage format (XHTML)"),
98
+ parentId: z.string().optional().describe("Parent page ID (omit for top-level)"),
99
+ draft: z.boolean().optional().describe("Create as draft instead of published"),
100
+ }, async ({ spaceKey, title, body, parentId, draft }) => {
101
+ try {
102
+ const client = getClient();
103
+ const space = await client.getSpaceByKey(spaceKey);
104
+ const resolvedBody = await resolveBody(body);
105
+ const page = await client.createPage({
106
+ spaceId: space.id,
107
+ title,
108
+ body: resolvedBody,
109
+ parentId,
110
+ status: draft ? "draft" : "current",
111
+ });
112
+ const text = [
113
+ `✓ Page created successfully.`,
114
+ ` Title: ${page.title}`,
115
+ ` ID: ${page.id}`,
116
+ ` Space: ${space.name} [${space.key}]`,
117
+ ` Status: ${page.status}`,
118
+ ` URL: ${process.env.CONFLUENCE_URL}/pages/${page.id}`,
119
+ ].join("\n");
120
+ return { content: [{ type: "text", text }] };
121
+ }
122
+ catch (err) {
123
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
124
+ }
125
+ });
126
+ server.tool("confluence_update_page", "Update an existing Confluence page. IMPORTANT: Ask the user for confirmation before calling this tool.", {
127
+ pageId: z.string().describe("The page ID to update"),
128
+ title: z.string().optional().describe("New title (omit to keep current)"),
129
+ body: z.string().optional().describe("New content in Markdown or Confluence storage format"),
130
+ versionMessage: z.string().optional().describe("Version change message"),
131
+ }, async ({ pageId, title, body, versionMessage }) => {
132
+ try {
133
+ const resolvedBody = body ? await resolveBody(body) : undefined;
134
+ const page = await getClient().updatePage({
135
+ pageId,
136
+ title,
137
+ body: resolvedBody,
138
+ versionMessage,
139
+ });
140
+ const text = [
141
+ `✓ Page updated successfully.`,
142
+ ` Title: ${page.title}`,
143
+ ` ID: ${page.id}`,
144
+ ` Version: ${page.version.number}`,
145
+ ` URL: ${process.env.CONFLUENCE_URL}/pages/${page.id}`,
146
+ ].join("\n");
147
+ return { content: [{ type: "text", text }] };
148
+ }
149
+ catch (err) {
150
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
151
+ }
152
+ });
153
+ server.tool("confluence_delete_page", "Delete a Confluence page. IMPORTANT: Ask the user for confirmation before calling this tool.", { pageId: z.string().describe("The page ID to delete") }, async ({ pageId }) => {
154
+ try {
155
+ // Fetch page info first so we can report what was deleted
156
+ const page = await getClient().getPage(pageId);
157
+ await getClient().deletePage(pageId);
158
+ return {
159
+ content: [
160
+ { type: "text", text: `✓ Deleted page "${page.title}" (id: ${pageId})` },
161
+ ],
162
+ };
163
+ }
164
+ catch (err) {
165
+ return { content: [{ type: "text", text: formatError(err) }], isError: true };
166
+ }
167
+ });
168
+ // ── Start ──────────────────────────────────────────────────────────
169
+ async function main() {
170
+ const transport = new StdioServerTransport();
171
+ await server.connect(transport);
172
+ console.error("Confluence MCP server running on stdio");
173
+ }
174
+ main().catch((err) => {
175
+ console.error("Fatal:", err);
176
+ process.exit(1);
177
+ });
178
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "confluence-tools",
3
+ "version": "0.1.0",
4
+ "description": "CLI and MCP server for Atlassian Confluence — read, create, update, and delete pages from your terminal or AI agent.",
5
+ "author": "GeeveeH Software",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "bin": {
9
+ "confluence": "./dist/cli/index.js",
10
+ "confluence-mcp": "./dist/mcp/index.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "exports": {
18
+ ".": "./dist/core/index.js",
19
+ "./mcp": "./dist/mcp/index.js"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "dev:cli": "tsx src/cli/index.ts",
24
+ "dev:mcp": "tsx src/mcp/index.ts",
25
+ "lint": "eslint src/",
26
+ "test": "vitest run",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "dependencies": {
30
+ "commander": "^13.1.0",
31
+ "chalk": "^5.4.1",
32
+ "@modelcontextprotocol/sdk": "^1.12.1",
33
+ "zod": "^3.24.4"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.15.0",
37
+ "tsx": "^4.19.0",
38
+ "typescript": "^5.8.0",
39
+ "vitest": "^3.1.0",
40
+ "eslint": "^9.20.0"
41
+ },
42
+ "engines": {
43
+ "node": ">=20"
44
+ }
45
+ }