#
tokens: 46020/50000 5/114 files (page 4/4)
lines: off (toggle) GitHub
raw markdown copy
This is page 4 of 4. Use http://codebase.md/aashari/mcp-server-atlassian-bitbucket?page={x} to view the full context.

# Directory Structure

```
├── .env.example
├── .github
│   ├── dependabot.yml
│   └── workflows
│       ├── ci-dependabot-auto-merge.yml
│       ├── ci-dependency-check.yml
│       └── ci-semantic-release.yml
├── .gitignore
├── .gitkeep
├── .npmignore
├── .npmrc
├── .prettierrc
├── .releaserc.json
├── .trigger-ci
├── CHANGELOG.md
├── eslint.config.mjs
├── jest.setup.js
├── package-lock.json
├── package.json
├── README.md
├── scripts
│   ├── ensure-executable.js
│   ├── package.json
│   └── update-version.js
├── src
│   ├── cli
│   │   ├── atlassian.diff.cli.ts
│   │   ├── atlassian.pullrequests.cli.test.ts
│   │   ├── atlassian.pullrequests.cli.ts
│   │   ├── atlassian.repositories.cli.test.ts
│   │   ├── atlassian.repositories.cli.ts
│   │   ├── atlassian.search.cli.test.ts
│   │   ├── atlassian.search.cli.ts
│   │   ├── atlassian.workspaces.cli.test.ts
│   │   ├── atlassian.workspaces.cli.ts
│   │   └── index.ts
│   ├── controllers
│   │   ├── atlassian.diff.controller.ts
│   │   ├── atlassian.diff.formatter.ts
│   │   ├── atlassian.pullrequests.approve.controller.ts
│   │   ├── atlassian.pullrequests.base.controller.ts
│   │   ├── atlassian.pullrequests.comments.controller.ts
│   │   ├── atlassian.pullrequests.controller.test.ts
│   │   ├── atlassian.pullrequests.controller.ts
│   │   ├── atlassian.pullrequests.create.controller.ts
│   │   ├── atlassian.pullrequests.formatter.ts
│   │   ├── atlassian.pullrequests.get.controller.ts
│   │   ├── atlassian.pullrequests.list.controller.ts
│   │   ├── atlassian.pullrequests.reject.controller.ts
│   │   ├── atlassian.pullrequests.update.controller.ts
│   │   ├── atlassian.repositories.branch.controller.ts
│   │   ├── atlassian.repositories.commit.controller.ts
│   │   ├── atlassian.repositories.content.controller.ts
│   │   ├── atlassian.repositories.controller.test.ts
│   │   ├── atlassian.repositories.details.controller.ts
│   │   ├── atlassian.repositories.formatter.ts
│   │   ├── atlassian.repositories.list.controller.ts
│   │   ├── atlassian.search.code.controller.ts
│   │   ├── atlassian.search.content.controller.ts
│   │   ├── atlassian.search.controller.test.ts
│   │   ├── atlassian.search.controller.ts
│   │   ├── atlassian.search.formatter.ts
│   │   ├── atlassian.search.pullrequests.controller.ts
│   │   ├── atlassian.search.repositories.controller.ts
│   │   ├── atlassian.workspaces.controller.test.ts
│   │   ├── atlassian.workspaces.controller.ts
│   │   └── atlassian.workspaces.formatter.ts
│   ├── index.ts
│   ├── services
│   │   ├── vendor.atlassian.pullrequests.service.ts
│   │   ├── vendor.atlassian.pullrequests.test.ts
│   │   ├── vendor.atlassian.pullrequests.types.ts
│   │   ├── vendor.atlassian.repositories.diff.service.ts
│   │   ├── vendor.atlassian.repositories.diff.types.ts
│   │   ├── vendor.atlassian.repositories.service.test.ts
│   │   ├── vendor.atlassian.repositories.service.ts
│   │   ├── vendor.atlassian.repositories.types.ts
│   │   ├── vendor.atlassian.search.service.ts
│   │   ├── vendor.atlassian.search.types.ts
│   │   ├── vendor.atlassian.workspaces.service.ts
│   │   ├── vendor.atlassian.workspaces.test.ts
│   │   └── vendor.atlassian.workspaces.types.ts
│   ├── tools
│   │   ├── atlassian.diff.tool.ts
│   │   ├── atlassian.diff.types.ts
│   │   ├── atlassian.pullrequests.tool.ts
│   │   ├── atlassian.pullrequests.types.test.ts
│   │   ├── atlassian.pullrequests.types.ts
│   │   ├── atlassian.repositories.tool.ts
│   │   ├── atlassian.repositories.types.ts
│   │   ├── atlassian.search.tool.ts
│   │   ├── atlassian.search.types.ts
│   │   ├── atlassian.workspaces.tool.ts
│   │   └── atlassian.workspaces.types.ts
│   ├── types
│   │   └── common.types.ts
│   └── utils
│       ├── adf.util.test.ts
│       ├── adf.util.ts
│       ├── atlassian.util.ts
│       ├── bitbucket-error-detection.test.ts
│       ├── cli.test.util.ts
│       ├── config.util.test.ts
│       ├── config.util.ts
│       ├── constants.util.ts
│       ├── defaults.util.ts
│       ├── diff.util.ts
│       ├── error-handler.util.test.ts
│       ├── error-handler.util.ts
│       ├── error.util.test.ts
│       ├── error.util.ts
│       ├── formatter.util.ts
│       ├── logger.util.ts
│       ├── markdown.util.test.ts
│       ├── markdown.util.ts
│       ├── pagination.util.ts
│       ├── path.util.test.ts
│       ├── path.util.ts
│       ├── query.util.ts
│       ├── shell.util.ts
│       ├── transport.util.test.ts
│       ├── transport.util.ts
│       └── workspace.util.ts
├── STYLE_GUIDE.md
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/src/cli/atlassian.pullrequests.cli.ts:
--------------------------------------------------------------------------------

```typescript
import { Command } from 'commander';
import { Logger } from '../utils/logger.util.js';
import { handleCliError } from '../utils/error.util.js';
import atlassianPullRequestsController from '../controllers/atlassian.pullrequests.controller.js';

/**
 * CLI module for managing Bitbucket pull requests.
 * Provides commands for listing, retrieving, and manipulating pull requests.
 * All commands require valid Atlassian credentials.
 */

// Create a contextualized logger for this file
const cliLogger = Logger.forContext('cli/atlassian.pullrequests.cli.ts');

// Log CLI initialization
cliLogger.debug('Bitbucket pull requests CLI module initialized');

/**
 * Register Bitbucket pull requests 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.pullrequests.cli.ts',
		'register',
	);
	methodLogger.debug('Registering Bitbucket Pull Requests CLI commands...');

	registerListPullRequestsCommand(program);
	registerGetPullRequestCommand(program);
	registerListPullRequestCommentsCommand(program);
	registerAddPullRequestCommentCommand(program);
	registerAddPullRequestCommand(program);
	registerUpdatePullRequestCommand(program);
	registerApprovePullRequestCommand(program);
	registerRejectPullRequestCommand(program);

	methodLogger.debug('CLI commands registered successfully');
}

/**
 * Register the command for listing Bitbucket pull requests
 * @param program - The Commander program instance
 */
function registerListPullRequestsCommand(program: Command): void {
	program
		.command('ls-prs')
		.description(
			'List pull requests in a Bitbucket repository, with filtering and pagination.',
		)
		.option(
			'-w, --workspace-slug <slug>',
			'Workspace slug containing the repository. If not provided, the system will use your default workspace (either configured via BITBUCKET_DEFAULT_WORKSPACE or the first workspace in your account). Example: "myteam"',
		)
		.requiredOption(
			'-r, --repo-slug <slug>',
			'Repository slug containing the pull requests. This must be a valid repository in the specified workspace. Example: "project-api"',
		)
		.option(
			'-s, --state <state>',
			'Filter by pull request state: "OPEN", "MERGED", "DECLINED", or "SUPERSEDED". If omitted, returns pull requests in all states.',
		)
		.option(
			'-q, --query <string>',
			'Filter pull requests by query string. Searches pull request title and description.',
		)
		.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 = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'ls-prs',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Map CLI options to controller params - keep only type conversions
				const filterOptions = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					state: options.state as
						| 'OPEN'
						| 'MERGED'
						| 'DECLINED'
						| 'SUPERSEDED'
						| undefined,
					query: options.query,
					limit: options.limit
						? parseInt(options.limit, 10)
						: undefined,
					cursor: options.cursor,
				};

				actionLogger.debug(
					'Fetching pull requests with filters:',
					filterOptions,
				);
				const result =
					await atlassianPullRequestsController.list(filterOptions);
				actionLogger.debug('Successfully retrieved pull requests');

				// Display the content which now includes pagination information
				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for retrieving a specific Bitbucket pull request
 * @param program - The Commander program instance
 */
function registerGetPullRequestCommand(program: Command): void {
	program
		.command('get-pr')
		.description(
			'Get detailed information about a specific Bitbucket pull request.',
		)
		.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 containing the pull request. Must be a valid repository in the specified workspace. Example: "project-api"',
		)
		.requiredOption(
			'-p, --pr-id <id>',
			'Numeric ID of the pull request to retrieve. Must be a valid pull request ID in the specified repository. Example: "42"',
		)
		.option(
			'--include-full-diff',
			'Retrieve the full diff content instead of just the summary. Default: true (rich output by default)',
			true,
		)
		.option(
			'--include-comments',
			'Retrieve comments for the pull request. Default: false. Note: Enabling this may increase response time for pull requests with many comments due to additional API calls',
			false,
		)
		.action(async (options) => {
			const actionLogger = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'get-pr',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Map CLI options to controller params
				const params = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					prId: options.prId,
					includeFullDiff: options.includeFullDiff,
					includeComments: options.includeComments,
				};

				actionLogger.debug('Fetching pull request:', params);
				const result =
					await atlassianPullRequestsController.get(params);
				actionLogger.debug('Successfully retrieved pull request');

				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for listing comments on a Bitbucket pull request
 * @param program - The Commander program instance
 */
function registerListPullRequestCommentsCommand(program: Command): void {
	program
		.command('ls-pr-comments')
		.description(
			'List comments on a specific Bitbucket pull request, with pagination.',
		)
		.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 containing the pull request. Must be a valid repository in the specified workspace. Example: "project-api"',
		)
		.requiredOption(
			'-p, --pr-id <id>',
			'Numeric ID of the pull request to retrieve comments from. Must be a valid pull request ID in the specified repository. Example: "42"',
		)
		.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 = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'ls-pr-comments',
			);
			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,
					prId: options.prId,
					limit: options.limit
						? parseInt(options.limit, 10)
						: undefined,
					cursor: options.cursor,
				};

				actionLogger.debug('Fetching pull request comments:', params);
				const result =
					await atlassianPullRequestsController.listComments(params);
				actionLogger.debug(
					'Successfully retrieved pull request comments',
				);

				// Display the content which now includes pagination information
				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for adding a comment to a pull request
 * @param program - The Commander program instance
 */
function registerAddPullRequestCommentCommand(program: Command): void {
	program
		.command('add-pr-comment')
		.description('Add a comment to a Bitbucket pull request.')
		.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 containing the pull request. Must be a valid repository in the specified workspace. Example: "project-api"',
		)
		.requiredOption(
			'-p, --pr-id <id>',
			'Numeric ID of the pull request to add a comment to. Must be a valid pull request ID in the specified repository. Example: "42"',
		)
		.requiredOption(
			'-m, --content <text>',
			'The content of the comment to add to the pull request. Can include markdown formatting.',
		)
		.option(
			'-f, --path <file-path>',
			'Optional: The file path to add an inline comment to.',
		)
		.option(
			'-L, --line <line-number>',
			'Optional: The line number to add the inline comment to.',
			parseInt,
		)
		.option(
			'--parent-id <id>',
			'Optional: The ID of the parent comment to reply to. If provided, this comment will be a reply to the specified comment.',
		)
		.action(async (options) => {
			const actionLogger = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'add-pr-comment',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Build parameters object
				const params: {
					workspaceSlug?: string;
					repoSlug: string;
					prId: string;
					content: string;
					inline?: {
						path: string;
						line: number;
					};
					parentId?: string;
				} = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					prId: options.prId,
					content: options.content,
				};

				// Add inline comment details if both path and line are provided
				if (options.path && options.line) {
					params.inline = {
						path: options.path,
						line: options.line,
					};
				} else if (options.path || options.line) {
					throw new Error(
						'Both -f/--path and -L/--line are required for inline comments',
					);
				}

				// Add parent ID if provided
				if (options.parentId) {
					params.parentId = options.parentId;
				}

				actionLogger.debug('Creating pull request comment:', {
					...params,
					content: '(content length: ' + options.content.length + ')',
				});
				const result =
					await atlassianPullRequestsController.addComment(params);
				actionLogger.debug('Successfully created pull request comment');

				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for adding a new pull request
 * @param program - The Commander program instance
 */
function registerAddPullRequestCommand(program: Command): void {
	program
		.command('add-pr')
		.description('Add a new pull request 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 create the pull request in. Must be a valid repository in the specified workspace. Example: "project-api"',
		)
		.requiredOption(
			'-t, --title <title>',
			'Title for the pull request. Example: "Add new feature"',
		)
		.requiredOption(
			'-s, --source-branch <branch>',
			'Source branch name (the branch containing your changes). Example: "feature/new-login"',
		)
		.option(
			'-d, --destination-branch <branch>',
			'Destination branch name (the branch you want to merge into, defaults to main). Example: "develop"',
		)
		.option(
			'--description <text>',
			'Optional description for the pull request.',
		)
		.option(
			'--close-source-branch',
			'Whether to close the source branch after the pull request is merged. Default: false',
			false,
		)
		.action(async (options) => {
			const actionLogger = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'add-pr',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Map CLI options to controller params
				const params = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					title: options.title,
					sourceBranch: options.sourceBranch,
					destinationBranch: options.destinationBranch,
					description: options.description,
					closeSourceBranch: options.closeSourceBranch,
				};

				actionLogger.debug('Creating pull request:', {
					...params,
					description: options.description
						? '(description provided)'
						: '(no description)',
				});
				const result =
					await atlassianPullRequestsController.add(params);
				actionLogger.debug('Successfully created pull request');

				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for updating a Bitbucket pull request
 * @param program - The Commander program instance
 */
function registerUpdatePullRequestCommand(program: Command): void {
	program
		.command('update-pr')
		.description(
			'Update an existing pull request in a Bitbucket repository.',
		)
		.option(
			'-w, --workspace-slug <slug>',
			'Workspace slug containing the repository (optional, uses default workspace if not provided). Example: "myteam"',
		)
		.requiredOption(
			'-r, --repo-slug <slug>',
			'Repository slug containing the pull request. Example: "project-api"',
		)
		.requiredOption(
			'-p, --pull-request-id <id>',
			'Pull request ID to update. Example: 123',
			parseInt,
		)
		.option(
			'-t, --title <title>',
			'Updated title for the pull request. Example: "Updated Feature Implementation"',
		)
		.option(
			'--description <text>',
			'Updated description for the pull request.',
		)
		.action(async (options) => {
			const actionLogger = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'update-pr',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Validate that at least one field to update is provided
				if (!options.title && !options.description) {
					throw new Error(
						'At least one field to update (title or description) must be provided',
					);
				}

				// Map CLI options to controller params
				const params = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					pullRequestId: options.pullRequestId,
					title: options.title,
					description: options.description,
				};

				actionLogger.debug('Updating pull request:', {
					...params,
					description: options.description
						? '(description provided)'
						: '(no description)',
				});
				const result =
					await atlassianPullRequestsController.update(params);
				actionLogger.debug('Successfully updated pull request');

				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for approving a Bitbucket pull request
 * @param program - The Commander program instance
 */
function registerApprovePullRequestCommand(program: Command): void {
	program
		.command('approve-pr')
		.description('Approve a pull request in a Bitbucket repository.')
		.option(
			'-w, --workspace-slug <slug>',
			'Workspace slug containing the repository (optional, uses default workspace if not provided). Example: "myteam"',
		)
		.requiredOption(
			'-r, --repo-slug <slug>',
			'Repository slug containing the pull request. Example: "project-api"',
		)
		.requiredOption(
			'-p, --pull-request-id <id>',
			'Pull request ID to approve. Example: 123',
			parseInt,
		)
		.action(async (options) => {
			const actionLogger = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'approve-pr',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Map CLI options to controller params
				const params = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					pullRequestId: options.pullRequestId,
				};

				actionLogger.debug('Approving pull request:', params);
				const result =
					await atlassianPullRequestsController.approve(params);
				actionLogger.debug('Successfully approved pull request');

				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

/**
 * Register the command for requesting changes on a Bitbucket pull request
 * @param program - The Commander program instance
 */
function registerRejectPullRequestCommand(program: Command): void {
	program
		.command('reject-pr')
		.description(
			'Request changes on a pull request in a Bitbucket repository.',
		)
		.option(
			'-w, --workspace-slug <slug>',
			'Workspace slug containing the repository (optional, uses default workspace if not provided). Example: "myteam"',
		)
		.requiredOption(
			'-r, --repo-slug <slug>',
			'Repository slug containing the pull request. Example: "project-api"',
		)
		.requiredOption(
			'-p, --pull-request-id <id>',
			'Pull request ID to request changes on. Example: 123',
			parseInt,
		)
		.action(async (options) => {
			const actionLogger = Logger.forContext(
				'cli/atlassian.pullrequests.cli.ts',
				'reject-pr',
			);
			try {
				actionLogger.debug('Processing command options:', options);

				// Map CLI options to controller params
				const params = {
					workspaceSlug: options.workspaceSlug,
					repoSlug: options.repoSlug,
					pullRequestId: options.pullRequestId,
				};

				actionLogger.debug(
					'Requesting changes on pull request:',
					params,
				);
				const result =
					await atlassianPullRequestsController.reject(params);
				actionLogger.debug(
					'Successfully requested changes on pull request',
				);

				console.log(result.content);
			} catch (error) {
				actionLogger.error('Operation failed:', error);
				handleCliError(error);
			}
		});
}

export default { register };

```

--------------------------------------------------------------------------------
/src/cli/atlassian.pullrequests.cli.test.ts:
--------------------------------------------------------------------------------

```typescript
import { CliTestUtil } from '../utils/cli.test.util.js';
import { getAtlassianCredentials } from '../utils/transport.util.js';
import { config } from '../utils/config.util.js';

describe('Atlassian Pull Requests CLI Commands', () => {
	// Load configuration and check for credentials before all tests
	beforeAll(() => {
		// Load configuration from all sources
		config.load();

		// Log warning if credentials aren't available
		const credentials = getAtlassianCredentials();
		if (!credentials) {
			console.warn(
				'Skipping Atlassian Pull Requests CLI tests: No credentials available',
			);
		}
	});

	// Helper function to skip tests when credentials are missing
	const skipIfNoCredentials = () => {
		const credentials = getAtlassianCredentials();
		if (!credentials) {
			return true;
		}
		return false;
	};

	// Helper to get workspace and repository for testing
	async function getWorkspaceAndRepo(): Promise<{
		workspace: string;
		repository: string;
	} | null> {
		// First, get a list of workspaces
		const workspacesResult = await CliTestUtil.runCommand([
			'ls-workspaces',
		]);

		// Skip if no workspaces are available
		if (
			workspacesResult.stdout.includes('No Bitbucket workspaces found.')
		) {
			return null; // Skip silently for this helper function
		}

		// Extract a workspace slug from the output
		const slugMatch = workspacesResult.stdout.match(
			/\*\*Slug\*\*:\s+([^\n]+)/,
		);
		if (!slugMatch || !slugMatch[1]) {
			return null; // Skip silently for this helper function
		}

		const workspaceSlug = slugMatch[1].trim();

		// Get repositories for this workspace
		const reposResult = await CliTestUtil.runCommand([
			'ls-repos',
			'--workspace-slug',
			workspaceSlug,
		]);

		// Skip if no repositories are available
		if (reposResult.stdout.includes('No repositories found')) {
			return null; // Skip silently for this helper function
		}

		// Extract a repository slug from the output
		const repoMatch = reposResult.stdout.match(/\*\*Name\*\*:\s+([^\n]+)/);
		if (!repoMatch || !repoMatch[1]) {
			return null; // Skip silently for this helper function
		}

		const repoSlug = repoMatch[1].trim();

		return {
			workspace: workspaceSlug,
			repository: repoSlug,
		};
	}

	describe('ls-prs command', () => {
		it('should list pull requests for a repository', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Get a valid workspace and repository
			const repoInfo = await getWorkspaceAndRepo();
			if (!repoInfo) {
				return; // Skip if no valid workspace/repo found
			}

			// Run the CLI command
			const result = await CliTestUtil.runCommand([
				'ls-prs',
				'--workspace-slug',
				repoInfo.workspace,
				'--repo-slug',
				repoInfo.repository,
			]);

			// Instead of expecting success, handle both success and failure
			if (result.exitCode !== 0) {
				console.warn(
					'Skipping test validation: Could not list pull requests',
				);
				return;
			}

			// Verify the output format
			if (!result.stdout.includes('No pull requests found')) {
				// Validate expected Markdown structure
				CliTestUtil.validateOutputContains(result.stdout, [
					'# Bitbucket Pull Requests',
					'**ID**',
					'**State**',
					'**Author**',
				]);

				// Validate Markdown formatting
				CliTestUtil.validateMarkdownOutput(result.stdout);
			}
		}, 30000); // Increased timeout for API calls

		it('should support filtering by state', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Get a valid workspace and repository
			const repoInfo = await getWorkspaceAndRepo();
			if (!repoInfo) {
				return; // Skip if no valid workspace/repo found
			}

			// States to test
			const states = ['OPEN', 'MERGED', 'DECLINED'];
			let testsPassed = false;

			for (const state of states) {
				// Run the CLI command with state filter
				const result = await CliTestUtil.runCommand([
					'ls-prs',
					'--workspace-slug',
					repoInfo.workspace,
					'--repo-slug',
					repoInfo.repository,
					'--state',
					state,
				]);

				// If any command succeeds, consider the test as passed
				if (result.exitCode === 0) {
					testsPassed = true;

					// Verify the output includes state if PRs are found
					if (!result.stdout.includes('No pull requests found')) {
						expect(result.stdout.toUpperCase()).toContain(state);
					}
				}
			}

			// If all commands failed, log a warning and consider the test skipped
			if (!testsPassed) {
				console.warn(
					'Skipping test validation: Could not list pull requests with state filter',
				);
			}
		}, 45000); // Increased timeout for multiple API calls

		it('should support pagination with --limit flag', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Get a valid workspace and repository
			const repoInfo = await getWorkspaceAndRepo();
			if (!repoInfo) {
				return; // Skip if no valid workspace/repo found
			}

			// Run the CLI command with limit
			const result = await CliTestUtil.runCommand([
				'ls-prs',
				'--workspace-slug',
				repoInfo.workspace,
				'--repo-slug',
				repoInfo.repository,
				'--limit',
				'1',
			]);

			// Instead of expecting success, handle both success and failure
			if (result.exitCode !== 0) {
				console.warn(
					'Skipping test validation: Could not list pull requests with pagination',
				);
				return;
			}

			// If there are multiple PRs, pagination section should be present
			if (
				!result.stdout.includes('No pull requests found') &&
				result.stdout.includes('items remaining')
			) {
				CliTestUtil.validateOutputContains(result.stdout, [
					'Pagination',
					'Next cursor:',
				]);
			}
		}, 30000);
	});

	describe('get-pr command', () => {
		it('should retrieve details for a specific pull request', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Get a valid workspace and repository
			const repoInfo = await getWorkspaceAndRepo();
			if (!repoInfo) {
				return; // Skip if no valid workspace/repo found
			}

			// First, list pull requests to find a valid ID
			const listResult = await CliTestUtil.runCommand([
				'ls-prs',
				'--workspace-slug',
				repoInfo.workspace,
				'--repo-slug',
				repoInfo.repository,
			]);

			// Skip if no pull requests are available
			if (listResult.stdout.includes('No pull requests found')) {
				return; // Skip silently - no pull requests available
			}

			// Extract a pull request ID from the output
			const prMatch = listResult.stdout.match(/\*\*ID\*\*:\s+(\d+)/);
			if (!prMatch || !prMatch[1]) {
				console.warn(
					'Skipping test: Could not extract pull request ID',
				);
				return;
			}

			const prId = prMatch[1].trim();

			// Skip the full validation since we can't guarantee PRs exist
			// Just verify that the test can find a valid ID and run the command
			if (prId) {
				// Run the get-pr command
				const getResult = await CliTestUtil.runCommand([
					'get-pr',
					'--workspace-slug',
					repoInfo.workspace,
					'--repo-slug',
					repoInfo.repository,
					'--pr-id',
					prId,
				]);

				// The test may pass or fail depending on if the PR exists
				// Just check that we get a result back
				expect(getResult).toBeDefined();
			} else {
				// Skip test if no PR ID found
				return; // Skip silently - no pull request ID available
			}
		}, 45000); // Increased timeout for multiple API calls

		it('should handle missing required parameters', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Test without workspace parameter (now optional)
			const missingWorkspace = await CliTestUtil.runCommand([
				'get-pr',
				'--repo-slug',
				'some-repo',
				'--pr-id',
				'1',
			]);

			// Now that workspace is optional, we should get a different error
			// (repository not found), but not a missing parameter error
			expect(missingWorkspace.exitCode).not.toBe(0);
			expect(missingWorkspace.stderr).not.toContain('workspace-slug');

			// Test without repository parameter
			const missingRepo = await CliTestUtil.runCommand([
				'get-pr',
				'--workspace-slug',
				'some-workspace',
				'--pr-id',
				'1',
			]);

			// Should fail with non-zero exit code
			expect(missingRepo.exitCode).not.toBe(0);
			expect(missingRepo.stderr).toContain('required option');

			// Test without pull-request parameter
			const missingPR = await CliTestUtil.runCommand([
				'get-pr',
				'--workspace-slug',
				'some-workspace',
				'--repo-slug',
				'some-repo',
			]);

			// Should fail with non-zero exit code
			expect(missingPR.exitCode).not.toBe(0);
			expect(missingPR.stderr).toContain('required option');
		}, 15000);
	});

	describe('ls-pr-comments command', () => {
		it('should list comments for a specific pull request', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Get a valid workspace and repository
			const repoInfo = await getWorkspaceAndRepo();
			if (!repoInfo) {
				return; // Skip if no valid workspace/repo found
			}

			// First, list pull requests to find a valid ID
			const listResult = await CliTestUtil.runCommand([
				'ls-prs',
				'--workspace-slug',
				repoInfo.workspace,
				'--repo-slug',
				repoInfo.repository,
			]);

			// Skip if no pull requests are available
			if (listResult.stdout.includes('No pull requests found')) {
				return; // Skip silently - no pull requests available
			}

			// Extract a pull request ID from the output
			const prMatch = listResult.stdout.match(/\*\*ID\*\*:\s+(\d+)/);
			if (!prMatch || !prMatch[1]) {
				console.warn(
					'Skipping test: Could not extract pull request ID',
				);
				return;
			}

			const prId = prMatch[1].trim();

			// Skip the full validation since we can't guarantee PRs exist
			// Just verify that the test can find a valid ID and run the command
			if (prId) {
				// Run the ls-pr-comments command
				const result = await CliTestUtil.runCommand([
					'ls-pr-comments',
					'--workspace-slug',
					repoInfo.workspace,
					'--repo-slug',
					repoInfo.repository,
					'--pr-id',
					prId,
				]);

				// The test may pass or fail depending on if the PR exists
				// Just check that we get a result back
				expect(result).toBeDefined();
			} else {
				// Skip test if no PR ID found
				return; // Skip silently - no pull request ID available
			}
		}, 45000); // Increased timeout for multiple API calls

		it('should handle missing required parameters', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Test without workspace parameter (now optional)
			const missingWorkspace = await CliTestUtil.runCommand([
				'ls-pr-comments',
				'--repo-slug',
				'some-repo',
				'--pr-id',
				'1',
			]);

			// Now that workspace is optional, we should get a different error
			// (repository not found), but not a missing parameter error
			expect(missingWorkspace.exitCode).not.toBe(0);
			expect(missingWorkspace.stderr).not.toContain('workspace-slug');

			// Test without repository parameter
			const missingRepo = await CliTestUtil.runCommand([
				'ls-pr-comments',
				'--workspace-slug',
				'some-workspace',
				'--pr-id',
				'1',
			]);

			// Should fail with non-zero exit code
			expect(missingRepo.exitCode).not.toBe(0);
			expect(missingRepo.stderr).toContain('required option');

			// Test without pull-request parameter
			const missingPR = await CliTestUtil.runCommand([
				'ls-pr-comments',
				'--workspace-slug',
				'some-workspace',
				'--repo-slug',
				'some-repo',
			]);

			// Should fail with non-zero exit code
			expect(missingPR.exitCode).not.toBe(0);
			expect(missingPR.stderr).toContain('required option');
		}, 15000);
	});

	describe('ls-pr-comments with pagination', () => {
		it('should list comments for a specific pull request with pagination', async () => {
			if (skipIfNoCredentials()) {
				return;
			}

			// Get a valid workspace and repository
			const repoInfo = await getWorkspaceAndRepo();
			if (!repoInfo) {
				return; // Skip if no valid workspace/repo found
			}

			// First, list pull requests to find a valid ID
			const listResult = await CliTestUtil.runCommand([
				'ls-prs',
				'--workspace-slug',
				repoInfo.workspace,
				'--repo-slug',
				repoInfo.repository,
			]);

			// Skip if no pull requests are available
			if (listResult.stdout.includes('No pull requests found')) {
				return; // Skip silently - no pull requests available
			}

			// Extract a pull request ID from the output
			const prMatch = listResult.stdout.match(/\*\*ID\*\*:\s+(\d+)/);
			if (!prMatch || !prMatch[1]) {
				console.warn(
					'Skipping test: Could not extract pull request ID',
				);
				return;
			}

			const prId = prMatch[1].trim();

			// Skip the full validation since we can't guarantee PRs exist
			// Just verify that the test can find a valid ID and run the command
			if (prId) {
				// Run with pagination limit
				const limitResult = await CliTestUtil.runCommand([
					'ls-pr-comments',
					'--workspace-slug',
					repoInfo.workspace,
					'--repo-slug',
					repoInfo.repository,
					'--pr-id',
					prId,
					'--limit',
					'1',
				]);

				// The test may pass or fail depending on if the PR exists
				// Just check that we get a result back
				expect(limitResult).toBeDefined();
			} else {
				// Skip test if no PR ID found
				return; // Skip silently - no pull request ID available
			}
		}, 45000); // Increased timeout for multiple API calls
	});

	describe('add-pr-comment command', () => {
		it('should display help information', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr-comment',
				'--help',
			]);
			expect(result.exitCode).toBe(0);
			expect(result.stdout).toContain(
				'Add a comment to a Bitbucket pull request.',
			);
			expect(result.stdout).toContain('--workspace-slug');
			expect(result.stdout).toContain('--repo-slug');
			expect(result.stdout).toContain('--pr-id');
			expect(result.stdout).toContain('--content');
			expect(result.stdout).toContain('--path');
			expect(result.stdout).toContain('--line');
			expect(result.stdout).toContain('--parent-id');
		});

		it('should require repo-slug parameter', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr-comment',
				'--workspace-slug',
				'codapayments',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			expect(result.stderr).toContain('repo-slug');
		});

		it('should use default workspace when workspace is not provided', async () => {
			const result = await CliTestUtil.runCommand(['add-pr-comment']);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			// Should require repo-slug but not workspace-slug
			expect(result.stderr).toContain('repo-slug');
			expect(result.stderr).not.toContain('workspace-slug');
		});

		it('should require pr-id parameter', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr-comment',
				'--workspace-slug',
				'codapayments',
				'--repo-slug',
				'repo-1',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			expect(result.stderr).toContain('pr-id');
		});

		it('should require content parameter', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr-comment',
				'--workspace-slug',
				'codapayments',
				'--repo-slug',
				'repo-1',
				'--pr-id',
				'1',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			expect(result.stderr).toContain('content');
		});

		it('should detect incomplete inline comment parameters', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr-comment',
				'--workspace-slug',
				'codapayments',
				'--repo-slug',
				'repo-1',
				'--pr-id',
				'1',
				'--content',
				'Test',
				'--path',
				'README.md',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain(
				'Both -f/--path and -L/--line are required for inline comments',
			);
		});

		it('should accept valid parentId parameter for comment replies', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr-comment',
				'--workspace-slug',
				'codapayments',
				'--repo-slug',
				'repo-1',
				'--pr-id',
				'1',
				'--content',
				'This is a reply',
				'--parent-id',
				'123',
			]);
			// Should fail due to invalid repo/PR, but not due to parentId parameter validation
			expect(result.exitCode).not.toBe(0);
			// Should NOT contain parameter validation errors for parentId
			expect(result.stderr).not.toContain('parent-id');
		});

		// Note: API call test has been removed to avoid creating comments on real PRs during tests
	});

	describe('add-pr command', () => {
		it('should display help information', async () => {
			const result = await CliTestUtil.runCommand(['add-pr', '--help']);
			expect(result.exitCode).toBe(0);
			expect(result.stdout).toContain(
				'Add a new pull request in a Bitbucket repository.',
			);
			expect(result.stdout).toContain('--workspace-slug');
			expect(result.stdout).toContain('--repo-slug');
			expect(result.stdout).toContain('--title');
			expect(result.stdout).toContain('--source-branch');
			expect(result.stdout).toContain('--destination-branch');
			expect(result.stdout).toContain('--description');
			expect(result.stdout).toContain('--close-source-branch');
		});

		it('should require repo-slug parameter', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr',
				'--workspace-slug',
				'test-ws',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			expect(result.stderr).toContain('repo-slug');
		});

		it('should use default workspace when workspace is not provided', async () => {
			const result = await CliTestUtil.runCommand(['add-pr']);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			// Should require repo-slug but not workspace-slug
			expect(result.stderr).toContain('repo-slug');
			expect(result.stderr).not.toContain('workspace-slug');
		});

		it('should require title parameter', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr',
				'--workspace-slug',
				'test-ws',
				'--repo-slug',
				'test-repo',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			expect(result.stderr).toContain('title');
		});

		it('should require source-branch parameter', async () => {
			const result = await CliTestUtil.runCommand([
				'add-pr',
				'--workspace-slug',
				'test-ws',
				'--repo-slug',
				'test-repo',
				'--title',
				'Test PR',
			]);
			expect(result.exitCode).not.toBe(0);
			expect(result.stderr).toContain('required option');
			expect(result.stderr).toContain('source-branch');
		});

		// Note: API call test has been removed to avoid creating PRs on real repos during tests
	});
});

```

--------------------------------------------------------------------------------
/src/controllers/atlassian.pullrequests.controller.test.ts:
--------------------------------------------------------------------------------

```typescript
import { McpError, ErrorType } from '../utils/error.util.js';
import atlassianPullRequestsController from './atlassian.pullrequests.controller.js';
import { getAtlassianCredentials } from '../utils/transport.util.js';
import atlassianPullRequestsService from '../services/vendor.atlassian.pullrequests.service.js';
import atlassianWorkspacesService from '../services/vendor.atlassian.workspaces.service.js';
import atlassianRepositoriesService from '../services/vendor.atlassian.repositories.service.js';

describe('Atlassian Pull Requests Controller', () => {
	const skipIfNoCredentials = () => !getAtlassianCredentials();

	async function getRepositoryInfo(): Promise<{
		workspaceSlug: string;
		repoSlug: string;
	} | null> {
		// Skip if no credentials
		if (skipIfNoCredentials()) return null;

		try {
			// Try to get workspaces
			const workspacesResponse = await atlassianWorkspacesService.list({
				pagelen: 1,
			});

			if (
				!workspacesResponse.values ||
				workspacesResponse.values.length === 0
			) {
				console.warn('No workspaces found for test account');
				return null;
			}

			const workspace = workspacesResponse.values[0];
			// The workspace slug might be in different locations depending on the response structure
			// Try to access it safely from possible locations
			const workspaceSlug =
				workspace.workspace?.slug ||
				(workspace as any).slug ||
				(workspace as any).name ||
				null;

			if (!workspaceSlug) {
				console.warn(
					'Could not determine workspace slug from response',
				);
				return null;
			}

			// Get repositories for this workspace
			const reposResponse = await atlassianRepositoriesService.list({
				workspace: workspaceSlug,
				pagelen: 1,
			});

			if (!reposResponse.values || reposResponse.values.length === 0) {
				console.warn(
					`No repositories found in workspace ${workspaceSlug}`,
				);
				return null;
			}

			const repo = reposResponse.values[0];
			// The repo slug might be in different locations or named differently
			const repoSlug =
				(repo as any).slug ||
				(repo as any).name ||
				(repo.full_name?.split('/').pop() as string) ||
				null;

			if (!repoSlug) {
				console.warn(
					'Could not determine repository slug from response',
				);
				return null;
			}

			return {
				workspaceSlug,
				repoSlug,
			};
		} catch (error) {
			console.warn('Failed to get repository info for tests:', error);
			return null;
		}
	}

	async function getFirstPullRequestId(): Promise<{
		workspaceSlug: string;
		repoSlug: string;
		prId: string;
	} | null> {
		const repoInfo = await getRepositoryInfo();
		if (!repoInfo) return null;

		try {
			// List PRs
			const prsResponse = await atlassianPullRequestsService.list({
				workspace: repoInfo.workspaceSlug,
				repo_slug: repoInfo.repoSlug,
				pagelen: 1,
			});

			if (!prsResponse.values || prsResponse.values.length === 0) {
				console.warn(
					`No pull requests found in ${repoInfo.workspaceSlug}/${repoInfo.repoSlug}`,
				);
				return null;
			}

			// Return the first PR's info
			return {
				workspaceSlug: repoInfo.workspaceSlug,
				repoSlug: repoInfo.repoSlug,
				prId: prsResponse.values[0].id.toString(),
			};
		} catch (error) {
			console.warn('Failed to get pull request ID for tests:', error);
			return null;
		}
	}

	async function getPullRequestInfo(): Promise<{
		workspaceSlug: string;
		repoSlug: string;
		prId: string;
	} | null> {
		// Attempt to get a first PR ID
		return await getFirstPullRequestId();
	}

	// List tests
	describe('list', () => {
		it('should list pull requests for a repository', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			const result = await atlassianPullRequestsController.list({
				workspaceSlug: repoInfo.workspaceSlug,
				repoSlug: repoInfo.repoSlug,
			});

			// Verify the response structure
			expect(result).toHaveProperty('content');
			expect(typeof result.content).toBe('string');

			// Check for expected format based on the formatter output
			expect(result.content).toMatch(/^# Pull Requests/);
		}, 30000);

		it('should handle query parameters correctly', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			// A query term that should not match any PRs in any normal repo
			const uniqueQuery = 'z9x8c7vb6nm5';

			const result = await atlassianPullRequestsController.list({
				workspaceSlug: repoInfo.workspaceSlug,
				repoSlug: repoInfo.repoSlug,
				query: uniqueQuery,
			});

			// Even with no matches, we expect a formatted empty list
			expect(result).toHaveProperty('content');
			expect(result.content).toMatch(/^# Pull Requests/);
			expect(result.content).toContain('No pull requests found');
		}, 30000);

		it('should handle pagination options (limit)', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			// Fetch with a small limit
			const result = await atlassianPullRequestsController.list({
				workspaceSlug: repoInfo.workspaceSlug,
				repoSlug: repoInfo.repoSlug,
				limit: 1,
			});

			// Verify the response structure
			expect(result).toHaveProperty('content');

			// Check if the result contains only one PR or none
			// First check if there are no PRs
			if (result.content.includes('No pull requests found')) {
				console.warn('No pull requests found for pagination test.');
				return;
			}

			// Extract count
			const countMatch = result.content.match(/\*Showing (\d+) item/);
			if (countMatch && countMatch[1]) {
				const count = parseInt(countMatch[1], 10);
				expect(count).toBeLessThanOrEqual(1);
			}
		}, 30000);

		it('should handle authorization errors gracefully', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			// Create mocked credentials error by using intentionally invalid credentials
			jest.spyOn(
				atlassianPullRequestsService,
				'list',
			).mockRejectedValueOnce(
				new McpError('Unauthorized', ErrorType.AUTH_INVALID, 401),
			);

			// Expect to throw a standardized error
			await expect(
				atlassianPullRequestsController.list({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
				}),
			).rejects.toThrow(McpError);

			// Verify it was called
			expect(atlassianPullRequestsService.list).toHaveBeenCalled();

			// Cleanup mock
			jest.restoreAllMocks();
		}, 30000);

		it('should require workspace and repository slugs', async () => {
			if (skipIfNoCredentials()) return;

			// Missing both slugs
			await expect(
				atlassianPullRequestsController.list({} as any),
			).rejects.toThrow(
				/workspace slug and repository slug are required/i,
			);

			// Missing repo slug
			await expect(
				atlassianPullRequestsController.list({
					workspaceSlug: 'some-workspace',
				} as any),
			).rejects.toThrow(
				/workspace slug and repository slug are required/i,
			);

			// Missing workspace slug but should try to use default
			// This will fail with a different error if no default workspace can be found
			try {
				await atlassianPullRequestsController.list({
					repoSlug: 'some-repo',
				} as any);
			} catch (error) {
				expect(error).toBeInstanceOf(Error);
				// Either it will fail with "could not determine default" or
				// it may succeed with a default workspace but fail with a different error
			}
		}, 10000);

		it('should apply default parameters correctly', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			const serviceSpy = jest.spyOn(atlassianPullRequestsService, 'list');

			try {
				await atlassianPullRequestsController.list({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
					// No limit provided, should use default
				});

				// Check that the service was called with the default limit
				const calls = serviceSpy.mock.calls;
				expect(calls.length).toBeGreaterThan(0);
				const lastCall = calls[calls.length - 1];
				expect(lastCall[0]).toHaveProperty('pagelen');
				expect(lastCall[0].pagelen).toBeGreaterThan(0); // Should have some positive default value
			} finally {
				serviceSpy.mockRestore();
			}
		}, 30000);

		it('should format pagination information correctly', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			// Mock a response with pagination
			const mockResponse = {
				values: [
					{
						id: 1,
						title: 'Test PR',
						state: 'OPEN',
						created_on: new Date().toISOString(),
						updated_on: new Date().toISOString(),
						author: {
							display_name: 'Test User',
						},
						source: {
							branch: { name: 'feature-branch' },
						},
						destination: {
							branch: { name: 'main' },
						},
						links: {},
					},
				],
				page: 1,
				size: 1,
				pagelen: 1,
				next: 'https://api.bitbucket.org/2.0/repositories/workspace/repo/pullrequests?page=2',
			};

			jest.spyOn(
				atlassianPullRequestsService,
				'list',
			).mockResolvedValueOnce(mockResponse as any);

			const result = await atlassianPullRequestsController.list({
				workspaceSlug: repoInfo.workspaceSlug,
				repoSlug: repoInfo.repoSlug,
				limit: 1,
			});

			// Verify pagination info is included
			expect(result.content).toContain('*Showing 1 item');
			expect(result.content).toContain('More results are available');
			expect(result.content).toContain('Next cursor: `2`');

			// Cleanup mock
			jest.restoreAllMocks();
		}, 10000);
	});

	// Get PR tests
	describe('get', () => {
		it('should retrieve detailed pull request information', async () => {
			if (skipIfNoCredentials()) return;

			const prInfo = await getPullRequestInfo();
			if (!prInfo) {
				console.warn('Skipping test: No pull request info found.');
				return;
			}

			const result = await atlassianPullRequestsController.get({
				workspaceSlug: prInfo.workspaceSlug,
				repoSlug: prInfo.repoSlug,
				prId: prInfo.prId,
				includeFullDiff: false,
				includeComments: false,
			});

			// Verify the response structure
			expect(result).toHaveProperty('content');
			expect(typeof result.content).toBe('string');

			// Check for expected format based on the formatter output
			expect(result.content).toMatch(/^# Pull Request/);
			expect(result.content).toContain('**ID**:');
			expect(result.content).toContain('**Title**:');
			expect(result.content).toContain('**State**:');
			expect(result.content).toContain('**Author**:');
			expect(result.content).toContain('**Created**:');
		}, 30000);

		it('should handle errors for non-existent pull requests', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			// Use a PR ID that is very unlikely to exist
			const nonExistentPrId = '999999999';

			await expect(
				atlassianPullRequestsController.get({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
					prId: nonExistentPrId,
					includeFullDiff: false,
					includeComments: false,
				}),
			).rejects.toThrow(McpError);

			// Test that the error has the right status code and type
			try {
				await atlassianPullRequestsController.get({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
					prId: nonExistentPrId,
					includeFullDiff: false,
					includeComments: false,
				});
			} catch (error) {
				expect(error).toBeInstanceOf(McpError);
				expect((error as McpError).statusCode).toBe(404);
				expect((error as McpError).message).toContain('not found');
			}
		}, 30000);

		it('should require all necessary parameters', async () => {
			if (skipIfNoCredentials()) return;

			// No parameters should throw
			await expect(
				atlassianPullRequestsController.get({} as any),
			).rejects.toThrow();

			// Missing PR ID should throw
			const repoInfo = await getRepositoryInfo();
			if (repoInfo) {
				await expect(
					atlassianPullRequestsController.get({
						workspaceSlug: repoInfo.workspaceSlug,
						repoSlug: repoInfo.repoSlug,
						// prId: missing
					} as any),
				).rejects.toThrow();
			}
		}, 10000);
	});

	// List comments tests
	describe('listComments', () => {
		it('should return formatted pull request comments in Markdown', async () => {
			if (skipIfNoCredentials()) return;

			const prInfo = await getFirstPullRequestId();
			if (!prInfo) {
				console.warn('Skipping test: No pull request ID found.');
				return;
			}

			const result = await atlassianPullRequestsController.listComments({
				workspaceSlug: prInfo.workspaceSlug,
				repoSlug: prInfo.repoSlug,
				prId: prInfo.prId,
			});

			// Verify the response structure
			expect(result).toHaveProperty('content');
			expect(typeof result.content).toBe('string');

			// Basic Markdown content checks
			if (result.content !== 'No comments found on this pull request.') {
				expect(result.content).toMatch(/^# Comments on Pull Request/m);
				expect(result.content).toContain('**Author**:');
				expect(result.content).toContain('**Updated**:');
				expect(result.content).toMatch(
					/---\s*\*Showing \d+ items?\.\*/,
				);
			}
		}, 30000);

		it('should handle pagination options (limit/cursor)', async () => {
			if (skipIfNoCredentials()) return;

			const prInfo = await getFirstPullRequestId();
			if (!prInfo) {
				console.warn('Skipping test: No pull request ID found.');
				return;
			}

			// Fetch first page with limit 1
			const result1 = await atlassianPullRequestsController.listComments({
				workspaceSlug: prInfo.workspaceSlug,
				repoSlug: prInfo.repoSlug,
				prId: prInfo.prId,
				limit: 1,
			});

			// Extract pagination info from content
			const countMatch1 = result1.content.match(
				/\*Showing (\d+) items?\.\*/,
			);
			const count1 = countMatch1 ? parseInt(countMatch1[1], 10) : 0;
			expect(count1).toBeLessThanOrEqual(1);

			// Extract cursor from content
			const cursorMatch1 = result1.content.match(
				/\*Next cursor: `([^`]+)`\*/,
			);
			const nextCursor = cursorMatch1 ? cursorMatch1[1] : null;

			// Check if pagination indicates more results
			const hasMoreResults = result1.content.includes(
				'More results are available.',
			);

			// If there's a next page, fetch it
			if (hasMoreResults && nextCursor) {
				const result2 =
					await atlassianPullRequestsController.listComments({
						workspaceSlug: prInfo.workspaceSlug,
						repoSlug: prInfo.repoSlug,
						prId: prInfo.prId,
						limit: 1,
						cursor: nextCursor,
					});

				// Extract count from result2
				const countMatch2 = result2.content.match(
					/\*Showing (\d+) items?\.\*/,
				);
				const count2 = countMatch2 ? parseInt(countMatch2[1], 10) : 0;
				expect(count2).toBeLessThanOrEqual(1);

				// Ensure content is different (or handle case where only 1 comment exists)
				if (
					result1.content !==
						'No comments found on this pull request.' &&
					result2.content !==
						'No comments found on this pull request.' &&
					count1 > 0 &&
					count2 > 0
				) {
					// Only compare if we actually have multiple comments
					expect(result1.content).not.toEqual(result2.content);
				}
			} else {
				console.warn(
					'Skipping cursor part of pagination test: Only one page of comments found or no comments available.',
				);
			}
		}, 30000);

		it('should handle empty result scenario', async () => {
			if (skipIfNoCredentials()) return;

			// First get a PR without comments, or use a non-existent but valid format PR ID
			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			// Try to find a PR without comments
			try {
				// First check if we can access the repository
				const repoResult = await atlassianPullRequestsController.list({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
					limit: 1,
				});

				// Extract PR ID from the content if we have any PRs
				const prIdMatch =
					repoResult.content.match(/\*\*ID\*\*:\s+(\d+)/);
				if (!prIdMatch || !prIdMatch[1]) {
					console.warn(
						'Skipping empty result test: No pull requests available.',
					);
					return;
				}

				const prId = prIdMatch[1];

				// Get comments for this PR
				const commentsResult =
					await atlassianPullRequestsController.listComments({
						workspaceSlug: repoInfo.workspaceSlug,
						repoSlug: repoInfo.repoSlug,
						prId,
					});

				// Check if there are no comments
				if (
					commentsResult.content ===
					'No comments found on this pull request.'
				) {
					// Verify the expected message for empty results
					expect(commentsResult.content).toBe(
						'No comments found on this pull request.',
					);
				} else {
					console.warn(
						'Skipping empty result test: All PRs have comments.',
					);
				}
			} catch (error) {
				console.warn('Error during empty result test:', error);
			}
		}, 30000);

		it('should throw an McpError for a non-existent pull request ID', async () => {
			if (skipIfNoCredentials()) return;

			const repoInfo = await getRepositoryInfo();
			if (!repoInfo) {
				console.warn('Skipping test: No repository info found.');
				return;
			}

			const nonExistentId = '999999999'; // Very high number unlikely to exist

			// Expect the controller call to reject with an McpError
			await expect(
				atlassianPullRequestsController.listComments({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
					prId: nonExistentId,
				}),
			).rejects.toThrow(McpError);

			// Check the status code via the error handler's behavior
			try {
				await atlassianPullRequestsController.listComments({
					workspaceSlug: repoInfo.workspaceSlug,
					repoSlug: repoInfo.repoSlug,
					prId: nonExistentId,
				});
			} catch (e) {
				expect(e).toBeInstanceOf(McpError);
				expect((e as McpError).statusCode).toBe(404); // Expecting Not Found
				expect((e as McpError).message).toContain('not found');
			}
		}, 30000);

		it('should require all necessary parameters', async () => {
			if (skipIfNoCredentials()) return;

			// No parameters
			await expect(
				atlassianPullRequestsController.listComments({} as any),
			).rejects.toThrow();

			// Missing PR ID
			const repoInfo = await getRepositoryInfo();
			if (repoInfo) {
				await expect(
					atlassianPullRequestsController.listComments({
						workspaceSlug: repoInfo.workspaceSlug,
						repoSlug: repoInfo.repoSlug,
						// prId: missing
					} as any),
				).rejects.toThrow();
			}
		}, 10000);
	});

	// Note: addComment test suite has been removed to avoid creating comments on real PRs during tests
});

```

--------------------------------------------------------------------------------
/src/services/vendor.atlassian.pullrequests.service.ts:
--------------------------------------------------------------------------------

```typescript
import { createAuthMissingError } from '../utils/error.util.js';
import { Logger } from '../utils/logger.util.js';
import {
	fetchAtlassian,
	getAtlassianCredentials,
} from '../utils/transport.util.js';
import {
	PullRequestDetailed,
	PullRequestsResponse,
	ListPullRequestsParams,
	GetPullRequestParams,
	GetPullRequestCommentsParams,
	PullRequestCommentsResponse,
	PullRequestComment,
	CreatePullRequestCommentParams,
	CreatePullRequestParams,
	UpdatePullRequestParams,
	ApprovePullRequestParams,
	RejectPullRequestParams,
	PullRequestParticipant,
	DiffstatResponse,
} from './vendor.atlassian.pullrequests.types.js';

/**
 * Base API path for Bitbucket REST API v2
 * @see https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/
 * @constant {string}
 */
const API_PATH = '/2.0';

/**
 * @namespace VendorAtlassianPullRequestsService
 * @description Service for interacting with Bitbucket Pull Requests API.
 * Provides methods for listing pull requests and retrieving pull request details.
 * All methods require valid Atlassian credentials configured in the environment.
 */

// Create a contextualized logger for this file
const serviceLogger = Logger.forContext(
	'services/vendor.atlassian.pullrequests.service.ts',
);

// Log service initialization
serviceLogger.debug('Bitbucket pull requests service initialized');

/**
 * List pull requests for a repository
 * @param {ListPullRequestsParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {PullRequestState | PullRequestState[]} [params.state] - Filter by pull request state (default: 'OPEN')
 * @param {string} [params.q] - Query string to filter pull requests
 * @param {string} [params.sort] - Property to sort by (e.g., 'created_on', '-updated_on')
 * @param {number} [params.page] - Page number for pagination
 * @param {number} [params.pagelen] - Number of items per page
 * @returns {Promise<PullRequestsResponse>} Response containing pull requests
 * @example
 * ```typescript
 * // List open pull requests in a repository, sorted by creation date
 * const response = await list({
 *   workspace: 'myworkspace',
 *   repo_slug: 'myrepo',
 *   sort: '-created_on',
 *   pagelen: 25
 * });
 * ```
 */
async function list(
	params: ListPullRequestsParams,
): Promise<PullRequestsResponse> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'list',
	);
	methodLogger.debug('Listing Bitbucket pull requests with params:', params);

	if (!params.workspace || !params.repo_slug) {
		throw new Error('Both workspace and repo_slug parameters are required');
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	// Construct query parameters
	const queryParams = new URLSearchParams();

	// Add state parameter(s) - default to OPEN if not specified
	if (params.state) {
		if (Array.isArray(params.state)) {
			// For multiple states, repeat the parameter
			params.state.forEach((state) => {
				queryParams.append('state', state);
			});
		} else {
			queryParams.set('state', params.state);
		}
	}

	// Add optional query parameters
	if (params.q) {
		queryParams.set('q', params.q);
	}
	if (params.sort) {
		queryParams.set('sort', params.sort);
	}
	if (params.pagelen) {
		queryParams.set('pagelen', params.pagelen.toString());
	}
	if (params.page) {
		queryParams.set('page', params.page.toString());
	}

	const queryString = queryParams.toString()
		? `?${queryParams.toString()}`
		: '';
	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests${queryString}`;

	methodLogger.debug(`Sending request to: ${path}`);
	return fetchAtlassian<PullRequestsResponse>(credentials, path);
}

/**
 * Get detailed information about a specific Bitbucket pull request
 *
 * Retrieves comprehensive details about a single pull request.
 *
 * @async
 * @memberof VendorAtlassianPullRequestsService
 * @param {GetPullRequestParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request
 * @returns {Promise<PullRequestDetailed>} Promise containing the detailed pull request information
 * @throws {Error} If Atlassian credentials are missing or API request fails
 * @example
 * // Get pull request details
 * const pullRequest = await get({
 *   workspace: 'my-workspace',
 *   repo_slug: 'my-repo',
 *   pull_request_id: 123
 * });
 */
async function get(params: GetPullRequestParams): Promise<PullRequestDetailed> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'get',
	);
	methodLogger.debug(
		`Getting Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	// Validate pull_request_id is a positive integer
	const prId = Number(params.pull_request_id);
	if (isNaN(prId) || prId <= 0 || !Number.isInteger(prId)) {
		throw new Error(
			`Invalid pull request ID: ${params.pull_request_id}. Pull request ID must be a positive integer.`,
		);
	}

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}`;

	methodLogger.debug(`Sending request to: ${path}`);
	return fetchAtlassian<PullRequestDetailed>(credentials, path);
}

/**
 * Get comments for a specific Bitbucket pull request
 *
 * Retrieves all comments on a specific pull request, including general comments and
 * inline code review comments. Supports pagination.
 *
 * @async
 * @memberof VendorAtlassianPullRequestsService
 * @param {GetPullRequestCommentsParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request
 * @param {number} [params.page] - Page number for pagination
 * @param {number} [params.pagelen] - Number of items per page
 * @returns {Promise<PullRequestCommentsResponse>} Promise containing the pull request comments
 * @throws {Error} If Atlassian credentials are missing or API request fails
 * @example
 * // Get comments for a pull request
 * const comments = await getComments({
 *   workspace: 'my-workspace',
 *   repo_slug: 'my-repo',
 *   pull_request_id: 123,
 *   pagelen: 25
 * });
 */
async function getComments(
	params: GetPullRequestCommentsParams,
): Promise<PullRequestCommentsResponse> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'getComments',
	);
	methodLogger.debug(
		`Getting comments for Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	// Validate pull_request_id is a positive integer
	const prId = Number(params.pull_request_id);
	if (isNaN(prId) || prId <= 0 || !Number.isInteger(prId)) {
		throw new Error(
			`Invalid pull request ID: ${params.pull_request_id}. Pull request ID must be a positive integer.`,
		);
	}

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	// Build query parameters
	const queryParams = new URLSearchParams();

	// Add pagination parameters if provided
	if (params.pagelen) {
		queryParams.set('pagelen', params.pagelen.toString());
	}
	if (params.page) {
		queryParams.set('page', params.page.toString());
	}
	// Add sort parameter if provided
	if (params.sort) {
		queryParams.set('sort', params.sort);
	}

	const queryString = queryParams.toString()
		? `?${queryParams.toString()}`
		: '';

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/comments${queryString}`;

	methodLogger.debug(`Sending request to: ${path}`);
	return fetchAtlassian<PullRequestCommentsResponse>(credentials, path);
}

/**
 * Add a comment to a specific Bitbucket pull request
 *
 * Creates a new comment on a pull request, either as a general comment or
 * as an inline code comment attached to a specific file and line.
 *
 * @async
 * @memberof VendorAtlassianPullRequestsService
 * @param {CreatePullRequestCommentParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request
 * @param {Object} params.content - The content of the comment
 * @param {string} params.content.raw - The raw text of the comment
 * @param {Object} [params.inline] - Optional inline comment location
 * @param {string} params.inline.path - The file path for the inline comment
 * @param {number} params.inline.to - The line number in the file
 * @returns {Promise<PullRequestComment>} Promise containing the created comment
 * @throws {Error} If Atlassian credentials are missing or API request fails
 * @example
 * // Add a general comment to a pull request
 * const comment = await addComment({
 *   workspace: 'my-workspace',
 *   repo_slug: 'my-repo',
 *   pull_request_id: 123,
 *   content: { raw: "This looks good to me!" }
 * });
 *
 * // Add an inline code comment
 * const comment = await addComment({
 *   workspace: 'my-workspace',
 *   repo_slug: 'my-repo',
 *   pull_request_id: 123,
 *   content: { raw: "Consider using a constant here instead." },
 *   inline: { path: "src/main.js", to: 42 }
 * });
 */
async function createComment(
	params: CreatePullRequestCommentParams,
): Promise<PullRequestComment> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'createComment',
	);
	methodLogger.debug(
		`Creating comment on Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	if (!params.content || !params.content.raw) {
		throw new Error('Comment content is required');
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/comments`;

	methodLogger.debug(`Sending POST request to: ${path}`);
	return fetchAtlassian<PullRequestComment>(credentials, path, {
		method: 'POST',
		body: {
			content: params.content,
			inline: params.inline,
			parent: params.parent,
		},
	});
}

/**
 * Create a new pull request
 * @param {CreatePullRequestParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {string} params.title - Title of the pull request
 * @param {string} params.source.branch.name - Source branch name
 * @param {string} params.destination.branch.name - Destination branch name (defaults to main/master)
 * @param {string} [params.description] - Optional description for the pull request
 * @param {boolean} [params.close_source_branch] - Whether to close the source branch after merge (default: false)
 * @returns {Promise<PullRequestDetailed>} Detailed information about the created pull request
 * @example
 * ```typescript
 * // Create a new pull request
 * const pullRequest = await create({
 *   workspace: 'myworkspace',
 *   repo_slug: 'myrepo',
 *   title: 'Add new feature',
 *   source: {
 *     branch: {
 *       name: 'feature/new-feature'
 *     }
 *   },
 *   destination: {
 *     branch: {
 *       name: 'main'
 *     }
 *   },
 *   description: 'This PR adds a new feature...',
 *   close_source_branch: true
 * });
 * ```
 */
async function create(
	params: CreatePullRequestParams,
): Promise<PullRequestDetailed> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'create',
	);
	methodLogger.debug(
		'Creating new Bitbucket pull request with params:',
		params,
	);

	if (!params.workspace || !params.repo_slug) {
		throw new Error('Both workspace and repo_slug parameters are required');
	}

	if (!params.title) {
		throw new Error('Pull request title is required');
	}

	if (!params.source || !params.source.branch || !params.source.branch.name) {
		throw new Error('Source branch name is required');
	}

	// Destination branch is required but may have a default
	if (
		!params.destination ||
		!params.destination.branch ||
		!params.destination.branch.name
	) {
		throw new Error('Destination branch name is required');
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests`;

	// Construct request body with only the fields needed by the API
	const requestBody = {
		title: params.title,
		source: {
			branch: {
				name: params.source.branch.name,
			},
		},
		destination: {
			branch: {
				name: params.destination.branch.name,
			},
		},
		description: params.description || '',
		close_source_branch: !!params.close_source_branch,
	};

	methodLogger.debug(`Sending POST request to: ${path}`);
	return fetchAtlassian<PullRequestDetailed>(credentials, path, {
		method: 'POST',
		body: requestBody,
	});
}

/**
 * Get raw diff content for a specific Bitbucket pull request
 *
 * Retrieves the raw diff content showing actual code changes in the pull request.
 * The diff is returned in a standard unified diff format.
 *
 * @async
 * @memberof VendorAtlassianPullRequestsService
 * @param {GetPullRequestParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request
 * @returns {Promise<string>} Promise containing the raw diff content
 * @throws {Error} If Atlassian credentials are missing or API request fails
 * @example
 * // Get raw diff content for a pull request
 * const diffContent = await getRawDiff({
 *   workspace: 'my-workspace',
 *   repo_slug: 'my-repo',
 *   pull_request_id: 123
 * });
 */
async function getRawDiff(params: GetPullRequestParams): Promise<string> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'getRawDiff',
	);
	methodLogger.debug(
		`Getting raw diff for Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	// Use the diff endpoint directly
	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/diff`;

	methodLogger.debug(`Sending request to: ${path}`);

	// Override the Accept header to get raw diff content instead of JSON
	// The transport utility handles the text response automatically
	return fetchAtlassian<string>(credentials, path, {
		headers: {
			Accept: 'text/plain',
		},
	});
}

/**
 * Get the diffstat information for a pull request
 *
 * Returns summary statistics about the changes in a pull request,
 * including files changed, insertions, and deletions.
 *
 * @async
 * @memberof VendorAtlassianPullRequestsService
 * @param {GetPullRequestParams} params - Parameters for the request
 * @returns {Promise<DiffstatResponse>} Promise containing the diffstat response
 */
async function getDiffstat(
	params: GetPullRequestParams,
): Promise<DiffstatResponse> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'getDiffstat',
	);
	methodLogger.debug(
		`Getting diffstat for Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/diffstat`;

	methodLogger.debug(`Sending request to: ${path}`);
	return fetchAtlassian<DiffstatResponse>(credentials, path);
}

/**
 * Fetches the raw diff content from a specific Bitbucket API URL.
 * Used primarily for fetching file-specific diffs linked from inline comments.
 *
 * @async
 * @param {string} url - The exact Bitbucket API URL to fetch the diff from.
 * @returns {Promise<string>} Promise containing the raw diff content as a string.
 * @throws {Error} If Atlassian credentials are missing or the API request fails.
 */
async function getDiffForUrl(url: string): Promise<string> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'getDiffForUrl',
	);
	methodLogger.debug(`Getting raw diff from URL: ${url}`);

	if (!url) {
		throw new Error('URL parameter is required');
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	// Parse the provided URL to extract the path and query string
	let urlPath = '';
	try {
		const parsedUrl = new URL(url);
		urlPath = parsedUrl.pathname + parsedUrl.search;
		methodLogger.debug(`Parsed path and query from URL: ${urlPath}`);
	} catch (parseError) {
		methodLogger.error(`Failed to parse URL: ${url}`, parseError);
		throw new Error(`Invalid URL provided for diff fetching: ${url}`);
	}

	// Pass only the path part to fetchAtlassian
	// Ensure the Accept header requests plain text for the raw diff.
	return fetchAtlassian<string>(credentials, urlPath, {
		headers: {
			Accept: 'text/plain',
		},
	});
}

/**
 * Update an existing pull request
 * @param {UpdatePullRequestParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request to update
 * @param {string} [params.title] - Updated title of the pull request
 * @param {string} [params.description] - Updated description for the pull request
 * @returns {Promise<PullRequestDetailed>} Updated pull request information
 * @example
 * ```typescript
 * // Update a pull request's title and description
 * const updatedPR = await update({
 *   workspace: 'myworkspace',
 *   repo_slug: 'myrepo',
 *   pull_request_id: 123,
 *   title: 'Updated Feature Implementation',
 *   description: 'This PR now includes additional improvements...'
 * });
 * ```
 */
async function update(
	params: UpdatePullRequestParams,
): Promise<PullRequestDetailed> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'update',
	);
	methodLogger.debug('Updating Bitbucket pull request with params:', params);

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	// At least one field to update must be provided
	if (!params.title && !params.description) {
		throw new Error(
			'At least one field to update (title or description) must be provided',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}`;

	// Construct request body with only the fields to update
	const requestBody: Record<string, unknown> = {};
	if (params.title !== undefined) {
		requestBody.title = params.title;
	}
	if (params.description !== undefined) {
		requestBody.description = params.description;
	}

	methodLogger.debug(`Sending PUT request to: ${path}`);
	return fetchAtlassian<PullRequestDetailed>(credentials, path, {
		method: 'PUT',
		body: requestBody,
	});
}

/**
 * Approve a pull request
 * @param {ApprovePullRequestParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request to approve
 * @returns {Promise<PullRequestParticipant>} Participant information showing approval status
 * @example
 * ```typescript
 * // Approve a pull request
 * const approval = await approve({
 *   workspace: 'myworkspace',
 *   repo_slug: 'myrepo',
 *   pull_request_id: 123
 * });
 * ```
 */
async function approve(
	params: ApprovePullRequestParams,
): Promise<PullRequestParticipant> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'approve',
	);
	methodLogger.debug(
		`Approving Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/approve`;

	methodLogger.debug(`Sending POST request to: ${path}`);
	return fetchAtlassian<PullRequestParticipant>(credentials, path, {
		method: 'POST',
	});
}

/**
 * Request changes on a pull request (reject)
 * @param {RejectPullRequestParams} params - Parameters for the request
 * @param {string} params.workspace - The workspace slug or UUID
 * @param {string} params.repo_slug - The repository slug or UUID
 * @param {number} params.pull_request_id - The ID of the pull request to request changes on
 * @returns {Promise<PullRequestParticipant>} Participant information showing rejection status
 * @example
 * ```typescript
 * // Request changes on a pull request
 * const rejection = await reject({
 *   workspace: 'myworkspace',
 *   repo_slug: 'myrepo',
 *   pull_request_id: 123
 * });
 * ```
 */
async function reject(
	params: RejectPullRequestParams,
): Promise<PullRequestParticipant> {
	const methodLogger = Logger.forContext(
		'services/vendor.atlassian.pullrequests.service.ts',
		'reject',
	);
	methodLogger.debug(
		`Requesting changes on Bitbucket pull request: ${params.workspace}/${params.repo_slug}/${params.pull_request_id}`,
	);

	if (!params.workspace || !params.repo_slug || !params.pull_request_id) {
		throw new Error(
			'workspace, repo_slug, and pull_request_id parameters are all required',
		);
	}

	const credentials = getAtlassianCredentials();
	if (!credentials) {
		throw createAuthMissingError(
			'Atlassian credentials are required for this operation',
		);
	}

	const path = `${API_PATH}/repositories/${params.workspace}/${params.repo_slug}/pullrequests/${params.pull_request_id}/request-changes`;

	methodLogger.debug(`Sending POST request to: ${path}`);
	return fetchAtlassian<PullRequestParticipant>(credentials, path, {
		method: 'POST',
	});
}

export default {
	list,
	get,
	getComments,
	createComment,
	create,
	update,
	approve,
	reject,
	getRawDiff,
	getDiffstat,
	getDiffForUrl,
};

```

--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
# [1.45.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.44.2...v1.45.0) (2025-10-05)


### Features

* api call timeout CWE-400 ([#118](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/118)) ([d8659ee](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d8659ee8f7d6baca1a5a391a4ee08368af63af84))

## [1.44.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.44.1...v1.44.2) (2025-09-09)


### Bug Fixes

* use single baseUrl for API token authentication ([#117](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/117)) ([a0d5ad1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a0d5ad1aa6333ab824f882de20af2e1f69540a55)), closes [#61](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/61)

## [1.44.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.44.0...v1.44.1) (2025-09-09)


### Bug Fixes

* Prevent dotenv from outputting to STDIO in MCP mode ([#106](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/106)) ([52a8e13](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/52a8e132e35bc215445a15d846d5c79bf49a06fc))

# [1.44.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.4...v1.44.0) (2025-09-09)


### Features

* modernize dependencies and ensure Zod v3.25.76 MCP SDK compatibility ([#115](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/115)) ([86ceaeb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/86ceaebed56326d32be0736a77e3b4d528af8003))

## [1.43.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.3...v1.43.4) (2025-08-07)


### Bug Fixes

* update .env.example with complete authentication options ([52da9a1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/52da9a1b37f71cfe6af16fe2322b8d040285718b))

## [1.43.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.2...v1.43.3) (2025-08-07)


### Bug Fixes

* correct authentication credentials and config structure ([b53b5d5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b53b5d569c97efb9b91ee34063b669210a2e3be5))

## [1.43.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.1...v1.43.2) (2025-08-02)


### Bug Fixes

* prevent double formatting in Bitbucket markdown (heading + bold) ([67ec325](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/67ec3253f1c3576cf8427ff6426ae3178e12f96a))

## [1.43.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.43.0...v1.43.1) (2025-08-02)


### Bug Fixes

* resolve bb_get_file tool failure with dynamic default branch detection ([74ca7e0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/74ca7e0f3f042f2f24cdf156d4a94c2e3e026cf5))

# [1.43.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.42.1...v1.43.0) (2025-08-02)


### Bug Fixes

* correct logger variable name in repository list controller ([1706725](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1706725a374826068c1d75c80e215543fb3ac4a6))


### Features

* add query logging for repository searches ([c8d776d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c8d776dcabf8dab4cc63724df508b3837e993cc0))

## [1.42.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.42.0...v1.42.1) (2025-08-02)


### Bug Fixes

* standardize dependencies and fix TypeScript linting issues ([4e5ab79](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4e5ab79431f07da5bd06db0fa5835191ccb2ef08))

# [1.42.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.41.1...v1.42.0) (2025-07-15)


### Features

* add support for threaded comments in pull request comments ([#50](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/50)) ([6bcb98a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6bcb98ad95c7073604c6f5173e78c7339821e689)), closes [#49](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/49)

## [1.41.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.41.0...v1.41.1) (2025-06-22)


### Bug Fixes

* change default transport from HTTP to STDIO for proper MCP client integration ([51d9a1c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/51d9a1c91490b47ea3498a11fdd4a3fd35940792))

# [1.41.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.40.1...v1.41.0) (2025-06-22)


### Features

* implement complete PR CRUD operations (update, approve, reject) ([de5a2a0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/de5a2a045cab06f0ce2a2bbfdd9028bae81d2b73)), closes [#38](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/38) [#39](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/39) [#38](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/38) [#39](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/39)

## [1.40.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.40.0...v1.40.1) (2025-06-22)


### Bug Fixes

* update dependencies ([dac5279](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/dac5279c7e5eb2c80adc33ae594c25af942c551b))

# [1.40.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.7...v1.40.0) (2025-06-22)


### Features

* add dual transport support (HTTP + STDIO) for MCP server ([313de85](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/313de85ff2be8e37db498a197aa7d873ddb6912e))

## [1.39.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.6...v1.39.7) (2025-06-02)


### Bug Fixes

* replace Unix-specific chmod with cross-platform ensure-executable script ([0140fb5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0140fb59a3bdc15c009a65e9384c49f9e9c7710b)), closes [#31](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/31)

## [1.39.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.5...v1.39.6) (2025-06-02)


### Bug Fixes

* update dependencies ([4f94fbc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4f94fbc7a150131aa852728d764ec1458eae2db1))

## [1.39.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.4...v1.39.5) (2025-05-21)


### Bug Fixes

* Move business logic to controllers and fix method naming to follow architectural standards ([51b1a4c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/51b1a4c666469c983393216e68ecc8d60bee17c6))
* update dependencies ([5a3c409](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5a3c409b406b9a935c47574e446c5531ea157c82))

## [1.39.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.3...v1.39.4) (2025-05-21)


### Bug Fixes

* update dependencies ([b7b7dc3](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b7b7dc39c9dcf3799ecafada2bed44462a91076e))

## [1.39.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.2...v1.39.3) (2025-05-21)


### Bug Fixes

* align search tool implementation with CLI for consistent behavior ([5b81f58](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5b81f580bb7b04366b645a5db1a7d72043a9c809))
* ensure consistent workspace handling across all Bitbucket tool implementations ([1e78be5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1e78be5fdde5ddb13f395cdc655ae4f0ee639555))
* ensure consistent workspace handling and parameter validation across all Bitbucket tools ([70d5cba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/70d5cba00c5f4ad71be28b1fa83ff03f30bbc50d))
* rename search tool from 'atlassian_search' to 'bb_search' for consistent naming convention ([a3c467c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a3c467c696bfe55f3f6ae519352324ced7274960))

## [1.39.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.1...v1.39.2) (2025-05-20)


### Bug Fixes

* fix linter errors and unused exports in repository clone feature ([c916f53](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c916f539aa45c6ac903459258dc4f8cc30fba508))
* improve repository clone feature with SSH support and better path handling ([f5955f3](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f5955f3888ded00136dfc6b76e909e2d2261fbf8))

## [1.39.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.39.0...v1.39.1) (2025-05-20)


### Bug Fixes

* update dependencies ([ae112a6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ae112a60fdd38f1f35e98fd61992a205efc0517c))

# [1.39.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.4...v1.39.0) (2025-05-19)


### Features

* removed backward compatibility flag from diff cli and deprecated sort parameter from workspaces types ([108ef54](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/108ef549c85e7f894191a1e95ccc39319dd3c32f))

## [1.38.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.3...v1.38.4) (2025-05-19)


### Bug Fixes

* remove unused code for better maintainability ([711f86d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/711f86d81a8f7e26b856560ffba576cedc671a25))

## [1.38.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.2...v1.38.3) (2025-05-19)


### Bug Fixes

* refactor repositories controller into separate controllers for better maintainability ([3461d8a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3461d8a32c18ba05be483ae7f24758f51e2b8f55))
* refactor search controller into separate controllers by search type ([38a7d35](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/38a7d35bf4dae83846dbaf316555cfb81cc394ab))

## [1.38.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.1...v1.38.2) (2025-05-19)


### Bug Fixes

* remove unused code and exports to improve maintainability ([e419c07](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e419c07f43128d334094fba50ff90b2a76bc0229))

## [1.38.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.38.0...v1.38.1) (2025-05-19)


### Bug Fixes

* correct code block formatting with tabs for nested code blocks ([2c19c16](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2c19c161247723fb04611701420d30f93d1e2cac))

# [1.38.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.37.0...v1.38.0) (2025-05-19)


### Features

* update dependencies ([76fd24f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/76fd24f53d69ccf987bcd3971af51204736f6d16))

# [1.37.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.5...v1.37.0) (2025-05-18)


### Features

* Refine ControllerResponse implementation ([dbe160f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/dbe160f085ec89c6856b822f16be22271c0fce7f))

## [1.36.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.4...v1.36.5) (2025-05-17)


### Bug Fixes

* remove empty metadata objects from Bitbucket tool responses ([ab65f71](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ab65f71c4eb62ea6a21323bf821650a1e9252c7a))

## [1.36.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.3...v1.36.4) (2025-05-17)


### Bug Fixes

* improve documentation and error guidance for counterintuitive branch and commit diff parameter ordering ([ec374e6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ec374e6443f383d8552ace999b852d4ecc8458e0))

## [1.36.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.2...v1.36.3) (2025-05-17)


### Bug Fixes

* improve diff_commits tool to better handle cases with empty diffstat but existing changes ([736304b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/736304b74b6a0f39644af55a972dde4ec9d9e041))

## [1.36.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.1...v1.36.2) (2025-05-17)


### Bug Fixes

* improve error handling for invalid PR IDs in Bitbucket pull request tool ([14afe1a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/14afe1a499f117ad8fd50b75b326e4d8082618fa))

## [1.36.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.36.0...v1.36.1) (2025-05-17)


### Bug Fixes

* ensure projectKey is passed from tool to controller for bb_ls_repos ([a0c26db](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a0c26db744edd1f383014c61aa9c25643035b8a3))

# [1.36.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.35.1...v1.36.0) (2025-05-17)


### Bug Fixes

* Improve tests, refactor, and document includeComments feature ([5d9fbfd](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5d9fbfd7598218af02abdf439d5b304e325753bd))
* Improve transport utility tests to use real environments ([20b8cf2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/20b8cf23ef09d42f8556a0f8840ad02f082cc215))


### Features

* Add includeComments option to get-pr command ([ba72020](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ba72020ea49bc0e58b0f559ead7df4d54563a8fa))
* Enhance get-pr to include comments with flag ([a0dbb89](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a0dbb89517e1bd7011b80fb8fcf90352214f784e))
* Enhance get-repo to include recent PRs by default ([0052629](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/005262911c975f5dd91c1a871659b86c16a454da))
* Standardize CLI parameter formats across commands ([c267a14](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c267a147c2d59db5ca7487c87d91fd8a123f39d8))

## [1.35.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.35.0...v1.35.1) (2025-05-17)


### Bug Fixes

* Update Bitbucket README for default workspace and diffs ([fe36a20](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fe36a20c834ecf584673c921b293cac050571046))

# [1.35.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.34.0...v1.35.0) (2025-05-17)


### Features

* make workspaceSlug optional in remaining tools and controllers ([6d2f4d6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6d2f4d6860e76cbcd7ff8cde0fd1e70b8377c464))

# [1.34.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.33.0...v1.34.0) (2025-05-17)


### Features

* make workspaceSlug parameter optional with default workspace support ([16e41f5](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/16e41f5c0a37b41078aeb940612f79399c8c4296))

# [1.33.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.5...v1.33.0) (2025-05-17)


### Features

* implement core principles of minimal input and rich output by default ([0dc2c0d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0dc2c0d2dad7a53f6a6202a67fed0372b80d9968))

## [1.32.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.4...v1.32.5) (2025-05-16)


### Bug Fixes

* implement getFileContent in atlassian.repositories.controller.ts ([5ebc2fb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5ebc2fbb54e1516de2ee9848dbfcddb643cd2512))

## [1.32.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.3...v1.32.4) (2025-05-16)


### Bug Fixes

* improve documentation and error handling for searching and diffing operations ([2670423](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/267042342b3102d82737aeee588db684e4cf00c5))

## [1.32.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.2...v1.32.3) (2025-05-16)


### Bug Fixes

* Make repoSlug conditionally required for pullrequests and commits scopes in search tool ([a1adc3a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a1adc3af40fec80f4c85dccf3b60c02770d0f306))

## [1.32.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.1...v1.32.2) (2025-05-16)


### Bug Fixes

* improve filtering in Bitbucket commands for projectKey, language, and scope parameters ([3cb34da](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3cb34dae514ee2f76449c3f099a86dd3bd0e47af))

## [1.32.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.32.0...v1.32.1) (2025-05-16)


### Bug Fixes

* resolve type errors in repository controller stub functions ([4ec45e7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4ec45e7e05deadc67b9c5e9f17da276f9302aba6))

# [1.32.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.31.0...v1.32.0) (2025-05-15)


### Features

* improve search, pagination, and filtering features ([167af40](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/167af40154b69868fdab26a7582d140ee658b0cb))

# [1.31.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.3...v1.31.0) (2025-05-15)


### Bug Fixes

* resolve duplicate exports in error-handler utilities ([fec7ecb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fec7ecb08512467e02a4cc52ef3856adff0c88e6))


### Features

* enhance Bitbucket-specific error handling ([165e566](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/165e566c25c0056bdb498fadf6d543372e41a1d8))
* enhanced error handling for Bitbucket API responses ([a9cf6c0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a9cf6c0184e0d50cbf179a77c3e83342b0376de0))
* enhanced error handling for Bitbucket API responses ([08cbf83](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/08cbf83d81b633201cc2873e4461302377ab9be1))
* enhanced error handling for Bitbucket API responses ([91e3354](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/91e3354746e106d3ed3d4ccca16631db00ef2ab4))

## [1.30.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.2...v1.30.3) (2025-05-15)


### Bug Fixes

* set default topic=false for diff operations and remove topic parameter from CLI/tools ([2300228](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/23002286221b70fede8c5d7986d8236c752b7766))

## [1.30.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.1...v1.30.2) (2025-05-15)


### Bug Fixes

* apply proper formatting to query handling in listBranches ([169f75b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/169f75b32bf05feb3551c569d12fdfa7e27f553f))

## [1.30.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.30.0...v1.30.1) (2025-05-14)


### Bug Fixes

* remove Dockerfile and smithery.yaml ([42ffad6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/42ffad6cbb0baf7d0644a580957d7c86d39da561))

# [1.30.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.29.1...v1.30.0) (2025-05-14)


### Features

* enhance error handling with vendor propagation and enriched CLI/Tool formatting ([db16d11](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/db16d1113d6148e5d207cdbc804e6fec4012d5ea))

## [1.29.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.29.0...v1.29.1) (2025-05-13)


### Bug Fixes

* route enhanced clone error via createApiError to keep details ([4c03cdb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4c03cdbe6e16bd85a78d106b957a33f51057bc80))

# [1.29.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.28.1...v1.29.0) (2025-05-13)


### Features

* enhance clone error handling with user guidance ([3921c1f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3921c1f8c1990aa6b70675622f9b747ea551ff96))

## [1.28.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.28.0...v1.28.1) (2025-05-13)


### Bug Fixes

* prefer ssh clone to use default ssh keys ([ef5a13f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ef5a13f150bc3a2a4a03c0aea2c2a6a5dc910819))

# [1.28.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.27.1...v1.28.0) (2025-05-13)


### Bug Fixes

* use HTTPS clone with embedded credentials to avoid SSH access denied in server mode ([3fa0bad](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3fa0bad1d8faeafe0659b76340a0b15682a74083))


### Features

* add list branches feature for Bitbucket repositories (CLI, MCP tool, controller, service, formatter) ([e68e8da](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e68e8da865d0f128b4930ee2c7b40cf799d3fd28))

## [1.27.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.27.0...v1.27.1) (2025-05-13)


### Bug Fixes

* update dependencies ([2c74c7a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2c74c7aae0e422380d19efb5fdccef823f3590af))

# [1.27.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.7...v1.27.0) (2025-05-13)


### Features

* add diff tools for branch and commit comparison ([e201f9e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e201f9e6cbe940fc8354eff2224dfe78bc7fa637))

## [1.26.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.6...v1.26.7) (2025-05-09)


### Bug Fixes

* increase test timeouts for API-dependent tests to improve reliability ([08a4d75](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/08a4d754c819207b96ff91f813599561c313c3e6))

## [1.26.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.5...v1.26.6) (2025-05-08)


### Bug Fixes

* Remove unused ADF conversion functions from Bitbucket implementation ([1abe807](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1abe807ec17ad21a06dde3e88ee90d9597f14519))

## [1.26.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.4...v1.26.5) (2025-05-08)


### Bug Fixes

* Fix bullet list rendering in Bitbucket markdown handling ([c3a4b71](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c3a4b71d2d6e7c2e077ef3941c6b5bea0f5efb15))
* improve markdown rendering in Bitbucket PR descriptions and comments ([4e73784](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4e7378425fd71e629b3fc3c6cc67a6d4f69672ce))

## [1.26.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.3...v1.26.4) (2025-05-07)


### Performance Improvements

* Update dependencies ([37f8849](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/37f884938d94bae4d832c780393f04f061831b56))

## [1.26.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.2...v1.26.3) (2025-05-07)


### Bug Fixes

* Improve directory validation and error handling for repository cloning ([d6c5c7f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d6c5c7f7f7f25be9149084b0ad7e96b0d6ca7ce2))


### Performance Improvements

* Update dependencies ([858dc27](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/858dc274af5a5bda7af4baa5c5c2628ad7aa3b1c))

## [1.26.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.1...v1.26.2) (2025-05-07)


### Bug Fixes

* Simplify bb_clone_repo documentation for clarity ([97871ba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/97871ba8b36d6aef6bb90cf5fbd646ce3e394425))

## [1.26.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.26.0...v1.26.1) (2025-05-07)


### Bug Fixes

* Add documentation for get-file functionality in README ([542933e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/542933e9eb14e2bf97e39ad11ad3b70bbd3eb99a))

# [1.26.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.25.1...v1.26.0) (2025-05-07)


### Features

* Add file content retrieval via CLI and Tool ([a8a306e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a8a306e154ff2aea30a5161faa7575c499bd82c0))

## [1.25.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.25.0...v1.25.1) (2025-05-06)


### Bug Fixes

* Clarify clone tool targetPath and update README ([92e4e53](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/92e4e53322a8e92324b8e7776503e767bcbcf4d1))

# [1.25.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.24.0...v1.25.0) (2025-05-06)


### Features

* Add repository clone functionality via CLI and Tool ([648392f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/648392f1fdd2e0faa3ce94882a550dca363e861c))

# [1.24.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.10...v1.24.0) (2025-05-06)


### Features

* sync ADF utility enhancements from Jira project ([9f0c4be](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9f0c4bed91262790e71c38201722f6bf76b9ff91))

## [1.23.10](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.9...v1.23.10) (2025-05-06)


### Performance Improvements

* Update dependencies ([e22ef5b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e22ef5b4af772f4c627c24021ba92d706483a8d3))

## [1.23.9](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.8...v1.23.9) (2025-05-06)


### Bug Fixes

* Standardize terminology from create to add across operations ([37b7735](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/37b7735727483756a3d530ad6a651a8f623feaa7))
* Update controller method names to match add pattern and fix test cases ([a10317c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a10317c2b1713a7aea91cfb2d73c100f7c7055e6))
* Update controller method references in tools file ([2682de8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2682de83a2caa4aa18f94b884d8d473454d9844d))

## [1.23.8](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.7...v1.23.8) (2025-05-06)


### Performance Improvements

* Update dependencies ([41ffc7b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/41ffc7b92f2cf135d2f67a80a5cf65de565633fa))

## [1.23.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.6...v1.23.7) (2025-05-06)


### Bug Fixes

* Revert back the index.ts and package.json ([57eeb01](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/57eeb01321e7995bae7a4ffa3363feda1f8008ae))

## [1.23.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.5...v1.23.6) (2025-05-06)


### Bug Fixes

* improve main module detection for npx compatibility ([efe5d4c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/efe5d4c0ed7c15c9729a4ad7d3c91afcb8925c31))

## [1.23.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.4...v1.23.5) (2025-05-06)


### Bug Fixes

* improve main module detection for npx compatibility ([90f0f26](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/90f0f2685bc8fe95e162e2e1fdae7ac7afbb5d76))

## [1.23.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.3...v1.23.4) (2025-05-05)


### Bug Fixes

* revert to working server version that stays running ([a80eef9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a80eef963c9a4de38110112261a772e1fb33385b))

## [1.23.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.2...v1.23.3) (2025-05-05)


### Bug Fixes

* improve signal handling for npx support ([a4a361c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a4a361ca3fd2983446880eacabb5fa979f1336d1))

## [1.23.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.1...v1.23.2) (2025-05-05)


### Bug Fixes

* Remove explicit exit after CLI execution in index.ts ([9b0bed0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9b0bed07040cb54516fff6e9f0c8cc667ccd5786))

## [1.23.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.23.0...v1.23.1) (2025-05-05)


### Bug Fixes

* Apply cross-platform compatibility improvements from boilerplate ([3426b97](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3426b97d62cfef5076436600be3126c7a0cf4382))

# [1.23.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.22.0...v1.23.0) (2025-05-05)


### Features

* Add --project-key filter to ls-repos command ([f07c044](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f07c0441a4757da5cdd659602ef3e72d6fc38776))
* Add create-branch command ([4cc5bdb](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4cc5bdb921e9d1e12c7b7689e3719d4f1c429821))
* Display comment and task counts in get-pr output ([a1513ef](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a1513efefd0992510a0e8e08e75db487ce87bf60))
* Display main branch name in get-repo output ([12cc91e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/12cc91ea89a241002ddfef4523633ddb90f79c2e))
* Improve search command usability ([c5d1550](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c5d155053a4ea6889f86e6861925b25c7b979727))

# [1.22.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.7...v1.22.0) (2025-05-05)


### Features

* Display code snippets for inline PR comments ([5a8024b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5a8024b3cd259fa6ff9804a717149d3933244cc2))

## [1.21.7](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.6...v1.21.7) (2025-05-05)


### Bug Fixes

* Indicate deleted PR comments in output ([f6069c7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f6069c79c38b8eb1e69b4c6531d5c3eb78c1bdfb))

## [1.21.6](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.5...v1.21.6) (2025-05-05)


### Bug Fixes

* Include PR ID in ls-pr-comments title ([f73c9da](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f73c9dacc50ee2a9450b4ca1bb73a79f29ca3f5c))


### Performance Improvements

* Update dependencies ([7166012](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7166012b406d435eea7dec7a0d80d7ed5a17727b))

## [1.21.5](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.4...v1.21.5) (2025-05-05)


### Bug Fixes

* Remove commented-out code and unused exports ([d81ad82](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d81ad8239c4f0975aa995dad775038a9fb1ae87d))

## [1.21.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.3...v1.21.4) (2025-05-05)


### Bug Fixes

* apply role filter in list repositories API call ([6ca7e4b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6ca7e4b29015aa689fd86d681ff28b0eabf52a09))

## [1.21.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.2...v1.21.3) (2025-05-04)


### Performance Improvements

* Update dependencies ([32bd5ae](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/32bd5aedf2368d4a1a42ee8709621042586416f8))

## [1.21.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.1...v1.21.2) (2025-05-04)


### Bug Fixes

* **search:** Correct query formatting for ls-prs and search scopes ([31d6def](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/31d6def83c27bc1da3d98cbbf94ff16f41161d69))

## [1.21.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.21.0...v1.21.1) (2025-05-04)


### Bug Fixes

* refine tool definitions and parameter naming ([1efb27e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1efb27e51c5b13ed4e548098a8600674f2034fd7))

# [1.21.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.4...v1.21.0) (2025-05-04)


### Features

* **format:** standardize CLI and Tool output formatting ([2ad3f05](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2ad3f05e08848271975695bfab7c9bd97a0d2ff0))

## [1.20.4](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.3...v1.20.4) (2025-05-04)


### Bug Fixes

* update pagination handling in search formatter ([ec8f6ce](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ec8f6ce21660c4e338bc16278fee393c131bc7eb))

## [1.20.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.2...v1.20.3) (2025-05-04)


### Bug Fixes

* **bitbucket:** implement Zod validation and align types ([7611404](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/761140440996878f0170c2e453def84d73f9af94))

## [1.20.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.1...v1.20.2) (2025-05-04)


### Bug Fixes

* Clean up unused exports and types in Bitbucket server ([3d469fc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3d469fcc2752f8a7eb817d60b04e164901665e3b))
* Remove re-exports from index.ts ([5ab1bf6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5ab1bf60d5f8c7e9b572edb093d7e071972fd222))

## [1.20.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.20.0...v1.20.1) (2025-05-02)


### Bug Fixes

* trigger release ([ae058d8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ae058d8eeb50f811c3c9afe7d0bfa38b16b696b1))

# [1.20.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.3...v1.20.0) (2025-05-02)


### Features

* Standardize pagination output in tool content text ([f072ae7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f072ae74a3ca9bfaecf6eb32ddc01cd35d25718a))

## [1.19.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.2...v1.19.3) (2025-05-02)


### Bug Fixes

* **bitbucket:** correct repository list formatting and remove redundant title in search ([ac6ce2a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ac6ce2a641751669ab1e345917059febb2b6bbf5))

## [1.19.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.1...v1.19.2) (2025-05-02)


### Bug Fixes

* **bitbucket:** correct repository list formatting and remove redundant title in search ([e32071f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e32071f223e83305de6c1056a97f26e9b352ca3a))

## [1.19.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.19.0...v1.19.1) (2025-05-02)


### Bug Fixes

* **bitbucket:** improve formatting for bb_search code results ([5469e37](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5469e3734aa02a532668c36468287ecc8a3760b8))

# [1.19.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.18.0...v1.19.0) (2025-05-02)


### Features

* **bitbucket:** add --full-diff option to bb_get_pr tool ([3039fae](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3039faec68ca605898872e87bedec05cc5b1e920))


### Performance Improvements

* Update dependencies ([77dcad9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/77dcad9050c7cd4001af2029bc58d781c1b4d3fe))

# [1.18.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.3...v1.18.0) (2025-05-01)


### Bug Fixes

* correct option flag format for get-commit-history command ([c97ad6f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c97ad6f25675d19eea953db08c49daad3a84ada6))
* remove unused configuration objects to reduce dead code ([f51dc65](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f51dc6502282c38fd54a8ec6f885f34165c1aa97))
* remove unused formatRelativeTime function for cleaner codebase ([6663157](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/666315765dce68e2ff4cb41c5a9e61580e8504ba))


### Features

* add commit history tool and cli command ([811c155](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/811c1559c1b7a7fbb32fa45a37cbebebc3b225f6))


### Performance Improvements

* streamline Bitbucket tool descriptions for better AI consumption ([1136c3f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1136c3f5f91dda81c34fde0c63e261c670b938cc))

## [1.17.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.2...v1.17.3) (2025-05-01)


### Bug Fixes

* standardize on 'create' verb for PR comments ([d3443ea](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d3443eac077fb2a93c77fc41df478a37c04d8709))
* Standardize on 'create' verb for PR comments ([cdcfb66](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/cdcfb663db8fb86d4c1f463114f697b77ffb7519))

## [1.17.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.1...v1.17.2) (2025-04-30)


### Bug Fixes

* **cli:** Align command names and descriptions with tool definitions ([d474994](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d474994c1f4b0358a53ac9557be4bd7a306247a8))

## [1.17.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.17.0...v1.17.1) (2025-04-30)


### Performance Improvements

* Update dependencies ([062b651](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/062b651830b0850cf627323fdf9b9606fc4673c2))

# [1.17.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.16.0...v1.17.0) (2025-04-30)


### Bug Fixes

* Standardize and shorten MCP tool names ([3c66a60](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3c66a6000be1033c657a52de37ca4c369664b23a))


### Features

* Support multiple keys for global config lookup ([7df9c41](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7df9c414e4719d547113eec58cf38f4b67bf268e))

# [1.16.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.3...v1.16.0) (2025-04-25)


### Bug Fixes

* unify tool names and descriptions for consistency ([075d996](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/075d9966cddad3101b5a1ea2331cffd44563d644))


### Features

* prefix Bitbucket tool names with 'bitbucket_' for uniqueness ([69d59a8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/69d59a80f9a3ef08c649136cd771fbfd8181337b))

## [1.15.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.2...v1.15.3) (2025-04-22)


### Performance Improvements

* Update dependencies ([fae420e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fae420ee00d9dd5c71dfce18610e33e8d8857403))

## [1.15.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.1...v1.15.2) (2025-04-20)


### Bug Fixes

* Update dependencies and fix related type errors ([4acea85](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4acea85c681dce9af6f23f751384c4aae08480b7))

## [1.15.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.15.0...v1.15.1) (2025-04-09)


### Bug Fixes

* **deps:** update dependencies to latest versions ([68c2f39](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/68c2f390499b7694da6771963f856cefa0b812d6))

# [1.15.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.14.2...v1.15.0) (2025-04-04)


### Bug Fixes

* improve README clarity and accuracy ([c09711f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c09711fc86dd29f6018907660b891e322bf089b2))


### Features

* **pullrequests:** add code diff and diffstat display to pull request details ([ed2fd3a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ed2fd3a2483117989701bc37b14f8aeed1233e2b))

## [1.14.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.14.1...v1.14.2) (2025-04-04)


### Bug Fixes

* add remaining search functionality improvements ([163d38f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/163d38fb5d18f3b2b7dc47cee778c48be61a23c4))
* improve search results consistency across all search types ([d5f8313](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d5f8313df4f04287d5c97824a3db98202e428f7d))
* standardize tool registration function names to registerTools ([4f4b7c6](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/4f4b7c6dce51b750048465526f0033239af54921))

## [1.14.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.14.0...v1.14.1) (2025-04-03)


### Performance Improvements

* trigger new release ([9c3cd52](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9c3cd52bf4ba820df9bb0a9f5a3b7ea6d6f90c99))

# [1.14.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.3...v1.14.0) (2025-04-03)


### Features

* **logging:** add file logging with session ID to ~/.mcp/data/ ([8e2eae1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/8e2eae16cdf78579bf7925704fb958a0a97411b7))

## [1.13.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.2...v1.13.3) (2025-04-03)


### Bug Fixes

* **logger:** ensure consistent logger implementation across all projects ([30f96e9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/30f96e96eb7576cfdac904534210915c40286aa3))

## [1.13.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.1...v1.13.2) (2025-04-03)


### Performance Improvements

* **bitbucket:** improve version handling and module exports ([76f9820](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/76f982098774f8dd22d4694c683fdd485c38112d))

## [1.13.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.13.0...v1.13.1) (2025-04-03)


### Bug Fixes

* update PR tool argument types for Windsurf wave 6 compatibility ([51b3824](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/51b38242cb553f77b73d025280db9cceaa2365d5)), closes [#7](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/7)

# [1.13.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.12.0...v1.13.0) (2025-04-01)


### Bug Fixes

* **cli:** rename create-pr to create-pull-request and update parameter names for consistency ([6e4dbb2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6e4dbb2112368544cdbf567561ef800575e91536))


### Features

* **pullrequests:** add create pull request feature to CLI and MCP tools ([73400af](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/73400af266fd787b8b216bcb3ec5058b1fa99ff9)), closes [#3](https://github.com/aashari/mcp-server-atlassian-bitbucket/issues/3)

# [1.12.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.11.1...v1.12.0) (2025-04-01)


### Bug Fixes

* **build:** remove unused skipIfNoCredentials function ([9173010](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/91730106c1a21f33879130ffb20b24d9d3731e78))
* **pr:** fix double JSON.stringify in PR comment API call ([a445dc7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a445dc7db71bcc6fd73f2b3bf6312686b9424ce1))


### Features

* **pr:** add CLI command and tests for PR comments ([d6d3dc2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d6d3dc20e3722b22f694e50e7b80542ba951ea54))

## [1.11.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.11.0...v1.11.1) (2025-03-29)


### Bug Fixes

* conflict ([e947249](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e9472496062a64bd9766c3ba8b61944076d16883))

# [1.11.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.10.1...v1.11.0) (2025-03-28)


### Bug Fixes

* **cli:** standardize CLI parameter naming conventions ([fe16246](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fe16246a550674470ce8b03441809e07c0c7016b))
* resolve TypeScript errors and lint warnings in Bitbucket MCP server ([29446b9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/29446b95151e3462f2bef3cd1f772e9726c97a29))
* standardize status parameter and workspace identifiers ([c11b2bf](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c11b2bf5b6cf7f4e3b0eae189c17f300d64c5534))
* **test:** improve Bitbucket workspaces integration tests with better error handling and reliability ([284447f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/284447f0897c9e53c271777d2f81178a65e32ca9))
* **tests:** improve test resiliency for CLI commands ([7f690ba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7f690ba4f3c42fb2f8bce6cf279ccfb5dc419a74))


### Features

* standardize CLI flag patterns and entity parameter naming ([7b4d719](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7b4d71948d3bf6a4b2cf8659e42b02e57b92f451))
* **test:** add comprehensive test coverage for Bitbucket MCP server ([b69fa8f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b69fa8f171efbe713f42e9cfde013a83898419dd))

## [1.10.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.10.0...v1.10.1) (2025-03-28)


### Performance Improvements

* rename tools to use underscore instead of hyphen ([bc1f65e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bc1f65e7d76d3c13f4fd96cde115c441c7d6212f))

# [1.10.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.1...v1.10.0) (2025-03-27)


### Bug Fixes

* remove sort option from Bitbucket workspaces endpoints, API does not support sorting ([e6ccd9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e6ccd9b7e78d6316dbbfa7def756b6897550ff29))
* standardize patterns across MCP server projects ([78ca874](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/78ca8748ba2b639e52e13bfc361c91d9573e1340))
* trigger new release ([63b2025](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/63b2025127c509e7db2d82945717b49ea223d77d))
* update applyDefaults utility to work with TypeScript interfaces ([2f682ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2f682cacef284ebeb9d2f40577209bf6b45ad1d9))
* update version to 1.10.0 to fix CI/CD workflows ([938f481](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/938f48109fc1a93c7375495d08598dca044a2235))


### Features

* update to version 1.11.0 with new repository command documentation ([0a714df](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0a714df36671f1a9bd94c90cab9d462cb90105ec))

## [1.9.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.1...v1.9.2) (2025-03-27)


### Bug Fixes

* remove sort option from Bitbucket workspaces endpoints, API does not support sorting ([e6ccd9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e6ccd9b7e78d6316dbbfa7def756b6897550ff29))
* standardize patterns across MCP server projects ([78ca874](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/78ca8748ba2b639e52e13bfc361c91d9573e1340))
* trigger new release ([63b2025](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/63b2025127c509e7db2d82945717b49ea223d77d))
* update applyDefaults utility to work with TypeScript interfaces ([2f682ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2f682cacef284ebeb9d2f40577209bf6b45ad1d9))
* update version to 1.10.0 to fix CI/CD workflows ([938f481](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/938f48109fc1a93c7375495d08598dca044a2235))

## [1.9.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.1...v1.9.2) (2025-03-27)


### Bug Fixes

* remove sort option from Bitbucket workspaces endpoints, API does not support sorting ([e6ccd9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e6ccd9b7e78d6316dbbfa7def756b6897550ff29))
* standardize patterns across MCP server projects ([78ca874](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/78ca8748ba2b639e52e13bfc361c91d9573e1340))
* trigger new release ([63b2025](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/63b2025127c509e7db2d82945717b49ea223d77d))
* update applyDefaults utility to work with TypeScript interfaces ([2f682ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2f682cacef284ebeb9d2f40577209bf6b45ad1d9))

## [1.9.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.9.0...v1.9.1) (2025-03-27)


### Bug Fixes

* **error:** standardize error handling across all MCP servers ([76834af](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/76834aff1d716e3e2caf210f667df65dfd21d466))

# [1.9.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.8.1...v1.9.0) (2025-03-27)


### Features

* **logger:** implement contextual logging pattern ([d6f16b7](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d6f16b76513990dce1e6d68c32767331d075c78b))

## [1.8.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.8.0...v1.8.1) (2025-03-27)


### Bug Fixes

* trigger release ([43a4d06](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/43a4d069c3702f748a751f6f8a5d8b8ff425f5ab))

# [1.8.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.3...v1.8.0) (2025-03-26)


### Features

* **bitbucket:** add default -updated_on sort to list operations ([ee5dbca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ee5dbcae32484b61e67f5852e21d5e63ed2ea4a4))
* **bitbucket:** add pull request comments and enhance repository details ([72a91c8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/72a91c89c7ce54aedbdf457ba818af83414c43a6))

## [1.7.3](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.2...v1.7.3) (2025-03-26)


### Bug Fixes

* empty commit to trigger patch version bump ([260911a](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/260911a1a2927aaadbe38e77fe04281a45d75334))

## [1.7.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.1...v1.7.2) (2025-03-26)


### Bug Fixes

* improve CLI and tool descriptions with consistent formatting and detailed guidance ([ce74835](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ce748354d84f7649d71a230b8e66e80c41547f34))

## [1.7.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.7.0...v1.7.1) (2025-03-26)


### Bug Fixes

* standardize parameter naming conventions in Bitbucket module ([458a6e2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/458a6e2ce714420794a83b334476c135353639fb))

# [1.7.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.6.0...v1.7.0) (2025-03-26)


### Features

* trigger release with semantic versioning ([f4895b8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f4895b82f93d842bf777c59e2707aeedb64fd30c))

# [1.6.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.5.0...v1.6.0) (2025-03-26)


### Features

* standardize CLI flags for consistent naming patterns ([b2ee0ba](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/b2ee0ba05dbd386ee3adb42c3fe82287d2b735ab))

# [1.5.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.4.2...v1.5.0) (2025-03-26)


### Features

* improve CLI interface by using named parameters instead of positional arguments ([99318be](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/99318bee1cc2f4706b63072800431e43b0c051a4))

## [1.4.2](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.4.1...v1.4.2) (2025-03-26)


### Bug Fixes

* standardize CLI pagination and query parameter names ([e116b25](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/e116b2582eda41f2241bf71454f82fcd2a6bdad0))

## [1.4.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.4.0...v1.4.1) (2025-03-25)


### Bug Fixes

* replace any with unknown in defaults.util.ts ([5dbc0b1](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5dbc0b1050df479ac844907ef1ed26fc26734561))

# [1.4.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.3.0...v1.4.0) (2025-03-25)


### Features

* **pagination:** standardize pagination display across all CLI commands ([34f4c91](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/34f4c91f8aeb5c00d56d6975b8fa4c3ee81f4a9a))

# [1.3.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.2.0...v1.3.0) (2025-03-25)


### Features

* **format:** implement standardized formatters and update CLI documentation ([9770402](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/9770402096de6b6dffda263b976f7dbf4f4a9ee4))

# [1.2.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.1.1...v1.2.0) (2025-03-25)


### Bug Fixes

* standardize logging patterns and fix linter and type errors ([368df0f](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/368df0f602e29eea982628ddbc6f4f0702a6fab7))


### Features

* **workspaces:** improve workspace and repository management ([f27daf2](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/f27daf2238362c897ca2990a252d268e9d005484))

## [1.1.1](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.1.0...v1.1.1) (2025-03-25)


### Bug Fixes

* trigger new release for parameter and pagination standardization ([5607ce9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5607ce91179b33ee9f3457e5150608300072a5f9))
* update CLI and tool handlers to use object-based identifiers ([2899adc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2899adc38e2b804bc85098aef1f0a26caa90f5aa))

# [1.1.0](https://github.com/aashari/mcp-server-atlassian-bitbucket/compare/v1.0.0...v1.1.0) (2025-03-25)


### Bug Fixes

* conflict ([91d2720](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/91d27204fdb7029d5fdd49282dbdfbdfe6da9090))
* conflict ([bccabbf](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bccabbf44991eda2c91de592d2662f614adf4fb2))
* improve documentation with additional section ([6849f9b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6849f9b2339c049e0017ef40aedadd184350cee0))
* remove dist directory from git tracking ([7343e65](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7343e65746001cb3465f9d0b0db30297ee43fb09))
* remove dist files from release commit assets ([74e53ce](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/74e53cee60c6a7785561354c81cbdf611323df5a))
* version consistency and release workflow improvements ([1a2baae](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1a2baae4326163c8caf4fa4cfeb9f4b8028d2b5a))


### Features

* enhance get-space command to support both numeric IDs and space keys ([2913153](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/29131536f302abf1923c0c6521d544c51ad222fa))

# 1.0.0 (2025-03-24)

### Bug Fixes

- add workflows permission to semantic-release workflow ([de3a335](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/de3a33510bd447af353444db1fcb58e1b1aa02e4))
- correct package name and version consistency ([374a660](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/374a660e88a62b9c7b7c59718beec09806c47c0e))
- ensure executable permissions for bin script ([395f1dc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/395f1dcb5f3b5efee99048d1b91e3b083e9e544f))
- handle empty strings properly in greet function ([546d3a8](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/546d3a84209e1065af46b2213053f589340158df))
- improve documentation with additional section ([ccbd814](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ccbd8146ef55bed1edb6ed005f923ac25bfa8dae))
- improve error logging with IP address details ([121f516](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/121f51655517ddbea7d25968372bd6476f1b3e0f))
- improve GitHub Packages publishing with a more robust approach ([fd2aec9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/fd2aec9926cf99d301cbb2b5f5ca961a6b6fec7e))
- improve GitHub Packages publishing with better error handling and debugging ([db25f04](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/db25f04925e884349fcf3ab85316550fde231d1f))
- improve GITHUB_OUTPUT syntax in semantic-release workflow ([6f154bc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6f154bc43f42475857e9256b0a671c3263dc9708))
- improve version detection for global installations ([97a95dc](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/97a95dca61d8cd7a86c81bde4cb38c509b810dc0))
- make publish workflow more resilient against version conflicts ([ffd3705](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ffd3705bc064ee9135402052a0dc7fe32645714b))
- remove dist directory from git tracking ([0ed5d4b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0ed5d4bad05e09cbae3350eb934c98ef1d28ed12))
- remove dist files from release commit assets ([86e486b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/86e486bb68cb18d077852e73eabf8f912d9d007e))
- remove incorrect limit expectation in transport utility tests ([6f7b689](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/6f7b689a7eb5db8a8592db88e7fa27ac04d641c8))
- remove invalid workflows permission ([c012e46](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/c012e46a29070c8394f7ab596fe7ba68c037d3a3))
- remove type module to fix CommonJS compatibility ([8b1f00c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/8b1f00c37467bc676ad8ec9ab672ba393ed084a9))
- resolve linter errors in version detection code ([5f1f33e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/5f1f33e88ae843b7a0d708899713be36fcd2ec2e))
- update examples to use correct API (greet instead of sayHello) ([7c062ca](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/7c062ca42765c659f018f990f4b1ec563d1172d3))
- update package name in config loader ([3b8157b](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/3b8157b076441e4dde562cddfe31671f3696434d))
- update package.json version and scripts, fix transport.util.test.ts, update README ([deefccd](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/deefccdc93311be572abf45feb9a5aae69ed57eb))
- update release workflow to ensure correct versioning in compiled files ([a365394](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a365394b8596defa33ff5a44583d52e2c43f0aa3))
- update version display in CLI ([2b7846c](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/2b7846cbfa023f4b1a8c81ec511370fa8f5aaf33))

### Features

- add automated dependency management ([efa1b62](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/efa1b6292e0e9b6efd0d43b40cf7099d50769487))
- add CLI usage examples for both JavaScript and TypeScript ([d5743b0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/d5743b07a6f2afe1c6cb0b03265228cba771e657))
- add support for custom name in greet command ([be48a05](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/be48a053834a1d910877864608a5e9942d913367))
- add version update script and fix version display ([ec831d3](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/ec831d3a3c966d858c15972365007f9dfd6115b8))
- implement Atlassian Bitbucket MCP server with pull request, repository, and workspace features ([a9ff1c9](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a9ff1c9ddecaa323ffdbd6620bd5bc02b517079b))
- implement Atlassian Confluence MCP server ([50ee69e](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/50ee69e37f4d453cb8f0447e10fa5708a787aa93))
- implement review recommendations ([a23cbc0](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/a23cbc0608a07e202396b3cd496c1f2078e304c1))
- implement testing, linting, and semantic versioning ([1d7710d](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/1d7710dfa11fd1cb04ba3c604e9a2eb785652394))
- improve CI workflows with standardized Node.js version, caching, and dual publishing ([0dc9470](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/0dc94705c81067d7ff63ab978ef9e6a6e3f75784))
- improve development workflow and update documentation ([4458957](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/445895777be6287a624cb19b8cd8a12590a28c7b))
- improve package structure and add better examples ([bd66891](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bd668915bde84445161cdbd55ff9da0b0af51944))
- initial implementation of Jira MCP server ([79e4651](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/79e4651ddf322d2dcc93d2a4aa2bd1294266550b))

### Reverts

- restore simple version handling ([bd0fadf](https://github.com/aashari/mcp-server-atlassian-bitbucket/commit/bd0fadfa8207b4a7cf472c3b9f4ee63d8e36189d))

## [1.1.4](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.3...v1.1.4) (2025-03-24)

### Bug Fixes

- remove dist directory from git tracking ([0ed5d4b](https://github.com/aashari/mcp-server-atlassian-jira/commit/0ed5d4bad05e09cbae3350eb934c98ef1d28ed12))

## [1.1.3](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.2...v1.1.3) (2025-03-24)

### Bug Fixes

- remove dist files from release commit assets ([86e486b](https://github.com/aashari/mcp-server-atlassian-jira/commit/86e486bb68cb18d077852e73eabf8f912d9d007e))

## [1.1.2](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.1...v1.1.2) (2025-03-24)

### Bug Fixes

- correct package name and version consistency ([374a660](https://github.com/aashari/mcp-server-atlassian-jira/commit/374a660e88a62b9c7b7c59718beec09806c47c0e))

## [1.1.1](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.1.0...v1.1.1) (2025-03-24)

### Bug Fixes

- improve documentation with additional section ([ccbd814](https://github.com/aashari/mcp-server-atlassian-jira/commit/ccbd8146ef55bed1edb6ed005f923ac25bfa8dae))

# [1.1.0](https://github.com/aashari/mcp-server-atlassian-jira/compare/v1.0.0...v1.1.0) (2025-03-23)

### Bug Fixes

- remove incorrect limit expectation in transport utility tests ([6f7b689](https://github.com/aashari/mcp-server-atlassian-jira/commit/6f7b689a7eb5db8a8592db88e7fa27ac04d641c8))
- update package.json version and scripts, fix transport.util.test.ts, update README ([deefccd](https://github.com/aashari/mcp-server-atlassian-jira/commit/deefccdc93311be572abf45feb9a5aae69ed57eb))

### Features

- improve development workflow and update documentation ([4458957](https://github.com/aashari/mcp-server-atlassian-jira/commit/445895777be6287a624cb19b8cd8a12590a28c7b))

# 1.0.0 (2025-03-23)

### Bug Fixes

- add workflows permission to semantic-release workflow ([de3a335](https://github.com/aashari/mcp-server-atlassian-jira/commit/de3a33510bd447af353444db1fcb58e1b1aa02e4))
- ensure executable permissions for bin script ([395f1dc](https://github.com/aashari/mcp-server-atlassian-jira/commit/395f1dcb5f3b5efee99048d1b91e3b083e9e544f))
- handle empty strings properly in greet function ([546d3a8](https://github.com/aashari/mcp-server-atlassian-jira/commit/546d3a84209e1065af46b2213053f589340158df))
- improve error logging with IP address details ([121f516](https://github.com/aashari/mcp-server-atlassian-jira/commit/121f51655517ddbea7d25968372bd6476f1b3e0f))
- improve GitHub Packages publishing with a more robust approach ([fd2aec9](https://github.com/aashari/mcp-server-atlassian-jira/commit/fd2aec9926cf99d301cbb2b5f5ca961a6b6fec7e))
- improve GitHub Packages publishing with better error handling and debugging ([db25f04](https://github.com/aashari/mcp-server-atlassian-jira/commit/db25f04925e884349fcf3ab85316550fde231d1f))
- improve GITHUB_OUTPUT syntax in semantic-release workflow ([6f154bc](https://github.com/aashari/mcp-server-atlassian-jira/commit/6f154bc43f42475857e9256b0a671c3263dc9708))
- improve version detection for global installations ([97a95dc](https://github.com/aashari/mcp-server-atlassian-jira/commit/97a95dca61d8cd7a86c81bde4cb38c509b810dc0))
- make publish workflow more resilient against version conflicts ([ffd3705](https://github.com/aashari/mcp-server-atlassian-jira/commit/ffd3705bc064ee9135402052a0dc7fe32645714b))
- remove invalid workflows permission ([c012e46](https://github.com/aashari/mcp-server-atlassian-jira/commit/c012e46a29070c8394f7ab596fe7ba68c037d3a3))
- remove type module to fix CommonJS compatibility ([8b1f00c](https://github.com/aashari/mcp-server-atlassian-jira/commit/8b1f00c37467bc676ad8ec9ab672ba393ed084a9))
- resolve linter errors in version detection code ([5f1f33e](https://github.com/aashari/mcp-server-atlassian-jira/commit/5f1f33e88ae843b7a0d708899713be36fcd2ec2e))
- update examples to use correct API (greet instead of sayHello) ([7c062ca](https://github.com/aashari/mcp-server-atlassian-jira/commit/7c062ca42765c659f018f990f4b1ec563d1172d3))
- update package name in config loader ([3b8157b](https://github.com/aashari/mcp-server-atlassian-jira/commit/3b8157b076441e4dde562cddfe31671f3696434d))
- update release workflow to ensure correct versioning in compiled files ([a365394](https://github.com/aashari/mcp-server-atlassian-jira/commit/a365394b8596defa33ff5a44583d52e2c43f0aa3))
- update version display in CLI ([2b7846c](https://github.com/aashari/mcp-server-atlassian-jira/commit/2b7846cbfa023f4b1a8c81ec511370fa8f5aaf33))

### Features

- add automated dependency management ([efa1b62](https://github.com/aashari/mcp-server-atlassian-jira/commit/efa1b6292e0e9b6efd0d43b40cf7099d50769487))
- add CLI usage examples for both JavaScript and TypeScript ([d5743b0](https://github.com/aashari/mcp-server-atlassian-jira/commit/d5743b07a6f2afe1c6cb0b03265228cba771e657))
- add support for custom name in greet command ([be48a05](https://github.com/aashari/mcp-server-atlassian-jira/commit/be48a053834a1d910877864608a5e9942d913367))
- add version update script and fix version display ([ec831d3](https://github.com/aashari/mcp-server-atlassian-jira/commit/ec831d3a3c966d858c15972365007f9dfd6115b8))
- implement Atlassian Confluence MCP server ([50ee69e](https://github.com/aashari/mcp-server-atlassian-jira/commit/50ee69e37f4d453cb8f0447e10fa5708a787aa93))
- implement review recommendations ([a23cbc0](https://github.com/aashari/mcp-server-atlassian-jira/commit/a23cbc0608a07e202396b3cd496c1f2078e304c1))
- implement testing, linting, and semantic versioning ([1d7710d](https://github.com/aashari/mcp-server-atlassian-jira/commit/1d7710dfa11fd1cb04ba3c604e9a2eb785652394))
- improve CI workflows with standardized Node.js version, caching, and dual publishing ([0dc9470](https://github.com/aashari/mcp-server-atlassian-jira/commit/0dc94705c81067d7ff63ab978ef9e6a6e3f75784))
- improve package structure and add better examples ([bd66891](https://github.com/aashari/mcp-server-atlassian-jira/commit/bd668915bde84445161cdbd55ff9da0b0af51944))
- initial implementation of Jira MCP server ([79e4651](https://github.com/aashari/mcp-server-atlassian-jira/commit/79e4651ddf322d2dcc93d2a4aa2bd1294266550b))

### Reverts

- restore simple version handling ([bd0fadf](https://github.com/aashari/mcp-server-atlassian-jira/commit/bd0fadfa8207b4a7cf472c3b9f4ee63d8e36189d))

## [1.0.1](https://github.com/aashari/mcp-server-atlassian-confluence/compare/v1.0.0...v1.0.1) (2025-03-23)

### Bug Fixes

- update package name in config loader ([3b8157b](https://github.com/aashari/mcp-server-atlassian-confluence/commit/3b8157b076441e4dde562cddfe31671f3696434d))

# 1.0.0 (2025-03-23)

### Bug Fixes

- add workflows permission to semantic-release workflow ([de3a335](https://github.com/aashari/mcp-server-atlassian-confluence/commit/de3a33510bd447af353444db1fcb58e1b1aa02e4))
- ensure executable permissions for bin script ([395f1dc](https://github.com/aashari/mcp-server-atlassian-confluence/commit/395f1dcb5f3b5efee99048d1b91e3b083e9e544f))
- handle empty strings properly in greet function ([546d3a8](https://github.com/aashari/mcp-server-atlassian-confluence/commit/546d3a84209e1065af46b2213053f589340158df))
- improve error logging with IP address details ([121f516](https://github.com/aashari/mcp-server-atlassian-confluence/commit/121f51655517ddbea7d25968372bd6476f1b3e0f))
- improve GitHub Packages publishing with a more robust approach ([fd2aec9](https://github.com/aashari/mcp-server-atlassian-confluence/commit/fd2aec9926cf99d301cbb2b5f5ca961a6b6fec7e))
- improve GitHub Packages publishing with better error handling and debugging ([db25f04](https://github.com/aashari/mcp-server-atlassian-confluence/commit/db25f04925e884349fcf3ab85316550fde231d1f))
- improve GITHUB_OUTPUT syntax in semantic-release workflow ([6f154bc](https://github.com/aashari/mcp-server-atlassian-confluence/commit/6f154bc43f42475857e9256b0a671c3263dc9708))
- improve version detection for global installations ([97a95dc](https://github.com/aashari/mcp-server-atlassian-confluence/commit/97a95dca61d8cd7a86c81bde4cb38c509b810dc0))
- make publish workflow more resilient against version conflicts ([ffd3705](https://github.com/aashari/mcp-server-atlassian-confluence/commit/ffd3705bc064ee9135402052a0dc7fe32645714b))
- remove invalid workflows permission ([c012e46](https://github.com/aashari/mcp-server-atlassian-confluence/commit/c012e46a29070c8394f7ab596fe7ba68c037d3a3))
- remove type module to fix CommonJS compatibility ([8b1f00c](https://github.com/aashari/mcp-server-atlassian-confluence/commit/8b1f00c37467bc676ad8ec9ab672ba393ed084a9))
- resolve linter errors in version detection code ([5f1f33e](https://github.com/aashari/mcp-server-atlassian-confluence/commit/5f1f33e88ae843b7a0d708899713be36fcd2ec2e))
- update examples to use correct API (greet instead of sayHello) ([7c062ca](https://github.com/aashari/mcp-server-atlassian-confluence/commit/7c062ca42765c659f018f990f4b1ec563d1172d3))
- update release workflow to ensure correct versioning in compiled files ([a365394](https://github.com/aashari/mcp-server-atlassian-confluence/commit/a365394b8596defa33ff5a44583d52e2c43f0aa3))
- update version display in CLI ([2b7846c](https://github.com/aashari/mcp-server-atlassian-confluence/commit/2b7846cbfa023f4b1a8c81ec511370fa8f5aaf33))

### Features

- add automated dependency management ([efa1b62](https://github.com/aashari/mcp-server-atlassian-confluence/commit/efa1b6292e0e9b6efd0d43b40cf7099d50769487))
- add CLI usage examples for both JavaScript and TypeScript ([d5743b0](https://github.com/aashari/mcp-server-atlassian-confluence/commit/d5743b07a6f2afe1c6cb0b03265228cba771e657))
- add support for custom name in greet command ([be48a05](https://github.com/aashari/mcp-server-atlassian-confluence/commit/be48a053834a1d910877864608a5e9942d913367))
- add version update script and fix version display ([ec831d3](https://github.com/aashari/mcp-server-atlassian-confluence/commit/ec831d3a3c966d858c15972365007f9dfd6115b8))
- implement Atlassian Confluence MCP server ([50ee69e](https://github.com/aashari/mcp-server-atlassian-confluence/commit/50ee69e37f4d453cb8f0447e10fa5708a787aa93))
- implement review recommendations ([a23cbc0](https://github.com/aashari/mcp-server-atlassian-confluence/commit/a23cbc0608a07e202396b3cd496c1f2078e304c1))
- implement testing, linting, and semantic versioning ([1d7710d](https://github.com/aashari/mcp-server-atlassian-confluence/commit/1d7710dfa11fd1cb04ba3c604e9a2eb785652394))
- improve CI workflows with standardized Node.js version, caching, and dual publishing ([0dc9470](https://github.com/aashari/mcp-server-atlassian-confluence/commit/0dc94705c81067d7ff63ab978ef9e6a6e3f75784))
- improve package structure and add better examples ([bd66891](https://github.com/aashari/mcp-server-atlassian-confluence/commit/bd668915bde84445161cdbd55ff9da0b0af51944))

### Reverts

- restore simple version handling ([bd0fadf](https://github.com/aashari/mcp-server-atlassian-confluence/commit/bd0fadfa8207b4a7cf472c3b9f4ee63d8e36189d))

# 1.0.0 (2025-03-23)

### Features

- Initial release of Atlassian Confluence MCP server
- Provides tools for accessing and searching Confluence spaces, pages, and content
- Integration with Claude Desktop and Cursor AI via Model Context Protocol
- CLI support for direct interaction with Confluence

```
Page 4/4FirstPrevNextLast