@aashari/mcp-server-atlassian-bitbucket
Version:
Node.js/TypeScript MCP server for Atlassian Bitbucket. Enables AI systems (LLMs) to interact with workspaces, repositories, and pull requests via tools (list, get, comment, search). Connects AI directly to version control workflows through the standard MC
150 lines (146 loc) • 5.12 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.saveRawResponse = saveRawResponse;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const crypto = __importStar(require("crypto"));
const logger_util_js_1 = require("./logger.util.js");
const constants_util_js_1 = require("./constants.util.js");
// Create a contextualized logger for this file
const responseLogger = logger_util_js_1.Logger.forContext('utils/response.util.ts');
/**
* Get the project name from PACKAGE_NAME, stripping the scope prefix
* e.g., "@aashari/mcp-server-atlassian-bitbucket" -> "mcp-server-atlassian-bitbucket"
*/
function getProjectName() {
const name = constants_util_js_1.PACKAGE_NAME.replace(/^@[^/]+\//, '');
return name;
}
/**
* Generate a unique filename with timestamp and random string
* Format: <timestamp>-<random>.txt
*/
function generateFilename() {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const randomStr = crypto.randomBytes(4).toString('hex');
return `${timestamp}-${randomStr}.txt`;
}
/**
* Ensure the directory exists, creating it if necessary
*/
function ensureDirectoryExists(dirPath) {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
responseLogger.debug(`Created directory: ${dirPath}`);
}
}
/**
* Save raw API response to a file in /tmp/mcp/<project-name>/
*
* @param url The URL that was called
* @param method The HTTP method used
* @param requestBody The request body (if any)
* @param responseData The raw response data
* @param statusCode The HTTP status code
* @param durationMs The request duration in milliseconds
* @returns The path to the saved file, or null if saving failed
*/
function saveRawResponse(url, method, requestBody, responseData, statusCode, durationMs) {
const methodLogger = logger_util_js_1.Logger.forContext('utils/response.util.ts', 'saveRawResponse');
try {
const projectName = getProjectName();
const dirPath = path.join('/tmp', 'mcp', projectName);
const filename = generateFilename();
const filePath = path.join(dirPath, filename);
ensureDirectoryExists(dirPath);
// Build the content
const content = buildResponseContent(url, method, requestBody, responseData, statusCode, durationMs);
// Write to file
fs.writeFileSync(filePath, content, 'utf8');
methodLogger.debug(`Saved raw response to: ${filePath}`);
return filePath;
}
catch (error) {
methodLogger.error('Failed to save raw response', error);
return null;
}
}
/**
* Build the content string for the response file
*/
function buildResponseContent(url, method, requestBody, responseData, statusCode, durationMs) {
const timestamp = new Date().toISOString();
const separator = '='.repeat(80);
let content = `${separator}
RAW API RESPONSE LOG
${separator}
Timestamp: ${timestamp}
URL: ${url}
Method: ${method}
Status Code: ${statusCode}
Duration: ${durationMs.toFixed(2)}ms
${separator}
REQUEST BODY
${separator}
`;
if (requestBody) {
content +=
typeof requestBody === 'string'
? requestBody
: JSON.stringify(requestBody, null, 2);
}
else {
content += '(no request body)';
}
content += `
${separator}
RESPONSE DATA
${separator}
`;
if (responseData !== undefined && responseData !== null) {
content +=
typeof responseData === 'string'
? responseData
: JSON.stringify(responseData, null, 2);
}
else {
content += '(no response data)';
}
content += `
${separator}
`;
return content;
}