A Model Context Protocol (MCP) server that provides a wrapper for Bitbucket Cloud REST API, enabling Pull Request operations through AI-powered tools. Built with Microsoft Kiota for type-safe API client generation.
- MCP Protocol Support: Full implementation of Model Context Protocol with two transport options:
- HTTP/SSE transport (Streamable HTTP) - for web-based clients
- Stdio transport - for process-based integration (e.g., Claude Desktop)
- Bitbucket App Password Authentication: Secure authentication using Bitbucket app passwords
- Docker Support: Ready-to-use Docker containers for both transport modes
- Modern .NET: Built on .NET 10 with flexible transport configuration
- Docker (for containerized deployment) OR
- .NET 10 SDK (for local development)
- Bitbucket Cloud account
- Bitbucket app password (with pull request and repository read permissions)
The stdio transport is now the default (tagged as latest), optimized for Claude Desktop and process-based integrations.
Run with Docker:
docker run -i \
-e BITBUCKET_USERNAME="your-username" \
-e BITBUCKET_APP_PASSWORD="your-app-password" \
-e BITBUCKET_WORKSPACE="your-workspace" \
ghcr.io/kubis1982/bitbucketmcp:latestClaude Desktop configuration:
{
"mcpServers": {
"bitbucket": {
"command": "docker",
"args": [
"run", "-i",
"-e", "BITBUCKET_USERNAME=your-username",
"-e", "BITBUCKET_APP_PASSWORD=your-app-password",
"-e", "BITBUCKET_WORKSPACE=your-workspace",
"ghcr.io/kubis1982/bitbucketmcp:latest"
]
}
}
}For HTTP/SSE-based clients, use the -http tagged images:
-
Clone the repository:
git clone https://github.com/kubis1982/BitbucketMCP.git cd BitbucketMCP -
Configure authentication in
docker-compose.yml:For app password authentication:
environment: ASPNETCORE_URLS: "http://+:8080" BITBUCKET_USERNAME: "your-username" BITBUCKET_APP_PASSWORD: "your-app-password" BITBUCKET_WORKSPACE: "your-workspace"
-
Run the HTTP server:
docker-compose up -d bitbucket-http
Or pull and run directly:
docker run -d -p 8080:8080 \ -e ASPNETCORE_URLS="http://+:8080" \ -e BITBUCKET_USERNAME="your-username" \ -e BITBUCKET_APP_PASSWORD="your-app-password" \ -e BITBUCKET_WORKSPACE="your-workspace" \ ghcr.io/kubis1982/bitbucketmcp:http-latest
The server will be available at: http://localhost:8080
-
Test the connection:
# Test with MCP-compatible client (requires Accept: text/event-stream header) curl -H "Accept: text/event-stream" http://localhost:8080/
-
Restore dependencies:
dotnet restore
-
Set environment variables:
# Windows (PowerShell) $env:ASPNETCORE_URLS="http://localhost:5000" $env:BITBUCKET_USERNAME="your-username" $env:BITBUCKET_APP_PASSWORD="your-app-password" $env:BITBUCKET_WORKSPACE="your-workspace" # Linux/Mac export ASPNETCORE_URLS=http://localhost:5000 export BITBUCKET_USERNAME=your-username export BITBUCKET_APP_PASSWORD=your-app-password export BITBUCKET_WORKSPACE=your-workspace
-
Run the server:
dotnet run --project src/BitbucketMCP -- --transport=http
The server will be available at: http://localhost:5000
# Set environment variables (same as above)
dotnet run --project src/BitbucketMCP -- --transport=stdioThis runs the server in stdio mode, communicating via standard input/output.
The server supports two MCP transport modes, controlled via the --transport argument:
--transport=http(default): HTTP/SSE transport for web-based clients--transport=stdio: Standard input/output transport for process-based integration
Examples:
# HTTP transport
dotnet run --project src/BitbucketMCP -- --transport=http
# Stdio transport
dotnet run --project src/BitbucketMCP -- --transport=stdio| Variable | Required | Description |
|---|---|---|
ASPNETCORE_URLS |
No* | Server listening URL (default: http://localhost:5000, Docker: http://+:8080). *Only used for HTTP transport |
BITBUCKET_USERNAME |
Yes | Bitbucket username for authentication |
BITBUCKET_APP_PASSWORD |
Yes | Bitbucket app password |
BITBUCKET_WORKSPACE |
Yes | Workspace for operations |
ASPNETCORE_LOGGING__LOGLEVEL__DEFAULT |
No | Logging level (Trace, Debug, Information, Warning, Error) |
The server supports two transport modes:
The server uses HTTP/SSE (Server-Sent Events) transport, implementing the Model Context Protocol's Streamable HTTP specification.
Connection Details:
- Local Development:
http://localhost:5000 - Docker Deployment:
http://localhost:8080 - Protocol: MCP over HTTP with Server-Sent Events
- Required Headers:
Accept: text/event-stream
Example MCP Client Configuration (Claude Desktop with HTTP):
{
"mcpServers": {
"bitbucket": {
"url": "http://localhost:8080/",
"transport": {
"type": "http"
}
}
}
}Testing the endpoint:
# The server expects MCP protocol headers
curl -H "Accept: text/event-stream" http://localhost:8080/
# For full MCP communication, use an MCP-compatible clientThe server can also run in stdio mode, where it communicates via standard input/output streams. This is ideal for process-based integration with MCP clients like Claude Desktop.
Example MCP Client Configuration (Claude Desktop with Stdio):
{
"mcpServers": {
"bitbucket": {
"command": "docker",
"args": [
"run", "-i",
"-e", "BITBUCKET_USERNAME=your-username",
"-e", "BITBUCKET_APP_PASSWORD=your-app-password",
"-e", "BITBUCKET_WORKSPACE=your-workspace",
"ghcr.io/kubis1982/bitbucketmcp:latest"
]
}
}
}Or with local dotnet:
{
"mcpServers": {
"bitbucket": {
"command": "dotnet",
"args": [
"run",
"--project", "/path/to/BitbucketMCP/src/BitbucketMCP",
"--", "--transport=stdio"
],
"env": {
"BITBUCKET_USERNAME": "your-username",
"BITBUCKET_APP_PASSWORD": "your-app-password",
"BITBUCKET_WORKSPACE": "your-workspace"
}
}
}
}- Go to Bitbucket Settings → Personal settings → App passwords
- Click "Create app password"
- Grant required permissions:
- Pull requests: Read, Write
- Repositories: Read
- Copy the generated password (shown only once)
- Use your Bitbucket username and the app password
The server exposes the following MCP tools:
Creates a new pull request in a Bitbucket repository.
Parameters:
repo(required): Repository slugtitle(required): PR titledescription(optional): PR descriptionsourceBranch(required): Source branch namedestinationBranch(required): Destination branch namereviewers(optional): Array of reviewer account UUIDs in format{account-id}isDraft(optional): Create as draft PR (default: false)
Example:
{
"repo": "myrepo",
"title": "Add new feature",
"description": "This PR adds amazing new features",
"sourceBranch": "feature/new-feature",
"destinationBranch": "main",
"reviewers": ["{user-uuid-1}", "{user-uuid-2}"],
"isDraft": false
}Updates an existing pull request.
Parameters:
repo(required): Repository slugprId(required): PR ID numbertitle(optional): New PR titledescription(optional): New PR descriptionreviewers(optional): Updated array of reviewer account UUIDsisDraft(optional): Change draft status
Example:
{
"repo": "myrepo",
"prId": 123,
"title": "Updated title",
"description": "Updated description"
}Retrieves details of a pull request.
Parameters:
repo(required): Repository slugprId(required): PR ID number
Example:
{
"repo": "myrepo",
"prId": 123
}Lists pull requests in a repository with optional state filtering.
Parameters:
repo(required): Repository slugstate(optional): Filter by state -OPEN,MERGED,DECLINED,SUPERSEDED(if not specified, defaults toOPEN)
Example:
{
"repo": "myrepo",
"state": "OPEN"
}The server wraps the following Bitbucket Cloud REST API v2.0 endpoints:
| MCP Tool | HTTP Method | Bitbucket API Endpoint |
|---|---|---|
| CreatePullRequest | POST | /repositories/{workspace}/{repo}/pullrequests |
| UpdatePullRequest | PUT | /repositories/{workspace}/{repo}/pullrequests/{pr_id} |
| GetPullRequest | GET | /repositories/{workspace}/{repo}/pullrequests/{pr_id} |
| ListPullRequests | GET | /repositories/{workspace}/{repo}/pullrequests |
Base URL: https://api.bitbucket.org/2.0
# Clone the repository
git clone https://github.com/kubis1982/BitbucketMCP.git
cd BitbucketMCP
# Build the project
dotnet build
# Run tests (if available)
dotnet test
# Publish for deployment
dotnet publish -c Release -o ./publish# Build the stdio transport Docker image
docker build -f stdio/Dockerfile -t bitbucket-mcp:latest .
# Run the container in stdio mode (interactive)
docker run -i --rm \
-e BITBUCKET_USERNAME=your-username \
-e BITBUCKET_APP_PASSWORD=your-password \
-e BITBUCKET_WORKSPACE=your-workspace \
bitbucket-mcp:latestNote: The stdio image does not expose any ports and communicates via stdin/stdout.
# Build the HTTP transport Docker image
docker build -f http/Dockerfile -t bitbucket-mcp:http-latest .
# Run the container with port mapping for HTTP/SSE
docker run -d --rm \
-p 8080:8080 \
-e ASPNETCORE_URLS="http://+:8080" \
-e BITBUCKET_USERNAME=your-username \
-e BITBUCKET_APP_PASSWORD=your-password \
-e BITBUCKET_WORKSPACE=your-workspace \
bitbucket-mcp:http-latestProblem: 401 Unauthorized errors
Solution:
- Verify your credentials are correct
- For app passwords, ensure you're using your Bitbucket username (not email)
- Check that app password has required permissions
Problem: Cannot connect to Bitbucket API
Solution:
- Check internet connectivity
- Verify firewall settings allow HTTPS outbound connections
- Ensure
https://api.bitbucket.orgis accessible
Problem: MCP client cannot communicate with server
Solution:
- Verify server is running and listening on correct port (5000 local, 8080 Docker)
- Ensure MCP client is configured with correct HTTP endpoint URL
- Check that client is sending
Accept: text/event-streamheader - Verify firewall allows connections on the server port
- Check server logs for error messages (use
docker logsor console output) - Validate JSON-RPC message format in MCP protocol communication
BitbucketMCP/
├── src/
│ └── BitbucketMCP/
│ ├── Configuration/ # Configuration models
│ ├── Tools/ # MCP tool implementations
│ └── Program.cs # Application entry point + DI + inline auth providers
├── http/
│ └── Dockerfile # HTTP transport Docker configuration
├── stdio/
│ └── Dockerfile # Stdio transport Docker configuration
├── docker-compose.yml # Docker Compose setup
└── README.md # This file
- HTTP/SSE Transport: Server uses ASP.NET Core with Streamable HTTP transport (MCP SDK 1.2.0+)
- Inline Authentication: Custom authentication providers are defined as file-scoped classes in
Program.cs - Simplified DI:
Program.csregisters only the Kiota client and authentication; Tools receive the client via constructor injection - Type Safety: Full IntelliSense and compile-time checking for all API operations
- Docker Ready: Uses
mcr.microsoft.com/dotnet/aspnet:10.0runtime image with port 8080 exposed
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Model Context Protocol C# SDK
- Uses .NET 10