@mseep/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
188 lines (187 loc) • 9.56 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vendor_atlassian_repositories_service_js_1 = __importDefault(require("../services/vendor.atlassian.repositories.service.js"));
const vendor_atlassian_pullrequests_service_js_1 = __importDefault(require("../services/vendor.atlassian.pullrequests.service.js"));
const logger_util_js_1 = require("../utils/logger.util.js");
const error_handler_util_js_1 = require("../utils/error-handler.util.js");
const pagination_util_js_1 = require("../utils/pagination.util.js");
const atlassian_repositories_formatter_js_1 = require("./atlassian.repositories.formatter.js");
const query_util_js_1 = require("../utils/query.util.js");
const defaults_util_js_1 = require("../utils/defaults.util.js");
/**
* Controller for managing Bitbucket repositories.
* Provides functionality for listing repositories and retrieving repository details.
*/
// Create a contextualized logger for this file
const controllerLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.repositories.controller.ts');
// Log controller initialization
controllerLogger.debug('Bitbucket repositories controller initialized');
/**
* Lists repositories for a specific workspace with pagination and filtering options
* @param options - Options for listing repositories including workspaceSlug
* @returns Formatted list of repositories with pagination information
*/
async function list(options) {
const { workspaceSlug } = options;
const methodLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.repositories.controller.ts', 'list');
methodLogger.debug(`Listing repositories for workspace: ${workspaceSlug}...`, options);
try {
// Create defaults object with proper typing
const defaults = {
limit: defaults_util_js_1.DEFAULT_PAGE_SIZE,
sort: '-updated_on',
};
// Apply defaults
const mergedOptions = (0, defaults_util_js_1.applyDefaults)(options, defaults);
// Format the query for Bitbucket API if provided
const formattedQuery = mergedOptions.query
? (0, query_util_js_1.formatBitbucketQuery)(mergedOptions.query)
: undefined;
// Map controller options to service parameters
const serviceParams = {
// Required workspace
workspace: workspaceSlug,
// Handle limit with default value
pagelen: mergedOptions.limit,
// Map cursor to page for page-based pagination
page: mergedOptions.cursor
? parseInt(mergedOptions.cursor, 10)
: undefined,
// Set default sort to updated_on descending if not specified
sort: mergedOptions.sort,
// Optional filter parameters
...(formattedQuery && { q: formattedQuery }),
...(mergedOptions.role && { role: mergedOptions.role }),
};
methodLogger.debug('Using service parameters:', serviceParams);
const repositoriesData = await vendor_atlassian_repositories_service_js_1.default.list(serviceParams);
// Log only the count of repositories returned instead of the entire response
methodLogger.debug(`Retrieved ${repositoriesData.values?.length || 0} repositories`);
// Extract pagination information using the utility
const pagination = (0, pagination_util_js_1.extractPaginationInfo)(repositoriesData, pagination_util_js_1.PaginationType.PAGE);
// Format the repositories data for display using the formatter
const formattedRepositories = (0, atlassian_repositories_formatter_js_1.formatRepositoriesList)(repositoriesData);
return {
content: formattedRepositories,
pagination,
};
}
catch (error) {
// Use the standardized error handler
(0, error_handler_util_js_1.handleControllerError)(error, {
entityType: 'Repositories',
operation: 'listing',
source: 'controllers/atlassian.repositories.controller.ts@list',
additionalInfo: { options },
});
}
}
/**
* Gets details of a specific Bitbucket repository
* @param identifier - Repository identifier containing workspaceSlug and repoSlug
* @returns Formatted repository details
*/
async function get(identifier) {
const { workspaceSlug, repoSlug } = identifier;
const methodLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.repositories.controller.ts', 'get');
methodLogger.debug(`Getting repository details for ${workspaceSlug}/${repoSlug}...`);
try {
// Map controller options to service parameters
const serviceParams = {
workspace: workspaceSlug,
repo_slug: repoSlug,
};
methodLogger.debug('Using service parameters:', serviceParams);
// Fetch repository data
const repositoryData = await vendor_atlassian_repositories_service_js_1.default.get(serviceParams);
methodLogger.debug(`Retrieved repository: ${repositoryData.full_name}`);
// Fetch recent pull requests to provide immediate context and activity history.
// This enhances usability by including relevant PRs directly in repository details,
// saving users from having to make a separate API call. While this crosses entity
// boundaries slightly, it significantly improves the user experience by showing
// recent activity alongside the repository's metadata.
let recentPullRequests = null;
try {
// Create pull request list parameters similar to how the PR controller would
const pullRequestsParams = {
workspace: workspaceSlug,
repo_slug: repoSlug,
pagelen: defaults_util_js_1.DEFAULT_PAGE_SIZE, // Limit to PRs using constant
sort: '-updated_on', // Sort by most recently updated
// No state filter to get all PRs regardless of state
};
methodLogger.debug('Fetching recent pull requests:', pullRequestsParams);
recentPullRequests =
await vendor_atlassian_pullrequests_service_js_1.default.list(pullRequestsParams);
methodLogger.debug(`Retrieved ${recentPullRequests.values?.length || 0} recent pull requests`);
}
catch (prError) {
methodLogger.warn('Failed to fetch pull requests:', prError);
// Continue with repository details even if PR fetch fails
}
// Format the repository data for display using the formatter
const formattedRepository = (0, atlassian_repositories_formatter_js_1.formatRepositoryDetails)(repositoryData, recentPullRequests);
return {
content: formattedRepository,
};
}
catch (error) {
(0, error_handler_util_js_1.handleControllerError)(error, {
source: 'controllers/atlassian.repositories.controller.ts@get',
entityType: 'Repository',
operation: 'retrieving',
entityId: { workspaceSlug, repoSlug },
});
}
}
/**
* Retrieves the commit history for a repository.
* @param identifier Repository identifier including workspace and repo slug.
* @param options Optional filtering and pagination options (revision, path, limit, cursor).
* @returns Formatted commit history with pagination information.
*/
async function getCommitHistory(identifier, options = {}) {
const { workspaceSlug, repoSlug } = identifier;
const methodLogger = logger_util_js_1.Logger.forContext('controllers/atlassian.repositories.controller.ts', 'getCommitHistory');
methodLogger.debug(`Getting commit history for ${workspaceSlug}/${repoSlug}`, options);
try {
const defaults = {
limit: defaults_util_js_1.DEFAULT_PAGE_SIZE,
};
const mergedOptions = (0, defaults_util_js_1.applyDefaults)(options, defaults);
const serviceParams = {
workspace: workspaceSlug,
repo_slug: repoSlug,
include: mergedOptions.revision,
path: mergedOptions.path,
pagelen: mergedOptions.limit,
page: mergedOptions.cursor
? parseInt(mergedOptions.cursor, 10)
: undefined,
};
methodLogger.debug('Using commit service parameters:', serviceParams);
const commitsData = await vendor_atlassian_repositories_service_js_1.default.listCommits(serviceParams);
methodLogger.debug(`Retrieved ${commitsData.values?.length || 0} commits`);
const pagination = (0, pagination_util_js_1.extractPaginationInfo)(commitsData, pagination_util_js_1.PaginationType.PAGE);
const formattedHistory = (0, atlassian_repositories_formatter_js_1.formatCommitHistory)(commitsData, {
revision: mergedOptions.revision,
path: mergedOptions.path,
});
return {
content: formattedHistory,
pagination,
};
}
catch (error) {
(0, error_handler_util_js_1.handleControllerError)(error, {
entityType: 'Commit History',
operation: 'retrieving',
source: 'controllers/atlassian.repositories.controller.ts@getCommitHistory',
additionalInfo: { identifier, options },
});
}
}
exports.default = { list, get, getCommitHistory };