v2.30.0

Bitbucket Data Center / Server

First-class integration with self-hosted enterprise Bitbucket โ€” see and act on pull requests, branches, builds, and repository administration from inside C3.

v2.30.0 SCM integration Read & write REST API 1.0 OS keyring

Overview

C3 ships with c3_bitbucket โ€” a single MCP tool that lets Claude Code (and the human, via the Hub UI) read and act on a self-hosted Bitbucket Data Center / Server instance. There is no separate browser context-switch: PRs, diffs, builds, branches, comments, approvals, and merges are all accessible inside the C3 workflow.

Scope: Bitbucket Data Center / Server only (the on-prem enterprise product, REST API /rest/api/1.0, Bearer-token auth via Personal Access Tokens). Bitbucket Cloud (bitbucket.org) is not currently supported โ€” its API path, auth model, and pagination differ.

What you get

SurfaceWhereUse it for
c3_bitbucket MCP tool Claude Code Action-dispatched Bitbucket operations from inside an AI session
c3 bitbucket CLI Terminal One-time login, account switching, default-repo pinning
Bitbucket tab Hub UI (per-project) Visual PR / branch / activity / admin browsing
/api/bitbucket/* Project server REST endpoints proxying to the Bitbucket REST client

Quick start

Three commands to wire up an enterprise Bitbucket server and pin a working repo.

1

Log in

c3 bitbucket login \
  --url https://bitbucket.example.com

Prompts for username and Personal Access Token (PAT). The PAT goes straight into the OS keyring; .c3/config.json only records the username + URL pair.

2

Pin defaults

c3 bitbucket set-default \
  --project PROJ \
  --repo my-service

Lets c3_bitbucket calls skip project= and repo= arguments โ€” the configured defaults are used automatically.

3

Verify

c3 bitbucket status

Lists active account + accounts list, runs an application-properties probe to confirm the PAT works.

First call from Claude Code

# Whoami
c3_bitbucket(action='whoami')

# Open PRs in the pinned repo
c3_bitbucket(action='list_prs', state='OPEN')

# Detail of a specific PR
c3_bitbucket(action='get_pr', pr_id=42)

Authentication & security

Personal Access Tokens

C3 uses Bitbucket Data Center Personal Access Tokens (Bearer auth). Generate one in your Bitbucket profile under Manage account โ†’ Personal access tokens. Choose a permission level matching what you intend to do:

PermissionWhat c3_bitbucket can do
REPO_READ Browse projects, repos, PRs, diffs, branches, builds, activity
REPO_WRITE + Create / comment / approve / decline / merge PRs ยท create / delete branches
REPO_ADMIN + Update repo settings ยท webhooks ยท permissions
PROJECT_* Equivalent permissions but scoped to a whole project key

Where the token lives

OS keyring Token text, under service c3-bitbucket, account {base_url}|{username}. Backed by Windows Credential Manager, macOS Keychain, or Linux Secret Service.
.c3/config.json Non-secret bitbucket section: list of known accounts, active-account pointer, default project + repo, TLS-verify flag. Never contains the token.

Why both? The OS keyring has no portable list API on every backend, so C3 also keeps a non-secret accounts index in .c3/config.json. This makes c3 bitbucket status able to show all configured accounts without prompting the keyring per-entry. Tokens themselves only flow through the keyring.

TLS verification

Default: verify_tls = true. To disable verification for self-signed enterprise CAs, pass --insecure on c3 bitbucket login, or flip bitbucket.verify_tls to false in .c3/config.json.

Use with care. Disabling TLS verification means a network-positioned attacker could steal your PAT. Only set it when the server certificate is signed by an internal CA you trust, and prefer importing the CA into the system trust store.

Multiple servers / accounts

save_credentials appends each (base_url, username) pair to the accounts index. Switch with c3 bitbucket use --url ... --username .... The active account is what every c3_bitbucket call resolves to.


Action reference

The MCP tool dispatches by action. Twenty-seven actions are grouped below by capability. Project + repo default from bitbucket.default_project / default_repo when not provided.

Read & discovery

ActionArgsDescription
status โ€” Active account, accounts list, defaults, server-version probe. Works without a valid token (returns connection: FAIL in that case)
whoami โ€” Authenticated user (PAT owner)
list_projectsname? All projects visible to the PAT, optionally filtered by name
list_repos project Repos under a project key
get_repo project, repoRepo metadata โ€” name, scmId, public flag, clone URLs
list_prs project, repo, state?, author?, reviewer?, limit?Pull requests โ€” default state=OPEN; supports MERGED, DECLINED, ALL
get_pr project, repo, pr_idFull PR detail incl. version, reviewers, description, open-tasks
get_pr_diff project, repo, pr_id, context_lines?Unified diff (truncated to 6000 chars in the response)
get_pr_activitiesproject, repo, pr_idPR event timeline (comments, approvals, reviewer changes)
list_branchesproject, repo, filter?Branches with ahead/behind counts and default-branch flag
list_commits project, repo, branch?, path?, limit?Commit log on a branch / path
list_activityproject, repo, limit?Repo activity feed (commit-based)
build_status commit? CI build statuses for a commit. If commit is omitted, the default branch's HEAD is used.

Pull-request writes

ActionArgsDescription
create_pr title, from_branch, to_branch, description?, reviewers?Open a new PR. reviewers may be a list or comma-separated string.
comment_pr pr_id, body Add a top-level comment
approve_pr pr_id Mark the PR approved as the current user
unapprove_prpr_id Withdraw approval
decline_pr pr_id Decline the PR. Auto-fetches the current PR version first.
merge_pr pr_id, message? Merge the PR. Auto-fetches the current PR version first; logs to the C3 edit ledger.

Branch writes

ActionArgsDescription
create_branchname, start_point, message?Create a branch from a ref. Goes through the /rest/branch-utils/1.0 API.
delete_branchname, dry_run? Delete a branch. Logs to the edit ledger.

Repository administration

ActionArgsDescription
repo_settings project, repo Read repo settings (currently the same as get_repo)
update_repo_settings project, repo, settingsPUT updated settings JSON to the repo. settings may be a dict or JSON string.
list_webhooks project, repo All webhooks on the repo
create_webhook name, url, events, active?, secret?Create a webhook. events is a list or comma-separated string (e.g. repo:refs_changed,pr:opened).
delete_webhook webhook_id Remove a webhook
list_permissions project, repo User and group permission grants on the repo

Argument fall-back. Any action in the table whose row says it needs project, repo will fall back to bitbucket.default_project and bitbucket.default_repo from .c3/config.json when the call omits them. Use c3 bitbucket set-default to pin them.


CLI commands

Five subcommands cover account lifecycle and repo defaults. Run any with --help for full flags.

CommandDescription
c3 bitbucket login --url <URL> [--username <U>] [--token <T>] [--insecure]Interactive PAT prompt (getpass masked). Writes to keyring, appends to accounts index, sets active. Runs a connection probe.
c3 bitbucket logout [--url <URL>] [--username <U>] Removes from keyring and accounts index. Falls back to the active account when args are omitted.
c3 bitbucket status Lists accounts, marks the active one, runs an application-properties probe.
c3 bitbucket use --url <URL> --username <U> Switch active account (no token re-entry needed if the keyring already has it).
c3 bitbucket set-default --project <K> --repo <R> Pin the project key + repo slug used by c3_bitbucket calls when args are omitted.

Hub UI tab

The per-project Hub UI gains a Bitbucket tab in its sidebar (between Edits and Instructions). Five sub-views:

Sub-viewShows
Overview Active account ยท default project + repo ยท server version & connection state ยท all configured accounts
Pull Requests State filter (OPEN / MERGED / DECLINED / ALL) ยท PR list with state badge ยท click-through detail JSON
Branches Branch list with latest commit hash and default-branch marker
Activity Recent commit feed
Admin Webhooks (id, active, name โ†’ URL, events) ยท user / group permission grants

Endpoints powering the tab live in cli/server.py under /api/bitbucket/*. The Hub server (port 3330) does not host these โ€” Bitbucket is per-project, so the API runs inside each project's session-server (default port 3333).


Audit trail โ€” Edit ledger integration

State changes that happen on the platform side (not in your local working tree) are still appended to the C3 edit ledger so the audit trail is complete. The path for these entries is virtual:

bitbucket://<project>/<repo>

The following actions log to the ledger when they succeed:

ActionWhy it's logged
create_pr New PR opened โ€” relevant for review timeline
comment_pr Discussion contribution worth recovering on / clear
approve_pr / unapprove_prReviewer state changes
decline_pr PR closed without merge
merge_pr Code now lives in the target branch โ€” high-impact
create_branch / delete_branchBranch topology changed
update_repo_settings Repo-level config drift
create_webhook / delete_webhookIntegration footprint changed

Read-only actions and the status probe are not logged. Token text is stripped from logged kwargs before persisting.


.c3/config.json โ€” bitbucket section

Default shape (gets created on first c3 bitbucket login):

{
  "bitbucket": {
    "active": { "base_url": "https://bitbucket.example.com", "username": "alice" },
    "accounts": [
      { "base_url": "https://bitbucket.example.com", "username": "alice" }
    ],
    "default_project": "PROJ",
    "default_repo": "my-service",
    "verify_tls": true
  }
}
active Pointer to the account whose token will be loaded for every c3_bitbucket call.
accounts Non-secret index of all known (base_url, username) pairs.
default_project Project key used when an action call omits project=.
default_repo Repo slug used when an action call omits repo=.
verify_tls Set to false for self-signed enterprise certificates. Prefer fixing the trust chain at the OS level instead.

.c3/ is gitignored by default. Even so, never write a token under this section by hand. The keyring is the authoritative store; this file is just the index.


Example workflows

Review and merge a PR

# 1. See what's open
c3_bitbucket(action='list_prs', state='OPEN')

# 2. Drill into one
c3_bitbucket(action='get_pr', pr_id=42)
c3_bitbucket(action='get_pr_diff', pr_id=42)

# 3. Comment with review notes
c3_bitbucket(action='comment_pr', pr_id=42,
             body='LGTM modulo the test in test_x.py:42')

# 4. Approve, then merge โ€” version is fetched automatically
c3_bitbucket(action='approve_pr', pr_id=42)
c3_bitbucket(action='merge_pr', pr_id=42,
             message='Merge feat/bitbucket โ€” release v2.30.0')

Open a PR for the current branch

# Push the branch first via c3_shell (auto-logs to ledger)
c3_shell(cmd='git push -u origin feat/bitbucket')

# Then open the PR
c3_bitbucket(action='create_pr',
             title='feat: Bitbucket Data Center integration (v2.30.0)',
             from_branch='feat/bitbucket',
             to_branch='main',
             description='See CHANGELOG [2.30.0] for details.',
             reviewers='alice,bob')

Cut a feature branch via the API

c3_bitbucket(action='create_branch',
             name='feat/oauth-fix',
             start_point='refs/heads/main')

Check CI status before merging

# Latest commit on the PR's source branch
pr = c3_bitbucket(action='get_pr', pr_id=42)
# (in agent code) โ†’ fromRef.latestCommit
c3_bitbucket(action='build_status', commit='<sha>')

Inventory webhooks before changing CI

c3_bitbucket(action='list_webhooks')
c3_bitbucket(action='create_webhook',
             name='jenkins',
             url='https://ci.example.com/hooks/bitbucket',
             events='repo:refs_changed,pr:opened,pr:merged',
             active=true,
             secret='shared-with-jenkins')

Troubleshooting

SymptomCause & fix
[bitbucket:no-account] Active account isn't set in .c3/config.json. Run c3 bitbucket login --url <URL> or c3 bitbucket use --url ... --username ... if the token is already stored.
[bitbucket:no-token] Account is in the index but the keyring entry is missing (e.g. .c3/ was copied to a different machine). Re-run c3 bitbucket login --url ... --username ... to put the PAT back into the keyring.
HTTP 401 on a fresh PAT The PAT was issued for a different Bitbucket server, or the project / repo permission isn't on the token. Generate a new token with at least REPO_READ.
HTTP 403 on PR write The token has REPO_READ but the action needs REPO_WRITE. Re-issue with the right level.
HTTP 409 on merge_pr / decline_pr PR version is stale (somebody else updated it). The handler auto-fetches the current version on each call, so simply retrying the same MCP action usually succeeds.
SSL: CERTIFICATE_VERIFY_FAILED Self-signed enterprise CA. Either import the CA into the OS trust store (preferred), or set bitbucket.verify_tls = false in .c3/config.json.
Connection probe times out Server is reachable from the browser but blocked at the OS firewall (e.g. corporate proxy). Set HTTPS_PROXY in your environment โ€” urllib picks it up automatically.
The 'keyring' package is required pip install keyring โ€” added as a dependency in v2.30.0 but missing if you upgraded without re-installing.

Where to look

  • Activity log: Hub UI โ†’ Bitbucket tab โ†’ Overview, plus .c3/activity_log.jsonl for raw events tagged bitbucket_action.
  • Edit ledger: c3_edits(action='history', file='bitbucket://<project>/<repo>') for all platform-side mutations.
  • Tool calls: c3_session(action='log') entries record every c3_bitbucket dispatch with action name and (sanitized) args.

Need to add an action this surface doesn't cover? File an issue or pull request โ€” the integration is intentionally thin around the Bitbucket REST 1.0 API in services/bitbucket_client.py.