# Bitbucket MCP Server
A FastMCP server for managing Pull Requests on Bitbucket Cloud. Create, list, view, update, and review PRs directly from Claude.
## Features
- Create PRs with automatic default reviewer support
- List and view PR details
- Update PR title, description, destination branch, and reviewers
- Approve, unapprove, or request changes on PRs
- Add comments to PRs
- List workspace members for reviewer selection
## Installation
```bash
git clone https://github.com/Acendas/bitbucket-mcp.git
cd bitbucket-mcp
pip install -r requirements.txt
```
Or with uv:
```bash
git clone https://github.com/Acendas/bitbucket-mcp.git
cd bitbucket-mcp
uv pip install -r requirements.txt
```
## Getting an API Token
1. Go to [Atlassian API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
2. Click **Create API token**
3. Give it a name (e.g., "Bitbucket MCP")
4. Copy the generated token
## Configuration
### Option 1: Interactive Setup (Recommended)
Use the `setup_bitbucket` tool:
```
setup_bitbucket(
workspace="your-workspace",
username="your-email@example.com",
api_token="your-api-token"
)
```
This stores credentials securely in `~/.bitbucket-mcp/config.json` with 600 permissions.
### Option 2: Environment Variables
```bash
export BITBUCKET_API_TOKEN="your-api-token"
export BITBUCKET_USERNAME="your-email@example.com"
export BITBUCKET_WORKSPACE="your-workspace" # optional default
```
## Claude Desktop Configuration
Add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"bitbucket": {
"command": "python",
"args": ["/path/to/bitbucket-mcp/server.py"]
}
}
}
```
Or with uv:
```json
{
"mcpServers": {
"bitbucket": {
"command": "uv",
"args": ["run", "--directory", "/path/to/bitbucket-mcp", "python", "server.py"]
}
}
}
```
## Available Tools
### Configuration
#### `setup_bitbucket`
Configure Bitbucket credentials.
```python
setup_bitbucket(
workspace="your-workspace",
username="your-email@example.com",
api_token="your-api-token"
)
```
#### `get_config_status`
Check if Bitbucket is configured.
```python
get_config_status()
# Returns: { "configured": true, "workspace": "...", "username": "..." }
```
### Workspace
#### `list_workspace_members`
List members of a workspace. Useful for finding reviewers.
```python
list_workspace_members(
workspace="your-workspace", # optional if configured
page=1,
pagelen=50
)
# Returns: { "members": [{ "uuid": "...", "display_name": "...", "account_id": "..." }] }
```
#### `get_default_reviewers`
Get the default reviewers configured for a repository.
```python
get_default_reviewers(
repo_slug="my-repo",
workspace="your-workspace" # optional if configured
)
# Returns: { "default_reviewers": [{ "uuid": "...", "display_name": "..." }] }
```
### Pull Requests
#### `create_pull_request`
Create a new Pull Request. Automatically includes default reviewers.
```python
create_pull_request(
repo_slug="my-repo",
title="Feature: Add new functionality",
source_branch="feature/my-feature",
destination_branch="main", # optional, defaults to "main"
description="This PR adds...", # optional
reviewers=["uuid-1", "uuid-2"], # optional, additional reviewers
use_default_reviewers=True, # optional, defaults to True
workspace="your-workspace" # optional if configured
)
```
#### `list_pull_requests`
List PRs for a repository.
```python
list_pull_requests(
repo_slug="my-repo",
state="OPEN", # OPEN, MERGED, DECLINED, SUPERSEDED, or ALL
workspace="your-workspace", # optional if configured
page=1,
pagelen=25
)
```
#### `get_pull_request`
Get details of a specific PR.
```python
get_pull_request(
repo_slug="my-repo",
pr_id=123,
workspace="your-workspace" # optional if configured
)
```
#### `update_pull_request`
Update an existing PR.
```python
update_pull_request(
repo_slug="my-repo",
pr_id=123,
title="New title", # optional
description="New description", # optional
destination_branch="develop", # optional
reviewers=["uuid-1", "uuid-2"], # optional, replaces current reviewers
close_source_branch=True, # optional
workspace="your-workspace" # optional if configured
)
```
### Reviews
#### `approve_pull_request`
Approve a PR.
```python
approve_pull_request(
repo_slug="my-repo",
pr_id=123,
workspace="your-workspace" # optional if configured
)
```
#### `unapprove_pull_request`
Remove your approval from a PR.
```python
unapprove_pull_request(
repo_slug="my-repo",
pr_id=123,
workspace="your-workspace" # optional if configured
)
```
#### `request_changes_pull_request`
Request changes on a PR.
```python
request_changes_pull_request(
repo_slug="my-repo",
pr_id=123,
workspace="your-workspace" # optional if configured
)
```
#### `add_pull_request_comment`
Add a comment to a PR (supports markdown).
```python
add_pull_request_comment(
repo_slug="my-repo",
pr_id=123,
comment="Looks good! Just one suggestion...",
workspace="your-workspace" # optional if configured
)
```
## Example Usage with Claude
1. **First time setup:**
> "Set up Bitbucket with my workspace 'mycompany', username 'me@example.com', and API token 'abc123'"
2. **Create a PR:**
> "Create a PR in my-repo from feature/login to main titled 'Add user login'"
3. **List open PRs:**
> "Show me all open PRs in my-repo"
4. **Review a PR:**
> "Approve PR #42 in my-repo"
5. **Add a comment:**
> "Add a comment to PR #42 saying 'LGTM!'"
6. **Find reviewers:**
> "List all members in my workspace so I can add them as reviewers"
## Security
- Credentials are stored in `~/.bitbucket-mcp/config.json` with 600 permissions (owner-only access)
- API tokens are never logged or exposed in error messages
- Environment variables are supported for CI/CD scenarios
## License
MIT License - see [LICENSE](LICENSE) for details.