@rui.branco/jira-mcp 1.7.1 → 1.7.2
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/index.js +24 -21
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -2505,24 +2505,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2505
2505
|
|
|
2506
2506
|
const content = [{ type: "text", text: result.text }];
|
|
2507
2507
|
|
|
2508
|
-
//
|
|
2509
|
-
//
|
|
2510
|
-
//
|
|
2511
|
-
|
|
2512
|
-
".png": "image/png",
|
|
2513
|
-
".jpg": "image/jpeg",
|
|
2514
|
-
".jpeg": "image/jpeg",
|
|
2515
|
-
".gif": "image/gif",
|
|
2516
|
-
".webp": "image/webp",
|
|
2517
|
-
};
|
|
2508
|
+
// Anthropic vision only accepts png/jpeg/gif/webp under 5MB. We sniff
|
|
2509
|
+
// the magic bytes instead of trusting the filename, since a misnamed
|
|
2510
|
+
// file (e.g. SVG saved as .png) gets the whole response rejected with
|
|
2511
|
+
// "Could not process image".
|
|
2518
2512
|
const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
2513
|
+
const detectImageMime = (buf) => {
|
|
2514
|
+
if (!buf || buf.length < 12) return null;
|
|
2515
|
+
if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) return "image/png";
|
|
2516
|
+
if (buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff) return "image/jpeg";
|
|
2517
|
+
if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38) return "image/gif";
|
|
2518
|
+
if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 &&
|
|
2519
|
+
buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50) return "image/webp";
|
|
2520
|
+
return null;
|
|
2521
|
+
};
|
|
2519
2522
|
for (const imagePath of result.jiraImages) {
|
|
2520
2523
|
try {
|
|
2521
|
-
const ext = path.extname(imagePath).toLowerCase();
|
|
2522
|
-
const mimeType = mimeByExt[ext];
|
|
2523
|
-
if (!mimeType) continue;
|
|
2524
2524
|
const imageData = fs.readFileSync(imagePath);
|
|
2525
2525
|
if (imageData.length > MAX_IMAGE_BYTES) continue;
|
|
2526
|
+
const mimeType = detectImageMime(imageData);
|
|
2527
|
+
if (!mimeType) continue;
|
|
2526
2528
|
content.push({
|
|
2527
2529
|
type: "image",
|
|
2528
2530
|
data: imageData.toString("base64"),
|
|
@@ -2533,17 +2535,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2533
2535
|
}
|
|
2534
2536
|
}
|
|
2535
2537
|
|
|
2536
|
-
//
|
|
2538
|
+
// Figma images (multiple per design). Validate magic bytes here too.
|
|
2537
2539
|
for (const design of result.figmaDesigns) {
|
|
2538
2540
|
if (design.images && design.images.length > 0) {
|
|
2539
2541
|
for (const img of design.images) {
|
|
2540
|
-
if (img.buffer
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2542
|
+
if (!img.buffer || img.buffer.length > MAX_IMAGE_BYTES) continue;
|
|
2543
|
+
const mimeType = detectImageMime(img.buffer);
|
|
2544
|
+
if (!mimeType) continue;
|
|
2545
|
+
content.push({
|
|
2546
|
+
type: "image",
|
|
2547
|
+
data: img.buffer.toString("base64"),
|
|
2548
|
+
mimeType: mimeType,
|
|
2549
|
+
});
|
|
2547
2550
|
}
|
|
2548
2551
|
}
|
|
2549
2552
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rui.branco/jira-mcp",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Jira MCP server for Claude Code - fetch tickets, search with JQL, update tickets, manage comments, change status, and get Figma designs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|