bitbucket-mcp-server-datacenter 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bitbucket_mcp_server_datacenter-0.1.0/.github/workflows/release.yml +43 -0
- bitbucket_mcp_server_datacenter-0.1.0/.gitignore +15 -0
- bitbucket_mcp_server_datacenter-0.1.0/.vscode/mcp.json +27 -0
- bitbucket_mcp_server_datacenter-0.1.0/LICENSE +21 -0
- bitbucket_mcp_server_datacenter-0.1.0/PKG-INFO +284 -0
- bitbucket_mcp_server_datacenter-0.1.0/PSA.md +91 -0
- bitbucket_mcp_server_datacenter-0.1.0/README.md +261 -0
- bitbucket_mcp_server_datacenter-0.1.0/pyproject.toml +46 -0
- bitbucket_mcp_server_datacenter-0.1.0/src/bitbucket_mcp/__init__.py +3 -0
- bitbucket_mcp_server_datacenter-0.1.0/src/bitbucket_mcp/client.py +232 -0
- bitbucket_mcp_server_datacenter-0.1.0/src/bitbucket_mcp/server.py +475 -0
- bitbucket_mcp_server_datacenter-0.1.0/tests/test_client.py +178 -0
- bitbucket_mcp_server_datacenter-0.1.0/tests/test_enablement.py +152 -0
- bitbucket_mcp_server_datacenter-0.1.0/tests/test_server_tools.py +108 -0
- bitbucket_mcp_server_datacenter-0.1.0/uv.lock +1491 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v5
|
|
18
|
+
- name: Run tests
|
|
19
|
+
run: uv run pytest -q
|
|
20
|
+
- name: Build distributions
|
|
21
|
+
run: uv build
|
|
22
|
+
- name: Upload artifacts
|
|
23
|
+
uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: dist
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment: pypi
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write # required for PyPI Trusted Publishing (OIDC)
|
|
34
|
+
steps:
|
|
35
|
+
- name: Download artifacts
|
|
36
|
+
uses: actions/download-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: dist
|
|
39
|
+
path: dist/
|
|
40
|
+
- name: Install uv
|
|
41
|
+
uses: astral-sh/setup-uv@v5
|
|
42
|
+
- name: Publish to PyPI
|
|
43
|
+
run: uv publish
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"inputs": [
|
|
3
|
+
{
|
|
4
|
+
"id": "bitbucket_token",
|
|
5
|
+
"type": "promptString",
|
|
6
|
+
"description": "Bitbucket Data Center HTTP access token (sent as Bearer)",
|
|
7
|
+
"password": true
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"servers": {
|
|
11
|
+
"bitbucket-datacenter": {
|
|
12
|
+
"type": "stdio",
|
|
13
|
+
"command": "uv",
|
|
14
|
+
"args": [
|
|
15
|
+
"run",
|
|
16
|
+
"--directory",
|
|
17
|
+
"${workspaceFolder}",
|
|
18
|
+
"bitbucket-mcp-server-datacenter"
|
|
19
|
+
],
|
|
20
|
+
"env": {
|
|
21
|
+
"BITBUCKET_BASE_URL": "https://bitbucket-stage.telekom-mms.com",
|
|
22
|
+
"BITBUCKET_TOKEN": "${input:bitbucket_token}",
|
|
23
|
+
"ENABLE_TOOLS": "all"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hektor1966
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bitbucket-mcp-server-datacenter
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for Bitbucket Data Center (Server), not Bitbucket Cloud.
|
|
5
|
+
Project-URL: Homepage, https://github.com/hektor1966/bitbucket-mcp-server-datacenter
|
|
6
|
+
Project-URL: Repository, https://github.com/hektor1966/bitbucket-mcp-server-datacenter
|
|
7
|
+
Project-URL: Issues, https://github.com/hektor1966/bitbucket-mcp-server-datacenter/issues
|
|
8
|
+
Author: hektor1966
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: bitbucket,bitbucket-data-center,bitbucket-server,fastmcp,mcp,model-context-protocol
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Version Control
|
|
18
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: fastmcp>=2.3.0
|
|
21
|
+
Requires-Dist: httpx>=0.27.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# bitbucket-mcp-server-datacenter
|
|
25
|
+
|
|
26
|
+
An MCP server for **Bitbucket Data Center / Server** (not Bitbucket Cloud).
|
|
27
|
+
It targets the Data Center REST API (`/rest/api/1.0`, project/repo-centric
|
|
28
|
+
paths, `start`/`limit`/`isLastPage` paging) and supports personal
|
|
29
|
+
repositories via `~username` project keys.
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
- Python >= 3.11
|
|
34
|
+
- [`uv`](https://docs.astral.sh/uv/) (used to run/test the server)
|
|
35
|
+
|
|
36
|
+
## Install / use without cloning
|
|
37
|
+
|
|
38
|
+
Once published to PyPI, the server can be run directly with
|
|
39
|
+
[`uvx`](https://docs.astral.sh/uv/guides/tools/) — no repository checkout and no
|
|
40
|
+
manual `pip install` required. `uvx` fetches the package into an isolated,
|
|
41
|
+
cached environment and runs its console entry point:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
BITBUCKET_BASE_URL="https://your-bitbucket.example.com" \
|
|
45
|
+
BITBUCKET_TOKEN="<your-token>" \
|
|
46
|
+
ENABLE_TOOLS="read" \
|
|
47
|
+
uvx bitbucket-mcp-server-datacenter
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
To wire it into an MCP client (e.g. VS Code), point the server `command` at
|
|
51
|
+
`uvx` instead of a local checkout. Example `mcp.json`:
|
|
52
|
+
|
|
53
|
+
```jsonc
|
|
54
|
+
{
|
|
55
|
+
"inputs": [
|
|
56
|
+
{
|
|
57
|
+
"id": "bitbucket_token",
|
|
58
|
+
"type": "promptString",
|
|
59
|
+
"description": "Bitbucket Data Center HTTP access token (sent as Bearer)",
|
|
60
|
+
"password": true
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"servers": {
|
|
64
|
+
"bitbucket-datacenter": {
|
|
65
|
+
"type": "stdio",
|
|
66
|
+
"command": "uvx",
|
|
67
|
+
"args": ["bitbucket-mcp-server-datacenter"],
|
|
68
|
+
"env": {
|
|
69
|
+
"BITBUCKET_BASE_URL": "https://your-bitbucket.example.com",
|
|
70
|
+
"BITBUCKET_TOKEN": "${input:bitbucket_token}",
|
|
71
|
+
"ENABLE_TOOLS": "read"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Pin a specific release with `uvx bitbucket-mcp-server-datacenter@0.1.0` (or
|
|
79
|
+
`"args": ["bitbucket-mcp-server-datacenter@0.1.0"]`).
|
|
80
|
+
|
|
81
|
+
### Without a package index (straight from Git)
|
|
82
|
+
|
|
83
|
+
If the package is not on an index, `uvx` can install it directly from the
|
|
84
|
+
repository — still no manual clone:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
uvx --from git+https://github.com/hektor1966/bitbucket-mcp-server-datacenter \
|
|
88
|
+
bitbucket-mcp-server-datacenter
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
The server reads configuration from environment variables:
|
|
94
|
+
|
|
95
|
+
| Variable | Required | Description |
|
|
96
|
+
| ---------------------- | -------- | ---------------------------------------------------------- |
|
|
97
|
+
| `BITBUCKET_BASE_URL` | yes | Base URL, e.g. `https://bitbucket-stage.telekom-mms.com` |
|
|
98
|
+
| `BITBUCKET_TOKEN` | \* | HTTP access token, sent as `Authorization: Bearer <token>` |
|
|
99
|
+
| `BITBUCKET_USERNAME` | \* | Username for Basic auth (used together with a secret) |
|
|
100
|
+
| `BITBUCKET_PASSWORD` | \* | Password / API token for Basic auth |
|
|
101
|
+
| `BITBUCKET_CA_BUNDLE` | no | Path to a CA bundle to trust an internal/private CA |
|
|
102
|
+
| `ENABLE_TOOLS` | no | Which tools to expose (see [Tool enablement](#tool-enablement)). Empty = read-only. |
|
|
103
|
+
|
|
104
|
+
\* Provide **either** `BITBUCKET_TOKEN` **or** `BITBUCKET_USERNAME` +
|
|
105
|
+
`BITBUCKET_PASSWORD`. When a username and secret are both set, Basic auth is
|
|
106
|
+
used; otherwise the token is sent as a Bearer header.
|
|
107
|
+
|
|
108
|
+
> **TLS is always verified.** Verification is enforced and cannot be turned
|
|
109
|
+
> off (PSA *Web Services* 3.02 Req 18 / *Cryptographic Algorithms* 3.50
|
|
110
|
+
> Req 43). Any attempt to disable it via `BITBUCKET_VERIFY_SSL` is ignored and
|
|
111
|
+
> logged as a warning. To trust an internal certificate authority, set
|
|
112
|
+
> `BITBUCKET_CA_BUNDLE` to its CA bundle path instead of disabling verification.
|
|
113
|
+
|
|
114
|
+
## Token lifecycle
|
|
115
|
+
|
|
116
|
+
The Bitbucket HTTP access token is the only long-lived secret used by this
|
|
117
|
+
server. Handle it as a technical-account credential:
|
|
118
|
+
|
|
119
|
+
- **Provisioning** — create a personal **HTTP access token** in Bitbucket Data
|
|
120
|
+
Center (*Manage account → HTTP access tokens*) with the **minimum scope**
|
|
121
|
+
needed (read-only unless write tools are enabled). Match the token scope to
|
|
122
|
+
`ENABLE_TOOLS`.
|
|
123
|
+
- **Storage** — never commit the token. In VS Code it is supplied through the
|
|
124
|
+
`bitbucket_token` prompt input (`password: true`) and passed via the
|
|
125
|
+
`BITBUCKET_TOKEN` environment variable only. Keep it out of logs and shell
|
|
126
|
+
history.
|
|
127
|
+
- **Transport** — the token is sent only over TLS in the `Authorization`
|
|
128
|
+
header, never in a URL (PSA *Web Services* 3.02 Req 21).
|
|
129
|
+
- **Rotation** — rotate regularly (at least every 12 months, sooner for
|
|
130
|
+
technical accounts) and immediately if it may have been exposed. Create the
|
|
131
|
+
new token, update the secret, then revoke the old one.
|
|
132
|
+
- **Revocation** — revoke the token in Bitbucket as soon as it is no longer
|
|
133
|
+
needed or on suspected compromise; revocation takes effect immediately.
|
|
134
|
+
|
|
135
|
+
> If a token ever appears in plain text (chat, logs, screen sharing), treat it
|
|
136
|
+
> as compromised and rotate it right away.
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
## Tool enablement
|
|
140
|
+
|
|
141
|
+
Tools must be **explicitly enabled**. `ENABLE_TOOLS` is a comma-separated list
|
|
142
|
+
of group names and/or individual tool names (case-insensitive):
|
|
143
|
+
|
|
144
|
+
| Token | Effect |
|
|
145
|
+
| ----------- | ------------------------------------------------------- |
|
|
146
|
+
| `read` | Enable all read-only tools |
|
|
147
|
+
| `write` | Enable all write/content tools |
|
|
148
|
+
| `all` | Enable every non-blocked tool |
|
|
149
|
+
| `<name>` | Enable a single tool, e.g. `create_pull_request` |
|
|
150
|
+
| `none`/`off`| Enable nothing |
|
|
151
|
+
|
|
152
|
+
- If `ENABLE_TOOLS` is **unset or empty**, only the **read-only** group is
|
|
153
|
+
enabled, so the server is safe by default.
|
|
154
|
+
- Unknown tool names are ignored.
|
|
155
|
+
- Examples:
|
|
156
|
+
- `ENABLE_TOOLS=read` — read-only (default).
|
|
157
|
+
- `ENABLE_TOOLS=read,create_pull_request,add_pull_request_comment` — reads plus PR authoring.
|
|
158
|
+
- `ENABLE_TOOLS=all` — everything except blocked tools.
|
|
159
|
+
|
|
160
|
+
The set of enabled tools is logged to stderr on startup.
|
|
161
|
+
|
|
162
|
+
### Permanently blocked tools
|
|
163
|
+
|
|
164
|
+
Destructive, repository/project-wide operations are intentionally **not
|
|
165
|
+
implemented** and cannot be enabled even with `all`:
|
|
166
|
+
|
|
167
|
+
- `delete_repository`
|
|
168
|
+
- `delete_project`
|
|
169
|
+
- `fork_repository`
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
## Run in VS Code
|
|
173
|
+
|
|
174
|
+
The workspace ships a `.vscode/mcp.json`. The base URL and `ENABLE_TOOLS` are
|
|
175
|
+
set directly in the server's `env`; only the access token is requested as a
|
|
176
|
+
masked input on startup and is never written to the file. Adjust
|
|
177
|
+
`ENABLE_TOOLS` in `.vscode/mcp.json` to change which tools are exposed.
|
|
178
|
+
|
|
179
|
+
## Run / smoke test from the CLI
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
uv sync
|
|
183
|
+
BITBUCKET_BASE_URL="https://bitbucket-stage.telekom-mms.com" \
|
|
184
|
+
BITBUCKET_TOKEN="<your-token>" \
|
|
185
|
+
ENABLE_TOOLS="read" \
|
|
186
|
+
uv run bitbucket-mcp-server-datacenter
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Publishing (maintainers)
|
|
190
|
+
|
|
191
|
+
The package ships a console entry point
|
|
192
|
+
(`bitbucket-mcp-server-datacenter`) and builds with `hatchling`, so consumers
|
|
193
|
+
can run it with `uvx` without cloning (see
|
|
194
|
+
[Install / use without cloning](#install--use-without-cloning)).
|
|
195
|
+
|
|
196
|
+
Build and inspect the distributions locally:
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
uv build
|
|
200
|
+
tar -tzf dist/*.tar.gz # sanity-check the sdist contents (no secrets)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Manual upload.** Authenticate with a PyPI API token and publish:
|
|
204
|
+
|
|
205
|
+
```sh
|
|
206
|
+
# optional dry run against TestPyPI first
|
|
207
|
+
uv publish --publish-url https://test.pypi.org/legacy/
|
|
208
|
+
|
|
209
|
+
# production
|
|
210
|
+
uv publish
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Automated release (recommended).** The
|
|
214
|
+
[`.github/workflows/release.yml`](.github/workflows/release.yml) workflow runs
|
|
215
|
+
the tests, builds the distributions, and publishes to PyPI via
|
|
216
|
+
[Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC, no stored
|
|
217
|
+
token) whenever a `v*` tag is pushed. Configure a trusted publisher for this
|
|
218
|
+
repository/workflow on PyPI once, then cut a release:
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
git tag v0.1.0
|
|
222
|
+
git push origin v0.1.0
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Tools
|
|
226
|
+
|
|
227
|
+
All tools below are gated by [`ENABLE_TOOLS`](#tool-enablement). The
|
|
228
|
+
**Category** column controls which group (`read` / `write`) enables a tool.
|
|
229
|
+
|
|
230
|
+
### Read tools (category `read`)
|
|
231
|
+
|
|
232
|
+
| Tool | Description |
|
|
233
|
+
| ----------------------------- | ----------------------------------------------------------------- |
|
|
234
|
+
| `get_current_user` | Verify auth/connectivity; returns the user and server version. |
|
|
235
|
+
| `list_projects` | List projects visible to the user (optional name filter). |
|
|
236
|
+
| `list_repositories` | List repositories in a project (`~username` for personal). |
|
|
237
|
+
| `get_repository` | Get details for a single repository. |
|
|
238
|
+
| `list_branches` | List branches (optional text filter). |
|
|
239
|
+
| `list_commits` | List commits, optionally from a branch/tag/commit ref. |
|
|
240
|
+
| `get_file_content` | Return raw text content of a file at an optional ref. |
|
|
241
|
+
| `browse_files` | List files/directories at a path (tree browsing). |
|
|
242
|
+
| `list_pull_requests` | List PRs by state (`OPEN`/`DECLINED`/`MERGED`/`ALL`). |
|
|
243
|
+
| `get_pull_request` | Get a single PR, including its current `version`. |
|
|
244
|
+
| `get_pull_request_diff` | Get the unified diff for a PR. |
|
|
245
|
+
| `get_pull_request_activities` | List PR activity (comments, approvals, updates). |
|
|
246
|
+
|
|
247
|
+
### Write / content tools (category `write`)
|
|
248
|
+
|
|
249
|
+
| Tool | Description |
|
|
250
|
+
| -------------------------- | -------------------------------------------------------------------- |
|
|
251
|
+
| `put_file` | Create/update a file via a commit; seeds the default branch if empty.|
|
|
252
|
+
| `create_branch` | Create a branch from a start point. |
|
|
253
|
+
| `create_pull_request` | Create a PR between two branches in the same repo. |
|
|
254
|
+
| `add_pull_request_comment` | Add a general comment to a PR. |
|
|
255
|
+
| `merge_pull_request` | Merge a PR (requires current PR `version`). |
|
|
256
|
+
| `decline_pull_request` | Decline a PR (requires current PR `version`). |
|
|
257
|
+
| `delete_branch` | Delete a branch (branch-utils API); useful for cleanup. |
|
|
258
|
+
|
|
259
|
+
### Notes specific to Bitbucket Data Center
|
|
260
|
+
|
|
261
|
+
- Personal repositories use the project key `~username` (e.g. `~sbwo`).
|
|
262
|
+
- `put_file` uses the `browse` endpoint, which requires `multipart/form-data`.
|
|
263
|
+
- `merge_pull_request` / `decline_pull_request` require the current PR
|
|
264
|
+
`version` (obtain it via `get_pull_request`) for optimistic locking.
|
|
265
|
+
- `delete_branch` uses the `branch-utils` API (`/rest/branch-utils/1.0/...`).
|
|
266
|
+
|
|
267
|
+
## Tests
|
|
268
|
+
|
|
269
|
+
Offline unit tests (no network; httpx `MockTransport`) cover three layers:
|
|
270
|
+
|
|
271
|
+
- **Client** (`test_client.py`): auth header selection, key/URL encoding,
|
|
272
|
+
paging, error extraction, multipart upload, and `whoami`.
|
|
273
|
+
- **Tool enablement** (`test_enablement.py`): `ENABLE_TOOLS` resolution,
|
|
274
|
+
blocked-tool enforcement, TLS enforcement, registry composition, and
|
|
275
|
+
`register_enabled_tools`.
|
|
276
|
+
- **Server tools** (`test_server_tools.py`): request paths and payloads built
|
|
277
|
+
by the tools (`refs/heads/` refs, `create_branch`, merge/decline `version`
|
|
278
|
+
param, and the `branch-utils` `delete_branch` path).
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
uv sync
|
|
282
|
+
uv run pytest -q
|
|
283
|
+
```
|
|
284
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# PSA security review — bitbucket-mcp-server-datacenter
|
|
2
|
+
|
|
3
|
+
This document records the PSA (Privacy & Security Assessment) review of the
|
|
4
|
+
Bitbucket Data Center MCP server. There is **no MCP-specific PSA**; this review
|
|
5
|
+
maps the generic, applicable PSA requirement documents to the server's design.
|
|
6
|
+
|
|
7
|
+
- **Scope:** Python MCP server acting as a REST **consumer** of a Bitbucket
|
|
8
|
+
Data Center instance over HTTPS, using an HTTP access token, run locally via
|
|
9
|
+
stdio (VS Code MCP).
|
|
10
|
+
- **Date:** 2026-06-04
|
|
11
|
+
- **Source:** Telekom PSA requirement documents (`telecontext` MCP server).
|
|
12
|
+
|
|
13
|
+
## Method
|
|
14
|
+
|
|
15
|
+
1. Listed all PSA subject areas and requirement documents.
|
|
16
|
+
2. Selected the requirement documents applicable to a token-authenticated REST
|
|
17
|
+
client/server over TLS (no MCP-specific document exists).
|
|
18
|
+
3. Reviewed the individual requirements of each selected document against the
|
|
19
|
+
implementation and recorded status + evidence.
|
|
20
|
+
|
|
21
|
+
## Applicable requirement documents
|
|
22
|
+
|
|
23
|
+
| PSA document | ID | Relevance |
|
|
24
|
+
| ----------------------------------------------- | ------ | ---------------------------------------------------------- |
|
|
25
|
+
| Web Services | 3.02 | Highest — REST consumer/provider, token auth, TLS, input validation |
|
|
26
|
+
| Cryptographic Algorithms and Security Protocols | 3.50 | TLS parameters for the Bitbucket connection |
|
|
27
|
+
| Technical Baseline Security for IT/NT Systems | 3.01 | Generic baseline (trusted software, hardening, logging) |
|
|
28
|
+
| IAM | 3.69 | Token usage, least privilege, technical accounts |
|
|
29
|
+
|
|
30
|
+
## Findings
|
|
31
|
+
|
|
32
|
+
Legend: ✅ met · ⚠️ conditional / configuration-dependent · 🔶 open / out of scope for the tool
|
|
33
|
+
|
|
34
|
+
### Web Services (3.02)
|
|
35
|
+
|
|
36
|
+
| Req | Topic | Status | Evidence |
|
|
37
|
+
| --- | ----- | ------ | -------- |
|
|
38
|
+
| Req 2 | Software from trusted sources, integrity-checked | ⚠️ | Dependencies pinned via `uv`/lockfile; verify lockfile hashes in CI |
|
|
39
|
+
| Req 10 | Auth based on strong cryptography | ✅ | Bearer token over TLS |
|
|
40
|
+
| Req 12/13 | Validate requests/responses against a spec | ✅/⚠️ | FastMCP argument schemas validate inputs; response validation partial |
|
|
41
|
+
| Req 15–18 | TLS 1.2/1.3, PFS ciphers, certificate validation | ✅ | httpx/OpenSSL defaults; **TLS verification now enforced in code** |
|
|
42
|
+
| Req 21 | No confidential data in the URL | ✅ | Token sent in `Authorization` header, never in URL |
|
|
43
|
+
| Req 22 | Validate content types | ✅ | `put_file` uses multipart/form-data; JSON elsewhere |
|
|
44
|
+
| Req 33–37 | Time-stamped logging, forwarding to log server / SIEM | 🔶 | Only stderr logging; central/SIEM logging is a deployment concern |
|
|
45
|
+
|
|
46
|
+
### Cryptographic Algorithms and Security Protocols (3.50)
|
|
47
|
+
|
|
48
|
+
| Req | Topic | Status | Evidence |
|
|
49
|
+
| --- | ----- | ------ | -------- |
|
|
50
|
+
| Req 40 | TLS 1.2 or 1.3 | ✅ | Provided by httpx/OpenSSL |
|
|
51
|
+
| Req 41/42 | PFS cipher suites, DH groups | ✅ | Modern OpenSSL defaults |
|
|
52
|
+
| Req 43 | Certificates from a CA, correctly validated | ✅ | **Verification enforced**; internal CAs via `BITBUCKET_CA_BUNDLE` |
|
|
53
|
+
|
|
54
|
+
### Technical Baseline Security (3.01)
|
|
55
|
+
|
|
56
|
+
| Req | Topic | Status | Evidence |
|
|
57
|
+
| --- | ----- | ------ | -------- |
|
|
58
|
+
| Req 9 | Outputs must not disclose internal structures/secrets | ✅ | `_extract_error` returns only `errors[].message`; token kept out of errors |
|
|
59
|
+
| Req 14/15 | Protect data needing protection at rest / in transit | ✅ | Token via VS Code `password` input + env; transport over TLS only |
|
|
60
|
+
| Req 23 | Least privilege | ✅ | `ENABLE_TOOLS` gating; destructive tools permanently blocked |
|
|
61
|
+
| Req 33–37 | Security logging, forwarding, retention | 🔶 | Only stderr logging (see Web Services 33–37) |
|
|
62
|
+
|
|
63
|
+
### IAM (3.69)
|
|
64
|
+
|
|
65
|
+
| Req | Topic | Status | Evidence |
|
|
66
|
+
| --- | ----- | ------ | -------- |
|
|
67
|
+
| Req 17 | Least privilege | ✅ | Default `ENABLE_TOOLS=read` |
|
|
68
|
+
| Req 22 | Use tokens only per the defined standard | ✅ | Bitbucket HTTP access token in Bearer header |
|
|
69
|
+
| Req 35 | Technical-account secrets ≥ 30 chars | ✅ | Bitbucket HTTP access token satisfies this |
|
|
70
|
+
| Req 42/43 | Time-limited assignment / automatic rotation | 🔶 | No rotation in the tool; see Token lifecycle in `README.md` |
|
|
71
|
+
|
|
72
|
+
## Result
|
|
73
|
+
|
|
74
|
+
- **Well covered:** TLS with enforced certificate validation, token in header
|
|
75
|
+
(never in URL), least-privilege tool gating, permanently blocked destructive
|
|
76
|
+
tools, secret handling via the VS Code input.
|
|
77
|
+
- **Resolved in this review:** TLS verification is now **enforced in code** and
|
|
78
|
+
can no longer be disabled (Web Services 3.02 Req 18 / Cryptographic
|
|
79
|
+
Algorithms 3.50 Req 43). Internal CAs are supported via `BITBUCKET_CA_BUNDLE`.
|
|
80
|
+
- **Documented:** Token lifecycle (provisioning, storage, transport, rotation,
|
|
81
|
+
revocation) added to `README.md`.
|
|
82
|
+
|
|
83
|
+
### Open points for a production deployment
|
|
84
|
+
|
|
85
|
+
1. **Central/SIEM logging** (3.02 Req 33–37, 3.01 Req 33–37): the tool only logs
|
|
86
|
+
to stderr; near-real-time forwarding to a log server / SIEM is a deployment
|
|
87
|
+
responsibility.
|
|
88
|
+
2. **Dependency integrity in CI** (3.02 Req 2): enforce lockfile hash
|
|
89
|
+
verification in the build pipeline.
|
|
90
|
+
3. **Token rotation** (IAM 3.69 Req 42/43): rotation/expiry is operational; see
|
|
91
|
+
the Token lifecycle section in `README.md`.
|