MCP server for Bitbucket Cloud API
2.0K
MCP (Model Context Protocol) server for Bitbucket Cloud API. Enables AI assistants like Claude to interact with Bitbucket repositories, pull requests, and branches.
Install from source:
git clone https://github.com/martinhlavacek/bitbucket-mcp.git
cd bitbucket-mcp
pip install -e .
Note: App Passwords were deprecated in September 2025. Use API tokens instead.
repository:readrepository:writepullrequest:readpullrequest:writeexport BITBUCKET_EMAIL="[email protected]"
export BITBUCKET_API_TOKEN="your-api-token"
export BITBUCKET_WORKSPACE="your-workspace" # optional, can be passed per-request
Finding your workspace: The workspace is the first part of your Bitbucket repository URL:
https://bitbucket.org/{workspace}/{repo}- for example, if your repo URL ishttps://bitbucket.org/acme-corp/my-project, your workspace isacme-corp.
Via CLI:
claude mcp add --transport stdio \
--env [email protected] \
--env BITBUCKET_API_TOKEN=your-api-token \
--env BITBUCKET_WORKSPACE=your-workspace \
bitbucket -- python -m bitbucket_mcp
Or add to your MCP configuration file:
{
"mcpServers": {
"bitbucket": {
"command": "python",
"args": ["-m", "bitbucket_mcp"],
"env": {
"BITBUCKET_EMAIL": "[email protected]",
"BITBUCKET_API_TOKEN": "your-api-token",
"BITBUCKET_WORKSPACE": "your-workspace"
}
}
}
}
python -m bitbucket_mcp
docker run -d \
-p 8000:8000 \
-e [email protected] \
-e BITBUCKET_API_TOKEN=your-api-token \
-e BITBUCKET_WORKSPACE=your-workspace \
hlavaceklab/bitbucket-mcp:latest
Via CLI:
claude mcp add --transport http bitbucket http://localhost:8000/mcp
Via JSON config:
{
"mcpServers": {
"bitbucket": {
"url": "http://your-server:8000/mcp"
}
}
}
Create a .env file with your credentials:
[email protected]
BITBUCKET_API_TOKEN=your-api-token
BITBUCKET_WORKSPACE=your-workspace
Run with Docker Compose:
docker compose up -d
docker build -t bitbucket-mcp .
docker run -d -p 8000:8000 \
-e [email protected] \
-e BITBUCKET_API_TOKEN=your-api-token \
-e BITBUCKET_WORKSPACE=your-workspace \
bitbucket-mcp
| Endpoint | Description |
|---|---|
/health | Health check (JSON) |
/metrics | Prometheus metrics |
| Tool | Description |
|---|---|
bitbucket_get_repo | Get repository information |
bitbucket_list_branches | List repository branches |
bitbucket_list_prs | List pull requests |
bitbucket_get_pr | Get pull request details |
bitbucket_create_pr | Create a new pull request |
bitbucket_merge_pr | Merge a pull request |
bitbucket_approve_pr | Approve a pull request |
bitbucket_unapprove_pr | Remove approval from a PR |
bitbucket_decline_pr | Decline a pull request |
bitbucket_get_diff | Get PR diff |
bitbucket_add_comment | Add comment to a PR |
bitbucket_list_comments | List PR comments |
bitbucket_get_pr_pipeline | Get the latest CI pipeline status for a PR (running / passed / failed) |
bitbucket_get_pipeline_step_log | Get a pipeline step's log (last 200 lines by default) |
bitbucket_list_pipelines | List recent pipelines, optionally filtered by branch |
bitbucket_get_pipeline | Get a pipeline with its per-step breakdown |
bitbucket_trigger_pipeline | Trigger a pipeline run (opt-in, see below) |
bitbucket_stop_pipeline | Signal a running pipeline to stop |
Triggering a pipeline is the one operation here that can spend build minutes and deploy to an environment, so it is off by default and gated by two independent settings.
export BITBUCKET_ALLOW_PIPELINE_TRIGGER="true"
export BITBUCKET_PIPELINE_ALLOWLIST="my-api:ci,my-api:preview,web:ci"
export BITBUCKET_ALLOW_PIPELINE_STOP="true" # this is the default
| Variable | Default | Answers |
|---|---|---|
BITBUCKET_ALLOW_PIPELINE_TRIGGER | false | May pipelines be triggered at all? |
BITBUCKET_PIPELINE_ALLOWLIST | empty | Which custom pipelines may be triggered? |
BITBUCKET_ALLOW_PIPELINE_STOP | true | May a running pipeline be stopped? |
The allowlist is scoped per repository (repo-slug:pipeline-name) because one server
instance serves every repository - a bare pipeline name would let a deploy allowed for a
staging repo also run the production deploy of another one. An empty allowlist means no
custom pipeline may run, not every one.
Running a branch's default pipeline needs no allowlist entry: it runs what a push to that branch would have run anyway, so it cannot deploy anything a push could not.
Token scope: these two tools need
write:pipeline:bitbucket. It does not implyread:pipeline:bitbucket, which the read-only pipeline tools already use, so add it to your API token rather than swapping the existing scope.
The settings are read from the environment of the server process, so they belong wherever that process is started - not in the client that connects to it.
Running the server over HTTP (Docker, shared host) rather than stdio, the client config holds only a URL and no environment at all; the variables go on the host running the container:
# docker-compose.yml on the server
services:
bitbucket-mcp:
image: hlavaceklab/bitbucket-mcp:latest
environment:
- BITBUCKET_ALLOW_PIPELINE_TRIGGER=true
- BITBUCKET_PIPELINE_ALLOWLIST=my-api:ci,web:preview
docker compose up -d # a restart is required; the config is read from the process env
A shared server means a shared allowlist. One container serves every client that can reach it, so enabling the trigger enables it for all of them, running under the token configured on that host. There is no per-client or per-session scoping.
# Clone
git clone https://github.com/martinhlavacek/bitbucket-mcp.git
cd bitbucket-mcp
# Setup
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Test
pytest
# Lint
ruff check .
Contributions are welcome! Please read our Contributing Guide and Code of Conduct.
MIT License - see LICENSE for details.
Content type
Image
Digest
sha256:2d747690c…
Size
82.4 MB
Last updated
about 1 month ago
docker pull hlavaceklab/bitbucket-mcp