@pollychrome/joan-mcp 1.2.0 → 1.3.1
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/dist/client/api-client.d.ts +55 -1
- package/dist/client/api-client.d.ts.map +1 -1
- package/dist/client/api-client.js +181 -3
- package/dist/client/api-client.js.map +1 -1
- package/dist/client/types.d.ts +147 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/resources/attachments.d.ts +7 -0
- package/dist/resources/attachments.d.ts.map +1 -0
- package/dist/resources/attachments.js +145 -0
- package/dist/resources/attachments.js.map +1 -0
- package/dist/resources/comments.d.ts +7 -0
- package/dist/resources/comments.d.ts.map +1 -0
- package/dist/resources/comments.js +39 -0
- package/dist/resources/comments.js.map +1 -0
- package/dist/resources/index.d.ts +3 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +5 -1
- package/dist/resources/index.js.map +1 -1
- package/dist/tools/attachments.d.ts +7 -0
- package/dist/tools/attachments.d.ts.map +1 -0
- package/dist/tools/attachments.js +428 -0
- package/dist/tools/attachments.js.map +1 -0
- package/dist/tools/comments.d.ts +7 -0
- package/dist/tools/comments.d.ts.map +1 -0
- package/dist/tools/comments.js +188 -0
- package/dist/tools/comments.js.map +1 -0
- package/dist/tools/index.d.ts +4 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/resources.d.ts +7 -0
- package/dist/tools/resources.d.ts.map +1 -0
- package/dist/tools/resources.js +380 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/tasks.js +4 -4
- package/dist/tools/tasks.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tools for file attachment management
|
|
3
|
+
*/
|
|
4
|
+
import { readFile } from 'fs/promises';
|
|
5
|
+
import { basename, extname } from 'path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { formatErrorForMcp } from '../utils/errors.js';
|
|
8
|
+
// Common MIME type mappings
|
|
9
|
+
const MIME_TYPES = {
|
|
10
|
+
// Documents
|
|
11
|
+
'.pdf': 'application/pdf',
|
|
12
|
+
'.doc': 'application/msword',
|
|
13
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
14
|
+
'.xls': 'application/vnd.ms-excel',
|
|
15
|
+
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
16
|
+
'.ppt': 'application/vnd.ms-powerpoint',
|
|
17
|
+
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
18
|
+
'.txt': 'text/plain',
|
|
19
|
+
'.rtf': 'application/rtf',
|
|
20
|
+
'.csv': 'text/csv',
|
|
21
|
+
'.md': 'text/markdown',
|
|
22
|
+
// Images
|
|
23
|
+
'.png': 'image/png',
|
|
24
|
+
'.jpg': 'image/jpeg',
|
|
25
|
+
'.jpeg': 'image/jpeg',
|
|
26
|
+
'.gif': 'image/gif',
|
|
27
|
+
'.svg': 'image/svg+xml',
|
|
28
|
+
'.webp': 'image/webp',
|
|
29
|
+
'.bmp': 'image/bmp',
|
|
30
|
+
// Videos
|
|
31
|
+
'.mp4': 'video/mp4',
|
|
32
|
+
'.mov': 'video/quicktime',
|
|
33
|
+
'.avi': 'video/x-msvideo',
|
|
34
|
+
'.mkv': 'video/x-matroska',
|
|
35
|
+
'.webm': 'video/webm',
|
|
36
|
+
// Audio
|
|
37
|
+
'.mp3': 'audio/mpeg',
|
|
38
|
+
'.wav': 'audio/wav',
|
|
39
|
+
'.ogg': 'audio/ogg',
|
|
40
|
+
'.m4a': 'audio/mp4',
|
|
41
|
+
'.flac': 'audio/flac',
|
|
42
|
+
// Archives
|
|
43
|
+
'.zip': 'application/zip',
|
|
44
|
+
'.tar': 'application/x-tar',
|
|
45
|
+
'.gz': 'application/gzip',
|
|
46
|
+
'.rar': 'application/vnd.rar',
|
|
47
|
+
'.7z': 'application/x-7z-compressed',
|
|
48
|
+
// Code
|
|
49
|
+
'.json': 'application/json',
|
|
50
|
+
'.js': 'text/javascript',
|
|
51
|
+
'.ts': 'text/typescript',
|
|
52
|
+
'.html': 'text/html',
|
|
53
|
+
'.css': 'text/css',
|
|
54
|
+
'.py': 'text/x-python',
|
|
55
|
+
'.java': 'text/x-java-source',
|
|
56
|
+
'.go': 'text/x-go',
|
|
57
|
+
'.rs': 'text/x-rust',
|
|
58
|
+
'.rb': 'text/x-ruby',
|
|
59
|
+
'.php': 'text/x-php',
|
|
60
|
+
'.c': 'text/x-c',
|
|
61
|
+
'.cpp': 'text/x-c++src',
|
|
62
|
+
'.h': 'text/x-c',
|
|
63
|
+
'.yaml': 'text/yaml',
|
|
64
|
+
'.yml': 'text/yaml',
|
|
65
|
+
'.xml': 'application/xml',
|
|
66
|
+
};
|
|
67
|
+
function getMimeType(filename) {
|
|
68
|
+
const ext = extname(filename).toLowerCase();
|
|
69
|
+
return MIME_TYPES[ext] || 'application/octet-stream';
|
|
70
|
+
}
|
|
71
|
+
function formatFileSize(bytes) {
|
|
72
|
+
if (bytes < 1024)
|
|
73
|
+
return `${bytes} B`;
|
|
74
|
+
if (bytes < 1024 * 1024)
|
|
75
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
76
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
77
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
78
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
79
|
+
}
|
|
80
|
+
export function registerAttachmentTools(server, client) {
|
|
81
|
+
// Upload Attachment
|
|
82
|
+
server.tool('upload_attachment', 'Upload a file attachment to Joan. Supports local file paths, base64-encoded content, or URLs to fetch from.', {
|
|
83
|
+
// File source (one of these is required)
|
|
84
|
+
file_path: z.string().optional().describe('Local file path to upload'),
|
|
85
|
+
file_base64: z.string().optional().describe('Base64-encoded file content'),
|
|
86
|
+
file_url: z.string().url().optional().describe('URL to fetch file from'),
|
|
87
|
+
// Required filename for base64/URL sources
|
|
88
|
+
filename: z.string().optional().describe('Filename (required for base64/URL, auto-detected for file_path)'),
|
|
89
|
+
// Attachment target (entity)
|
|
90
|
+
entity_type: z.enum(['project', 'milestone', 'task', 'note', 'folder', 'user']).optional()
|
|
91
|
+
.describe('Entity type to attach to'),
|
|
92
|
+
entity_id: z.string().uuid().optional().describe('Entity ID to attach to'),
|
|
93
|
+
// Metadata
|
|
94
|
+
display_name: z.string().optional().describe('Custom display name'),
|
|
95
|
+
description: z.string().optional().describe('Description of the attachment'),
|
|
96
|
+
category: z.enum(['document', 'image', 'video', 'audio', 'archive', 'code', 'other']).optional()
|
|
97
|
+
.describe('Category (auto-detected from MIME type if not specified)'),
|
|
98
|
+
tags: z.array(z.string()).optional().describe('Tags for organization'),
|
|
99
|
+
}, async (input) => {
|
|
100
|
+
try {
|
|
101
|
+
let fileBuffer;
|
|
102
|
+
let filename;
|
|
103
|
+
let mimeType;
|
|
104
|
+
// Determine file source and load content
|
|
105
|
+
if (input.file_path) {
|
|
106
|
+
// Local file path
|
|
107
|
+
fileBuffer = await readFile(input.file_path);
|
|
108
|
+
filename = input.filename || basename(input.file_path);
|
|
109
|
+
mimeType = getMimeType(filename);
|
|
110
|
+
}
|
|
111
|
+
else if (input.file_base64) {
|
|
112
|
+
// Base64 encoded content
|
|
113
|
+
if (!input.filename) {
|
|
114
|
+
return {
|
|
115
|
+
content: [{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: 'Error: filename is required when using file_base64',
|
|
118
|
+
}],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
fileBuffer = Buffer.from(input.file_base64, 'base64');
|
|
122
|
+
filename = input.filename;
|
|
123
|
+
mimeType = getMimeType(filename);
|
|
124
|
+
}
|
|
125
|
+
else if (input.file_url) {
|
|
126
|
+
// Fetch from URL
|
|
127
|
+
const response = await fetch(input.file_url);
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
return {
|
|
130
|
+
content: [{
|
|
131
|
+
type: 'text',
|
|
132
|
+
text: `Error: Failed to fetch file from URL (${response.status})`,
|
|
133
|
+
}],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
137
|
+
fileBuffer = Buffer.from(arrayBuffer);
|
|
138
|
+
// Try to get filename from URL or Content-Disposition
|
|
139
|
+
const contentDisposition = response.headers.get('Content-Disposition');
|
|
140
|
+
if (input.filename) {
|
|
141
|
+
filename = input.filename;
|
|
142
|
+
}
|
|
143
|
+
else if (contentDisposition) {
|
|
144
|
+
const match = contentDisposition.match(/filename="?([^";\n]+)"?/);
|
|
145
|
+
filename = match?.[1] || basename(new URL(input.file_url).pathname) || 'downloaded_file';
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
filename = basename(new URL(input.file_url).pathname) || 'downloaded_file';
|
|
149
|
+
}
|
|
150
|
+
// Try to get MIME type from response or filename
|
|
151
|
+
mimeType = response.headers.get('Content-Type')?.split(';')[0] || getMimeType(filename);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
return {
|
|
155
|
+
content: [{
|
|
156
|
+
type: 'text',
|
|
157
|
+
text: 'Error: Must provide one of file_path, file_base64, or file_url',
|
|
158
|
+
}],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Validate entity_type and entity_id are both provided or both omitted
|
|
162
|
+
if ((input.entity_type && !input.entity_id) || (!input.entity_type && input.entity_id)) {
|
|
163
|
+
return {
|
|
164
|
+
content: [{
|
|
165
|
+
type: 'text',
|
|
166
|
+
text: 'Error: Both entity_type and entity_id must be provided together',
|
|
167
|
+
}],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// Build metadata
|
|
171
|
+
const metadata = {
|
|
172
|
+
entity_type: input.entity_type,
|
|
173
|
+
entity_id: input.entity_id,
|
|
174
|
+
display_name: input.display_name,
|
|
175
|
+
description: input.description,
|
|
176
|
+
category: input.category,
|
|
177
|
+
tags: input.tags,
|
|
178
|
+
};
|
|
179
|
+
const attachment = await client.uploadAttachment(fileBuffer, filename, mimeType, metadata);
|
|
180
|
+
return {
|
|
181
|
+
content: [{
|
|
182
|
+
type: 'text',
|
|
183
|
+
text: `Uploaded "${attachment.display_name}" (ID: ${attachment.id})\n` +
|
|
184
|
+
` File: ${attachment.filename}\n` +
|
|
185
|
+
` Size: ${formatFileSize(attachment.size)}\n` +
|
|
186
|
+
` Type: ${attachment.mime_type}\n` +
|
|
187
|
+
` Category: ${attachment.category}` +
|
|
188
|
+
(attachment.entity_type ? `\n Attached to: ${attachment.entity_type} (${attachment.entity_id})` : ''),
|
|
189
|
+
}],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
return { content: formatErrorForMcp(error) };
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// List Attachments
|
|
197
|
+
server.tool('list_attachments', 'List file attachments for a specific entity (project, milestone, task, note, folder, or user).', {
|
|
198
|
+
entity_type: z.enum(['project', 'milestone', 'task', 'note', 'folder', 'user'])
|
|
199
|
+
.describe('Entity type'),
|
|
200
|
+
entity_id: z.string().uuid().describe('Entity ID'),
|
|
201
|
+
}, async (input) => {
|
|
202
|
+
try {
|
|
203
|
+
const attachments = await client.listAttachmentsByEntity(input.entity_type, input.entity_id);
|
|
204
|
+
if (attachments.length === 0) {
|
|
205
|
+
return {
|
|
206
|
+
content: [{
|
|
207
|
+
type: 'text',
|
|
208
|
+
text: `No attachments found for ${input.entity_type} ${input.entity_id}`,
|
|
209
|
+
}],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
const lines = attachments.map(a => `- ${a.display_name} (ID: ${a.id})\n` +
|
|
213
|
+
` File: ${a.filename} | Size: ${formatFileSize(a.size)} | Type: ${a.category}`);
|
|
214
|
+
return {
|
|
215
|
+
content: [{
|
|
216
|
+
type: 'text',
|
|
217
|
+
text: `Attachments for ${input.entity_type} ${input.entity_id}:\n\n${lines.join('\n\n')}`,
|
|
218
|
+
}],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
return { content: formatErrorForMcp(error) };
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
// Get Attachment
|
|
226
|
+
server.tool('get_attachment', 'Get metadata for a specific attachment.', {
|
|
227
|
+
attachment_id: z.string().uuid().describe('Attachment ID'),
|
|
228
|
+
}, async (input) => {
|
|
229
|
+
try {
|
|
230
|
+
const attachment = await client.getAttachmentMetadata(input.attachment_id);
|
|
231
|
+
const info = [
|
|
232
|
+
`Attachment: ${attachment.display_name}`,
|
|
233
|
+
`ID: ${attachment.id}`,
|
|
234
|
+
`Filename: ${attachment.filename}`,
|
|
235
|
+
`Size: ${formatFileSize(attachment.size)}`,
|
|
236
|
+
`MIME Type: ${attachment.mime_type}`,
|
|
237
|
+
`Category: ${attachment.category}`,
|
|
238
|
+
];
|
|
239
|
+
if (attachment.description) {
|
|
240
|
+
info.push(`Description: ${attachment.description}`);
|
|
241
|
+
}
|
|
242
|
+
if (attachment.tags && attachment.tags.length > 0) {
|
|
243
|
+
info.push(`Tags: ${attachment.tags.join(', ')}`);
|
|
244
|
+
}
|
|
245
|
+
if (attachment.entity_type) {
|
|
246
|
+
info.push(`Attached to: ${attachment.entity_type} (${attachment.entity_id})`);
|
|
247
|
+
}
|
|
248
|
+
info.push(`Uploaded: ${attachment.uploaded_at}`);
|
|
249
|
+
info.push(`Download URL: ${attachment.url}`);
|
|
250
|
+
return {
|
|
251
|
+
content: [{
|
|
252
|
+
type: 'text',
|
|
253
|
+
text: info.join('\n'),
|
|
254
|
+
}],
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
return { content: formatErrorForMcp(error) };
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
// Update Attachment
|
|
262
|
+
server.tool('update_attachment', 'Update metadata for an attachment.', {
|
|
263
|
+
attachment_id: z.string().uuid().describe('Attachment ID'),
|
|
264
|
+
display_name: z.string().optional().describe('New display name'),
|
|
265
|
+
description: z.string().optional().describe('New description'),
|
|
266
|
+
category: z.enum(['document', 'image', 'video', 'audio', 'archive', 'code', 'other']).optional()
|
|
267
|
+
.describe('New category'),
|
|
268
|
+
tags: z.array(z.string()).optional().describe('New tags'),
|
|
269
|
+
}, async (input) => {
|
|
270
|
+
try {
|
|
271
|
+
const updateData = {};
|
|
272
|
+
if (input.display_name !== undefined)
|
|
273
|
+
updateData.display_name = input.display_name;
|
|
274
|
+
if (input.description !== undefined)
|
|
275
|
+
updateData.description = input.description;
|
|
276
|
+
if (input.category !== undefined)
|
|
277
|
+
updateData.category = input.category;
|
|
278
|
+
if (input.tags !== undefined)
|
|
279
|
+
updateData.tags = input.tags;
|
|
280
|
+
const attachment = await client.updateAttachment(input.attachment_id, updateData);
|
|
281
|
+
return {
|
|
282
|
+
content: [{
|
|
283
|
+
type: 'text',
|
|
284
|
+
text: `Updated attachment "${attachment.display_name}" (ID: ${attachment.id})`,
|
|
285
|
+
}],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
return { content: formatErrorForMcp(error) };
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
// Delete Attachment
|
|
293
|
+
server.tool('delete_attachment', 'Delete an attachment.', {
|
|
294
|
+
attachment_id: z.string().uuid().describe('Attachment ID'),
|
|
295
|
+
}, async (input) => {
|
|
296
|
+
try {
|
|
297
|
+
await client.deleteAttachment(input.attachment_id);
|
|
298
|
+
return {
|
|
299
|
+
content: [{
|
|
300
|
+
type: 'text',
|
|
301
|
+
text: `Attachment ${input.attachment_id} deleted`,
|
|
302
|
+
}],
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
return { content: formatErrorForMcp(error) };
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
// Get Attachment Download URL
|
|
310
|
+
server.tool('get_attachment_download_url', 'Get a download URL for an attachment.', {
|
|
311
|
+
attachment_id: z.string().uuid().describe('Attachment ID'),
|
|
312
|
+
expires_in: z.number().optional().describe('URL expiration time in seconds (default: 3600)'),
|
|
313
|
+
}, async (input) => {
|
|
314
|
+
try {
|
|
315
|
+
const info = await client.getAttachmentDownloadUrl(input.attachment_id, input.expires_in);
|
|
316
|
+
return {
|
|
317
|
+
content: [{
|
|
318
|
+
type: 'text',
|
|
319
|
+
text: `Download URL for "${info.display_name}":\n` +
|
|
320
|
+
` URL: ${info.download_url}\n` +
|
|
321
|
+
` Expires: ${info.expires_at}\n` +
|
|
322
|
+
` Size: ${formatFileSize(info.file_size)}`,
|
|
323
|
+
}],
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
return { content: formatErrorForMcp(error) };
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
// Get Project Attachment Hierarchy
|
|
331
|
+
server.tool('get_project_attachment_hierarchy', 'Get all attachments organized by project hierarchy (project → milestones → tasks).', {
|
|
332
|
+
project_id: z.string().uuid().describe('Project ID'),
|
|
333
|
+
}, async (input) => {
|
|
334
|
+
try {
|
|
335
|
+
const hierarchy = await client.getProjectAttachmentHierarchy(input.project_id);
|
|
336
|
+
const lines = [];
|
|
337
|
+
lines.push(`Project Attachments (${hierarchy.total_files} total files)`);
|
|
338
|
+
lines.push('');
|
|
339
|
+
// Project level
|
|
340
|
+
if (hierarchy.project.attachments.length > 0) {
|
|
341
|
+
lines.push(`📁 Project (${hierarchy.project.attachments.length} files)`);
|
|
342
|
+
for (const a of hierarchy.project.attachments) {
|
|
343
|
+
lines.push(` - ${a.display_name} (${formatFileSize(a.size)})`);
|
|
344
|
+
}
|
|
345
|
+
lines.push('');
|
|
346
|
+
}
|
|
347
|
+
// Milestones
|
|
348
|
+
for (const milestone of hierarchy.milestones) {
|
|
349
|
+
const milestoneFiles = milestone.attachments.length +
|
|
350
|
+
milestone.tasks.reduce((sum, t) => sum + t.attachments.length, 0);
|
|
351
|
+
if (milestoneFiles > 0) {
|
|
352
|
+
lines.push(`🎯 ${milestone.name} [${milestone.status}] (${milestoneFiles} files)`);
|
|
353
|
+
for (const a of milestone.attachments) {
|
|
354
|
+
lines.push(` - ${a.display_name} (${formatFileSize(a.size)})`);
|
|
355
|
+
}
|
|
356
|
+
for (const task of milestone.tasks) {
|
|
357
|
+
if (task.attachments.length > 0) {
|
|
358
|
+
lines.push(` 📋 ${task.title} [${task.status}]`);
|
|
359
|
+
for (const a of task.attachments) {
|
|
360
|
+
lines.push(` - ${a.display_name} (${formatFileSize(a.size)})`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
lines.push('');
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// Unassigned tasks
|
|
368
|
+
if (hierarchy.unassigned_tasks.length > 0) {
|
|
369
|
+
const unassignedFiles = hierarchy.unassigned_tasks.reduce((sum, t) => sum + t.attachments.length, 0);
|
|
370
|
+
if (unassignedFiles > 0) {
|
|
371
|
+
lines.push(`📋 Unassigned Tasks (${unassignedFiles} files)`);
|
|
372
|
+
for (const task of hierarchy.unassigned_tasks) {
|
|
373
|
+
if (task.attachments.length > 0) {
|
|
374
|
+
lines.push(` ${task.title} [${task.status}]`);
|
|
375
|
+
for (const a of task.attachments) {
|
|
376
|
+
lines.push(` - ${a.display_name} (${formatFileSize(a.size)})`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
content: [{
|
|
384
|
+
type: 'text',
|
|
385
|
+
text: lines.join('\n'),
|
|
386
|
+
}],
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
return { content: formatErrorForMcp(error) };
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
// Get Storage Usage
|
|
394
|
+
server.tool('get_storage_usage', 'Get storage usage statistics for your account.', {}, async () => {
|
|
395
|
+
try {
|
|
396
|
+
const usage = await client.getStorageUsage();
|
|
397
|
+
const lines = [
|
|
398
|
+
'Storage Usage',
|
|
399
|
+
'─'.repeat(30),
|
|
400
|
+
`Total Files: ${usage.total_files}`,
|
|
401
|
+
`Total Size: ${usage.total_size_mb.toFixed(2)} MB`,
|
|
402
|
+
`Usage: ${usage.usage_percentage}% of ${usage.storage_limit_mb} MB limit`,
|
|
403
|
+
'',
|
|
404
|
+
'By Entity Type:',
|
|
405
|
+
];
|
|
406
|
+
for (const [type, count] of Object.entries(usage.by_entity)) {
|
|
407
|
+
lines.push(` ${type}: ${count} files`);
|
|
408
|
+
}
|
|
409
|
+
if (usage.by_type.length > 0) {
|
|
410
|
+
lines.push('');
|
|
411
|
+
lines.push('By File Type:');
|
|
412
|
+
for (const item of usage.by_type) {
|
|
413
|
+
lines.push(` ${item.file_type}: ${item.count} files (${formatFileSize(item.total_size)})`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
content: [{
|
|
418
|
+
type: 'text',
|
|
419
|
+
text: lines.join('\n'),
|
|
420
|
+
}],
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
return { content: formatErrorForMcp(error) };
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/tools/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tools for comment management on tasks and milestones
|
|
3
|
+
*/
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import type { JoanApiClient } from '../client/api-client.js';
|
|
6
|
+
export declare function registerCommentTools(server: McpServer, client: JoanApiClient): void;
|
|
7
|
+
//# sourceMappingURL=comments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA0PnF"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tools for comment management on tasks and milestones
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { formatErrorForMcp } from '../utils/errors.js';
|
|
6
|
+
export function registerCommentTools(server, client) {
|
|
7
|
+
// ============ Task Comments ============
|
|
8
|
+
// List Task Comments
|
|
9
|
+
server.tool('list_task_comments', 'List all comments on a specific task.', {
|
|
10
|
+
task_id: z.string().uuid().describe('Task ID to list comments for'),
|
|
11
|
+
}, async (input) => {
|
|
12
|
+
try {
|
|
13
|
+
const comments = await client.listTaskComments(input.task_id);
|
|
14
|
+
if (comments.length === 0) {
|
|
15
|
+
return {
|
|
16
|
+
content: [{
|
|
17
|
+
type: 'text',
|
|
18
|
+
text: `No comments found for task ${input.task_id}.`,
|
|
19
|
+
}],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const commentList = comments.map(c => {
|
|
23
|
+
const author = c.user_name || 'Unknown';
|
|
24
|
+
const date = new Date(c.created_at).toLocaleString();
|
|
25
|
+
return `- **${author}** (${date}):\n "${c.content}"`;
|
|
26
|
+
}).join('\n\n');
|
|
27
|
+
return {
|
|
28
|
+
content: [{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: `Found ${comments.length} comment(s):\n\n${commentList}`,
|
|
31
|
+
}],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return { content: formatErrorForMcp(error) };
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// Create Task Comment
|
|
39
|
+
server.tool('create_task_comment', 'Add a comment to a task.', {
|
|
40
|
+
task_id: z.string().uuid().describe('Task ID to comment on'),
|
|
41
|
+
content: z.string().min(1).max(10000).describe('Comment content (supports markdown)'),
|
|
42
|
+
}, async (input) => {
|
|
43
|
+
try {
|
|
44
|
+
const comment = await client.createTaskComment(input.task_id, {
|
|
45
|
+
content: input.content,
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
content: [{
|
|
49
|
+
type: 'text',
|
|
50
|
+
text: `Comment added to task ${input.task_id}.\nComment ID: ${comment.id}`,
|
|
51
|
+
}],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
return { content: formatErrorForMcp(error) };
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// Update Task Comment
|
|
59
|
+
server.tool('update_task_comment', 'Edit an existing comment on a task. Only the comment author or project admins can edit.', {
|
|
60
|
+
task_id: z.string().uuid().describe('Task ID'),
|
|
61
|
+
comment_id: z.string().uuid().describe('Comment ID to update'),
|
|
62
|
+
content: z.string().min(1).max(10000).describe('New comment content'),
|
|
63
|
+
}, async (input) => {
|
|
64
|
+
try {
|
|
65
|
+
await client.updateTaskComment(input.task_id, input.comment_id, {
|
|
66
|
+
content: input.content,
|
|
67
|
+
});
|
|
68
|
+
return {
|
|
69
|
+
content: [{
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: `Comment ${input.comment_id} updated successfully.`,
|
|
72
|
+
}],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return { content: formatErrorForMcp(error) };
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
// Delete Task Comment
|
|
80
|
+
server.tool('delete_task_comment', 'Remove a comment from a task. Only the comment author or project admins can delete.', {
|
|
81
|
+
task_id: z.string().uuid().describe('Task ID'),
|
|
82
|
+
comment_id: z.string().uuid().describe('Comment ID to delete'),
|
|
83
|
+
}, async (input) => {
|
|
84
|
+
try {
|
|
85
|
+
await client.deleteTaskComment(input.task_id, input.comment_id);
|
|
86
|
+
return {
|
|
87
|
+
content: [{
|
|
88
|
+
type: 'text',
|
|
89
|
+
text: `Comment ${input.comment_id} deleted from task ${input.task_id}.`,
|
|
90
|
+
}],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return { content: formatErrorForMcp(error) };
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
// ============ Milestone Comments ============
|
|
98
|
+
// List Milestone Comments
|
|
99
|
+
server.tool('list_milestone_comments', 'List all comments on a specific milestone.', {
|
|
100
|
+
project_id: z.string().uuid().describe('Project ID'),
|
|
101
|
+
milestone_id: z.string().uuid().describe('Milestone ID to list comments for'),
|
|
102
|
+
}, async (input) => {
|
|
103
|
+
try {
|
|
104
|
+
const comments = await client.listMilestoneComments(input.project_id, input.milestone_id);
|
|
105
|
+
if (comments.length === 0) {
|
|
106
|
+
return {
|
|
107
|
+
content: [{
|
|
108
|
+
type: 'text',
|
|
109
|
+
text: `No comments found for milestone ${input.milestone_id}.`,
|
|
110
|
+
}],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const commentList = comments.map(c => {
|
|
114
|
+
const author = c.user_name || 'Unknown';
|
|
115
|
+
const date = new Date(c.created_at).toLocaleString();
|
|
116
|
+
return `- **${author}** (${date}):\n "${c.content}"`;
|
|
117
|
+
}).join('\n\n');
|
|
118
|
+
return {
|
|
119
|
+
content: [{
|
|
120
|
+
type: 'text',
|
|
121
|
+
text: `Found ${comments.length} comment(s):\n\n${commentList}`,
|
|
122
|
+
}],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
return { content: formatErrorForMcp(error) };
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// Create Milestone Comment
|
|
130
|
+
server.tool('create_milestone_comment', 'Add a comment to a milestone.', {
|
|
131
|
+
project_id: z.string().uuid().describe('Project ID'),
|
|
132
|
+
milestone_id: z.string().uuid().describe('Milestone ID to comment on'),
|
|
133
|
+
content: z.string().min(1).max(10000).describe('Comment content (supports markdown)'),
|
|
134
|
+
}, async (input) => {
|
|
135
|
+
try {
|
|
136
|
+
const comment = await client.createMilestoneComment(input.project_id, input.milestone_id, { content: input.content });
|
|
137
|
+
return {
|
|
138
|
+
content: [{
|
|
139
|
+
type: 'text',
|
|
140
|
+
text: `Comment added to milestone ${input.milestone_id}.\nComment ID: ${comment.id}`,
|
|
141
|
+
}],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return { content: formatErrorForMcp(error) };
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// Update Milestone Comment
|
|
149
|
+
server.tool('update_milestone_comment', 'Edit an existing comment on a milestone. Only the comment author or project admins can edit.', {
|
|
150
|
+
project_id: z.string().uuid().describe('Project ID'),
|
|
151
|
+
milestone_id: z.string().uuid().describe('Milestone ID'),
|
|
152
|
+
comment_id: z.string().uuid().describe('Comment ID to update'),
|
|
153
|
+
content: z.string().min(1).max(10000).describe('New comment content'),
|
|
154
|
+
}, async (input) => {
|
|
155
|
+
try {
|
|
156
|
+
await client.updateMilestoneComment(input.project_id, input.milestone_id, input.comment_id, { content: input.content });
|
|
157
|
+
return {
|
|
158
|
+
content: [{
|
|
159
|
+
type: 'text',
|
|
160
|
+
text: `Comment ${input.comment_id} updated successfully.`,
|
|
161
|
+
}],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
return { content: formatErrorForMcp(error) };
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
// Delete Milestone Comment
|
|
169
|
+
server.tool('delete_milestone_comment', 'Remove a comment from a milestone. Only the comment author or project admins can delete.', {
|
|
170
|
+
project_id: z.string().uuid().describe('Project ID'),
|
|
171
|
+
milestone_id: z.string().uuid().describe('Milestone ID'),
|
|
172
|
+
comment_id: z.string().uuid().describe('Comment ID to delete'),
|
|
173
|
+
}, async (input) => {
|
|
174
|
+
try {
|
|
175
|
+
await client.deleteMilestoneComment(input.project_id, input.milestone_id, input.comment_id);
|
|
176
|
+
return {
|
|
177
|
+
content: [{
|
|
178
|
+
type: 'text',
|
|
179
|
+
text: `Comment ${input.comment_id} deleted from milestone ${input.milestone_id}.`,
|
|
180
|
+
}],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
return { content: formatErrorForMcp(error) };
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=comments.js.map
|