Metadata-Version: 2.4
Name: bitbucket-llm-bridge
Version: 1.0.0
Summary: MCP server for Bitbucket – manage pull requests, comments, reviews, and diffs via AI assistants.
Author: Bardia Barabadi
License-Expression: MIT
Keywords: bitbucket,claude,cursor,mcp,pull-request
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.0.0
Description-Content-Type: text/markdown

# Bitbucket MCP Server

An MCP (Model Context Protocol) server for **Bitbucket**. Connect Cursor, Claude Desktop, or any MCP-compatible client to your Bitbucket instance and let an AI assistant create PRs, review code, comment on diffs, and more -- all through natural language.

Two fully equivalent implementations are provided -- pick whichever fits your stack:

| Implementation | Directory   | Runtime      |
|----------------|-------------|--------------|
| **TypeScript** | [typescript/](typescript/) | Node.js 18+  |
| **Python**     | [python/](python/)         | Python 3.10+ |

Both expose identical tools and produce the same output. Supports **Bitbucket Cloud** (API v2.0) and **Bitbucket Server / Data Center** (REST API 1.0).

## Features

| Tool                    | Description                                              |
|-------------------------|----------------------------------------------------------|
| `create_pr`             | Create a new pull request                                |
| `get_pr`                | Get PR details (title, description, state, author, reviewers) |
| `list_prs`              | List pull requests with filters (state, author, limit)   |
| `add_reviewer`          | Add reviewer(s) / approver(s) to a PR                   |
| `approve_pr`            | Approve a pull request                                   |
| `get_pr_comments`       | Read all comments on a PR                                |
| `add_pr_comment`        | Add a general comment to a PR                            |
| `add_pr_inline_comment` | Comment on a specific line of code in the diff           |
| `resolve_pr_comment`    | Resolve or unresolve a PR comment                        |
| `get_pr_diff`           | Get the full unified diff for a PR                       |
| `get_pr_commit_diff`    | Get the diff for a specific commit in a PR               |
| `merge_pr`              | Merge a pull request                                     |
| `decline_pr`            | Decline (close) a pull request                           |

## Prerequisites

- A **Bitbucket Cloud** account or a **Bitbucket Server / Data Center** instance with API access
- Credentials (see Configuration below)

## Configuration

The server requires environment variables depending on which Bitbucket variant you use:

| Variable                       | Required For | Description                                                                   |
|--------------------------------|-------------|-------------------------------------------------------------------------------|
| `BITBUCKET_TYPE`               | All          | `"cloud"` (default) or `"server"`                                            |
| `BITBUCKET_CLOUD_USERNAME`     | Cloud        | Your Bitbucket username                                                       |
| `BITBUCKET_CLOUD_APP_PASSWORD` | Cloud        | [App password](https://bitbucket.org/account/settings/app-passwords/) with PR read/write permissions |
| `BITBUCKET_SERVER_URL`         | Server/DC    | Base URL of your Bitbucket Server instance (e.g. `https://bitbucket.mycompany.com`) |
| `BITBUCKET_SERVER_TOKEN`       | Server/DC    | [Personal Access Token](https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html) |
| `BITBUCKET_DEFAULT_WORKSPACE`  | Optional     | Default workspace slug (Cloud) or project key (Server). Saves you from passing `workspace` on every tool call. |
| `BITBUCKET_DEFAULT_REPO_SLUG`  | Optional     | Default repository slug. Saves you from passing `repo_slug` on every tool call. |

When `BITBUCKET_DEFAULT_WORKSPACE` and `BITBUCKET_DEFAULT_REPO_SLUG` are set, every tool call that accepts `workspace` / `repo_slug` will use them as defaults. The LLM can still override them by explicitly passing different values in any individual tool call.

---

## TypeScript

### Prerequisites

Node.js 18+ -- [download](https://nodejs.org/)

### Installation

**From npm (recommended):**

```bash
npm install -g bitbucket-mcp
```

Or run directly with `npx`:

```bash
npx bitbucket-mcp
```

**From source:**

```bash
git clone https://github.com/bardiabarabadi/Bitbucket-MCP.git
cd Bitbucket-MCP/typescript
npm install
npm run build
```

### Connecting to Cursor

Add the server to your Cursor MCP configuration. Create or edit `.cursor/mcp.json` in your project root (or your global Cursor config).

**Bitbucket Cloud:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "npx",
      "args": ["-y", "bitbucket-mcp"],
      "env": {
        "BITBUCKET_TYPE": "cloud",
        "BITBUCKET_CLOUD_USERNAME": "your_username",
        "BITBUCKET_CLOUD_APP_PASSWORD": "your_app_password",
        "BITBUCKET_DEFAULT_WORKSPACE": "your_workspace",
        "BITBUCKET_DEFAULT_REPO_SLUG": "your_repo"
      }
    }
  }
}
```

**Bitbucket Server / Data Center:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "npx",
      "args": ["-y", "bitbucket-mcp"],
      "env": {
        "BITBUCKET_TYPE": "server",
        "BITBUCKET_SERVER_URL": "https://bitbucket.mycompany.com",
        "BITBUCKET_SERVER_TOKEN": "your_personal_access_token",
        "BITBUCKET_DEFAULT_WORKSPACE": "YOUR_PROJECT_KEY",
        "BITBUCKET_DEFAULT_REPO_SLUG": "your_repo"
      }
    }
  }
}
```

Restart Cursor after saving. To verify, open Cursor's MCP panel (gear icon -> MCP) and check that `bitbucket` appears as connected.

### Connecting to Claude Desktop

Edit `claude_desktop_config.json`:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "npx",
      "args": ["-y", "bitbucket-mcp"],
      "env": {
        "BITBUCKET_TYPE": "cloud",
        "BITBUCKET_CLOUD_USERNAME": "your_username",
        "BITBUCKET_CLOUD_APP_PASSWORD": "your_app_password"
      }
    }
  }
}
```

Restart Claude Desktop after saving. You should see the MCP tools icon in the chat input.

### Development

```bash
cd typescript

# Run in development mode (no build needed)
BITBUCKET_TYPE=cloud BITBUCKET_CLOUD_USERNAME=user BITBUCKET_CLOUD_APP_PASSWORD=pass npm run dev

# Type-check without emitting
npx tsc --noEmit
```

### Project Structure

```
typescript/
  src/
    index.ts                    — Entry point: creates MCP server, registers tools, starts stdio transport
    config.ts                   — Environment variable parsing and config types
    client/
      base.ts                  — Abstract BitbucketClient interface
      cloud.ts                 — Bitbucket Cloud API v2.0 implementation
      datacenter.ts            — Bitbucket Server/DC REST API 1.0 implementation
    tools/
      pull-requests.ts         — create_pr, get_pr, list_prs, merge_pr, decline_pr
      comments.ts              — get_pr_comments, add_pr_comment, add_pr_inline_comment, resolve_pr_comment
      reviews.ts               — add_reviewer, approve_pr
      diff.ts                  — get_pr_diff, get_pr_commit_diff
```

---

## Python

### Prerequisites

Python 3.10+ -- [download](https://python.org/)

### Installation

**From PyPI (recommended):**

```bash
pip install bitbucket-llm-bridge
```

**From source:**

```bash
git clone https://github.com/bardiabarabadi/Bitbucket-MCP.git
cd Bitbucket-MCP/python
pip install -e .
```

### Connecting to Cursor

Add the server to your Cursor MCP configuration. Create or edit `.cursor/mcp.json` in your project root (or your global Cursor config).

**Global install** (i.e. `pip install bitbucket-llm-bridge`):

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "bitbucket-llm-bridge",
      "args": [],
      "env": {
        "BITBUCKET_TYPE": "cloud",
        "BITBUCKET_CLOUD_USERNAME": "your_username",
        "BITBUCKET_CLOUD_APP_PASSWORD": "your_app_password"
      }
    }
  }
}
```

**Venv install -- macOS / Linux:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "/path/to/your/venv/bin/bitbucket-llm-bridge",
      "args": [],
      "env": {
        "BITBUCKET_TYPE": "cloud",
        "BITBUCKET_CLOUD_USERNAME": "your_username",
        "BITBUCKET_CLOUD_APP_PASSWORD": "your_app_password"
      }
    }
  }
}
```

**Venv install -- Windows:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "C:/path/to/your/venv/Scripts/bitbucket-llm-bridge.exe",
      "args": [],
      "env": {
        "BITBUCKET_TYPE": "cloud",
        "BITBUCKET_CLOUD_USERNAME": "your_username",
        "BITBUCKET_CLOUD_APP_PASSWORD": "your_app_password"
      }
    }
  }
}
```

Replace the credentials and venv path with your own values. Restart Cursor after saving.

### Connecting to Claude Desktop

Edit `claude_desktop_config.json`:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

**Global install:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "bitbucket-llm-bridge",
      "args": [],
      "env": {
        "BITBUCKET_TYPE": "cloud",
        "BITBUCKET_CLOUD_USERNAME": "your_username",
        "BITBUCKET_CLOUD_APP_PASSWORD": "your_app_password"
      }
    }
  }
}
```

**Venv install -- macOS / Linux:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "/path/to/your/venv/bin/bitbucket-llm-bridge",
      "args": [],
      "env": {
        "BITBUCKET_TYPE": "server",
        "BITBUCKET_SERVER_URL": "https://bitbucket.mycompany.com",
        "BITBUCKET_SERVER_TOKEN": "your_personal_access_token"
      }
    }
  }
}
```

**Venv install -- Windows:**

```json
{
  "mcpServers": {
    "bitbucket": {
      "command": "C:/path/to/your/venv/Scripts/bitbucket-llm-bridge.exe",
      "args": [],
      "env": {
        "BITBUCKET_TYPE": "server",
        "BITBUCKET_SERVER_URL": "https://bitbucket.mycompany.com",
        "BITBUCKET_SERVER_TOKEN": "your_personal_access_token"
      }
    }
  }
}
```

Restart Claude Desktop after saving. You should see the MCP tools icon in the chat input.

### Development

```bash
cd python

# Install in editable mode
pip install -e .

# Run the server
BITBUCKET_TYPE=cloud BITBUCKET_CLOUD_USERNAME=user BITBUCKET_CLOUD_APP_PASSWORD=pass bitbucket-llm-bridge

# Or run as module
python -m bitbucket_mcp

# Install dev dependencies and run tests
pip install pytest pytest-asyncio
pytest tests/ -v
```

### Project Structure

```
python/
  src/bitbucket_mcp/
    server.py                   — Entry point: creates FastMCP server, registers tools, starts stdio transport
    config.py                   — Environment variable parsing and BitbucketConfig dataclass
    client/
      base.py                  — Abstract BitbucketClient ABC
      cloud.py                 — Bitbucket Cloud API v2.0 implementation
      datacenter.py            — Bitbucket Server/DC REST API 1.0 implementation
    tools/
      pull_requests.py         — create_pr, get_pr, list_prs, merge_pr, decline_pr
      comments.py              — get_pr_comments, add_pr_comment, add_pr_inline_comment, resolve_pr_comment
      reviews.py               — add_reviewer, approve_pr
      diff.py                  — get_pr_diff, get_pr_commit_diff
```

---

## Tool Reference

### create_pr

Create a new pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `title` (string, required) -- PR title
- `source_branch` (string, required) -- Source branch name
- `destination_branch` (string, required) -- Destination/target branch name
- `description` (string, optional) -- PR description (markdown supported)
- `reviewers` (string[], optional) -- List of reviewer usernames to add
- `close_source_branch` (boolean, optional) -- Delete source branch on merge

### get_pr

Get full details for a pull request including title, description, state, author, and reviewers.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID

### list_prs

List pull requests with optional filters.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `state` (string, optional) -- Filter by state: OPEN, MERGED, DECLINED, SUPERSEDED
- `author` (string, optional) -- Filter by author username
- `limit` (number, optional, default 25) -- Maximum results

### add_reviewer

Add reviewer(s) / approver(s) to a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID
- `reviewers` (string[], required) -- List of usernames to add as reviewers

### approve_pr

Approve a pull request as the authenticated user.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID

### get_pr_comments

Read all comments on a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID

### add_pr_comment

Add a general comment to a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID
- `content` (string, required) -- Comment text (markdown supported)

### add_pr_inline_comment

Comment on a specific line of code in the pull request diff.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID
- `content` (string, required) -- Comment text (markdown supported)
- `file_path` (string, required) -- Path of the file in the diff (e.g. `"src/main.py"`)
- `line` (number, required) -- Line number to comment on
- `line_type` (string, optional) -- `"new"` (added lines, default) or `"old"` (removed lines)

### resolve_pr_comment

Resolve or unresolve a comment on a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID
- `comment_id` (number, required) -- The ID of the comment to resolve
- `resolved` (boolean, optional, default true) -- True to resolve, false to unresolve

### get_pr_diff

Get the full unified diff for a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID

### get_pr_commit_diff

Get the diff for a specific commit in a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID
- `commit_hash` (string, required) -- Full or short SHA of the commit

### merge_pr

Merge a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID
- `merge_strategy` (string, optional) -- `"merge_commit"` (default), `"squash"`, or `"fast_forward"`
- `close_source_branch` (boolean, optional) -- Delete source branch after merge
- `message` (string, optional) -- Custom merge commit message

### decline_pr

Decline (close without merging) a pull request.

**Parameters:**

- `workspace` (string, required) -- Cloud workspace slug or Server project key
- `repo_slug` (string, required) -- Repository slug
- `pr_id` (number, required) -- Pull request ID

---

## Example Prompts

Once connected, you can ask your AI assistant things like:

- *"Show me all open pull requests in workspace myteam, repo backend-api"*
- *"Get the details and diff of PR #42"*
- *"Create a PR from feature-login to main with title 'Add login page'"*
- *"Add alice and bob as reviewers to PR #15"*
- *"Approve pull request #33"*
- *"Comment on line 42 of src/auth.py in PR #7 saying 'This needs null checking'"*
- *"Resolve the comment with ID 12345 on PR #7"*
- *"Merge PR #10 using squash strategy"*

## Publishing

### Publish to npm

```bash
cd typescript
npm login
npm publish
```

The `prepublishOnly` script runs `tsc` automatically before publish. Only the `dist/`, `README.md`, and `LICENSE` files are included in the package.

### Publish to PyPI

```bash
cd python
pip install hatch
hatch build
hatch publish
```

Or using twine:

```bash
pip install build twine
python -m build
twine upload dist/*
```

## Troubleshooting

**"BITBUCKET_CLOUD_USERNAME and BITBUCKET_CLOUD_APP_PASSWORD must be set"**
Make sure both environment variables are set in your MCP configuration. Check for typos.

**"BITBUCKET_SERVER_URL and BITBUCKET_SERVER_TOKEN must be set"**
Set `BITBUCKET_TYPE=server` and provide both the URL and token.

**API returns 401 / 403**
Your credentials are invalid or lack sufficient permissions. For Bitbucket Cloud, ensure your App Password has Repositories: Read/Write and Pull Requests: Read/Write permissions.

**Server doesn't appear in Cursor/Claude**

- Ensure the `node`/`python` path is correct
- Restart Cursor/Claude Desktop after editing the config
- TypeScript: Check that `npm run build` completed without errors
- Python: Check that `pip install` completed without errors

**Comment appears at end of file instead of inline**
For Bitbucket Cloud, the `line_type` parameter controls which side of the diff the comment targets. Use `"new"` for added lines and `"old"` for removed lines. Do not specify both.

## License

MIT
