@nbakka/mcp-appium 2.0.37 → 2.0.39
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/lib/server.js +128 -0
- package/package.json +3 -2
package/lib/server.js
CHANGED
|
@@ -14,6 +14,7 @@ const ios_1 = require("./ios");
|
|
|
14
14
|
const png_1 = require("./png");
|
|
15
15
|
const image_utils_1 = require("./image-utils");
|
|
16
16
|
const { google } = require('googleapis');
|
|
17
|
+
const axios = require('axios');
|
|
17
18
|
const getAgentVersion = () => {
|
|
18
19
|
const json = require("../package.json");
|
|
19
20
|
return json.version;
|
|
@@ -316,6 +317,133 @@ const createMcpServer = () => {
|
|
|
316
317
|
}
|
|
317
318
|
);
|
|
318
319
|
|
|
320
|
+
tool(
|
|
321
|
+
"mobile_fetch_jira_ticket",
|
|
322
|
+
"Fetch JIRA ticket information including summary, description, and extract Figma links from description",
|
|
323
|
+
{
|
|
324
|
+
ticketId: zod_1.z.string().describe("The JIRA ticket ID (e.g., HDA-434)"),
|
|
325
|
+
},
|
|
326
|
+
async ({ ticketId }) => {
|
|
327
|
+
try {
|
|
328
|
+
// Read JIRA credentials from desktop/jira.json file
|
|
329
|
+
const jiraConfigPath = path.join(os.homedir(), 'Desktop', 'jira.json');
|
|
330
|
+
|
|
331
|
+
let jiraConfig;
|
|
332
|
+
try {
|
|
333
|
+
const configContent = await fs.readFile(jiraConfigPath, 'utf-8');
|
|
334
|
+
jiraConfig = JSON.parse(configContent);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
throw new Error(`Failed to read JIRA config from ${jiraConfigPath}: ${error.message}`);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Extract all required values from JSON file
|
|
340
|
+
const { api: jiraApiToken, baseUrl: jiraBaseUrl, email: jiraEmail } = jiraConfig;
|
|
341
|
+
|
|
342
|
+
if (!jiraApiToken) {
|
|
343
|
+
throw new Error('JIRA API token not found in jira.json file. Please ensure the file contains "api" field.');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (!jiraBaseUrl) {
|
|
347
|
+
throw new Error('JIRA base URL not found in jira.json file. Please ensure the file contains "baseUrl" field.');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (!jiraEmail) {
|
|
351
|
+
throw new Error('JIRA email not found in jira.json file. Please ensure the file contains "email" field.');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Create Basic Auth token
|
|
355
|
+
const auth = Buffer.from(`${jiraEmail}:${jiraApiToken}`).toString('base64');
|
|
356
|
+
|
|
357
|
+
// Fetch ticket from JIRA API
|
|
358
|
+
const response = await axios.get(
|
|
359
|
+
`${jiraBaseUrl}/rest/api/3/issue/${ticketId}`,
|
|
360
|
+
{
|
|
361
|
+
headers: {
|
|
362
|
+
'Authorization': `Basic ${auth}`,
|
|
363
|
+
'Accept': 'application/json',
|
|
364
|
+
'Content-Type': 'application/json'
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
const issue = response.data;
|
|
370
|
+
|
|
371
|
+
// Extract summary and description
|
|
372
|
+
const summary = issue.fields.summary || 'No summary available';
|
|
373
|
+
const description = issue.fields.description ?
|
|
374
|
+
extractTextFromADF(issue.fields.description) :
|
|
375
|
+
'No description available';
|
|
376
|
+
|
|
377
|
+
// Extract Figma links from description
|
|
378
|
+
const figmaLinks = extractFigmaLinks(description);
|
|
379
|
+
|
|
380
|
+
// Format response
|
|
381
|
+
const result = {
|
|
382
|
+
ticketId: ticketId,
|
|
383
|
+
summary: summary,
|
|
384
|
+
description: description,
|
|
385
|
+
figmaLinks: figmaLinks.length > 0 ? figmaLinks : ['No Figma links found']
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
return `JIRA Ticket Information:
|
|
389
|
+
Ticket ID: ${result.ticketId}
|
|
390
|
+
Summary: ${result.summary}
|
|
391
|
+
Description: ${result.description}
|
|
392
|
+
Figma Links: ${result.figmaLinks.join(', ')}`;
|
|
393
|
+
|
|
394
|
+
} catch (error) {
|
|
395
|
+
if (error.response && error.response.status === 404) {
|
|
396
|
+
return `Error: JIRA ticket ${ticketId} not found. Please check the ticket ID.`;
|
|
397
|
+
} else if (error.response && error.response.status === 401) {
|
|
398
|
+
return `Error: Authentication failed. Please check your JIRA credentials.`;
|
|
399
|
+
} else {
|
|
400
|
+
return `Error fetching JIRA ticket: ${error.message}`;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// Helper function to extract text from Atlassian Document Format (ADF)
|
|
407
|
+
function extractTextFromADF(adfContent) {
|
|
408
|
+
if (!adfContent || typeof adfContent !== 'object') {
|
|
409
|
+
return String(adfContent || '');
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
let text = '';
|
|
413
|
+
|
|
414
|
+
function traverse(node) {
|
|
415
|
+
if (node.type === 'text') {
|
|
416
|
+
text += node.text || '';
|
|
417
|
+
} else if (node.content && Array.isArray(node.content)) {
|
|
418
|
+
node.content.forEach(traverse);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Add line breaks for paragraphs
|
|
422
|
+
if (node.type === 'paragraph') {
|
|
423
|
+
text += '\n';
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (adfContent.content) {
|
|
428
|
+
adfContent.content.forEach(traverse);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return text.trim();
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Helper function to extract Figma links from text
|
|
435
|
+
function extractFigmaLinks(text) {
|
|
436
|
+
if (!text || typeof text !== 'string') {
|
|
437
|
+
return [];
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Regular expression to match Figma URLs
|
|
441
|
+
const figmaRegex = /https?:\/\/(?:www\.)?figma\.com\/[^\s<>"{}|\\^`\[\]]+/gi;
|
|
442
|
+
const matches = text.match(figmaRegex);
|
|
443
|
+
|
|
444
|
+
return matches ? [...new Set(matches)] : []; // Remove duplicates
|
|
445
|
+
}
|
|
446
|
+
|
|
319
447
|
return server;
|
|
320
448
|
};
|
|
321
449
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nbakka/mcp-appium",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.39",
|
|
4
4
|
"description": "Appium MCP",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18"
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.6.1",
|
|
22
22
|
"fast-xml-parser": "^5.0.9",
|
|
23
23
|
"googleapis": "^149.0.0",
|
|
24
|
-
"zod-to-json-schema": "^3.24.4"
|
|
24
|
+
"zod-to-json-schema": "^3.24.4",
|
|
25
|
+
"axios": "^1.6.0"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@eslint/eslintrc": "^3.2.0",
|