MCP server for Bitbucket Data Center (Server), not Bitbucket Cloud.
Project description
bitbucket-mcp-server-datacenter
An MCP server for Bitbucket Data Center / Server (not Bitbucket Cloud).
It targets the Data Center REST API (/rest/api/1.0, project/repo-centric
paths, start/limit/isLastPage paging) and supports personal
repositories via ~username project keys.
Requirements
- Python >= 3.11
uv(used to run/test the server)
Install / use without cloning
Once published to PyPI, the server can be run directly with
uvx — no repository checkout and no
manual pip install required. uvx fetches the package into an isolated,
cached environment and runs its console entry point:
BITBUCKET_BASE_URL="https://your-bitbucket.example.com" \
BITBUCKET_TOKEN="<your-token>" \
ENABLE_TOOLS="read" \
uvx bitbucket-mcp-server-datacenter
To wire it into an MCP client (e.g. VS Code), point the server command at
uvx instead of a local checkout. Example mcp.json:
{
"inputs": [
{
"id": "bitbucket_token",
"type": "promptString",
"description": "Bitbucket Data Center HTTP access token (sent as Bearer)",
"password": true
}
],
"servers": {
"bitbucket-datacenter": {
"type": "stdio",
"command": "uvx",
"args": ["bitbucket-mcp-server-datacenter"],
"env": {
"BITBUCKET_BASE_URL": "https://your-bitbucket.example.com",
"BITBUCKET_TOKEN": "${input:bitbucket_token}",
"ENABLE_TOOLS": "read"
}
}
}
}
Pin a specific release with uvx bitbucket-mcp-server-datacenter@0.1.0 (or
"args": ["bitbucket-mcp-server-datacenter@0.1.0"]).
Without a package index (straight from Git)
If the package is not on an index, uvx can install it directly from the
repository — still no manual clone:
uvx --from git+https://github.com/telekom-mms/bitbucket-mcp-server-datacenter \
bitbucket-mcp-server-datacenter
Configuration
The server reads configuration from environment variables:
| Variable | Required | Description |
|---|---|---|
BITBUCKET_BASE_URL |
yes | Base URL, e.g. https://bitbucket-stage.telekom-mms.com |
BITBUCKET_TOKEN |
* | HTTP access token, sent as Authorization: Bearer <token> |
BITBUCKET_USERNAME |
* | Username for Basic auth (used together with a secret) |
BITBUCKET_PASSWORD |
* | Password / API token for Basic auth |
BITBUCKET_CA_BUNDLE |
no | Path to a CA bundle to trust an internal/private CA |
ENABLE_TOOLS |
no | Which tools to expose (see Tool enablement). Empty = read-only. |
* Provide either BITBUCKET_TOKEN or BITBUCKET_USERNAME +
BITBUCKET_PASSWORD. When a username and secret are both set, Basic auth is
used; otherwise the token is sent as a Bearer header.
TLS is always verified. Verification is enforced and cannot be turned off (PSA Web Services 3.02 Req 18 / Cryptographic Algorithms 3.50 Req 43). Any attempt to disable it via
BITBUCKET_VERIFY_SSLis ignored and logged as a warning. To trust an internal certificate authority, setBITBUCKET_CA_BUNDLEto its CA bundle path instead of disabling verification.
Token lifecycle
The Bitbucket HTTP access token is the only long-lived secret used by this server. Handle it as a technical-account credential:
- Provisioning — create a personal HTTP access token in Bitbucket Data
Center (Manage account → HTTP access tokens) with the minimum scope
needed (read-only unless write tools are enabled). Match the token scope to
ENABLE_TOOLS. - Storage — never commit the token. In VS Code it is supplied through the
bitbucket_tokenprompt input (password: true) and passed via theBITBUCKET_TOKENenvironment variable only. Keep it out of logs and shell history. - Transport — the token is sent only over TLS in the
Authorizationheader, never in a URL (PSA Web Services 3.02 Req 21). - Rotation — rotate regularly (at least every 12 months, sooner for technical accounts) and immediately if it may have been exposed. Create the new token, update the secret, then revoke the old one.
- Revocation — revoke the token in Bitbucket as soon as it is no longer needed or on suspected compromise; revocation takes effect immediately.
If a token ever appears in plain text (chat, logs, screen sharing), treat it as compromised and rotate it right away.
Tool enablement
Tools must be explicitly enabled. ENABLE_TOOLS is a comma-separated list
of group names and/or individual tool names (case-insensitive):
| Token | Effect |
|---|---|
read |
Enable all read-only tools |
write |
Enable all write/content tools |
all |
Enable every non-blocked tool |
<name> |
Enable a single tool, e.g. create_pull_request |
none/off |
Enable nothing |
- If
ENABLE_TOOLSis unset or empty, only the read-only group is enabled, so the server is safe by default. - Unknown tool names are ignored.
- Examples:
ENABLE_TOOLS=read— read-only (default).ENABLE_TOOLS=read,create_pull_request,add_pull_request_comment— reads plus PR authoring.ENABLE_TOOLS=all— everything except blocked tools.
The set of enabled tools is logged to stderr on startup.
Permanently blocked tools
Destructive, repository/project-wide operations are intentionally not
implemented and cannot be enabled even with all:
delete_repositorydelete_projectfork_repository
Run in VS Code
The workspace ships a .vscode/mcp.json. The base URL and ENABLE_TOOLS are
set directly in the server's env; only the access token is requested as a
masked input on startup and is never written to the file. Adjust
ENABLE_TOOLS in .vscode/mcp.json to change which tools are exposed.
Run / smoke test from the CLI
uv sync
BITBUCKET_BASE_URL="https://bitbucket-stage.telekom-mms.com" \
BITBUCKET_TOKEN="<your-token>" \
ENABLE_TOOLS="read" \
uv run bitbucket-mcp-server-datacenter
Releasing (maintainers)
The package ships a console entry point
(bitbucket-mcp-server-datacenter) and builds with hatchling, so consumers
can run it with uvx without cloning (see
Install / use without cloning).
Releases are automated: the
.github/workflows/release.yml workflow runs
the tests, builds the wheel + sdist, and publishes to PyPI via
Trusted Publishing (OIDC, no
stored token) whenever a v* tag is pushed.
One-time setup
Already configured for this project; only needed when forking or re-creating it.
- PyPI trusted publisher — on the project's
publishing settings,
add a GitHub publisher with:
- Owner:
telekom-mms - Repository:
bitbucket-mcp-server-datacenter - Workflow:
release.yml - Environment:
pypi
- Owner:
- GitHub environment — create an environment named
pypiin the repo settings. Optionally restrict its deployment branches/tags tov*so only release tags can publish.
Cutting a release
-
Update
versioninpyproject.tomlfollowing SemVer. PyPI never allows re-uploading an existing version, so every release needs a new number. -
Commit the bump and push to
main. -
Tag the release and push the tag — this triggers the workflow:
git tag v0.1.1 git push origin v0.1.1
-
Watch the run under Actions; on success the new version appears on PyPI.
-
Verify the published release installs cleanly:
uvx bitbucket-mcp-server-datacenter@<version> --help
Manual publish (fallback)
Only if CI is unavailable. Build, inspect, and upload locally with a PyPI API token (never commit it):
uv build
tar -tzf dist/*.tar.gz # no secrets in sdist
uv publish --publish-url https://test.pypi.org/legacy/ # optional TestPyPI dry run
uv publish # production (prompts for token)
Tools
All tools below are gated by ENABLE_TOOLS. The
Category column controls which group (read / write) enables a tool.
Read tools (category read)
| Tool | Description |
|---|---|
get_current_user |
Verify auth/connectivity; returns the user and server version. |
list_projects |
List projects visible to the user (optional name filter). |
list_repositories |
List repositories in a project (~username for personal). |
get_repository |
Get details for a single repository. |
list_branches |
List branches (optional text filter). |
list_commits |
List commits, optionally from a branch/tag/commit ref. |
get_file_content |
Return raw text content of a file at an optional ref. |
browse_files |
List files/directories at a path (tree browsing). |
list_pull_requests |
List PRs by state (OPEN/DECLINED/MERGED/ALL). |
get_pull_request |
Get a single PR, including its current version. |
get_pull_request_diff |
Get the unified diff for a PR. |
get_pull_request_activities |
List PR activity (comments, approvals, updates). |
Write / content tools (category write)
| Tool | Description |
|---|---|
put_file |
Create/update a file via a commit; seeds the default branch if empty. |
create_branch |
Create a branch from a start point. |
create_pull_request |
Create a PR between two branches; resolves & applies the repo's default reviewers by default. |
add_pull_request_comment |
Add a general comment to a PR. |
merge_pull_request |
Merge a PR (requires current PR version). |
decline_pull_request |
Decline a PR (requires current PR version). |
delete_branch |
Delete a branch (branch-utils API); useful for cleanup. |
Notes specific to Bitbucket Data Center
- Personal repositories use the project key
~username(e.g.~sbwo). put_fileuses thebrowseendpoint, which requiresmultipart/form-data.merge_pull_request/decline_pull_requestrequire the current PRversion(obtain it viaget_pull_request) for optimistic locking.delete_branchuses thebranch-utilsAPI (/rest/branch-utils/1.0/...).create_pull_requestapplies the repository's default reviewers by default: it resolves them via the default-reviewers add-on API (/rest/default-reviewers/1.0/...) for the given source/target branch pair and adds them to the PR. Passapply_default_reviewers=falseto skip this, and/orreviewers=["user1", ...]to add explicit reviewers by username. The PR author is always excluded (Bitbucket rejects a PR whose author is also a reviewer). If the default-reviewers endpoint is unavailable, PR creation still succeeds without default reviewers.
Tests
Offline unit tests (no network; httpx MockTransport) cover three layers:
- Client (
test_client.py): auth header selection, key/URL encoding, paging, error extraction, multipart upload, andwhoami. - Tool enablement (
test_enablement.py):ENABLE_TOOLSresolution, blocked-tool enforcement, TLS enforcement, registry composition, andregister_enabled_tools. - Server tools (
test_server_tools.py): request paths and payloads built by the tools (refs/heads/refs,create_branch, merge/declineversionparam, and thebranch-utilsdelete_branchpath).
uv sync
uv run pytest -q
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bitbucket_mcp_server_datacenter-0.1.3.tar.gz.
File metadata
- Download URL: bitbucket_mcp_server_datacenter-0.1.3.tar.gz
- Upload date:
- Size: 94.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8a091e506cf61a4500a136de9a9ba2e1b73814d6d592fb8e4908f60b6c64f88
|
|
| MD5 |
6faec33ce287c0a33c650b6af8358178
|
|
| BLAKE2b-256 |
d529c40affb27427fd3192a9ab5c49a5ad223db304b83bd08f7130fd0f2e4f38
|
File details
Details for the file bitbucket_mcp_server_datacenter-0.1.3-py3-none-any.whl.
File metadata
- Download URL: bitbucket_mcp_server_datacenter-0.1.3-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63b36de86e895d1ffd48500ac95b72408eb84ecc2dd64cf5ec125db66a09ea22
|
|
| MD5 |
4e6d2c0e5dc86a08aa24b668a20a1a04
|
|
| BLAKE2b-256 |
092ce735bfb6fb88caedd46483f9deb087454d4ce8571ed33ad96c7b5f751e36
|