@atlassian-dc-mcp/confluence 0.28.0 → 0.30.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/CHANGELOG.md +22 -0
- package/README.md +57 -0
- package/build/__tests__/confluence-download.test.d.ts +2 -0
- package/build/__tests__/confluence-download.test.d.ts.map +1 -0
- package/build/__tests__/confluence-download.test.js +69 -0
- package/build/__tests__/confluence-download.test.js.map +1 -0
- package/build/__tests__/confluence-upload.test.d.ts +2 -0
- package/build/__tests__/confluence-upload.test.d.ts.map +1 -0
- package/build/__tests__/confluence-upload.test.js +59 -0
- package/build/__tests__/confluence-upload.test.js.map +1 -0
- package/build/confluence-service.d.ts +63 -0
- package/build/confluence-service.d.ts.map +1 -1
- package/build/confluence-service.js +135 -3
- package/build/confluence-service.js.map +1 -1
- package/build/index.js +25 -2
- package/build/index.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/confluence-download.test.ts +89 -0
- package/src/__tests__/confluence-upload.test.ts +71 -0
- package/src/confluence-service.ts +177 -3
- package/src/index.ts +55 -2
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.30.0](https://github.com/b1ff/atlassian-dc-mcp/compare/v0.29.0...v0.30.0) (2026-08-30)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @atlassian-dc-mcp/confluence
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [0.29.0](https://github.com/b1ff/atlassian-dc-mcp/compare/v0.28.0...v0.29.0) (2026-07-26)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* add confluence_uploadAttachment tool ([b73cf9e](https://github.com/b1ff/atlassian-dc-mcp/commit/b73cf9ef1e296ca6639bf2a3f162d3f142115019))
|
|
20
|
+
* **attachments:** sandbox local filesystem access behind an opt-in gateway ([5cc1776](https://github.com/b1ff/atlassian-dc-mcp/commit/5cc177632d1441e1a644cb9db7396fbb9b754fe6))
|
|
21
|
+
* **confluence:** add confluence_downloadAttachment tool ([aae8aab](https://github.com/b1ff/atlassian-dc-mcp/commit/aae8aabd43602aece8da98c13a8052805ba0d14d))
|
|
22
|
+
* **confluence:** add versionIfExists flag to uploadAttachment ([1e0453f](https://github.com/b1ff/atlassian-dc-mcp/commit/1e0453fa01d984939def34a3da8a37927e13f4fe))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [0.28.0](https://github.com/b1ff/atlassian-dc-mcp/compare/v0.27.0...v0.28.0) (2026-07-22)
|
|
7
29
|
|
|
8
30
|
**Note:** Version bump only for package @atlassian-dc-mcp/confluence
|
package/README.md
CHANGED
|
@@ -103,6 +103,37 @@ Available flags: `--host`/`-H`, `--api-base-path`/`-b`, `--token`/`-t`, `--defau
|
|
|
103
103
|
|
|
104
104
|
See [Configuration sources](#configuration-sources) for the full precedence chain.
|
|
105
105
|
|
|
106
|
+
### Attachment filesystem access (opt-in)
|
|
107
|
+
|
|
108
|
+
By default this server is an API-only client: the attachment tools never read from or write to the local filesystem, and `confluence_uploadAttachment` is **not even registered**. `confluence_downloadAttachment` is always available but can only return file bytes inline (base64/text) — it cannot touch local disk.
|
|
109
|
+
|
|
110
|
+
Local filesystem access is opt-in and confined to operator-configured directories that the model cannot choose:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
# Enable each direction separately (default: false)
|
|
114
|
+
CONFLUENCE_ATTACHMENTS_UPLOAD_ENABLED=true
|
|
115
|
+
CONFLUENCE_ATTACHMENTS_DOWNLOAD_ENABLED=true
|
|
116
|
+
|
|
117
|
+
# Allowed roots (os path-separator list). Uploads may only read from these,
|
|
118
|
+
# downloads may only write into the first configured download root.
|
|
119
|
+
CONFLUENCE_ATTACHMENTS_UPLOAD_ROOTS=/srv/confluence-exchange/in
|
|
120
|
+
CONFLUENCE_ATTACHMENTS_DOWNLOAD_ROOTS=/srv/confluence-exchange/out
|
|
121
|
+
|
|
122
|
+
# Convenience: a single dedicated exchange directory used as both roots
|
|
123
|
+
CONFLUENCE_ATTACHMENTS_DIR=/srv/confluence-exchange
|
|
124
|
+
|
|
125
|
+
# Hard per-file size limits in bytes (default: 25 MiB)
|
|
126
|
+
CONFLUENCE_ATTACHMENTS_MAX_UPLOAD_BYTES=26214400
|
|
127
|
+
CONFLUENCE_ATTACHMENTS_MAX_DOWNLOAD_BYTES=26214400
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Guardrails applied when enabled:
|
|
131
|
+
- A direction only activates when its flag is set **and** at least one root resolves; otherwise the tool stays disabled and a warning is logged.
|
|
132
|
+
- Roots are canonicalized (realpath) at startup. Requested paths are relative to a root; absolute paths and `..` segments are rejected, and a path that escapes a root through a symlinked directory is refused.
|
|
133
|
+
- Uploads reject symlinks and non-regular files (FIFOs, devices, directories).
|
|
134
|
+
- Downloads never overwrite an existing file (including a symlink) — they use an exclusive write.
|
|
135
|
+
- Both directions enforce the configured hard size limit.
|
|
136
|
+
|
|
106
137
|
To create a personal access token:
|
|
107
138
|
- In Confluence, select your profile picture at the top right
|
|
108
139
|
- Select **Settings** > **Personal Access Tokens**
|
|
@@ -209,3 +240,29 @@ Parameters:
|
|
|
209
240
|
- `start` (number, optional): Start index for pagination
|
|
210
241
|
- `expand` (string, optional): Comma-separated list of properties to expand
|
|
211
242
|
- `excerpt` (`none` | `highlight`, optional): Excerpt mode for search results. Defaults to `none`.
|
|
243
|
+
|
|
244
|
+
#### 6. confluence_uploadAttachment
|
|
245
|
+
|
|
246
|
+
Upload a local file as an attachment to a Confluence content (page). Only registered when filesystem uploads are enabled (see [Attachment filesystem access](#attachment-filesystem-access-opt-in)).
|
|
247
|
+
|
|
248
|
+
Parameters:
|
|
249
|
+
- `contentId` (string, required): ID of the content (page) to attach the file to
|
|
250
|
+
- `sourcePath` (string, required): Path to the file to upload, **relative to a server-configured upload directory**. Absolute paths and `..` segments are rejected; symlinks and non-regular files are refused.
|
|
251
|
+
- `filename` (string, optional): Override for the attachment filename (defaults to the basename of `sourcePath`)
|
|
252
|
+
- `comment` (string, optional): Comment describing the attachment
|
|
253
|
+
- `minorEdit` (boolean, optional): If true, no notification email is sent to watchers
|
|
254
|
+
- `hidden` (boolean, optional): If true, no notification email or activity stream entry is generated
|
|
255
|
+
- `allowDuplicated` (boolean, optional): Allow upload even if an attachment with the same filename already exists
|
|
256
|
+
- `versionIfExists` (boolean, optional): If true and an attachment with the same filename already exists, upload as a new version instead of failing
|
|
257
|
+
|
|
258
|
+
#### 7. confluence_downloadAttachment
|
|
259
|
+
|
|
260
|
+
Download one or more attachments from a Confluence content (page). Returns the file content inline (base64 or text) — useful for inspecting a file or moving it elsewhere (e.g. re-uploading to a Jira issue). When filesystem downloads are enabled (see [Attachment filesystem access](#attachment-filesystem-access-opt-in)), it can also save into the server-configured download directory.
|
|
261
|
+
|
|
262
|
+
Parameters:
|
|
263
|
+
- `contentId` (string, required): ID of the content (page) whose attachment(s) to download
|
|
264
|
+
- `filename` (string, optional): Exact filename of a single attachment to download. If omitted, all attachments on the content are downloaded.
|
|
265
|
+
- `returnContent` (`none` | `base64` | `text`, optional): Whether to embed the file bytes in the response. Defaults to `none`.
|
|
266
|
+
- `maxInlineBytes` (number, optional): Maximum bytes to embed inline when `returnContent` is `base64`/`text`. Larger files are omitted from the inline content. Defaults to 1 MiB.
|
|
267
|
+
- `save` (boolean, optional): Save the attachment(s) into the server-configured download directory. Requires filesystem downloads to be enabled; existing files are never overwritten. *(Only available when downloads are enabled.)*
|
|
268
|
+
- `saveName` (string, optional): File name (no directories) to use when saving a single attachment; defaults to the attachment's own name. *(Only available when downloads are enabled.)*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence-download.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/confluence-download.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ConfluenceService } from '../confluence-service.js';
|
|
2
|
+
import { AttachmentsService } from '../confluence-client/index.js';
|
|
3
|
+
const DISABLED_DOWNLOAD = { enabled: false, roots: [], maxBytes: 25 * 1024 * 1024 };
|
|
4
|
+
jest.mock('../confluence-client/index.js', () => ({
|
|
5
|
+
AttachmentsService: {
|
|
6
|
+
getAttachments: jest.fn(),
|
|
7
|
+
},
|
|
8
|
+
ContentResourceService: {},
|
|
9
|
+
SearchService: {},
|
|
10
|
+
UserService: {},
|
|
11
|
+
OpenAPI: { BASE: '', TOKEN: '', VERSION: '' },
|
|
12
|
+
}));
|
|
13
|
+
function mockFetchText(text) {
|
|
14
|
+
global.fetch = jest.fn().mockResolvedValue({
|
|
15
|
+
ok: true,
|
|
16
|
+
status: 200,
|
|
17
|
+
statusText: 'OK',
|
|
18
|
+
headers: { get: () => 'text/plain' },
|
|
19
|
+
arrayBuffer: async () => Buffer.from(text),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
describe('ConfluenceService.downloadAttachmentFromContent', () => {
|
|
23
|
+
let service;
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
service = new ConfluenceService('test-host', 'test-token');
|
|
26
|
+
jest.clearAllMocks();
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => jest.restoreAllMocks());
|
|
29
|
+
it('builds an absolute download URL from the relative _links.download and returns content', async () => {
|
|
30
|
+
AttachmentsService.getAttachments.mockResolvedValue({
|
|
31
|
+
results: [
|
|
32
|
+
{ title: 'doc.txt', metadata: { mediaType: 'text/plain' }, _links: { download: '/download/attachments/123/doc.txt?version=1' } },
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
mockFetchText('file body');
|
|
36
|
+
const result = await service.downloadAttachmentFromContent({ contentId: '123', filename: 'doc.txt', returnContent: 'text', downloadSide: DISABLED_DOWNLOAD });
|
|
37
|
+
expect(AttachmentsService.getAttachments).toHaveBeenCalledWith('123', undefined, 'doc.txt');
|
|
38
|
+
expect(global.fetch).toHaveBeenCalledWith('https://test-host/download/attachments/123/doc.txt?version=1', expect.objectContaining({ headers: expect.objectContaining({ Authorization: 'Bearer test-token' }) }));
|
|
39
|
+
expect(result.success).toBe(true);
|
|
40
|
+
expect(result.data).toMatchObject({ contentId: '123', count: 1 });
|
|
41
|
+
expect(result.data.attachments[0]).toMatchObject({ filename: 'doc.txt', content: 'file body', mediaType: 'text/plain' });
|
|
42
|
+
});
|
|
43
|
+
it('downloads all attachments when no filename is given', async () => {
|
|
44
|
+
AttachmentsService.getAttachments.mockResolvedValue({
|
|
45
|
+
results: [
|
|
46
|
+
{ title: 'a.txt', _links: { download: '/download/attachments/123/a.txt' } },
|
|
47
|
+
{ title: 'b.txt', _links: { download: '/download/attachments/123/b.txt' } },
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
mockFetchText('x');
|
|
51
|
+
const result = await service.downloadAttachmentFromContent({ contentId: '123', downloadSide: DISABLED_DOWNLOAD });
|
|
52
|
+
expect(result.success).toBe(true);
|
|
53
|
+
expect(result.data.count).toBe(2);
|
|
54
|
+
expect(global.fetch).toHaveBeenCalledTimes(2);
|
|
55
|
+
});
|
|
56
|
+
it('returns a failure when the content has no matching attachment', async () => {
|
|
57
|
+
AttachmentsService.getAttachments.mockResolvedValue({ results: [] });
|
|
58
|
+
const result = await service.downloadAttachmentFromContent({ contentId: '123', filename: 'missing.txt', downloadSide: DISABLED_DOWNLOAD });
|
|
59
|
+
expect(result.success).toBe(false);
|
|
60
|
+
expect(result.error).toContain('No attachment named "missing.txt"');
|
|
61
|
+
});
|
|
62
|
+
it('refuses to save to disk when downloads are disabled', async () => {
|
|
63
|
+
const result = await service.downloadAttachmentFromContent({ contentId: '123', filename: 'doc.txt', save: true, downloadSide: DISABLED_DOWNLOAD });
|
|
64
|
+
expect(result.success).toBe(false);
|
|
65
|
+
expect(result.error).toContain('disabled');
|
|
66
|
+
expect(global.fetch).not.toHaveBeenCalled();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=confluence-download.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence-download.test.js","sourceRoot":"","sources":["../../src/__tests__/confluence-download.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence-upload.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/confluence-upload.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { ConfluenceService } from '../confluence-service.js';
|
|
5
|
+
import { AttachmentsService } from '../confluence-client/index.js';
|
|
6
|
+
jest.mock('../confluence-client/index.js', () => ({
|
|
7
|
+
AttachmentsService: {
|
|
8
|
+
getAttachments: jest.fn(),
|
|
9
|
+
createAttachments: jest.fn(),
|
|
10
|
+
updateData: jest.fn(),
|
|
11
|
+
},
|
|
12
|
+
ContentResourceService: {},
|
|
13
|
+
SearchService: {},
|
|
14
|
+
UserService: {},
|
|
15
|
+
OpenAPI: { BASE: '', TOKEN: '', VERSION: '', HEADERS: undefined },
|
|
16
|
+
}));
|
|
17
|
+
describe('ConfluenceService.uploadAttachment', () => {
|
|
18
|
+
let service;
|
|
19
|
+
let root;
|
|
20
|
+
const uploadSide = () => ({ enabled: true, roots: [fs.realpathSync(root)], maxBytes: 1024 });
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
service = new ConfluenceService('test-host', 'test-token');
|
|
23
|
+
root = fs.mkdtempSync(path.join(os.tmpdir(), 'dc-mcp-cup-'));
|
|
24
|
+
jest.clearAllMocks();
|
|
25
|
+
AttachmentsService.createAttachments.mockResolvedValue({ results: [{ id: '1', title: 'a.txt' }] });
|
|
26
|
+
});
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
29
|
+
jest.restoreAllMocks();
|
|
30
|
+
});
|
|
31
|
+
it('uploads a file resolved within the upload root', async () => {
|
|
32
|
+
fs.writeFileSync(path.join(root, 'a.txt'), 'hello');
|
|
33
|
+
const result = await service.uploadAttachment('42', 'a.txt', uploadSide());
|
|
34
|
+
expect(result.success).toBe(true);
|
|
35
|
+
expect(AttachmentsService.createAttachments).toHaveBeenCalledTimes(1);
|
|
36
|
+
const formData = AttachmentsService.createAttachments.mock.calls[0][4];
|
|
37
|
+
expect(formData.file.name).toBe('a.txt');
|
|
38
|
+
});
|
|
39
|
+
it('rejects an absolute path outside the root', async () => {
|
|
40
|
+
const result = await service.uploadAttachment('42', '/etc/passwd', uploadSide());
|
|
41
|
+
expect(result.success).toBe(false);
|
|
42
|
+
expect(AttachmentsService.createAttachments).not.toHaveBeenCalled();
|
|
43
|
+
});
|
|
44
|
+
it('rejects a symlink inside the root', async () => {
|
|
45
|
+
const target = path.join(root, 'real.txt');
|
|
46
|
+
fs.writeFileSync(target, 'secret');
|
|
47
|
+
fs.symlinkSync(target, path.join(root, 'link.txt'));
|
|
48
|
+
const result = await service.uploadAttachment('42', 'link.txt', uploadSide());
|
|
49
|
+
expect(result.success).toBe(false);
|
|
50
|
+
expect(AttachmentsService.createAttachments).not.toHaveBeenCalled();
|
|
51
|
+
});
|
|
52
|
+
it('rejects a file over the size limit', async () => {
|
|
53
|
+
fs.writeFileSync(path.join(root, 'big.txt'), 'x'.repeat(2048));
|
|
54
|
+
const result = await service.uploadAttachment('42', 'big.txt', uploadSide());
|
|
55
|
+
expect(result.success).toBe(false);
|
|
56
|
+
expect(AttachmentsService.createAttachments).not.toHaveBeenCalled();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=confluence-upload.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence-upload.test.js","sourceRoot":"","sources":["../../src/__tests__/confluence-upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,IAAI,CAAC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,kBAAkB,EAAE;QAClB,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;QACzB,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5B,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;KACtB;IACD,sBAAsB,EAAE,EAAE;IAC1B,aAAa,EAAE,EAAE;IACjB,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;CAClE,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,IAAI,OAA0B,CAAC;IAC/B,IAAI,IAAY,CAAC;IACjB,MAAM,UAAU,GAAG,GAA0B,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpH,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC3D,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,aAAa,EAAE,CAAC;QACpB,kBAAkB,CAAC,iBAA+B,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACpH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAE3E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAI,kBAAkB,CAAC,iBAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAC;QACjF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC3C,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;QAC7E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { type AttachmentContentEncoding, type AttachmentGatewaySide } from '@atlassian-dc-mcp/common';
|
|
2
3
|
import { ConfluenceBodyMode } from './confluence-response-mapper.js';
|
|
3
4
|
/**
|
|
4
5
|
* Escapes user input for safe use inside a CQL quoted string.
|
|
@@ -29,7 +30,14 @@ export interface ConfluenceContent {
|
|
|
29
30
|
}
|
|
30
31
|
export declare class ConfluenceService {
|
|
31
32
|
private readonly getPageSize;
|
|
33
|
+
private readonly baseUrl;
|
|
34
|
+
private readonly tokenProvider;
|
|
32
35
|
constructor(host: string | undefined, token: string | (() => string | undefined), apiBasePath?: string, getPageSize?: () => number);
|
|
36
|
+
/**
|
|
37
|
+
* Builds an absolute download URL from a Confluence attachment `_links.download`
|
|
38
|
+
* value, which is a path relative to the site base (context path included).
|
|
39
|
+
*/
|
|
40
|
+
private buildDownloadUrl;
|
|
33
41
|
/**
|
|
34
42
|
* Get a Confluence page by ID
|
|
35
43
|
* @param contentId The ID of the page to retrieve
|
|
@@ -74,6 +82,41 @@ export declare class ConfluenceService {
|
|
|
74
82
|
* @param content The updated content object
|
|
75
83
|
*/
|
|
76
84
|
updateContent(contentId: string, content: ConfluenceContent): Promise<import("@atlassian-dc-mcp/common").ApiErrorResponse<import("./confluence-client/index.js").Content>>;
|
|
85
|
+
/**
|
|
86
|
+
* Upload a file as an attachment to a Confluence content entity
|
|
87
|
+
* @param contentId The ID of the content the attachment will be attached to
|
|
88
|
+
* @param sourcePath Path to the file to upload, relative to a server-configured upload directory
|
|
89
|
+
* @param uploadSide Resolved upload gateway (roots, size limit, enabled flag)
|
|
90
|
+
* @param filename Optional override for the attachment filename (defaults to basename of sourcePath)
|
|
91
|
+
* @param comment Optional comment describing the attachment
|
|
92
|
+
* @param minorEdit If true, no notification email will be generated
|
|
93
|
+
* @param hidden If true, no notification email or activity stream entry will be generated
|
|
94
|
+
* @param allowDuplicated Allow upload even if an attachment with the same filename exists
|
|
95
|
+
*/
|
|
96
|
+
uploadAttachment(contentId: string, sourcePath: string, uploadSide: AttachmentGatewaySide, filename?: string, comment?: string, minorEdit?: boolean, hidden?: boolean, allowDuplicated?: boolean, versionIfExists?: boolean): Promise<import("@atlassian-dc-mcp/common").ApiErrorResponse<import("./confluence-client/index.js").Content>>;
|
|
97
|
+
/**
|
|
98
|
+
* Download one or more attachments from a Confluence content entity.
|
|
99
|
+
* @param params.contentId The ID of the content the attachment(s) are on
|
|
100
|
+
* @param params.filename If provided, download only the attachment with this exact filename; otherwise download all attachments on the content
|
|
101
|
+
* @param params.save Whether to write the attachment(s) to the operator-configured download directory
|
|
102
|
+
* @param params.saveName Optional file name (basename only) when saving a single attachment
|
|
103
|
+
* @param params.returnContent Whether/how to embed the bytes inline in the response
|
|
104
|
+
* @param params.maxInlineBytes Inline embedding cap
|
|
105
|
+
* @param params.downloadSide Resolved download gateway (roots, size limit, enabled flag)
|
|
106
|
+
*/
|
|
107
|
+
downloadAttachmentFromContent(params: {
|
|
108
|
+
contentId: string;
|
|
109
|
+
filename?: string;
|
|
110
|
+
save?: boolean;
|
|
111
|
+
saveName?: string;
|
|
112
|
+
returnContent?: AttachmentContentEncoding;
|
|
113
|
+
maxInlineBytes?: number;
|
|
114
|
+
downloadSide: AttachmentGatewaySide;
|
|
115
|
+
}): Promise<import("@atlassian-dc-mcp/common").ApiErrorResponse<{
|
|
116
|
+
contentId: string;
|
|
117
|
+
count: number;
|
|
118
|
+
attachments: import("@atlassian-dc-mcp/common").AttachmentDownloadResult[];
|
|
119
|
+
}>>;
|
|
77
120
|
/**
|
|
78
121
|
* Search for spaces by text
|
|
79
122
|
* @param searchText Text to search for in space names or descriptions
|
|
@@ -136,5 +179,25 @@ export declare const confluenceToolSchemas: {
|
|
|
136
179
|
expand: z.ZodOptional<z.ZodString>;
|
|
137
180
|
excerpt: z.ZodOptional<z.ZodEnum<["none", "highlight"]>>;
|
|
138
181
|
};
|
|
182
|
+
uploadAttachment: {
|
|
183
|
+
contentId: z.ZodString;
|
|
184
|
+
sourcePath: z.ZodString;
|
|
185
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
186
|
+
comment: z.ZodOptional<z.ZodString>;
|
|
187
|
+
minorEdit: z.ZodOptional<z.ZodBoolean>;
|
|
188
|
+
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
189
|
+
allowDuplicated: z.ZodOptional<z.ZodBoolean>;
|
|
190
|
+
versionIfExists: z.ZodOptional<z.ZodBoolean>;
|
|
191
|
+
};
|
|
192
|
+
downloadAttachment: {
|
|
193
|
+
contentId: z.ZodString;
|
|
194
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
195
|
+
returnContent: z.ZodOptional<z.ZodEnum<["none", "base64", "text"]>>;
|
|
196
|
+
maxInlineBytes: z.ZodOptional<z.ZodNumber>;
|
|
197
|
+
};
|
|
198
|
+
downloadAttachmentSaveFields: {
|
|
199
|
+
save: z.ZodOptional<z.ZodBoolean>;
|
|
200
|
+
saveName: z.ZodOptional<z.ZodString>;
|
|
201
|
+
};
|
|
139
202
|
};
|
|
140
203
|
//# sourceMappingURL=confluence-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confluence-service.d.ts","sourceRoot":"","sources":["../src/confluence-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"confluence-service.d.ts","sourceRoot":"","sources":["../src/confluence-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { File } from 'node:buffer';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { basename } from 'node:path';
|
|
1
4
|
import { z } from 'zod';
|
|
2
|
-
import { ContentResourceService, OpenAPI, SearchService, UserService } from './confluence-client/index.js';
|
|
3
|
-
import { handleApiOperation, resolveOpenApiBase } from '@atlassian-dc-mcp/common';
|
|
5
|
+
import { AttachmentsService, ContentResourceService, OpenAPI, SearchService, UserService } from './confluence-client/index.js';
|
|
6
|
+
import { downloadAttachment, handleApiOperation, resolveDownloadDestination, resolveOpenApiBase, resolveUploadSource, } from '@atlassian-dc-mcp/common';
|
|
4
7
|
import { CONFLUENCE_PRODUCT, getDefaultPageSize, getMissingConfig } from './config.js';
|
|
5
8
|
import { shapeConfluenceContent } from './confluence-response-mapper.js';
|
|
6
9
|
/**
|
|
@@ -22,17 +25,33 @@ function resolveToken(token, missingTokenMessage) {
|
|
|
22
25
|
}
|
|
23
26
|
export class ConfluenceService {
|
|
24
27
|
getPageSize;
|
|
28
|
+
baseUrl;
|
|
29
|
+
tokenProvider;
|
|
25
30
|
constructor(host, token, apiBasePath, getPageSize = getDefaultPageSize) {
|
|
26
|
-
|
|
31
|
+
const base = resolveOpenApiBase({
|
|
27
32
|
host,
|
|
28
33
|
apiBasePath,
|
|
29
34
|
defaultBasePath: CONFLUENCE_PRODUCT.defaultApiBasePath ?? '',
|
|
30
35
|
strippableSuffixes: CONFLUENCE_PRODUCT.apiBasePathStrippableSuffixes,
|
|
31
36
|
});
|
|
37
|
+
OpenAPI.BASE = base;
|
|
32
38
|
OpenAPI.TOKEN = resolveToken(token, 'Missing required environment variable: CONFLUENCE_API_TOKEN');
|
|
33
39
|
OpenAPI.VERSION = '1.0';
|
|
40
|
+
this.baseUrl = base;
|
|
41
|
+
this.tokenProvider = token;
|
|
34
42
|
this.getPageSize = getPageSize;
|
|
35
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Builds an absolute download URL from a Confluence attachment `_links.download`
|
|
46
|
+
* value, which is a path relative to the site base (context path included).
|
|
47
|
+
*/
|
|
48
|
+
buildDownloadUrl(downloadLink) {
|
|
49
|
+
if (/^https?:\/\//i.test(downloadLink)) {
|
|
50
|
+
return downloadLink;
|
|
51
|
+
}
|
|
52
|
+
const base = this.baseUrl.replace(/\/$/, '');
|
|
53
|
+
return `${base}${downloadLink.startsWith('/') ? '' : '/'}${downloadLink}`;
|
|
54
|
+
}
|
|
36
55
|
/**
|
|
37
56
|
* Get a Confluence page by ID
|
|
38
57
|
* @param contentId The ID of the page to retrieve
|
|
@@ -80,6 +99,99 @@ export class ConfluenceService {
|
|
|
80
99
|
async updateContent(contentId, content) {
|
|
81
100
|
return handleApiOperation(() => ContentResourceService.update2(contentId, content), 'Error updating content');
|
|
82
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Upload a file as an attachment to a Confluence content entity
|
|
104
|
+
* @param contentId The ID of the content the attachment will be attached to
|
|
105
|
+
* @param sourcePath Path to the file to upload, relative to a server-configured upload directory
|
|
106
|
+
* @param uploadSide Resolved upload gateway (roots, size limit, enabled flag)
|
|
107
|
+
* @param filename Optional override for the attachment filename (defaults to basename of sourcePath)
|
|
108
|
+
* @param comment Optional comment describing the attachment
|
|
109
|
+
* @param minorEdit If true, no notification email will be generated
|
|
110
|
+
* @param hidden If true, no notification email or activity stream entry will be generated
|
|
111
|
+
* @param allowDuplicated Allow upload even if an attachment with the same filename exists
|
|
112
|
+
*/
|
|
113
|
+
async uploadAttachment(contentId, sourcePath, uploadSide, filename, comment, minorEdit, hidden, allowDuplicated, versionIfExists) {
|
|
114
|
+
return handleApiOperation(async () => {
|
|
115
|
+
const { absolutePath } = await resolveUploadSource({ requestedPath: sourcePath, side: uploadSide });
|
|
116
|
+
const buffer = await readFile(absolutePath);
|
|
117
|
+
const name = filename || basename(absolutePath);
|
|
118
|
+
const file = new File([buffer], name);
|
|
119
|
+
// X-Atlassian-Token: nocheck is required for multipart attachment POSTs (XSRF bypass).
|
|
120
|
+
// Set it only for the duration of this call; restore afterwards.
|
|
121
|
+
const prevHeaders = OpenAPI.HEADERS;
|
|
122
|
+
OpenAPI.HEADERS = { 'X-Atlassian-Token': 'nocheck' };
|
|
123
|
+
try {
|
|
124
|
+
if (versionIfExists) {
|
|
125
|
+
const existing = await AttachmentsService.getAttachments(contentId, undefined, name);
|
|
126
|
+
const existingId = existing?.results?.[0]?.id;
|
|
127
|
+
if (existingId) {
|
|
128
|
+
// MockAttachmentRequest types file as string, but getFormData handles Blob/File via isBlob()
|
|
129
|
+
return await AttachmentsService.updateData(existingId, contentId, { file });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// MockAttachmentRequest types file as string, but getFormData in request.ts handles Blob/File via isBlob()
|
|
133
|
+
const formData = { file, comment, minorEdit, hidden };
|
|
134
|
+
return await AttachmentsService.createAttachments(contentId, undefined, allowDuplicated ? 'true' : undefined, undefined, formData);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
OpenAPI.HEADERS = prevHeaders;
|
|
138
|
+
}
|
|
139
|
+
}, 'Error uploading attachment');
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Download one or more attachments from a Confluence content entity.
|
|
143
|
+
* @param params.contentId The ID of the content the attachment(s) are on
|
|
144
|
+
* @param params.filename If provided, download only the attachment with this exact filename; otherwise download all attachments on the content
|
|
145
|
+
* @param params.save Whether to write the attachment(s) to the operator-configured download directory
|
|
146
|
+
* @param params.saveName Optional file name (basename only) when saving a single attachment
|
|
147
|
+
* @param params.returnContent Whether/how to embed the bytes inline in the response
|
|
148
|
+
* @param params.maxInlineBytes Inline embedding cap
|
|
149
|
+
* @param params.downloadSide Resolved download gateway (roots, size limit, enabled flag)
|
|
150
|
+
*/
|
|
151
|
+
async downloadAttachmentFromContent(params) {
|
|
152
|
+
return handleApiOperation(async () => {
|
|
153
|
+
if (params.save && !params.downloadSide.enabled) {
|
|
154
|
+
throw new Error('Saving attachments to disk is disabled on this server. Enable it with ' +
|
|
155
|
+
'CONFLUENCE_ATTACHMENTS_DOWNLOAD_ENABLED and configure a download directory.');
|
|
156
|
+
}
|
|
157
|
+
const list = await AttachmentsService.getAttachments(params.contentId, undefined, params.filename);
|
|
158
|
+
const results = (list?.results ?? []);
|
|
159
|
+
if (results.length === 0) {
|
|
160
|
+
throw new Error(params.filename
|
|
161
|
+
? `No attachment named "${params.filename}" found on content ${params.contentId}`
|
|
162
|
+
: `No attachments found on content ${params.contentId}`);
|
|
163
|
+
}
|
|
164
|
+
const targets = params.filename ? [results[0]] : results;
|
|
165
|
+
const multiple = targets.length > 1;
|
|
166
|
+
const attachments = [];
|
|
167
|
+
for (const attachment of targets) {
|
|
168
|
+
const downloadLink = attachment?._links?.download;
|
|
169
|
+
if (!downloadLink) {
|
|
170
|
+
throw new Error(`Attachment "${attachment?.title ?? params.filename}" has no download link`);
|
|
171
|
+
}
|
|
172
|
+
const name = attachment?.title ?? params.filename ?? 'attachment';
|
|
173
|
+
const mediaType = attachment?.metadata?.mediaType ?? attachment?.extensions?.mediaType;
|
|
174
|
+
let destination;
|
|
175
|
+
if (params.save) {
|
|
176
|
+
const requestedName = multiple ? name : params.saveName ?? name;
|
|
177
|
+
destination = await resolveDownloadDestination({ requestedName, side: params.downloadSide });
|
|
178
|
+
}
|
|
179
|
+
attachments.push(await downloadAttachment({
|
|
180
|
+
url: this.buildDownloadUrl(downloadLink),
|
|
181
|
+
token: this.tokenProvider,
|
|
182
|
+
filename: name,
|
|
183
|
+
mediaType,
|
|
184
|
+
options: {
|
|
185
|
+
destination,
|
|
186
|
+
returnContent: params.returnContent,
|
|
187
|
+
maxInlineBytes: params.maxInlineBytes,
|
|
188
|
+
maxDownloadBytes: params.downloadSide.maxBytes,
|
|
189
|
+
},
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
return { contentId: params.contentId, count: attachments.length, attachments };
|
|
193
|
+
}, 'Error downloading attachment');
|
|
194
|
+
}
|
|
83
195
|
/**
|
|
84
196
|
* Search for spaces by text
|
|
85
197
|
* @param searchText Text to search for in space names or descriptions
|
|
@@ -138,6 +250,26 @@ export const confluenceToolSchemas = {
|
|
|
138
250
|
start: z.number().optional().describe("Start index for pagination"),
|
|
139
251
|
expand: z.string().optional().describe("Comma-separated list of properties to expand"),
|
|
140
252
|
excerpt: z.enum(['none', 'highlight']).optional().describe("Excerpt mode for search results. Defaults to none.")
|
|
253
|
+
},
|
|
254
|
+
uploadAttachment: {
|
|
255
|
+
contentId: z.string().describe("ID of the Confluence content (page) to attach the file to"),
|
|
256
|
+
sourcePath: z.string().describe("Path to the file to upload, relative to a server-configured attachment upload directory. Absolute paths and '..' segments are rejected; symlinks and non-regular files are refused."),
|
|
257
|
+
filename: z.string().optional().describe("Override for the attachment filename (defaults to the basename of sourcePath)"),
|
|
258
|
+
comment: z.string().optional().describe("Optional comment describing the attachment"),
|
|
259
|
+
minorEdit: z.boolean().optional().describe("If true, no notification email is sent to watchers"),
|
|
260
|
+
hidden: z.boolean().optional().describe("If true, no notification email or activity stream entry is generated"),
|
|
261
|
+
allowDuplicated: z.boolean().optional().describe("Allow upload even if an attachment with the same filename already exists"),
|
|
262
|
+
versionIfExists: z.boolean().optional().describe("If true and an attachment with the same filename already exists, upload as a new version instead of failing")
|
|
263
|
+
},
|
|
264
|
+
downloadAttachment: {
|
|
265
|
+
contentId: z.string().describe("ID of the Confluence content (page) whose attachment(s) to download"),
|
|
266
|
+
filename: z.string().optional().describe("Exact filename of a single attachment to download. If omitted, all attachments on the content are downloaded."),
|
|
267
|
+
returnContent: z.enum(['none', 'base64', 'text']).optional().describe("Whether to embed the file bytes in the response: 'none' (default), 'base64' for binary, or 'text' for UTF-8 text."),
|
|
268
|
+
maxInlineBytes: z.number().optional().describe("Maximum bytes to embed inline when returnContent is base64/text. Larger files are omitted from the inline content. Defaults to 1 MiB.")
|
|
269
|
+
},
|
|
270
|
+
downloadAttachmentSaveFields: {
|
|
271
|
+
save: z.boolean().optional().describe("Save the attachment(s) into the server-configured download directory. Requires disk downloads to be enabled on the server."),
|
|
272
|
+
saveName: z.string().optional().describe("Optional file name (no directories) to use when saving a single attachment; defaults to the attachment's own name. Existing files are never overwritten.")
|
|
141
273
|
}
|
|
142
274
|
};
|
|
143
275
|
//# sourceMappingURL=confluence-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confluence-service.js","sourceRoot":"","sources":["../src/confluence-service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"confluence-service.js","sourceRoot":"","sources":["../src/confluence-service.ts"],"names":[],"mappings":"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"}
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { connectServer, createMcpServer, formatToolResponse, initializeRuntimeConfig } from '@atlassian-dc-mcp/common';
|
|
1
|
+
import { connectServer, createMcpServer, formatToolResponse, initializeRuntimeConfig, resolveAttachmentGateway } from '@atlassian-dc-mcp/common';
|
|
2
2
|
import { ConfluenceService, confluenceToolSchemas } from './confluence-service.js';
|
|
3
3
|
import { shapeConfluenceMutationAck } from './confluence-response-mapper.js';
|
|
4
|
-
import { getConfluenceRuntimeConfig, getDefaultPageSize } from './config.js';
|
|
4
|
+
import { CONFLUENCE_PRODUCT, getConfluenceRuntimeConfig, getDefaultPageSize } from './config.js';
|
|
5
5
|
import { createRequire } from 'node:module';
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
7
|
const { version } = require('../package.json');
|
|
@@ -94,6 +94,29 @@ server.tool("confluence_updateContent", `Update existing content in ${confluence
|
|
|
94
94
|
}
|
|
95
95
|
return formatToolResponse(result);
|
|
96
96
|
});
|
|
97
|
+
const attachmentGateway = resolveAttachmentGateway(CONFLUENCE_PRODUCT);
|
|
98
|
+
// Filesystem-reading upload is only registered when the operator explicitly enables it.
|
|
99
|
+
if (attachmentGateway.upload.enabled) {
|
|
100
|
+
server.tool("confluence_uploadAttachment", `Upload a local file as an attachment to a Confluence content (page) in the ${confluenceInstanceType}. The file must live under the server-configured upload directory; the path is given relative to that directory.`, confluenceToolSchemas.uploadAttachment, async ({ contentId, sourcePath, filename, comment, minorEdit, hidden, allowDuplicated, versionIfExists }) => {
|
|
101
|
+
const result = await confluenceService.uploadAttachment(contentId, sourcePath, attachmentGateway.upload, filename, comment, minorEdit, hidden, allowDuplicated, versionIfExists);
|
|
102
|
+
return formatToolResponse(result);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Download always returns content inline (no filesystem access). Saving to disk is
|
|
106
|
+
// only offered when the operator enables it, and is confined to the configured directory.
|
|
107
|
+
const downloadSaveEnabled = attachmentGateway.download.enabled;
|
|
108
|
+
server.tool("confluence_downloadAttachment", `Download one or more attachments from a Confluence content (page) in the ${confluenceInstanceType}. Returns the file content inline (base64 or text). Useful for inspecting a file or moving it elsewhere (e.g. re-uploading to a Jira issue).${downloadSaveEnabled ? ' Can also save into the server-configured download directory; existing files are never overwritten.' : ' Saving to local disk is disabled on this server.'}`, { ...confluenceToolSchemas.downloadAttachment, ...(downloadSaveEnabled ? confluenceToolSchemas.downloadAttachmentSaveFields : {}) }, async ({ contentId, filename, returnContent, maxInlineBytes, save, saveName }) => {
|
|
109
|
+
const result = await confluenceService.downloadAttachmentFromContent({
|
|
110
|
+
contentId,
|
|
111
|
+
filename,
|
|
112
|
+
save,
|
|
113
|
+
saveName,
|
|
114
|
+
returnContent,
|
|
115
|
+
maxInlineBytes,
|
|
116
|
+
downloadSide: attachmentGateway.download,
|
|
117
|
+
});
|
|
118
|
+
return formatToolResponse(result);
|
|
119
|
+
});
|
|
97
120
|
server.tool('confluence_searchSpace', `Search for spaces in ${confluenceInstanceType}`, confluenceToolSchemas.searchSpaces, async ({ searchText, limit, start, expand, excerpt }) => {
|
|
98
121
|
const result = await confluenceService.searchSpaces(searchText, limit, start, expand, excerpt);
|
|
99
122
|
return formatToolResponse(result);
|