Add code
This commit is contained in:
334
README.md
334
README.md
@@ -1,162 +1,264 @@
|
||||
<div align="center">
|
||||
|
||||
# Bitbucket MCP Server
|
||||
|
||||
MCP (Model Context Protocol) server for AI agents to interact with **Bitbucket Cloud Pull Requests**.
|
||||
**A Model Context Protocol server for AI agents to interact with Bitbucket Cloud Pull Requests**
|
||||
|
||||
## Features
|
||||
[](https://nodejs.org/)
|
||||
[](https://www.typescriptlang.org/)
|
||||
[](https://modelcontextprotocol.io/)
|
||||
[](LICENSE)
|
||||
|
||||
- ✅ List pull requests in repositories
|
||||
- ✅ Get detailed PR information
|
||||
- ✅ Get PR activities/events
|
||||
- ✅ Get PR changes (files modified)
|
||||
- ✅ Get PR comments and individual comments
|
||||
- ✅ Get PR commits
|
||||
- ✅ Get PR diff and patch
|
||||
- ✅ Get PR participants and reviewers
|
||||
- ✅ Get PR status/state
|
||||
- ✅ Get PR tasks
|
||||
- ✅ Flexible credential configuration (env var or .env file)
|
||||
- ✅ Rate limiting protection
|
||||
- ✅ Error handling and retry logic
|
||||
</div>
|
||||
|
||||
## Installation
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This MCP server exposes **read-only** Bitbucket Cloud Pull Request operations as tools that AI agents (Claude, etc.) can invoke over stdio. It connects your AI workflow directly to your Bitbucket repositories.
|
||||
|
||||
### Capabilities
|
||||
|
||||
| Category | Operations |
|
||||
|----------|-----------|
|
||||
| **Pull Requests** | List, get details, get full expanded PR |
|
||||
| **Code Review** | Diff, patch, file changes, commits |
|
||||
| **Collaboration** | Comments, activities, participants, reviewers |
|
||||
| **Workflow** | Status, tasks, task count |
|
||||
| **Auth** | Token validation |
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js **24.13+** (see `.nvmrc`)
|
||||
- A Bitbucket Cloud [App Password](https://bitbucket.org/account/settings/app-passwords/) with **repository read** permissions
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd bitbucket-mcp
|
||||
npm install
|
||||
```
|
||||
|
||||
## Configuration
|
||||
### Configuration
|
||||
|
||||
### Credentials Sources (Priority Order)
|
||||
Create a `.env` file in the project root:
|
||||
|
||||
1. **Environment Variables** (highest priority):
|
||||
```bash
|
||||
export BITBUCKET_MCP_EMAIL=your_email@example.com
|
||||
export BITBUCKET_MCP_TOKEN=your_token_here
|
||||
```
|
||||
```env
|
||||
BITBUCKET_MCP_EMAIL=your_email@example.com
|
||||
BITBUCKET_MCP_TOKEN=your_app_password
|
||||
|
||||
2. **.env file** in project root:
|
||||
```
|
||||
BITBUCKET_MCP_EMAIL=your_email@example.com
|
||||
BITBUCKET_MCP_TOKEN=your_token_here
|
||||
```
|
||||
# Optional defaults (avoids passing workspace/repo on every call)
|
||||
DEFAULT_WORKSPACE=my-workspace
|
||||
DEFAULT_REPO=my-repo
|
||||
```
|
||||
|
||||
3. **Interactive prompt** (development fallback)
|
||||
|
||||
### Getting Your Access Token
|
||||
|
||||
1. Go to [Bitbucket Applications](https://bitbucket.org/account/applications/)
|
||||
2. Click "New application" or select existing
|
||||
3. Set callback URL to `http://localhost:8080` (or any placeholder)
|
||||
4. Copy the **Access token**
|
||||
|
||||
**Note:** Bitbucket uses Basic Authentication with your email as username and the access token as password.
|
||||
|
||||
## Usage
|
||||
|
||||
### Start the Server
|
||||
Or export as environment variables (takes priority over `.env`):
|
||||
|
||||
```bash
|
||||
export BITBUCKET_MCP_EMAIL=your_email@example.com
|
||||
export BITBUCKET_MCP_TOKEN=your_app_password
|
||||
```
|
||||
|
||||
### Run
|
||||
|
||||
```bash
|
||||
# Production
|
||||
npm start
|
||||
# Or for development:
|
||||
|
||||
# Development (hot reload)
|
||||
npm run dev
|
||||
|
||||
# Build
|
||||
npm run build
|
||||
```
|
||||
|
||||
The server will output:
|
||||
```
|
||||
✅ Bitbucket MCP Server started
|
||||
Name: bitbucket-pullrequests v1.0.0
|
||||
Token source: environment variable
|
||||
---
|
||||
|
||||
## MCP Client Configuration
|
||||
|
||||
### Claude Code
|
||||
|
||||
Add the following to your Claude Code MCP settings (`~/.claude/settings.json` or project `.claude/settings.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"bitbucket": {
|
||||
"command": "node",
|
||||
"args": [
|
||||
"/absolute/path/to/bitbucket-mcp/dist/index.js"
|
||||
],
|
||||
"env": {
|
||||
"BITBUCKET_MCP_EMAIL": "your_email@example.com",
|
||||
"BITBUCKET_MCP_TOKEN": "your_bitbucket_app_password",
|
||||
"DEFAULT_WORKSPACE": "your-workspace",
|
||||
"DEFAULT_REPO": "your-repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Available Tools
|
||||
### Claude Desktop
|
||||
|
||||
| Tool | Description | Parameters |
|
||||
|------|-------------|------------|
|
||||
| `list_pull_requests` | List PRs in a repository | workspace, repository, state (optional), author (optional) |
|
||||
| `get_pull_request` | Get PR details | workspace, repository, pullRequestId |
|
||||
| `get_pull_request_activities` | Get PR activities/events | workspace, repository, pullRequestId, limit (optional), start (optional) |
|
||||
| `get_pull_request_changes` | Get files changed in PR | workspace, repository, pullRequestId, limit (optional), start (optional) |
|
||||
| `get_pull_request_comments` | Get all PR comments | workspace, repository, pullRequestId, limit (optional), start (optional) |
|
||||
| `get_pull_request_comment` | Get a specific PR comment | workspace, repository, pullRequestId, commentId |
|
||||
| `get_pull_request_commits` | Get commits in PR | workspace, repository, pullRequestId, limit (optional), start (optional) |
|
||||
| `get_pull_request_diff` | Get PR diff | workspace, repository, pullRequestId, path (optional), context (optional) |
|
||||
| `get_pull_request_patch` | Get PR patch | workspace, repository, pullRequestId |
|
||||
| `get_pull_request_participants` | Get PR participants | workspace, repository, pullRequestId |
|
||||
| `get_pull_request_reviewers` | Get PR reviewers | workspace, repository, pullRequestId |
|
||||
| `get_pull_request_status` | Get PR status/state | workspace, repository, pullRequestId |
|
||||
| `get_pull_request_tasks` | Get PR tasks | workspace, repository, pullRequestId |
|
||||
| `get_pull_request_task_count` | Get PR task count | workspace, repository, pullRequestId |
|
||||
| `get_full_pull_request` | Get full PR details | workspace, repository, pullRequestId |
|
||||
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
|
||||
|
||||
### Example MCP Call
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"bitbucket": {
|
||||
"command": "node",
|
||||
"args": [
|
||||
"/absolute/path/to/bitbucket-mcp/dist/index.js"
|
||||
],
|
||||
"env": {
|
||||
"BITBUCKET_MCP_EMAIL": "your_email@example.com",
|
||||
"BITBUCKET_MCP_TOKEN": "your_bitbucket_app_password",
|
||||
"DEFAULT_WORKSPACE": "your-workspace",
|
||||
"DEFAULT_REPO": "your-repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** You must build the project first (`npm run build`) since the config points to `dist/index.js`. Use the **absolute path** to the compiled entry point. Setting `DEFAULT_WORKSPACE` and `DEFAULT_REPO` is optional but convenient — it lets you omit those parameters from every tool call.
|
||||
|
||||
---
|
||||
|
||||
## Available Tools
|
||||
|
||||
### Authentication
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `validate_token` | Verify credentials are valid |
|
||||
|
||||
### Pull Request Discovery
|
||||
|
||||
| Tool | Description | Key Parameters |
|
||||
|------|-------------|----------------|
|
||||
| `list_pull_requests` | List PRs in a repository | `workspace`, `repository`, `state?`, `author?` |
|
||||
| `get_pull_request` | Get PR summary | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_full_pull_request` | Get PR with all fields expanded | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_status` | Get PR state (open/merged/declined) | `workspace`, `repository`, `pullRequestId` |
|
||||
|
||||
### Code Changes
|
||||
|
||||
| Tool | Description | Key Parameters |
|
||||
|------|-------------|----------------|
|
||||
| `get_pull_request_diff` | Get unified diff | `workspace`, `repository`, `pullRequestId`, `path?`, `context?` |
|
||||
| `get_pull_request_patch` | Get raw patch file | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_changes` | List modified files | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_commits` | List commits in PR | `workspace`, `repository`, `pullRequestId` |
|
||||
|
||||
### Collaboration
|
||||
|
||||
| Tool | Description | Key Parameters |
|
||||
|------|-------------|----------------|
|
||||
| `get_pull_request_comments` | Get all comments | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_comment` | Get a specific comment | `workspace`, `repository`, `pullRequestId`, `commentId` |
|
||||
| `get_pull_request_activities` | Get activity feed | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_participants` | Get all participants | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_reviewers` | Get assigned reviewers | `workspace`, `repository`, `pullRequestId` |
|
||||
|
||||
### Tasks
|
||||
|
||||
| Tool | Description | Key Parameters |
|
||||
|------|-------------|----------------|
|
||||
| `get_pull_request_tasks` | Get PR tasks | `workspace`, `repository`, `pullRequestId` |
|
||||
| `get_pull_request_task_count` | Get task count | `workspace`, `repository`, `pullRequestId` |
|
||||
|
||||
> **Pagination:** Tools that return lists support `limit` and `start` parameters.
|
||||
|
||||
---
|
||||
|
||||
## Example
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "list_pull_requests",
|
||||
"arguments": {
|
||||
"workspace": "my-workspace",
|
||||
"repository": "my-repo",
|
||||
"workspace": "my-team",
|
||||
"repository": "backend-api",
|
||||
"state": "open"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
Response:
|
||||
|
||||
### list_pull_requests(workspace, repository, options?)
|
||||
```json
|
||||
{
|
||||
"pull_requests": [
|
||||
{
|
||||
"id": 42,
|
||||
"title": "feat: add user authentication",
|
||||
"state": "OPEN",
|
||||
"author": { "display_name": "Jane Doe" },
|
||||
"source": { "branch": { "name": "feature/auth" } },
|
||||
"destination": { "branch": { "name": "main" } }
|
||||
}
|
||||
],
|
||||
"count": 1
|
||||
}
|
||||
```
|
||||
|
||||
List pull requests in a repository.
|
||||
|
||||
**Options:**
|
||||
- `state`: 'open' | 'closed' | 'all' (default: open)
|
||||
- `author`: Filter by author username
|
||||
|
||||
**Returns:** Array of pull request objects with metadata.
|
||||
|
||||
### get_pull_request(workspace, repository, pullRequestId)
|
||||
|
||||
Get detailed information about a specific pull request.
|
||||
|
||||
**Returns:** Complete PR object including title, description, source/destination branches, reviewers, etc.
|
||||
|
||||
### merge_pull_request(workspace, repository, pullRequestId, options?)
|
||||
|
||||
Merge a pull request into the target branch.
|
||||
|
||||
**Options:**
|
||||
- `mergeStrategy`: 'merge' | 'squash' | 'fastforward' (default: merge)
|
||||
- `deleteSourceBranch`: boolean (default: false)
|
||||
|
||||
### create_pull_request(workspace, repository, title, description, sourceBranch, destinationBranch)
|
||||
|
||||
Create a new pull request.
|
||||
|
||||
**Returns:** Created PR object with ID and URL.
|
||||
|
||||
## Error Handling
|
||||
|
||||
The server handles the following errors:
|
||||
|
||||
| Error | Cause |
|
||||
|-------|-------|
|
||||
| `AuthenticationFailed` | Invalid or expired token |
|
||||
| `RateLimited` | API rate limit exceeded (429) |
|
||||
| `RepositoryNotFound` | Workspace/repo doesn't exist |
|
||||
| `PRNotFound` | Pull request ID invalid |
|
||||
---
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
# Run tests
|
||||
npm test
|
||||
|
||||
# Run in development mode with hot reload
|
||||
npm run dev
|
||||
# Run tests in watch mode
|
||||
npm run test:watch
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
# Integration tests (requires valid credentials)
|
||||
npm run test:integration
|
||||
|
||||
# Type check
|
||||
npx tsc --noEmit
|
||||
|
||||
# Coverage report
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── index.ts # MCP server & tool schema definitions
|
||||
├── router.ts # Tool name → API method dispatcher
|
||||
├── bitbucket-client.ts # Axios HTTP client for Bitbucket Cloud API
|
||||
└── config.ts # Credential & default config loading
|
||||
tests/
|
||||
├── unit/ # Mocked unit tests
|
||||
└── integration/ # Live API tests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authentication Details
|
||||
|
||||
This server uses **HTTP Basic Authentication** with the Bitbucket Cloud REST API v2.0:
|
||||
|
||||
- **Username** = your Bitbucket email
|
||||
- **Password** = an [App Password](https://bitbucket.org/account/settings/app-passwords/)
|
||||
|
||||
Credential resolution order:
|
||||
1. Environment variables (`BITBUCKET_MCP_EMAIL` + `BITBUCKET_MCP_TOKEN`)
|
||||
2. `.env` file in project root
|
||||
3. Interactive prompt (development only)
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
[MIT](LICENSE)
|
||||
|
||||
Reference in New Issue
Block a user