Skip to main content
Glama

Atlassian Bitbucket MCP Server

by aashari
atlassian.repositories.cli.ts14.2 kB
import { Command } from 'commander'; import { Logger } from '../utils/logger.util.js'; import { handleCliError } from '../utils/error.util.js'; // Import directly from specialized controllers import { handleRepositoriesList } from '../controllers/atlassian.repositories.list.controller.js'; import { handleRepositoryDetails } from '../controllers/atlassian.repositories.details.controller.js'; import { handleCommitHistory } from '../controllers/atlassian.repositories.commit.controller.js'; import { handleCreateBranch, handleListBranches, } from '../controllers/atlassian.repositories.branch.controller.js'; import { handleCloneRepository, handleGetFileContent, } from '../controllers/atlassian.repositories.content.controller.js'; /** * CLI module for managing Bitbucket repositories. * Provides commands for listing repositories and retrieving repository details. * All commands require valid Atlassian credentials. */ // Create a contextualized logger for this file const cliLogger = Logger.forContext('cli/atlassian.repositories.cli.ts'); // Log CLI initialization cliLogger.debug('Bitbucket repositories CLI module initialized'); /** * Register Bitbucket repositories CLI commands with the Commander program * * @param program - The Commander program instance to register commands with * @throws Error if command registration fails */ function register(program: Command): void { const methodLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'register', ); methodLogger.debug('Registering Bitbucket Repositories CLI commands...'); registerListRepositoriesCommand(program); registerGetRepositoryCommand(program); registerGetCommitHistoryCommand(program); registerAddBranchCommand(program); registerCloneRepositoryCommand(program); registerGetFileCommand(program); registerListBranchesCommand(program); methodLogger.debug('CLI commands registered successfully'); } /** * Register the command for listing Bitbucket repositories in a workspace * * @param program - The Commander program instance */ function registerListRepositoriesCommand(program: Command): void { program .command('ls-repos') .description( 'List repositories in a Bitbucket workspace, with filtering and pagination.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repositories. If not provided, uses your default workspace (configured via BITBUCKET_DEFAULT_WORKSPACE or first workspace in your account). Example: "myteam"', ) .option( '-q, --query <string>', 'Filter repositories by this query string. Searches repository name and description.', ) .option( '-p, --project-key <key>', 'Filter repositories belonging to the specified project key. Example: "PROJ"', ) .option( '-r, --role <string>', 'Filter repositories where the authenticated user has the specified role or higher. Valid roles: `owner`, `admin`, `contributor`, `member`. Note: `member` typically includes all accessible repositories.', ) .option( '-s, --sort <string>', 'Sort repositories by this field. Examples: "name", "-updated_on" (default), "size".', ) .option( '-l, --limit <number>', 'Maximum number of items to return (1-100). Defaults to 25 if omitted.', ) .option( '-c, --cursor <string>', 'Pagination cursor for retrieving the next set of results.', ) .action(async (options) => { const actionLogger = cliLogger.forMethod('ls-repos'); try { actionLogger.debug('CLI ls-repos called', options); // Map CLI options to controller options - keep only type conversions const controllerOptions = { workspaceSlug: options.workspaceSlug, query: options.query, projectKey: options.projectKey, role: options.role, sort: options.sort, limit: options.limit ? parseInt(options.limit, 10) : undefined, cursor: options.cursor, }; // Call controller directly const result = await handleRepositoriesList(controllerOptions); // Output result content console.log(result.content); } catch (error) { handleCliError(error); } }); } /** * Register the command for retrieving a specific Bitbucket repository * @param program - The Commander program instance */ function registerGetRepositoryCommand(program: Command): void { program .command('get-repo') .description( 'Get detailed information about a specific Bitbucket repository.', ) .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace (either configured via BITBUCKET_DEFAULT_WORKSPACE or first workspace in your account). Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug to retrieve. Must be a valid repository in the workspace. Example: "project-api"', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'get-repo', ); try { actionLogger.debug( `Fetching repository: ${options.workspaceSlug}/${options.repoSlug}`, ); const result = await handleRepositoryDetails({ workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, }); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for retrieving commit history from a repository * @param program - The Commander program instance */ function registerGetCommitHistoryCommand(program: Command): void { program .command('get-commit-history') .description('Get commit history for a Bitbucket repository.') .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug to get commit history from. Example: "project-api"', ) .option( '-v, --revision <branch-or-tag>', 'Filter commits by a specific branch, tag, or commit hash.', ) .option( '--path <file-path>', 'Filter commits to those that affect this specific file path.', ) .option( '-l, --limit <number>', 'Maximum number of commits to return (1-100). Defaults to 25 if omitted.', ) .option( '-c, --cursor <string>', 'Pagination cursor for retrieving the next set of results.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'get-commit-history', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params - keep only type conversions const requestOptions = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, revision: options.revision, path: options.path, limit: options.limit ? parseInt(options.limit, 10) : undefined, cursor: options.cursor, }; actionLogger.debug( 'Fetching commit history with options:', requestOptions, ); const result = await handleCommitHistory(requestOptions); actionLogger.debug('Successfully retrieved commit history'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for adding a branch to a repository * @param program - The Commander program instance */ function registerAddBranchCommand(program: Command): void { program .command('add-branch') .description('Add a new branch in a Bitbucket repository.') .requiredOption( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository.', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug where the branch will be created.', ) .requiredOption( '-n, --new-branch-name <n>', 'The name for the new branch.', ) .requiredOption( '-s, --source-branch-or-commit <target>', 'The name of the existing branch or a full commit hash to branch from.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'add-branch', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params const requestOptions = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, newBranchName: options.newBranchName, sourceBranchOrCommit: options.sourceBranchOrCommit, }; actionLogger.debug( 'Creating branch with options:', requestOptions, ); const result = await handleCreateBranch(requestOptions); actionLogger.debug('Successfully created branch'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for cloning a Bitbucket repository. * * @param program - The Commander program instance */ function registerCloneRepositoryCommand(program: Command): void { program .command('clone') .description( 'Clone a Bitbucket repository to your local filesystem using SSH (preferred) or HTTPS. ' + 'The repository will be cloned into a subdirectory at targetPath/repoSlug. ' + 'Requires Bitbucket credentials and proper SSH key setup for optimal usage.', ) .requiredOption( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug to clone. Example: "project-api"', ) .requiredOption( '-t, --target-path <path>', 'Directory path where the repository will be cloned. Absolute paths are strongly recommended. Example: "/home/user/projects"', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'clone', ); try { actionLogger.debug( 'Processing clone command options:', options, ); // Map CLI options to controller params (already correct case) const controllerOptions = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, targetPath: options.targetPath, }; actionLogger.debug( 'Initiating repository clone with options:', controllerOptions, ); const result = await handleCloneRepository(controllerOptions); actionLogger.info('Clone operation initiated successfully.'); console.log(result.content); } catch (error) { actionLogger.error('Clone operation failed:', error); handleCliError(error); } }); } /** * Register the command for getting a file from a Bitbucket repository * * @param program - The Commander program instance */ function registerGetFileCommand(program: Command): void { program .command('get-file') .description('Get the content of a file from a Bitbucket repository.') .requiredOption( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. Must be a valid workspace slug from your Bitbucket account. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug to get the file from. Must be a valid repository slug in the specified workspace. Example: "project-api"', ) .requiredOption( '-f, --file-path <path>', 'Path to the file in the repository. Example: "README.md" or "src/main.js"', ) .option( '-v, --revision <branch-tag-or-commit>', 'Branch name, tag, or commit hash to retrieve the file from. If omitted, the default branch is used.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'get-file', ); try { actionLogger.debug( `Fetching file: ${options.workspaceSlug}/${options.repoSlug}/${options.filePath}`, options.revision ? { revision: options.revision } : {}, ); const result = await handleGetFileContent({ workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, path: options.filePath, ref: options.revision, }); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } /** * Register the command for listing branches in a repository * @param program - The Commander program instance */ function registerListBranchesCommand(program: Command): void { program .command('list-branches') .description('List branches in a Bitbucket repository.') .option( '-w, --workspace-slug <slug>', 'Workspace slug containing the repository. If not provided, uses your default workspace. Example: "myteam"', ) .requiredOption( '-r, --repo-slug <slug>', 'Repository slug to list branches from. Example: "project-api"', ) .option( '-q, --query <string>', 'Filter branches by name or other properties (text search).', ) .option( '-s, --sort <string>', 'Sort branches by this field. Examples: "name" (default), "-name", "target.date".', ) .option( '-l, --limit <number>', 'Maximum number of branches to return (1-100). Defaults to 25 if omitted.', ) .option( '-c, --cursor <string>', 'Pagination cursor for retrieving the next set of results.', ) .action(async (options) => { const actionLogger = Logger.forContext( 'cli/atlassian.repositories.cli.ts', 'list-branches', ); try { actionLogger.debug('Processing command options:', options); // Map CLI options to controller params - keep only type conversions const params = { workspaceSlug: options.workspaceSlug, repoSlug: options.repoSlug, query: options.query, sort: options.sort, limit: options.limit ? parseInt(options.limit, 10) : undefined, cursor: options.cursor, }; actionLogger.debug( 'Fetching branches with parameters:', params, ); const result = await handleListBranches(params); actionLogger.debug('Successfully retrieved branches'); console.log(result.content); } catch (error) { actionLogger.error('Operation failed:', error); handleCliError(error); } }); } export default { register };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aashari/mcp-server-atlassian-bitbucket'

If you have feedback or need assistance with the MCP directory API, please join our Discord server